Skip to content

Design system

Documentation

DesignComponents / Field

Components / Field

Beta

Field

Use Field to keep a label, control, supporting description, and validation message connected without coupling the component to business rules.

On this page

Examples

Label and description

Keep the visible label and supporting instruction in one logical group.

Use the name people see in invitations.

Field with a label and description

Required value

Mark required form semantics on the control while keeping the instruction visible.

Required to create a workspace.

Required Field

Validation error

A specific error is connected to the invalid control and announced politely.

Use the name people see in invitations.

Choose a name with at least three characters.

Invalid Field with a validation error

Input and Switch composition

Field groups different controls without taking ownership of business state.

Receive one summary each Monday.

Field compositions for text and binary controls

Long supporting content

Long guidance wraps naturally and remains readable at narrow widths.

Explain the trigger, the people affected, and what someone should check before enabling this automation in a production workspace.

Field with long supporting content

When to use

Use Field for one logical input and its guidance. It works with Input and other native or Base UI controls; validation remains the responsibility of the form or feature. For a binary setting, compose Field with Switch so the label and description stay connected while the feature owns the setting state.

Usage

field-basic.tsx
import {
  Field,
  FieldControl,
  FieldDescription,
  FieldError,
  FieldLabel,
} from "@phuctech/ui/components/field";

export function Example() {
  return (
    <Field invalid>
      <FieldLabel>Workspace name</FieldLabel>
      <FieldControl defaultValue="PhucTech" aria-invalid="true" />
      <FieldDescription>Use the name people see in invitations.</FieldDescription>
      <FieldError match>Choose a name with at least three characters.</FieldError>
    </Field>
  );
}

Use FieldControl when the Base UI field should own the input relationship. Use Input inside Field when you need the Input API, and connect IDs explicitly when you control the validation message.

Settings example

This example keeps the form state in the feature: Field only describes the relationship, while the screen owns validation, save/cancel, and loading behavior.

Settings form

Keep validation and save/cancel state in the feature while the shared components preserve the relationships.

Workspace settings

Update the name shown in invitations and project headers.

Use a name your whole team will recognize.

Settings form with Field, Input, validation, and save/cancel actions

API

Component API
PropTypeDefaultDescriptionConstraints
invalidbooleanfalseMarks the field invalid when validation is controlled outside Base UI.Render a useful error message and connect it to the control.
validationMode"onSubmit" | "onBlur" | "onChange""onSubmit"Base UI validation timing when using validate.Choose the least noisy timing for the form.
validate(value, formValues) => string | string[] | nullOptional synchronous or asynchronous field validator.Keep domain rules in the feature when they need server context.
FieldLabelBase UI label propsAssociates the visible label with the field control.Use visible text; do not use placeholder as the label.
FieldControlBase UI control propsNative input-like control connected to the Field root.Use Input instead when the feature needs the shared Input API.
FieldDescription / FieldErrorHTML paragraph/div propsSupporting and validation feedback.Keep the error specific and connected with IDs when using a custom control.

Tokens

Component tokens
TokenRoleEffective valueUsage
--space-2 / --space-3Field rhythm0.5rem / 0.75remSeparates labels, controls, descriptions, and errors.
--color-dangerValidation intentsemantic dangerError text and invalid control styling share one meaning.
--focus-ring-*Keyboard focusshared focusThe control keeps focus visible inside the field group.

Accessibility

  • Keep the visible label, control, and error in one logical group.
  • Use aria-invalid only when the value is invalid, and connect the explanation with aria-describedby.
  • Do not announce validation on every keystroke unless the task genuinely benefits from live feedback.

Do and don’t

Do

Let the feature own the rule and loading state; let Field own the accessible grouping.

Don’t

Put business requests, fetch calls, or form submission logic inside Field.

  • Input is the standard single-line control to compose with Field.
  • Switch uses the same label and description relationship for binary settings.
  • Button provides submit, cancel, and loading states around the form.