Forms and overlays
A form is a column of fields and one verb. Which control a field takes is decided by what the value is — free text, one of a known set, one of a long list, a date, a paragraph. Whether the form is a page, a sheet beside the page or a dialog over it is decided by whether the person has to answer before going on. MAFO’s Dashboard controls, its OKR dialog and the Click Cap page’s create and edit dialog are built this way.
Beta · Pattern · field.css · label.css · input.css · select.css and 9 more · in use on MAFO’s Dashboard controls and Click Cap dialogs
Field · Label · Input · Select · Combobox · Date picker · Textarea · Dialog · Alert dialog · Sheet · Dropdown menu · Icon button · Button
Composed from the markup blocks at the top of dialog.css, field.css, date-picker.css and button.css, on the static scrim the specimen uses. Cancel first, the verb last; the fields read dd/mm/yyyy; a month-only picker is a later component, so a day snaps to its month. The dates are placeholders.
Select OKR month range
Whole months — a day picked on either calendar snaps to its month.
What it is for
Section titled “What it is for”Use when any control that needs a visible label — one Field per control, stacked in a form with the form’s own gap. Do not use when the control sits in a table cell or a toolbar where the column or the icon is the label; for a group of checkboxes or radios (that is a fieldset with a legend, coming with the Checkbox family). A form on a product screen sits in a card or a dialog; a form on the site is the page itself. In either, the column is one field wide, the label keeps one size at every control size (field.css), and the verb is at the end.
The components it is made of
Section titled “The components it is made of”One row per part: its job here, and when the part itself is the one to use. Its own page holds the rest — the markup, the modifiers, the measured rows.
| Component | Its job in the arrangement | Use it when |
|---|---|---|
| Field | one control, its label above, its helper or its error below | any control that needs a visible label — one Field per control, stacked in a form with the form’s own gap |
| Label | a control’s name where the Field wrapper is too much — a switch row, an inline control | a control needs a visible name without the Field wrapper — a checkbox or switch row, a radio group’s items, an inline control in a toolbar or a dialog |
| Input | free text, one line | free text, one line |
| Select | one of a known set | one option from a list too long to show as radios — about seven or more — or when space is tight |
| Combobox | one of a list long enough to search — the typed searches MAFO still runs on react-select | one choice from a list long enough to search — accounts, offers, people, countries — roughly twenty or more, or any list the user knows by name |
| Date picker | a date or a range — typed as dd/mm/yyyy or picked on the calendar under the field | a form or a filter needs one date — a start, a deadline, a report day — or a range of them |
| Textarea | free text longer than a line | free text longer than a line — a message, a description, a note |
| Dialog | a question that must be answered before going on — a card over the scrim | the user must answer before going on — confirm, name, choose, send |
| Alert dialog | an action that cannot be undone — Cancel and one confirming verb | an action cannot be undone or costs something (delete, leave, overwrite, spend) and the person must confirm it knowingly |
| Sheet | a task that belongs beside the page and returns to it | a task belongs beside the page and returns to it — filters on a Data table, a row’s detail with its fields, a settings group longer than a Popover holds |
| Dropdown menu | three or more actions off one control — the notifications, the user pill | three or more actions hang off one control — a row’s ⋯, a File or Export button, the user pill, a right-click on a table row (Context menu: the same menu at the pointer) |
| Icon button | the ghost close in a dialog’s header; the round trigger in a top bar | a toolbar, a table row’s actions, a dialog’s close, a topbar’s notifications — an action whose icon is universally read (close, edit, delete, search, more) |
| Button | the footer: the secondary first, the verb last | the one action a view exists for — submit, save, create |
The rules that hold between them
Section titled “The rules that hold between them”- Which control a value takes. Input — free text, one line. Select — one option from a list too long to show as radios — about seven or more — or when space is tight. Combobox — one choice from a list long enough to search — accounts, offers, people, countries — roughly twenty or more, or any list the user knows by name. Date picker — a form or a filter needs one date — a start, a deadline, a report day — or a range of them. Textarea — free text longer than a line — a message, a description, a note.
- One Field per control; the label above, the helper or the error below. Any control that needs a visible label — one Field per control, stacked in a form with the form’s own gap.
- No asterisk. Ever. “(optional)” in the label, never an asterisk; error text says what to do, not what the label says.
- And the label’s own list. Never: an asterisk for required · a label in ALL CAPS or Title Case (Writing rules) · a label that is a sentence · a label with no control · a colour changed on the instance.
- Dates are dd/mm/yyyy, typed or picked. Mm/dd/yyyy nowhere in the house; the browser’s own popup never.
- What a date picker never is. Never: the browser’s own calendar popup (the reason this exists) · a picker with no typed way in · a range on one month · mm/dd/yyyy anywhere in the house · a fill changed on the instance.
- A Native select is never on a product screen. Not when: the page runs the design system’s JavaScript (that is Select); the list needs search or typing (Combobox); the options are few enough to show (Radio); on any deck-tool or MAFO screen.
- When a task is a dialog, a sheet or a page. Dialog — the user must answer before going on — confirm, name, choose, send; not when the content is a whole task (a page or a Sheet), the message needs no answer (Alert, Toast), or the surface anchors to a trigger (Popover). Sheet — a task belongs beside the page and returns to it — filters on a Data table, a row’s detail with its fields, a settings group longer than a Popover holds. Alert dialog — an action cannot be undone or costs something (delete, leave, overwrite, spend) and the person must confirm it knowingly.
- The footer: the secondary first, the verb last. The Dialog’s footer is the secondary first and the verb last.
- What a dialog never does. Never: a dialog over a dialog · a dialog without a way out · three primaries in the footer · a title that is a sentence with a full stop · scrolling inside a small dialog.
- One primary per view. Not when: two actions compete (one primary per view, principle 1); for navigation (that is a link); for on/off (that is Toggle).
- And one primary per group. Never: two primaries in one group · a connected group of filled buttons · buttons of different sizes in one group · a row looped from Button with a hand-set gap instead of this component · more than five, which is a menu.
- A form’s inline action is the black button. Beside inputs or selects (the end of a filter row, a form’s inline action) the button is the black one, never the outlined secondary — an outline next to outlined controls reads as one more control.
- Three or more actions off one control are a menu. Three or more actions hang off one control — a row’s ⋯, a File or Export button, the user pill, a right-click on a table row (Context menu: the same menu at the pointer). more than one destructive row · a menu without a trigger · a two-level submenu · a menu that scrolls (split it — a notification list is the exception and may scroll) · a fill changed on the instance.
- The confirming button carries the verb, never OK. Never: OK / Cancel with no verb · a close X that pretends the question is optional · three or more buttons · a scary title with a friendly primary (Delete everything? — Continue) · using it for every save.
Pepper UI v1.5.0
The Mobupps design system. 386 tokens, 88 components, 65 pages in the workshop — every page of this site generated from the repository, so nothing here is typed twice.