Text Field
Forms · TextField
Text input with label, required or optional mark, hint, and inline validation (error or success).
Props: label, required, optional, hint, error, success, icon (leading IconName), suffix (unit text), type, value, defaultValue, onChange, onBlur, disabled, readOnly, placeholder, autoComplete, autoFocus, id, name.
Native constraints go straight to the input, so the browser checks them and Form reads them: min, max and step (for type="number", dates and times), minLength, maxLength, pattern, and inputMode for the touch keyboard.
tsx
<TextField label="Seats" name="seats" type="number" min={1} max={50} step={1} required />
nameis the value's key inFormand where its validation message shows;requiredmarks the label and sets the native attribute.- Validate on blur, not on every key: show the error once the person leaves the field, then clear it live as they fix it.
- Error text says what is wrong in plain words ("That doesn’t look like an email address"), never "Invalid input".
- Use
successsparingly, for checks that took effort (a free username, a verified domain). - Mark the minority: if most fields are required, mark the optional ones instead.
FormFieldis the same shell without an input, for wrapping custom controls.
Looks good
That doesn’t look like an email address
Shown on invoices
EUR
Ask an owner to change it
Props
TextField
| Prop | Type | Notes |
|---|---|---|
type? | string | Input type (`"text"` by default): `"email"`, `"number"`, `"tel"`, `"url"`, `"password"` … |
icon? | IconName | |
suffix? | ReactNode | |
value? | string | |
defaultValue? | string | |
placeholder? | string | |
disabled? | boolean | |
readOnly? | boolean | |
autoComplete? | string | |
autoFocus? | boolean | |
min? | number | string | Smallest value for `type="number"`, `"date"` and the like (native `min`). |
max? | number | string | Largest value (native `max`). |
step? | number | string | Step between valid values (native `step`), e.g. `1` for whole numbers or `"any"`. |
minLength? | number | Fewest characters (native `minlength`). |
maxLength? | number | Most characters (native `maxlength`). |
pattern? | string | Pattern the value must match (native `pattern`). |
inputMode? | "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" | Virtual keyboard on touch devices (native `inputmode`), e.g. `"numeric"` or `"decimal"`. |
onChange? | (e: ChangeEvent<HTMLInputElement>) => void | |
onBlur? | (e: ChangeEvent<HTMLInputElement>) => void | |
onKeyDown? | (e: KeyboardEvent<HTMLInputElement>) => void | |
action? | ReactNode | An interactive control at the end of the field (an `IconButton`: clear, copy, locate …). Unlike `suffix` it can be clicked, and it stays when the field shows an error or success mark. |
reveal? | boolean | For `type="password"`: a button that shows and hides the password (default true). |
label? | string | |
hint? | string | |
error? | string |