Forms
Field
A labelled form row: label, control, and the one message below it.
Examples
states
We never share it.
Name is required.
Markdown is fine.
Notes
A labelled form row: label, control, and the one message below it.
The visible message is only half of accessible validation — it must also reach the control. This wires aria-describedby, aria-required and aria-invalid onto the single control child so the requirement and the error are announced, not merely drawn (WCAG 1.3.1 / 3.3.1 / 4.1.2).
An earlier version derived the message id from htmlFor, which meant a caller who left htmlFor off got a hint that was rendered and never announced — the failure was invisible in the browser and total for a screen reader. The id is now generated when it is not supplied.
hint and error are one slot, not two stacked messages: when a field is wrong, the thing to read is what is wrong with it.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| childrenrequired | ReactNode | — | |
| error | ReactNode | Validation message; takes precedence over `hint` when present. | |
| hint | ReactNode | Helper copy shown below the control when there is no `error`. | |
| htmlFor | string | The control's `id`. Optional: when omitted, the field generates one and puts it on the control child itself, so the label still points at something. Pass it explicitly when the id has to be stable across renders — a form library referencing it by name, say. | |
| label | ReactNode | Visible label text; renders a `--danger` asterisk when `required`. | |
| required | boolean | — |
Also accepts everything in HTMLAttributes<HTMLDivElement>. Those are forwarded to the underlying element and are not listed row by row.
Accessibility
- Generates an id when none is given, so the label always points at something.
- Wires aria-describedby, aria-required and aria-invalid onto the control, so validation is announced and not merely drawn.
- hint and error are one slot: when a field is wrong, the thing to read is what is wrong with it.