---
name: Field
package: '@wordpress/ui'
category: '@wordpress-ui'
status: stable
canonical: 'https://system.automattic.design/components/field/'
storybook: 'https://wordpress.github.io/gutenberg/?path=/docs/design-system-components-form-primitives-field--docs'
github: 'https://github.com/WordPress/gutenberg/tree/trunk/packages/ui/src/form'
---

# Field

A low-level component that associates an accessible label and description
with a single form control element.

To label a group of multiple form control elements, use the `Fieldset` component instead.

Simply wrapping a control with this component does not guarantee
accessible labeling. See examples for how to associate the label in different cases.

```tsx
import { Field } from '@wordpress/ui';
```

## Props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `name` | `string` | — | Identifies the field when a form is submitted. Takes precedence over the `name` prop on the `<Field.Control>` component. |
| `render` | `ComponentRenderFn<HTMLAttributesWithRef<any>> \| ReactElement<Record<string, unknown>, string \| JSXElementConstructor<any>> \| undefined` | `( props: React.ComponentProps< typeof Stack > ) => ( 	<Stack { ...props } direction="column" gap="sm" /> )` | Replaces the component's default HTML element using a given React element, or a function that returns a React element. |
| `style` | `CSSProperties` | — | CSS style to apply to the element. |
| `className` | `string` | — | CSS class name to apply to the element. |
| `actionsRef` | `RefObject<FieldRootActions \| null>` | — | A ref to imperative actions. - `validate`: Validates the field when called. |
| `children` | `ReactNode` | — |  |
| `disabled` | `boolean` | `false` | Whether the field is disabled. |


## Examples

### Default

If your control component forwards refs, as well as the `aria-labelledby` and `aria-describedby` props
to the actual underlying HTML element to be labeled,
you can simply place your control in the `render` prop of `Field.Control`.

```tsx
const Default = () => <Field.Root>{[
        <Field.Label key="label">Label</Field.Label>,
        <Field.Control
            render={ <input type="text" placeholder="Placeholder" /> }
            key="control"
        />,

        <Field.Description key="description">
            The accessible description.
        </Field.Description>,
    ]}</Field.Root>;
```

### Using htmlFor

If your control component does not forward refs, but does forward the `id` prop
to the actual underlying HTML element to be labeled, use the `htmlFor` prop
of the `Field.Label` component to associate the label with the control.

This is preferred over `aria-labelledby` because it allows users to click the
label to focus the control.

```tsx
const UsingHtmlFor = () => {
    const controlId = useId();
    const descriptionId = useId();

    return (
        <Field.Root>
            <Field.Label htmlFor={ controlId }>Label</Field.Label>
            <MyNonRefForwardingControl
                placeholder="Placeholder"
                id={ controlId }
                aria-describedby={ descriptionId } />
            <Field.Description id={ descriptionId }>The accessible description.
                                </Field.Description>
        </Field.Root>
    );
};
```

### Using aria-labelledby

If your control component does not forward refs nor the `id` prop, but does
forward the `aria-labelledby` prop to the actual underlying HTML element to be
labeled, use the `id` prop of the `Field.Label` component to associate the
label with the control.

```tsx
const UsingAriaLabelledby = () => {
    const labelId = useId();
    const descriptionId = useId();

    return (
        <Field.Root>
            <Field.Label id={ labelId }>Label</Field.Label>
            <MyNonRefForwardingControl
                placeholder="Placeholder"
                aria-labelledby={ labelId }
                aria-describedby={ descriptionId } />
            <Field.Description id={ descriptionId }>The accessible description.
                                </Field.Description>{ ' ' }
        </Field.Root>
    );
};
```

### Hidden Label

When `hideFromVision` is set on `Field.Label`, the label is visually
hidden but remains accessible to screen readers.

```tsx
const HiddenLabel = () => <Field.Root>{[
        <Field.Label hideFromVision key="label">
            Label
        </Field.Label>,
        <Field.Control
            render={ <input type="text" placeholder="Placeholder" /> }
            key="control"
        />,
    ]}</Field.Root>;
```

### With Details

To add rich content (such as links) to the description, use `Field.Details`.

Although this content is not associated with the field using direct semantics,
it is made discoverable to screen reader users via a visually hidden description,
alerting them to the presence of additional information below.

If the content only includes plain text, use `Field.Description` instead,
so the readout is not unnecessarily verbose for screen reader users.

```tsx
const WithDetails = () => <Field.Root>{[
        <Field.Label key="label">Label</Field.Label>,
        <Field.Control
            render={ <input type="text" placeholder="Placeholder" /> }
            key="control"
        />,

        <Field.Details key="details">{ DETAILS_EXAMPLE }</Field.Details>,
    ]}</Field.Root>;
```

### With Visual Label

`Field.VisualLabel` renders a purely visual label with the same styling as
`Field.Label`. It can be used outside `Field.Root` when the control is
already accessibly labeled, but a visual label is still needed for layout
consistency.

```tsx
const WithVisualLabel = () => (
    <Stack direction="column" gap="sm" align="flex-start">
        <Field.VisualLabel>Author</Field.VisualLabel>
        <Button variant="outline">Select an author</Button>
    </Stack>
);
```