Sorry, but you either have no stories or none are selected somehow.
If the problem persists, check the browser console, or the terminal you've run Storybook from.
The component failed to render properly, likely due to a configuration issue in Storybook. Here are some common causes and how you can address them:
This is a pre-release version and is not production ready. For new and ongoing projects, please refer to the latest Design System version.
All things need to be contained inside a container. The container limits the size of the content and centers it on the page.
<div class="container">...</div>
For accessibility reasons, form fields should always have a label linked via the id/for attributes. Screen-readers will announce the label when the input gets the focus. If there is no label, screen-reader users have no idea what the input should be, even if there is other text next to the field.
next.design-system.post.ch/?path=/docs/d83829b2-7de2-48d2-be64-07a80c9caef3--docs&story=Basic Input#d83829b2-7de2-48d2-be64-07a80c9caef3--basic-input
/?path=/story/d83829b2-7de2-48d2-be64-07a80c9caef3--basic-input&full=true
<label class="form-label" for="firstname">Firstname</label> <input type="text" id="firstname" class="form-control" />
To add space between input, you can use margin utilities.
next.design-system.post.ch/?path=/docs/d83829b2-7de2-48d2-be64-07a80c9caef3--docs&story=Vertical Spacing#d83829b2-7de2-48d2-be64-07a80c9caef3--vertical-spacing
/?path=/story/d83829b2-7de2-48d2-be64-07a80c9caef3--vertical-spacing&full=true
<div class="mb-16"> <label for="firstname">Firstname</label> <input type="text" id="firstname" class="form-control" /> </div> <div class="mb-16"> <label for="lastname">Lastname</label> <input type="text" id="lastname" class="form-control" /> </div>
If you want a form field to span the whole available width, you don't need a row nor a col. You only need those, if you want to place two things next to each other.
Simply use .row
and .col
to have the width distributed evenly between all inputs.
To make it responsive, you can add .row-cols-*
classes to the row (see Grid page).
next.design-system.post.ch/?path=/docs/d83829b2-7de2-48d2-be64-07a80c9caef3--docs&story=Row Simple#d83829b2-7de2-48d2-be64-07a80c9caef3--row-simple
/?path=/story/d83829b2-7de2-48d2-be64-07a80c9caef3--row-simple&full=true
<div class="row row-cols-1 row-cols-md-2"> <div class="col"> <label class="form-label" for="firstname">Firstname</label> <input type="text" id="firstname" class="form-control" /> </div> <div class="col"> <label class="form-label" for="lastname">Lastname</label> <input type="text" id="lastname" class="form-control" /> </div> </div>
For finer adjustment, you can also use the .col-*
classes (see Columns page) on your columns. For example for a 2/1 ratio, given that a row has twelve columns in total,
just add .col-8
and .col-4
to you two columns respectively.
next.design-system.post.ch/?path=/docs/d83829b2-7de2-48d2-be64-07a80c9caef3--docs&story=Col Simple#d83829b2-7de2-48d2-be64-07a80c9caef3--col-simple
/?path=/story/d83829b2-7de2-48d2-be64-07a80c9caef3--col-simple&full=true
<div class="row"> <div class="col-8"> <label class="form-label" for="city">City</label> <input type="text" id="city" class="form-control" /> </div> <div class="col-4"> <label class="form-label" for="state">State</label> <input type="text" id="state" class="form-control" /> </div> </div>
Some fields may not fit into the twelve row schema, they need a custom width. The PLZ field may
be one of those cases. Two .col
next to each other will have equal width. If one of the cols has the
.col-auto
class, this col is sized based on it's content. The other row is stretched to the container
width. With this setup, we can define a max-width on the input field to shrink it.
next.design-system.post.ch/?path=/docs/d83829b2-7de2-48d2-be64-07a80c9caef3--docs&story=Custom Width#d83829b2-7de2-48d2-be64-07a80c9caef3--custom-width
/?path=/story/d83829b2-7de2-48d2-be64-07a80c9caef3--custom-width&full=true
<div class="row"> <div class="col-auto"> <label class="form-label" for="zip">Zip</label> <input type="number" id="zip" class="form-control" style="max-width: 11ch" /> </div> <div class="col"> <label class="form-label" for="city">City</label> <input type="text" id="city" class="form-control" /> </div> </div>
Buttons, often at the end of the form are right aligned. We can achieve this with the classes d-flex flex-row-reverse
. This will ensure that the primary button is focused first (because of the markup order) but is
still aligned to the right. To get some margin between the button we can use the .gap-8
class. Note that for the buttons, we don't need any row/col structure.
<div class="mb-16"> <label for="firstname">Firstname</label> <input type="text" id="firstname" class="form-control" /> </div> <div class="d-flex flex-row-reverse gap-8"> <button class="btn btn-primary">Send</button> <button class="btn btn-secondary">Cancel</button> </div>
For internet applications, bigger input fields with floating labels are the Post way of creating
forms. The particularity of these fields, is that the <label>
and <input>
elements are inverted and wrapped in a .form-floating
div.
In addition, the input field needs a placeholder attribute, preferably equal to a single space.
next.design-system.post.ch/?path=/docs/d83829b2-7de2-48d2-be64-07a80c9caef3--docs&story=Floating Labels#d83829b2-7de2-48d2-be64-07a80c9caef3--floating-labels
/?path=/story/d83829b2-7de2-48d2-be64-07a80c9caef3--floating-labels&full=true
<div class="row"> <div class="col"> <div class="form-floating"> <input type="text" id="firstname" class="form-control" placeholder=" " /> <label class="form-label" for="firstname">Firstname</label> </div> </div> <div class="col"> <div class="form-floating"> <input type="text" id="lastname" class="form-control" placeholder=" " /> <label class="form-label" for="lastname">Lastname</label> </div> </div> </div>
Validation messages are placed directly after the <input>
(or after the <label>
in the case of floating label). Showing and hiding of these messages is typically controlled by
adding and removing validation classes on the input:
.invalid-feedback/.valid-feedback
.was-validated
. With this class you can manage when to display errors. Usually, errors should not be
shown on untouched fields.Or
The input field needs the class .is-invalid/.is-valid
next.design-system.post.ch/?path=/docs/d83829b2-7de2-48d2-be64-07a80c9caef3--docs&story=Validation#d83829b2-7de2-48d2-be64-07a80c9caef3--validation
/?path=/story/d83829b2-7de2-48d2-be64-07a80c9caef3--validation&full=true
<form action="/"> <!-- Form Control --> <div class="row mb-16"> <div class="col-md-6"> <div class="form-floating"> <input id="formControlInvalid" type="text" class="form-control is-invalid" placeholder=" " required="" /> <label class="form-label" for="formControlInvalid">Invalid Input</label> <p class="invalid-feedback">Error message</p> </div> </div> <div class="col-md-6"> <div class="form-floating"> <input id="FormControlValid" type="text" class="form-control is-valid" placeholder=" " value="Value" /> <label class="form-label" for="FormControlValid">Valid Input</label> <p class="valid-feedback">Success message (optional)</p> </div> </div> </div> <!-- Form Select --> <div class="row mb-16"> <div class="col-md-6"> <div class="form-floating"> <select id="FormSelectInvalid" class="form-select is-invalid" required=""></select> <label class="form-label" for="FormSelectInvalid">Invalid Select</label> <p class="invalid-feedback">Error message</p> </div> </div> <div class="col-md-6"> <div class="form-floating"> <select id="FormSelectValid" class="form-select is-valid"> <option disabled="">Select one..</option> <option value="1">Value 1</option> <option value="2">Value 2</option> </select> <label class="form-label" for="FormSelectValid">Valid Select</label> <p class="valid-feedback">Success message (optional)</p> </div> </div> </div> <!-- Form Select Multiple--> <div class="row mb-16"> <div class="col-md-6"> <div class="form-floating"> <select id="FormSelectMultipleInvalid" class="form-select is-invalid" multiple="" required="" ></select> <label class="form-label" for="FormSelectMultipleInvalid"> Invalid Select Multiple </label> <p class="invalid-feedback">Error message</p> </div> </div> <div class="col-md-6"> <div class="form-floating"> <select id="FormSelectMultipleValid" class="form-select is-valid" multiple=""> <option value="1">Value 1</option> <option value="2">Value 2</option> </select> <label class="form-label" for="FormSelectMultipleValid">Valid Select Multiple</label> <p class="valid-feedback">Success message (optional)</p> </div> </div> </div> <!-- Form File --> <div class="row mb-16"> <div class="col-md-6"> <div class="form-floating"> <input id="FormFileInvalid" type="file" class="form-control is-invalid" required="" /> <label class="form-label" for="FormFileInvalid">Invalid File</label> <p class="invalid-feedback">Error message</p> </div> </div> <div class="col-md-6"> <div class="form-floating"> <input id="FormFileValid" type="file" class="form-control is-valid" /> <label class="form-label" for="FormFileValid">Valid File</label> <p class="valid-feedback">Success message (optional)</p> </div> </div> </div> <!-- Form Textarea --> <div class="row mb-16"> <div class="col-md-6"> <div class="form-floating"> <textarea id="FormTextareaInvalid" type="text" class="form-control is-invalid" placeholder=" " required="" ></textarea> <label class="form-label" for="FormTextareaInvalid">Invalid Textarea</label> <p class="invalid-feedback">Error message</p> </div> </div> <div class="col-md-6"> <div class="form-floating"> <textarea id="FormTextareaValid" type="text" class="form-control is-valid" placeholder=" "> Value </textarea > <label class="form-label" for="FormTextareaValid">Valid Textarea</label> <p class="valid-feedback">Success message (optional)</p> </div> </div> </div> <!-- Form Checkbox --> <div class="row mb-16"> <div class="col-md-6"> <div class="form-check"> <input class="form-check-input is-invalid" id="FormCheckboxInvalid" type="checkbox" /> <label class="form-check-label" for="FormCheckboxInvalid">Invalid Checkbox</label> <p class="invalid-feedback">Error message</p> </div> </div> <div class="col-md-6"> <div class="form-check"> <input class="form-check-input is-valid" id="FormCheckboxValid" type="checkbox" checked="" /> <label class="form-check-label" for="FormCheckboxValid">Valid Checkbox</label> <p class="valid-feedback">Success message (optional)</p> </div> </div> </div> <!-- Form Radio --> <div class="row mb-16"> <div class="col-md-6"> <div class="form-check"> <input class="form-check-input is-invalid" id="FormRadioInvalid" type="radio" /> <label class="form-check-label" for="FormRadioInvalid">Invalid Radio</label> <p class="invalid-feedback">Error message</p> </div> </div> <div class="col-md-6"> <div class="form-check"> <input class="form-check-input is-valid" id="FormRadioValid" type="radio" checked="" /> <label class="form-check-label" for="FormRadioValid">Valid Radio</label> <p class="valid-feedback">Success message (optional)</p> </div> </div> </div> <!-- Form Range --> <div class="row mb-16"> <div class="col-md-6"> <div class=""> <label class="form-label" for="FormRangeInvalid">Invalid Range</label> <input class="form-range is-invalid" id="FormRangeInvalid" type="range" /> <p class="invalid-feedback">Error message</p> </div> </div> <div class="col-md-6"> <div class=""> <label class="form-label" for="FormRangeValid">Valid Range</label> <input class="form-range is-valid" id="FormRangeValid" type="range" /> <p class="valid-feedback">Success message (optional)</p> </div> </div> </div> <!-- Form Switch --> <div class="row mb-16"> <div class="col-md-6"> <div class="form-check form-switch"> <input id="FormSwitchInvalid" class="form-check-input is-invalid" type="checkbox" role="switch" /> <label class="form-check-label" for="FormSwitchInvalid">Invalid Switch</label> <p class="invalid-feedback">Error message</p> </div> </div> <div class="col-md-6"> <div class="form-check form-switch"> <input id="FormSwitchValid" class="form-check-input is-valid" type="checkbox" role="switch" checked="" /> <label class="form-check-label" for="FormSwitchValid">Valid Switch</label> <p class="valid-feedback">Success message (optional)</p> </div> </div> </div> </form>
Hints can help users better understand the type of information they need to provide. Hints, like
validation messages, must be placed after the <input>
(or <label>
in the case of floating label) and after validation messages if there are some.
Hints use the class .form-hint
.
To enable screen-readers to detect and read your hints, link the <input>
with the aria-describedby attribute to the hint via id.
next.design-system.post.ch/?path=/docs/d83829b2-7de2-48d2-be64-07a80c9caef3--docs&story=Hints#d83829b2-7de2-48d2-be64-07a80c9caef3--hints
/?path=/story/d83829b2-7de2-48d2-be64-07a80c9caef3--hints&full=true
Also provide any middle names in this field
<div class="form-floating"> <input type="text" id="firstname" aria-describedby="firstname-hint" class="form-control" placeholder=" " /> <label class="form-label" for="firstname">Firstname</label> <p id="firstname-hint" class="form-hint">Also provide any middle names in this field</p> </div>
The form footer is placed at the end/bottom of a form or a form step, in case the form is splitted with a stepper. It provides workflow-related actions to the form or form step.
<div class="form-footer"> <div class="form-footer-primary-actions"> <button class="btn btn-primary"> Send<post-icon aria-hidden="true" name="3020"></post-icon> </button> <button class="btn btn-secondary">Cancel</button> </div> <button class="btn btn-tertiary px-0"> <post-icon aria-hidden="true" name="3024"></post-icon>Back </button> </div>