Field
The React Field component helps you build form fields with labels, inputs, helper text, and error messages. It keeps everything connected and structured in one place.
It makes forms easier to build and more accessible by linking labels, descriptions, and errors to the input. For example, a field can show a label, helper text, and an error message for an email input.
Installation
Install the component using the Tailgrids CLI.
npx @tailgrids/cli add fieldAnatomy
Import the sub-components you need and compose them together.
import {
FieldSet,
FieldLegend,
FieldGroup,
FieldContent,
FieldLabel,
FieldTitle,
FieldDescription,
FieldError,
FieldSeparator
} from "@/components/tailgrids/core/field";
import { TextField } from "@/components/tailgrids/core/text-field";
export const FieldAnatomy = () => (
<FieldSet>
<FieldLegend>Section heading</FieldLegend>
<FieldDescription>Short description</FieldDescription>
<FieldGroup>
<TextField>
<FieldLabel htmlFor="input-id">Label</FieldLabel>
{/* Input, Select, Textarea, etc. */}
<FieldDescription>Optional helper text.</FieldDescription>
<FieldError>Validation message.</FieldError>
</TextField>
<FieldSeparator />
<TextField orientation="horizontal">
<FieldTitle>Title</FieldTitle>
{/* Input, Select, Textarea, etc. */}
<FieldDescription>Helper text.</FieldDescription>
</TextField>
</FieldGroup>
</FieldSet>
);Examples
Input
Compose a TextField with FieldLabel, Input, FieldDescription, and FieldError to create a labeled text field with optional description and error state.
Textarea
The same composition pattern works with any form control, including TextArea.
Horizontal
Use TextField with orientation="horizontal" to place the label and control side by side.
Validation
Pass a validate function and use FieldError to display error messages within any field components (i.e. TextField, NumberField etc.). Set invalid on the field to trigger the error state.
Field Set and Field Group
Use FieldSet and FieldGroup to visually group related fields with consistent spacing. Add FieldSeparator to create visual dividers between sections.
See the Composition section below for more details on how to use these components together.
API Reference
FieldSet
Semantic <fieldset> wrapper for grouping related form controls.
| Prop | Type | Default | Description |
|---|---|---|---|
hasCheckboxGroup | boolean | false | Reduces gap when a checkbox group is present inside the fieldset. |
hasRadioGroup | boolean | false | Reduces gap when a radio group is present inside the fieldset. |
className | string | — | Additional CSS classes. |
children | React.ReactNode | — | The field controls rendered inside the fieldset. |
FieldLegend
Styled <legend> element for use inside FieldSet.
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'label' | 'legend' | 'legend' | Visual variant. 'label' renders smaller text, 'legend' renders base size. |
className | string | — | Additional CSS classes. |
children | React.ReactNode | — | Legend content. |
FieldGroup
Layout wrapper for related fields. It keeps field groups aligned and passes shared state to its children.
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | — | The field controls rendered inside the group. |
disabled | boolean | — | Disables the grouped controls. |
readOnly | boolean | — | Marks the grouped controls as read only. |
className | string | — | Additional CSS classes applied to the container. |
FieldContent
Layout helper for arranging field text content.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional CSS classes. |
children | React.ReactNode | — | Content elements (labels, descriptions, etc.). |
FieldLabel
Visible label for a field.
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | — | Label content. |
className | string | — | Additional CSS classes. |
FieldTitle
Label-like text for horizontal layouts or supporting text blocks.
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | — | Title text or elements. |
slot | string | — | Optional slot prop supported by React Aria Text for ARIA linking. |
className | string | — | Additional CSS classes. |
FieldDescription
Helper text for hints, instructions, or supplemental details. It is linked to the field through the description slot.
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | — | Helper text content. |
className | string | — | Additional CSS classes. |
Note: FieldDescription uses the description slot so React Aria can connect it to the active field.
FieldError
Validation message for invalid fields. Accepts either static text or a render function for validation-aware messaging.
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | ((validation: ValidationResult) => React.ReactNode) | — | Validation message content. Can be a render function receiving the current validation state. |
className | string | — | Additional CSS classes. |
Note: When used with a render function, FieldError can adapt the message to the current validation result.
FieldSeparator
Visual divider between field sections. It can also show centered inline content.
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | — | Optional inline content. If present, the divider centers the content. |
role | "separator" | "separator" | Present only when children are provided and the component renders a div. |
className | string | — | Additional CSS classes. |
Note: FieldSeparator renders either as a plain separator or as a centered-content divider depending on whether children are provided.
Composition
Use these components together to build accessible field layouts. Each piece has a clear role, so you can choose only the parts your form needs.
FieldSet
├── FieldLegend
└── FieldGroup
├── TextField / NumberField / DateField / TimeField
│ ├── FieldLabel
│ ├── FieldContent
│ │ ├── FieldTitle
│ │ └── FieldDescription
│ ├── FieldError
│ └── Input / DateInput / TimeInput / etc.
└── FieldSeparator- Use
FieldSetfor section-level grouping, such as a billing address or account settings block. - Use
FieldLegendfor the section title inside aFieldSet. - Use
FieldGroupto keep related fields together and preserve shared field state like disabled or read-only. - Use
TextField,NumberField,DateField, orTimeFieldas the actual interactive control, depending on the value type you want to collect. - Use
FieldLabelfor the visible label attached to a field. - Use
FieldTitlewhen you want label-like text that is not the primary interactive label, such as a row title in a horizontal layout. - Use
FieldContentto group the title, description, and related helper content in horizontal field layouts. - Use
FieldDescriptionfor helper text, hints, or short instructions. - Use
FieldErrorfor validation messages. - Use
FieldSeparatorto visually divide related fields inside a group.
Accessibility
- Label association: Inside
TextField, React Aria's context automatically links labels to inputs viaaria-labelledby. Clicking a label focuses the input. - ARIA linking:
TextFieldautomatically links the label, description, and error message to the input.FieldDescriptionandFieldErrorare wired viaslotand React Aria context. - Error messages:
FieldErrordisplays validation messages and connects them to the input viaaria-errormessageso screen readers can announce them. - Descriptions:
FieldDescriptionprovides helper text that is linked to the input viaaria-describedby. - Semantic grouping:
FieldGroupwraps React Aria'sGroupcomponent, providing interactive state support (isDisabled,isInvalid,isReadOnly) for groups of related fields.FieldSetprovides native<fieldset>semantics for section-level grouping. - Legend:
FieldLegendrenders a<legend>insideFieldSet, providing accessible section labeling for grouped controls.
