A switch sets one boolean, and it takes effect immediately: there is no Save button beside
it, which is what separates it from a checkbox. A checkbox is a value a form submits later;
a switch is a setting that is now on or now off. That is why the label names the setting
rather than asking a question, and why the description says what turning it on does, a
switch is read at rest as often as it is flipped.

```tsx demo="forms/switch-preview"
```

## Usage

```tsx
import { Switch } from "@asheeui/web";

<Switch label="Email notifications" defaultChecked />
```

Uncontrolled is enough while the setting is only read when the form is submitted. When the
value has to live with the rest of the page, to enable another field, to save it as soon
as it changes, drive it with `checked` and `onChange`:

```tsx
<Switch
  label="Email notifications"
  description="We tell you when an invoice is paid."
  checked={notifications}
  onChange={setNotifications}
/>
```

## States

The track fills with the accent once the switch is on, and the knob travels from one end to
the other; both follow `size`, and the accent follows `color`. The track and the knob keep
their size in every state, so nothing in the row moves when the value changes.

`disabled` marks the setting unavailable and keeps the label and the track in the layout and
in the reading order. `isLoading` marks it busy, the value is being read or written
elsewhere, and also stops interaction, because pressing a switch whose value is still in
flight is the mistake the state exists to prevent. Neither state rewrites the label.

```tsx demo="forms/switch-states"
```

## Props

```props Switch
```

The cascade is the field family's. `radius` is registered as `full` and `size` as `md`, so
the track is a pill and the density is the one a form uses by default; `color` is not
registered, so it follows the application's `defaultColor`, and `labelAlign` follows the
field's `left`.

`Switch` takes no `message` and no `status`: a boolean is either stored or not, so there is
no invalid value for a message to explain. What the reader needs before flipping it belongs
in `description`, and what happened afterwards is the page's to show.

## Accessibility

- The control is a real `<input type="checkbox">` with `role="switch"`, so <kbd>Space</kbd>
  toggles it, it sits in the tab order without a `tabindex`, and its state is announced from
  `aria-checked` as on or off rather than as checked or unchecked.
- The `label` element points at the input with `htmlFor`, so the visible label is the
  accessible name, and `description` is referenced with `aria-describedby`. The track and
  the knob are decoration drawn from the input's state, never a second control.
- `isLoading` sets `aria-busy` and disables the input, so a busy switch announces that it is
  working and refuses a second press while its label stays put. `disabled` is the native
  attribute, so the switch leaves the tab order and is announced as unavailable.
- `required` is set on the input as well as marked on the label, so the requirement travels
  with the control instead of living only in the asterisk.

The label and description behave as the [field anatomy](/concepts/fields) describes.

## Related

```related radio, input, form
```
