Field
Form field wrapper combining label, helper text, and error message. Compose with Input, Textarea, and other form controls.
We'll never share your email.
Installation
npx asteria-ui add fieldUsage
import { Field } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
<Field label="Email" description="We'll never share your email.">
<Input placeholder="you@example.com" />
</Field>Field takes label/description/error as props rather than child slots —
that's a deliberate match to how the real spec models it, not a shortcut.
The one genuinely swappable part, the control itself, is composed in as
children and gets id, aria-describedby, aria-invalid, and error
wired onto it automatically.
Examples
Error state
Enter a valid email address.
With Textarea
Field isn't Input-specific — it composes with any control that accepts
id/aria-describedby/aria-invalid/error.
Shown on your public profile.
API reference
| Prop | Type | Default | Description |
|---|---|---|---|
| label | ReactNode | — | Linked to the control via for/id. |
| description | ReactNode | — | Helper text, wired into the control's aria-describedby. |
| error | ReactNode | — | Error message. When present, sets aria-invalid on the control and adds its id to aria-describedby alongside the description. |
| children | ReactElement | — | A single form control (Input, Textarea, ...) — receives id, aria-describedby, aria-invalid, and error automatically via cloneElement. |
Accessibility
Accessibility
Label. Linked to the control via a generated
idandhtmlFor— clicking the label focuses the control.Helper text. Wired into the control's
aria-describedbyonly when present, so there's never a dangling reference to an element that doesn't exist.Error. Sets
aria-invalidon the control and adds the error message's id toaria-describedbyalongside the description, if both are present.