Input
Text input — the bare control.
Beta · Forms · packages/css/src/components/input.css · React on Base UI: @pepperui/input
.pui-input · size --small --large · error aria-invalid="true" · :disabled. Icons belong to Input group; label, helper and error to Field.
Sizes across, states down.
What it is for
Section titled “What it is for”- Placeholder and Value are separate text properties — toggle Has placeholder / Has value
- Optional leading and trailing icons, off by default
- Three sizes mirroring Button’s padding steps (small 28 / medium 36 / large 44 — each hugs its text at 140% line-height) so a form row aligns within 2px of a Button
- Five states: default, hover, focus, error, disabled. Hover darkens the border to border/strong. Disabled is opacity 0.5
- The label, helper and error text belong to Field, which wraps this
Use when free text, one line.
Do not use when the value is one of a known set (Select, Combobox); it is multi-line (Textarea); it is a date (Date picker); it needs a label, helper or error text (that is Field).
Relates to Field (parent), Label, Input group (addons), Textarea (same chrome), Button (same sizes).
Anti-patterns a placeholder as the only label · an input narrower than its content · a border colour changed on the instance (fix the component) · ALL CAPS placeholder text.
Keywords: input, text field, textbox, form, control
Figma — page Input: Input (15 variants)
shadcn: input
The markup — copy this
Section titled “The markup — copy this”The class, the parts, and nothing that is not in the package. The same block opens input.css.
<input class="pui-input" type="text" aria-label="Search decks" placeholder="Search decks"> (a bare input needs a name: a <label for>, a Field, or aria-label)<input class="pui-input pui-input--small" aria-invalid="true">The modifiers
Section titled “The modifiers”| What it is | Note | |
|---|---|---|
| Size | --small 28 (12 px, 4 / 12) · (none) medium 36 (14 px, 8 / 12) · --large 44 (16 px, 12 / 16) | — |
| State | :hover · :focus · error = [aria-invalid=“true”], --error, :user-invalid (a red glow at rest, and the solid error ring when it also has focus) · :disabled | — |
| Icons | an Input has no children in HTML — a leading or trailing glyph is Input group (input-group.css), the box that holds an input with company. Label, helper and error text are Field’s. | — |
Accessibility — measured, not assumed
Section titled “Accessibility — measured, not assumed”Every number here is measured on the rendered component: contrast (npm run contrast:render), the focus ring (npm run focus) and the keyboard (npm run keyboard). The floors are principle 12’s.
Contrast
Section titled “Contrast”| ink on ground | reads | floor | the matrix calls it | |
|---|---|---|---|---|
#544d4d on #ffffff |
8.24 | 4.5 | text.muted on surface.page (promised) | ok |
#0b0202 on #ffffff |
20.51 | 4.5 | text.default on surface.page (promised) | ok |
2 distinct pair(s) rendered, 0 that axe calls a violation.
The focus ring
Section titled “The focus ring”| primitive | on | the indicator | over | the change | |
|---|---|---|---|---|---|
| Input | surface/page | shadow #6a66e4 2 px |
#ffffff |
4.53 | ok |
| Input | surface/card | shadow #6a66e4 2 px |
#f2f2f7 |
4.06 | ok |
| Input | surface/sunken | shadow #6a66e4 2 px |
#f2f2f2 |
4.05 | ok |
| Textarea | surface/page | shadow #6a66e4 2 px |
#ffffff |
4.53 | ok |
| Textarea | surface/card | shadow #6a66e4 2 px |
#f2f2f7 |
4.06 | ok |
| Textarea | surface/sunken | shadow #6a66e4 2 px |
#f2f2f2 |
4.05 | ok |
5 of 5 focus stop(s) in this block meet WCAG 2.4.13 on screen — the same crop screenshotted focused and unfocused, and the difference measured.
Keyboard
Section titled “Keyboard”Nothing in this component claims an ARIA role with a keyboard contract; its controls are ordinary ones and the browser already gives them their keys.
Tab order across the whole library is document order over 344 stops, and Shift+Tab is its exact reverse — no keyboard trap anywhere (WCAG 2.1.2).
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.