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.

We'll never share your email.

Installation

Install the component using the Tailgrids CLI.

npx @tailgrids/cli add field

Anatomy

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.

This appears on invoices and emails.
This username is already taken.

Textarea

The same composition pattern works with any form control, including TextArea.

Brief description for your profile. Maximum 280 characters.

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.

We'll never share your email.
We'll never share your email.
Re-enter your password.

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.

ProfileUpdate your personal information.
This will be used for account recovery.

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.

PropTypeDefaultDescription
hasCheckboxGroupbooleanfalseReduces gap when a checkbox group is present inside the fieldset.
hasRadioGroupbooleanfalseReduces gap when a radio group is present inside the fieldset.
classNamestringAdditional CSS classes.
childrenReact.ReactNodeThe field controls rendered inside the fieldset.

FieldLegend

Styled <legend> element for use inside FieldSet.

PropTypeDefaultDescription
variant'label' | 'legend''legend'Visual variant. 'label' renders smaller text, 'legend' renders base size.
classNamestringAdditional CSS classes.
childrenReact.ReactNodeLegend content.

FieldGroup

Layout wrapper for related fields. It keeps field groups aligned and passes shared state to its children.

PropTypeDefaultDescription
childrenReact.ReactNodeThe field controls rendered inside the group.
disabledbooleanDisables the grouped controls.
readOnlybooleanMarks the grouped controls as read only.
classNamestringAdditional CSS classes applied to the container.

FieldContent

Layout helper for arranging field text content.

PropTypeDefaultDescription
classNamestringAdditional CSS classes.
childrenReact.ReactNodeContent elements (labels, descriptions, etc.).

FieldLabel

Visible label for a field.

PropTypeDefaultDescription
childrenReact.ReactNodeLabel content.
classNamestringAdditional CSS classes.

FieldTitle

Label-like text for horizontal layouts or supporting text blocks.

PropTypeDefaultDescription
childrenReact.ReactNodeTitle text or elements.
slotstringOptional slot prop supported by React Aria Text for ARIA linking.
classNamestringAdditional CSS classes.

FieldDescription

Helper text for hints, instructions, or supplemental details. It is linked to the field through the description slot.

PropTypeDefaultDescription
childrenReact.ReactNodeHelper text content.
classNamestringAdditional 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.

PropTypeDefaultDescription
childrenReact.ReactNode | ((validation: ValidationResult) => React.ReactNode)Validation message content. Can be a render function receiving the current validation state.
classNamestringAdditional 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.

PropTypeDefaultDescription
childrenReact.ReactNodeOptional inline content. If present, the divider centers the content.
role"separator""separator"Present only when children are provided and the component renders a div.
classNamestringAdditional 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 FieldSet for section-level grouping, such as a billing address or account settings block.
  • Use FieldLegend for the section title inside a FieldSet.
  • Use FieldGroup to keep related fields together and preserve shared field state like disabled or read-only.
  • Use TextField, NumberField, DateField, or TimeField as the actual interactive control, depending on the value type you want to collect.
  • Use FieldLabel for the visible label attached to a field.
  • Use FieldTitle when you want label-like text that is not the primary interactive label, such as a row title in a horizontal layout.
  • Use FieldContent to group the title, description, and related helper content in horizontal field layouts.
  • Use FieldDescription for helper text, hints, or short instructions.
  • Use FieldError for validation messages.
  • Use FieldSeparator to visually divide related fields inside a group.

Accessibility

  • Label association: Inside TextField, React Aria's context automatically links labels to inputs via aria-labelledby. Clicking a label focuses the input.
  • ARIA linking: TextField automatically links the label, description, and error message to the input. FieldDescription and FieldError are wired via slot and React Aria context.
  • Error messages: FieldError displays validation messages and connects them to the input via aria-errormessage so screen readers can announce them.
  • Descriptions: FieldDescription provides helper text that is linked to the input via aria-describedby.
  • Semantic grouping: FieldGroup wraps React Aria's Group component, providing interactive state support (isDisabled, isInvalid, isReadOnly) for groups of related fields. FieldSet provides native <fieldset> semantics for section-level grouping.
  • Legend: FieldLegend renders a <legend> inside FieldSet, providing accessible section labeling for grouped controls.