Home

Field, label and form

The frame around one form control: Field ties a FieldLabel, a FieldDescription and a FieldError to it, and Fieldset groups fields under a legend.

ui.fieldcomponents/ui/field.tsx

Use case

For the AI

Use it for every control in a form, so each has its label, its hint and its error in the same place: the company name and email on a new client form, the due date and terms on an invoice, a Delivery section on an order form. Field marks its control invalid and shows the error; Fieldset with a FieldsetLegend titles a section. When the server answers with errors by field name, Base UI's Form (components/ui/form) takes them through its errors prop, keyed by each Field's name.

Use it when

  • Any input, text area, number field or select in a form
  • A hint under a control (As it appears on invoices.)
  • An error under a control after it is checked
  • A titled section of a form (Fieldset)

Use something else when

  • An error about the whole form, not one control (Could not save): Alert
  • A short form that opens over the page: Dialog
  • A single search box above a list: Search field

Examples

Your company

As it appears on invoices.

Add the .com or .ca at the end.

Code

Import

import { Button } from "@/components/ui/button"
import { Field, FieldDescription, FieldError, FieldLabel } from "@/components/ui/field"
import { Fieldset, FieldsetLegend } from "@/components/ui/fieldset"
import { Input } from "@/components/ui/input"

Usage

<form className="grid gap-6" onSubmit={save}>
  <Fieldset className="grid gap-5">
    <FieldsetLegend className="text-[15px] font-medium">Your company</FieldsetLegend>
    <Field>
      <FieldLabel>Company name</FieldLabel>
      <Input name="company" placeholder="Atelier Nord" />
      <FieldDescription>As it appears on invoices.</FieldDescription>
    </Field>
    <Field invalid={Boolean(emailError)}>
      <FieldLabel>Email</FieldLabel>
      <Input name="email" type="email" placeholder="bonjour@ateliernord.ca" />
      {emailError && <FieldError match>{emailError}</FieldError>}
    </Field>
  </Fieldset>
  <div className="flex justify-end gap-2">
    <Button variant="ghost">Cancel</Button>
    <Button type="submit">Save Changes</Button>
  </div>
</form>

Rules

  • One control per Field; the Field ties the FieldLabel to it, so no htmlFor is needed.
  • Show an error by setting invalid on the Field and rendering FieldError match only while there is an error (match always shows it).
  • Labels, legends and descriptions in sentence case; the buttons in Title Case, the submit one with type="submit".
  • FieldsetLegend is semibold by default: give it className="text-[15px] font-medium", as the showcase does, since weights stop at 500.
  • A label for something outside a Field is Label (components/ui/label) with htmlFor.