Skip to content

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.

Input — every size and every stateOpen in the workshop

Sizes across, states down.

  • 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 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">
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. —

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.

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.

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.

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.