Components

Field

A React field with a Liquid Glass label, description, and validation message for one form control.

Field wraps one Base UI form control with a visible label, supporting text, and a validation message. It owns the labeling and validity wiring, while the child control owns its own glass surface and interaction.

Use Field to give Input a visible label, description, and validation message. Controls that already render their own label, such as Checkbox, Select, CheckboxGroup, RadioGroup, and Switch, keep their built-in label prop. Use Fieldset when several fields need one shared legend.

Basic example

Pass the control as children. Field renders a real <label> and connects it to the control, so the input needs no separate label. children must be a single Base UI control; a native <input> is not wired into the field context.

We only use this address for account notices.

Validation

validate receives the current value and returns a string, an array of strings, or nothing when the value is valid. validationMode controls when it runs: onSubmit by default, or onBlur and onChange for earlier feedback. validationDebounceTime delays onChange validation while typing.

Use a work address so we can reach your team.

Native constraints such as required, minLength, pattern, and type participate automatically because the control is a real form element.

Error message

Set error to show an externally controlled message. A string renders directly as the message. A truthy error marks the field invalid and takes precedence over built-in validation until it is cleared. The message is linked to the control with aria-describedby, and the control receives aria-invalid.

This address is already in use.

Change the address to see the error clear.

Pass a React element as error to take over the entire error body. The outer message element still owns the id and aria-describedby wiring, so custom content stays accessible.

This key expired on May 1.

Keys rotate every 90 days.

Sizes

Supports xs / sm / md / lg / xl, defaulting to md. Pass the same size to the control so the label, message, and control rows stay aligned.

Accessibility

Field renders a real <label> linked to the control. description and error register their ids with the control's aria-describedby; an error also sets aria-invalid on the control.

Keyboard behavior belongs to the wrapped control. Use label rather than a placeholder so the accessible name survives zoom, translation, and voice control. Group controls keep their own label; use Fieldset for a shared legend. When the field is disabled, the label and message fade and the control is disabled through the shared field state. See the accessibility guide for form patterns.

API reference

Field

PropTypeDefaultDescription
childrenReactElement—Single Base UI control labelled and validated by the field. Required.
labelReactNode—Visible label associated with the control.
descriptionReactNode—Supporting text rendered under the control and linked with aria-describedby.
errorReactNode—Error message. A string renders directly; a React element replaces the body. A truthy value marks the field invalid.
size"xs" | "sm" | "md" | "lg" | "xl""md"Label, message, and spacing size.
validate(value, formValues) => string | string[] | null | void | Promise<...>—Custom validation. Return a message or messages when the value is invalid.
validationMode"onSubmit" | "onBlur" | "onChange""onSubmit"When the field validates.
validationDebounceTimenumber0Delay in milliseconds between validate calls in onChange mode.
invalidboolean—Marks the field invalid from external state.
disabledbooleanfalseDisables the control through the field and fades the label and message.
namestring—Form field name registered by the field.
dirtyboolean—Marks the field dirty from external state.
touchedboolean—Marks the field touched from external state.
actionsRefRefObject<Field.Root.Actions | null>—Imperative actions. validate validates the field on demand.
classNamestring—Tailwind classes merged into the field root.
styleCSSProperties—Inline styles merged into the same element as className.
ui{ root?: ClassValue; label?: ClassValue; error?: ClassValue; description?: ClassValue }—Tailwind classes for internal slots, keyed by data-slot.
renderReactElement | ((props, state) => ReactElement)—Replaces the field root element.

Additional Base UI Field.Root props are forwarded, including id. The child control also accepts its own props; set required, disabled, and native constraints on the control when they belong to that element.

AttributeDescription
data-disabledPresent when the field is disabled.
data-validPresent when the field is valid.
data-invalidPresent when the field is invalid.
data-dirtyPresent when the field value has changed.
data-touchedPresent after the field is touched.
data-filledPresent when the control has a value.
data-focusedPresent when the control is focused.
data-slotMarks internal parts (root, label, error, description) for styling.

Theming

Field has no glass surface of its own; it inherits the control's material. Tune the shared --ui-drop-shadow-label token for the label, adjust spacing and type with --ui-field-gap, --ui-field-label-size, and --ui-field-message-size, and use ui for internal slots keyed by data-slot. The error message uses text-red-700 in light themes and ui-dark:text-red-400 in dark themes; override it with ui.error. A custom error node renders directly inside ui.error. Component-specific values live in src/theme/field.ts. See the theming guide for token layers and presets.

  • Input — The standard text field to place inside Field.
  • Fieldset — Groups related fields under one shared legend.
  • Checkbox Group — A grouped control that keeps its own label and description.