An input field lets the user enter free text, numbers or search terms. It can have a label, a left icon, right-hand action icons and a message that explains or validates the value.
Tokens, sizes, measurements, states and requirements. Values come from the live token package and from Figma: Base Input.
Resolved from the live token package.
| State | Part | Token | Value |
|---|
Figma binds icon/disabled, which is not in tokens.json, so the disabled icon uses text-disabled (same value).
| Breakpoint · size | Height | Padding (left, right) | Left icon | Right icons | Label | Input text |
|---|---|---|---|---|---|---|
| Desktop · Large | 48px | 12px, 8px | 24px | Button (32px) | label-md 16/16, 0.48px | body-md 17/24, 0.32px |
| Desktop · Small | 40px | 8px, 4px | 20px | Button (32px) | label-sm 14/14, 0.56px | body-sm 14/20, 0.36px |
| Desktop · XSmall | 32px | 8px, 6px | 20px | Icon Button (20px) | label-sm 14/14, 0.56px | body-sm 14/20, 0.36px |
| Mobile · Large | 40px | 8px, 4px | 24px | Button (32px) | label-sm 12/12, 0.48px | body-md 16/22, 0.32px |
| Mobile · Small | 32px | 8px, 6px | 20px | Icon Button (20px) | label-sm 12/12, 0.48px | body-sm 14/20, 0.36px |
Right-hand icons are 20px in every size, but the component that holds them differs. A Button (eco-button, Blank, icon only, 6px padding = 32px, grey fill on hover) holds them on Desktop Large, Desktop Small and Mobile Large. An Icon Button (just the 20px icon, it turns grey on hover) holds them on Desktop XSmall and Mobile Small. Icon color is text-action-primary. Padding top and bottom comes from the fixed height. The 6px values and the 10px gap before the icons on Mobile Large are literals: there is no spacing token for them.
Padding of the input box at each size. The shaded areas are the padding to the left and right; the box is fixed in height, so there is no padding above or below. The numbers are read from the component.
| Attribute | Large | Small | XSmall |
|---|---|---|---|
| Height, Desktop | 48px | 40px | 32px |
| Height, Mobile | 40px | 32px | Not available (use Small) |
| Padding, left and right, Desktop | 12px, 8px | 8px, 4px | 8px, 6px |
| Padding, left and right, Mobile | 8px, 4px | 8px, 6px | Not available |
| Left icon | 24px | 20px | 20px |
| Gap, left icon to text | 8px | 8px | 8px |
| Border | 1px | ||
| Corners | Square | ||
| Divider | 1px × 16px | ||
The same padding and distances as spacing tokens.
| Part | Value |
|---|---|
| Label to box | space-4 |
| Box to message | space-4 |
| Padding left, Desktop Large | space-12 |
| Padding left, Large mobile and Small, XSmall | space-8 |
| Padding right, Desktop Large | space-8 |
| Padding right, Small desktop and Large mobile | space-4 |
| Padding right, XSmall and Small mobile | 6px: literal, no token |
| Gap between the icon and the text | space-8 |
| Gap between right icons | space-4 |
| Gap before the right icons | Large desktop and Small desktop space-4; Large mobile 10px (literal); XSmall, and Small mobile space-16 |
| Focus ring | 2px line, 3px outside the box |
All seven states from Figma, with and without icons. Hover and focus are forced on this page; in your code they come from :hover and keyboard focus. Active means the field has a value.
| State | Plain | Left icon | Left + right icons |
|---|
| Part | Type | Size / line height | Letter spacing | Weight |
|---|---|---|---|---|
| Label, Desktop Large | label-md | 16/16 | 0.48px | Bold, uppercase |
| Label, Desktop Small, XSmall | label-sm | 14/14 | 0.56px | Bold, uppercase |
| Label, Mobile | label-sm | 12/12 | 0.48px | Bold, uppercase |
| Input text, Large | body-md | 16/22 mobile, 17/24 from 769px | 0.32px | Regular |
| Input text, Small, XSmall | body-sm | 14/20 | 0.36px | Regular |
| Message | body-sm | 14/20 | 0.36px | Regular |
Breuer Condensed with ss02 and ss03 (the message also ss06). The placeholder and the message use text-tertiary.
| Element | Class | Notes |
|---|---|---|
| Field | form-field | Label, input wrapper and message in a column, 4px apart. |
| Label | form-label, form-label--sm | Uppercase. --sm for Small and XSmall. |
| Input wrapper | input-wrap | Carries the focus ring (2px, 3px outside the box). |
| Input box | input-box, --sm, --xs, --error, --success | Border, fill and height. Holds the icon, the input and the right icons. |
| Left icon | input-icon, --lg | Material Symbols. --lg is 24px (Large). |
| Input | form-input | The native input. |
| Right icons | input-actions, __btn, __clear, __divider | Clear shows only while the field has a value. |
| Message | form-helper, --error, --success, --disabled | Optional icon (input-icon). |
| Type | Left icon | Right icons |
|---|---|---|
| Plain | No | No |
| Left icon | Yes | No |
| Left and right icons | Yes | Clear, divider and action icons |
| Clear only | Optional | Clear |
| Actions only | Optional | Action icons (no clear, no divider) |
The field fills its container.
| Property | Duration | Easing |
|---|---|---|
opacity of the focus ring | duration-fast-3 | ease-standard |
| Input | Result |
|---|---|
| Type a value | The field becomes Active: black border and the clear button appears. |
| Clear button | Empties the field and returns focus to it. It is a real button with an aria-label. |
| Tab | The blue ring shows on keyboard focus only (body.keyboard-nav, set by a small script). |
| Hover on a right icon | Button: grey fill (surface-opacity-black-05). Icon Button: the icon turns text-action-primary-hover. |
| Disabled | Not focusable. Grey fill, light border, text-disabled for text, icons and message. |
| Topic | Requirement |
|---|---|
| Label | Always a label with for and id. Search fields without a visible label need an aria-label. |
| Error | Set aria-invalid="true" and point aria-describedby at the message. |
| Icon buttons | Real button elements with an aria-label. The decorative icons are aria-hidden="true". |
| Focus | A 2px ring on keyboard focus (border-focus), not on mouse click (WCAG 2.4.7, 1.4.11). |
| Color | Error and success are not shown by color alone: the message says it, and an icon helps. |
| Disabled | Not focusable. Disabled tokens are exempt from contrast requirements. |
Open point: multi-line text fields are a separate component: see Text area.