<!-- Generated by emit-docs.ts — do not edit. -->
# Field

Labeled form-row wrapper: label above, control, one message line below — description normally, error when set (aria-live). Auto-wires id/aria-describedby/aria-invalid into Input and Select (D49).

## Props

| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
| `label` | `ReactNode` | — | no | Label content; renders a <label> (or <legend> in group mode). |
| `description` | `ReactNode` | — | no | Helper line under the control; replaced by error when error is set. |
| `error` | `ReactNode` | — | no | Error content; when truthy it replaces the description and switches the field (and a wrapped Input/Select) into error state. |
| `required` | `boolean` | false | no | Renders the required marker and flows `required` to the control. |
| `group` | `boolean` | false | no | Group mode: fieldset/legend wrapping several self-labeled controls (Checkbox/Switch); the message describes the whole group. |
| `htmlFor` | `string` | — | no | Override the generated control id (pair it with the same id on the control). |
| `ref` | `Ref<HTMLDivElement \| HTMLFieldSetElement>` | — | no | Forwarded ref to the root element. |
| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |

## Keyboard & assistive tech

| Keys | Behavior |
|---|---|
| Tab | Focus moves to the wrapped control; the label is announced with it. |

Wires label association, aria-describedby and aria-invalid into a wrapped Input/Select automatically; the message line is aria-live=polite. Group mode renders fieldset/legend.

## Theming

Override `--psi-field-*` custom properties at any scope; interactive states derive automatically (L - 0.04 hover, L - 0.08 active).



## Rules

- One accent per visual group; everything else neutral or ghost.
- danger only for actions with real consequences.
- Sizes are px numbers (24|32|40|48), never S/M/L.
- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
- Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
