Zostel
Forms Form

Form

Fields, checks and errors that say what to fix — built on react-hook-form, or by hand as in the preview.

Preview

Usage

tsx
import { useForm } from "react-hook-form";
import {
  Form, FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage,
  Input, Checkbox, Button,
} from "zostel-ui";

const form = useForm({ defaultValues: { email: "", news: false } });

<Form {...form}>
  <form onSubmit={form.handleSubmit(send)} className="space-y-4">
    <FormField
      control={form.control}
      name="email"
      rules={{ required: "Add an email." }}
      render={({ field }) => (
        <FormItem>
          <FormLabel>Email</FormLabel>
          <FormControl><Input type="email" placeholder="you@example.com" {...field} /></FormControl>
          <FormDescription>We'll write when your bed is ready.</FormDescription>
          <FormMessage />
        </FormItem>
      )}
    />
    {/* a Checkbox (or Switch, RadioGroupItem) takes FormControl's id and aria-labelledby: FormLabel names it */}
    <FormField
      control={form.control}
      name="news"
      render={({ field }) => (
        <FormItem className="flex items-center gap-2 space-y-0">
          <FormControl><Checkbox checked={field.value} onCheckedChange={field.onChange} /></FormControl>
          <FormLabel>Send me news from the road</FormLabel>
        </FormItem>
      )}
    />
    <Button type="submit">Send</Button>
  </form>
</Form>

Parts

Form
Type: FormProvider
Default: —

Spread the useForm() result into it.

FormField
Type: { control, name, rules?, render }
Default: —

One field (react-hook-form Controller).

FormItem
Type: div
Default: —

Groups a label, control, description and message; links their ids.

FormLabel
Type: Label
Default: —

Turns destructive when the field has an error.

FormControl
Type: Slot
Default: —

Wraps the control (an Input, a Checkbox, a Switch, a RadioGroupItem): gives it the field’s id (FormLabel’s htmlFor) and, with a FormLabel in the item, aria-labelledby, so the label names it the way axe counts too; sets aria-invalid and aria-describedby.

FormDescription
Type: p
Default: —

A hint under the field.

FormMessage
Type: p
Default: —

The field’s error, when there is one.

useFormField
Type: hook
Default: —

The ids and state of the field it is used in.