Fieldset
Groups related fields under a shared legend so the relationship is announced to
assistive tech. Built on Base UI Fieldset, it renders a native <fieldset>
and links the legend to it via aria-labelledby.
Import
import { Fieldset } from "@photon-ai/pho-ui/components/fieldset";
Basic
Fieldset.Legend titles the group; place any fields inside Fieldset.Root.
<Fieldset.Root>
<Fieldset.Legend>Billing address</Fieldset.Legend>
<Input label="Street" />
<Input label="City" />
</Fieldset.Root>
Disabled
disabled on Fieldset.Root turns off every control in the group at once — it
flows through both the native <fieldset disabled> and Base UI Field, so
contained Inputs dim and block input together.
<Fieldset.Root disabled>
<Fieldset.Legend>Billing address</Fieldset.Legend>
<Input label="Street" />
<Input label="City" />
</Fieldset.Root>
Anatomy
- Fieldset.Root — the group container; renders
<fieldset>and owns the shareddisabledstate. - Fieldset.Legend — the group title, linked to the fieldset via
aria-labelledby.
Props
Fieldset.Root
- disabled —
boolean(defaultfalse) — disable every contained field at once - className —
string— class applied to the<fieldset> - …native
<fieldset>attributes —children,aria-*, … forwarded to the element
Fieldset.Legend
- className —
string— class applied to the legend - children —
ReactNode— the group title - …native attributes — forwarded to the element
Accessibility
- Grouping —
Fieldset.Rootrenders a native<fieldset>and points itsaria-labelledbyat the legend, so assistive tech announces the group name when focus enters any field inside it. - Legend —
Fieldset.Legendrenders as an associated label element; keep it a short noun phrase so the announcement stays tight. - Disabled —
disabledsets the native<fieldset disabled>and propagates through Base UIField, so every contained control is disabled and removed from the tab order together.
The fieldset has no interactions of its own — keyboard focus moves through the contained fields as normal.
Best practices
- Group fields that form one logical unit — an address, a date range, a set of preferences. Don’t wrap a lone field in a fieldset.
- Keep the legend a short noun phrase (“Billing address”), not a sentence.
- Reach for
disabledon theRootto gate a whole section (e.g. until a toggle is on) rather than disabling each field by hand. - For a whole multi-section form, nest fieldsets under a
Formrather than inventing your own headings.