The field family is one component wearing different controls. A text input, a textarea, a
search field, a PIN, a dropdown, a multi-select, an autocomplete, a calendar, a radio group
and a switch all render the same four parts, resolve the same axes and announce themselves
the same way. Learn one and you have learned the shape of the rest.

## The four parts

| Part | Prop | Purpose |
| --- | --- | --- |
| **Label** | `label` | Names the control. It is the accessible name, not decoration. |
| **Description** | `description` | Says how to fill it in, before the reader tries. |
| **Control** | the component's own children | The input, menu, grid or radio set. |
| **Message** | `message` + `status` | Says what happened, after the reader tried. |

A field draws them in that order, so the reading order and the visual order agree.

## Status

`status` colours the field and decides how the message is announced. It takes
`"default"`, `"error"`, `"warning"` or `"success"`.

An `"error"` message is announced immediately, the field's message element carries
`role="alert"`, because a validation failure the reader has to go looking for is a
validation failure they will miss. Every other status is a note, and a note does not
interrupt.

```tsx
<Input
  label="Email"
  description="We send the invoice here."
  message="An email address needs an @."
  status="error"
  required
/>
```

The message is not a tooltip, and the status is not a colour: both are part of the field, so
a screenshot, a printed page and a screen reader all carry them.

## The shared axes

Every field resolves the same seven axes through the cascade, so a form is configured once
rather than per control:

| Axis | Values | What it moves |
| --- | --- | --- |
| `size` | `sm`, `md`, `lg` | Density of the control and its label |
| `variant` | `solid`, `faded`, `bordered`, `ghost`, `underlined` | How the control is bounded |
| `color` | `primary`, `secondary`, `success`, `warning`, `danger` | The accent, in the resolved status |
| `radius` | `none` … `full` | Corner rounding |
| `labelAlign` | `left`, `center`, `right` | Where the label sits above the control |
| `fullWidth` | boolean | Whether the field fills its column |
| `status` | `default`, `error`, `warning`, `success` | The message's meaning and the field's colour |

They are set once in the configuration (see [Configuration](/concepts/configuration)) and
overridden per instance when one field differs:

```ts
export default {
  components: {
    input: { size: "lg", radius: "full" },
    radio: { variant: "card" },
  },
};
```

## States

A field is available, unavailable or busy:

- `required` marks it mandatory. The marker on the label is decorative; the control itself
  carries the `required` attribute, so the requirement is announced rather than only drawn.
  `aria-invalid` follows `status`, so an error field is invalid to assistive technology and
  not merely red.
- `isDisabled` (or `disabled`) marks it unavailable. The control stays findable, and the
  label explains what it is.
- `isLoading` marks it busy, reading a remote value, checking a handle, and the control
  stops accepting input while the label stays put.

## How the parts are associated

The label, description and message are wired to the control by id: the label uses `htmlFor`,
and the control points at the description and the message through `aria-describedby`. That is
why nothing has to be restated and why a field cannot ship with a message that nothing
announces.

When a field's label is visually hidden, a search field in a toolbar, for instance, it is
still rendered, and referenced with `aria-labelledby` instead of `htmlFor`. A hidden label is
still a label.

## Every field

| Component | What it adds |
| --- | --- |
| [Input](/components/forms/input) | Single-line text, with a password variant, adornments and an optional on-screen keyboard |
| [Textarea](/components/forms/textarea) | Several lines, with a row count |
| [SearchInput](/components/forms/search-input) | A search region, a clear control, a submit path and a shortcut |
| [PinInput](/components/forms/pin-input) | A fixed-length code, with completion |
| [Radio](/components/forms/radio) | One choice from a small set, as a list or as cards |
| [Switch](/components/forms/switch) | One boolean |
| [Dropdown](/components/forms/dropmenu) | One option from a list |
| [MultiSelect](/components/forms/multi-select) | Several options, drawn as chips |
| [Autocomplete](/components/forms/autocomplete) | Free text with matching suggestions |
| [Calendar](/components/forms/calendar) | A date, with a month grid |
| [FileUpload](/components/forms/file-upload) | Files, with a size limit and a list |
| [Form](/components/forms/form) | The legend, the submit control and the pending state |
| [Stepper](/components/forms/stepper) | Progress through a form's steps |

For how these compose into a working form, validation, submission, focus, see
[Building a form](/guides/building-a-form).
