Field
Layout wrapper that pairs a form control with its label, description, and error.
Description
Field is the form-layout primitive of the design system. It renders a <div role="group"> and owns the shared context (size, orientation, invalid, disabled, loading) that every part inside it reads. It is a compound component: Field is the wrapper, and parts like FieldLabel, FieldDescription, FieldError, and FieldHelper slot inside it around a control.
Reach for it whenever a form control needs a label, helper text, or validation message. Wrap a single Input, Select, Textarea, Checkbox, Switch, or Slider in a Field so spacing, sizing, and error styling stay consistent. Use FieldGroup to stack several fields with even rhythm, and FieldSet with FieldLegend to label a related cluster (a set of checkboxes, a plan picker).
Don't use Field as the control itself. For the input, use Input; for the dropdown, use Select. For a multi-option group that shares one value, reach for RadioGroup or CheckboxGroup, which manage selection state. FieldSet groups form controls, not page sections; for page layout use your layout primitives.
Installation
Anatomy
Field sets the size and state context once; the parts inside it read that context instead of being sized one by one. FieldContent is optional and only needed when a label plus description sit beside a control (checkbox, switch) in a horizontal layout.
Group related fields, optionally under a legend:
Usage
Examples
Sizes
size is xs, sm, or md (sm is the default). It sets the density for the label, description, and the control inside, all from one prop on Field.
Orientation
orientation="vertical" stacks the label above the control. horizontal puts them on one row, which fits checkboxes and switches. responsive stacks on narrow containers and inlines once there is room.
Rich Label
FieldLabel accepts the Label parts as children: LabelIcon, LabelRequired, LabelOptional, and LabelBadgeSlot. Pair them with FieldHelper (which takes an icon) and FieldFooter for a supporting link.
Validation
Set invalid on Field and add a FieldError. Pass a single message as children, or hand FieldError an errors array and it renders a deduped bulleted list. Wire aria-invalid on the control so assistive tech announces the state.
Composition
Field works the same around any control. One size on each Field cascades to the Input, Select, Textarea, or Switch it wraps, so you set density once per field.
Rich Choice
For a checkbox or switch that carries an icon, a badge, a description, and a follow-up link, put the supporting content in FieldContent. Wrap the Label (with LabelIcon and LabelBadgeSlot) and its LabelDescription in LabelMain to keep them tightly grouped beside the control, then add a FieldFooter for the link. Reach for Label + LabelDescription here rather than FieldLabel + FieldDescription, since LabelMain is what binds a title to its description.
Grouping
FieldSet with FieldLegend variant="label" labels a cluster of related controls. Nest a FieldGroup inside to keep the spacing even.
Separator
FieldSeparator draws a divider between fields. Pass children to label it (e.g. or) for alternative-input flows.
Accessibility
Field is a layout group, not a focus target. Focus lands on the control inside it; Tab moves between controls in source order.
ARIA notes:
Fieldsetsrole="group"and mirrorsinvalid,disabled, andloadingtodata-*attributes so descendants can style off the shared state.- Wire
FieldLabel'shtmlForto the control'sidso clicking the label focuses the control and screen readers announce the name. FieldErrorrenders withrole="alert", so a newly shown error is announced. Setaria-invalidon the control to link it to the error visually and semantically.FieldSetandFieldLegendrender native<fieldset>/<legend>, which group the controls for assistive tech automatically.
Styling
Tailwind override: pass className to merge Tailwind classes with the component's CVA classes (via cn()):
Data slots and attributes: the parts set these for CSS targeting:
data-slot="field"on theFieldroot, withdata-size,data-orientation, anddata-invalid/data-disabled/data-loadingwhen active.data-slot="field-set"onFieldSet,data-slot="field-legend"onFieldLegend(withdata-variant),data-slot="field-group"onFieldGroup.data-slot="field-content"onFieldContent(withdata-size).data-slot="field-label"onFieldLabelandFieldTitle,data-slot="field-description"onFieldDescription.data-slot="field-helper"onFieldHelper(withdata-tone),data-slot="field-error"onFieldError,data-slot="field-footer"onFieldFooter(withdata-size).data-slot="field-separator"onFieldSeparator,data-slot="field-separator-content"on its inner label.
Target a specific state in CSS:
Related Components
- Label: the standalone label and its parts (
LabelIcon,LabelRequired,LabelBadgeSlot) thatFieldLabelbuilds on. - Radio Group: use this for a set of mutually exclusive options that share one value.
- Checkbox Group: use this for a set of independent toggles managed together.
- Input / Select / Textarea: the controls a
Fieldwraps; reach for them directly when you only need the control.
API Reference
Field
The wrapper that provides size and state context to every part inside it. Renders a <div role="group"> and extends Omit<React.ComponentProps<"div">, "size">, so standard div attributes (id, aria-*, etc.) pass through.
Props
Variants
FieldGroup
Stacks several Fields with even spacing and provides a container-query context for responsive fields. Extends React.ComponentProps<"div">.
Props
FieldSet
Native <fieldset> wrapper for a related cluster of fields. Extends React.ComponentProps<"fieldset">, so disabled disables the whole set.
Props
FieldLegend
Native <legend> for the FieldSet. Extends React.ComponentProps<"legend">.
Props
Variants
FieldLabel
The field's label. Extends Label (React.ComponentProps<typeof Label>) and reads size from Field context when not set. Accepts the Label parts (LabelIcon, LabelRequired, LabelOptional, LabelBadgeSlot) as children; see the Label component for their API.
Props
FieldTitle
A non-<label> heading for a field, used when the control is wrapped by an outer label (a checkbox card). Renders a <div> and extends React.ComponentProps<"div">.
Props
Variants
FieldContent
Stacks a label and description beside a control in horizontal layouts. Renders a <div> and extends React.ComponentProps<"div">. Reads size from Field context for its gap.
Props
FieldDescription
Supporting text below the label or control. Renders a <p> and extends React.ComponentProps<"p">. Tints to the error color when the Field is invalid.
Props
Variants
FieldHelper
Inline helper row with an optional leading icon. Renders a <div> and extends React.ComponentProps<"div">. Defaults its tone to error when the Field is invalid.
Props
Variants
FieldError
The validation message. Renders a <div role="alert"> and extends React.ComponentProps<"div">. Renders children if present, otherwise the errors array (deduped by message, as a bulleted list when there is more than one). Returns nothing when empty.
Props
Variants
FieldFooter
A supporting action row, typically a link. Renders a <div> and extends React.ComponentProps<"div">.
Props
Variants
FieldSeparator
A divider between fields, with an optional centered label. Renders a <div> and extends React.ComponentProps<"div">.