Input

Single-line text entry with labels, hints and honest validation.

v1.0.0·Updated Jul 8, 2026 · 10:45
Live Demo — Fully Interactive
Sizes
L · 44px
M · 36px
S · 28px
Configuration
Size
State
Icon
Label
Work email
<Input label="Work email" size="m" />
Behavior — The Engineering Contract
Props
PropTypeDefaultDescription
value / defaultValuestringControlled or uncontrolled content
typetext · email · password · number…textNative input type
labelstringLinked by htmlFor/id; always visible
hintstringHelper text below the field
statuserror · successValidation border + message colour
icon / affixReactNode / stringLeading glyph or trailing adornment
sizel · m · sm44 / 36 / 28px
disabled / readOnlybooleanfalseBlocks editing; read-only keeps focus
Events & keyboard
EventPayloadFires when
onChangeChangeEventEvery keystroke, paste and cut
onFocus / onBlurFocusEventFocus enters / leaves; validate on blur
EnterSubmits the surrounding form
aria-invalidbooleanSet true whenever status is error
Live behavior — every demo is real
Debounced AsyncGET /username
UsernameType 3+ characters.

Keystrokes are debounced 500ms; only the last one hits the network. A stale reply never overwrites a fresher one.

Controlled + Countvalue / onChange
Headline11/40

Fully controlled: the count and the limit warning react to every keystroke, never lagging the value.

Anatomy
Work email *We only use it to send receipts.
1Label & requiredMono caption, always present. A warm asterisk marks required fields.
2ContainerFixed height per size, radius 8, warm focus ring on focus-visible.
3Value / placeholderPlaceholder is a hint, never a substitute for the label.
4Helper / messageGuidance in calm grey; validation swaps it for green or red.
Do's and Don'ts
✓ Do
Email

Keep the label visible above the field. It stays legible once the field is filled.

✕ Don't

Don't rely on the placeholder as the label. It vanishes the moment someone types.

✓ Do
That address is missing an @.

Say what is wrong and how to fix it, in plain words, right under the field.

✕ Don't
Error 422: invalid input

Never make the reader decode a status code. The field is not a server log.

In context: Examples
A · In a form
Full nameWork email

Stacked fields, labels above, consistent width. One idea per row.

B · As search

Leading icon, no label needed. The placeholder carries the intent here.

C · With affix
BudgetUSD

Units and adornments sit inside as an affix, never in the value.

Measurements & Tokens
TokenValueRole
--in-height-l/m/s44 / 36 / 28pxMatches the button scale
--in-radius8px6px at size S
--in-bg#0E0F12Inset field surface
--in-border#242428Resting border
--in-text#E7E9EEEntered value
--in-placeholder#565A62Placeholder hint
--in-focusrgba(255,122,0,.6) + .14 glowWarm ring on focus
--in-error#EB4A4FInvalid border & message
--in-success#1FA35CValid border & message
--in-pad-icon38pxLeft pad with a leading icon
Code
<label class="o-field">
  <span class="o-field__label">Work email</span>
  <input class="o-input o-input--m" type="email" placeholder="you@company.com" />
  <span class="o-field__hint">We only use it to send receipts.</span>
</label>

<input class="o-input o-input--m is-error" aria-invalid="true" />