import { Meta, Canvas, Controls } from '@storybook/addon-docs/blocks'
import * as FieldStories from './Field.stories'

<Meta of={FieldStories} />

# Field

A label over a control — the form row. The label is the `input-label`
token; `required` marks it with the error-coloured asterisk.

<Canvas of={FieldStories.Required} />

## When

- Any labelled control in a form or dialog: a TextInput, a Textarea, a
  Select, a ChipInput.

## When not

- Displaying a label–value pair → **Property**; Field is for editing.
- The line belongs to a **group** of controls rather than to one — a value
  with Save beside it, a row of action controls → **FieldLine**, the same
  small line on its own.

## How

```tsx
import { Field, TextInput } from '@estiva-app/ui'

<Field label="Name" required helper="One line, and it can be changed later.">
  <TextInput value={name} onChange={(e) => setName(e.target.value)} />
</Field>
```

- **The label names the control. Add nothing.** No `aria-label`, no
  `id`/`htmlFor` pair — this page asked for both until stage 3 and the
  advice was already stale. Base UI's `Field` associates the pair, for its
  own `Input` and `Checkbox`, for `TextInput`, `Textarea` and
  `SearchInput`, and for anything else rendered through `Field.Control`. A
  control you write yourself is the one case that still has to opt in, by
  being one of those.
- An `id` you set on the control is kept, and the label follows it. That
  reversed at stage 3: the Field used to win and override it.
- `helper` is the line under the control — the format, or what happens if
  it is left empty. `error` **replaces** it and marks the control invalid,
  so you no longer pass `aria-invalid` yourself. Both are announced; a line
  written by hand beside the control is not.
- With neither, the control stays a direct child of the field, so nothing
  that predates the two props moved a pixel.
- **`required` marks the control as well as the label.** The asterisk is a
  picture of the requirement; `aria-required` on the control is the word for
  it. Base UI's
  `Field` has no `required` of its own, so the Field puts it there. A control
  that says so already is left alone, and a `children` of several elements
  keeps the asterisk and owes its own.
- **The whole field is one thing under the pointer** (Katerina, 28
  September): the label, the space under it, the box and the line under the
  box. Anywhere on it strengthens the box's border, as hovering the box does;
  a focused box keeps its focus colour, and a switched-off one stays as it is.

## What it owns

It does these by itself. Write none of them around it.

| It does | So you never write | Refused when written by hand |
|---|---|---|
| Ties the label, the description and the error to the control inside it | `aria-label`, an `id` / `htmlFor` pair, or `aria-describedby` |  |
| Marks the control invalid when it has an `error`, and announces it | `aria-invalid` |  |
| Strengthens the box's border while the pointer is anywhere on the field | a hover of your own on the label or around the box |  |

## Props

<Controls of={FieldStories.Default} />
