Input
A single-line text control, with an inline error state and an optional adornment.
import Input from '@/components/ui/Input';Source: src/components/ui/Input.tsx
Examples
Sizes and states
The error state, live
The border turns red and the message is linked by aria-describedby. It replaces the field’s help text rather than stacking under it.
Type something without an @ to see the error state.
Props
<Input> props
| Prop | Type | Default | Description |
|---|---|---|---|
size | 'sm' | 'md' | 'md' | — |
error | string | — | Shown below the field in red, switches the border to red and reveals the cross icon, matching the style guide's `.input__error`. |
icon | ReactNode | — | Adornment inside the field at the right edge — a plain <Icon .../> or an interactive <IconButton size="sm" .../> (30px, fits the 60px field). With an IconButton, widen the text inset via className="pr-[60px]" so long values don't run underneath it. Hidden while `error` shows its cross. |
Also accepts everything in Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> — so native attributes (id, onClick, aria-*, data-*) pass straight through.
Accessibility
- On focus the border turns navy-700 rather than losing its indicator.
- aria-invalid and aria-describedby are set whenever `error` is present.
Usage
Do
- Set the right `type` — email, tel, number. It changes the phone keyboard, which is most of the usability of a mobile form.
- Wrap it in a Field so it gets a real label.
Don’t
- Don’t use a placeholder as the label. It vanishes as soon as someone types, and it is not announced as a name.