Form
Composable form primitives built on react-hook-form, providing accessible labels, descriptions, and validation messages.
Install
npx shadcn@latest add https://atomx.acau.net/r/form.jsonInstalling form also installs the atomx label component as a registry dependency, since FormLabel composes it.
Usage
Form is a thin layer over react-hook-form. The exported Form is just FormProvider, and the other exports — FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage — wire react-hook-form's state into accessible markup automatically: associated htmlFor, aria-describedby, aria-invalid, and id management are handled for you via the useFormField hook.
A typical field looks like this:
<FormField
control={form.control}
name="username"
rules={{ required: "Username is required" }}
render={({ field }) => (
<FormItem>
<FormLabel>Username</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>Your public display name.</FormDescription>
<FormMessage />
</FormItem>
)}
/>FormControl uses Radix Slot, so any input-like child receives the generated id, aria-describedby, and aria-invalid. The FormMessage slot is empty when the field has no error; it renders the error message in text-destructive when validation fails.
Preview
A two-field form with built-in validation. Submit it empty to see error messages; submit with valid values to see the parsed result.
Exports
| Export | Type | Purpose |
|---|---|---|
Form | FormProvider from react-hook-form | Wraps the form tree so children can access the form context. |
FormField | Component | Wraps Controller; provides the field name to descendants via context. |
FormItem | Component | Generates a unique id and spaces label/control/description/message in a grid. |
FormLabel | Component | Renders an atomx Label, wired via htmlFor to the field's control. |
FormControl | Component | Renders a Radix Slot that forwards id, aria-describedby, and aria-invalid to its child. |
FormDescription | Component | Renders helper text below the control. |
FormMessage | Component | Renders the field's validation error (or its children if no error). |
useFormField | Hook | Returns the field's id, name, generated ids, and fieldState. Use it for custom field layouts. |