# Toggle

> Slug: `toggle` · Category: Form Controls

## When to use

- An on/off setting that takes effect immediately (notifications, autopay, dark mode, "Use saved address").
- Settings panels and list rows with binary state.

## When NOT to use

- Form-style consent that's submitted with other fields — use `Checkbox`.
- Multiple independent options — use a checkbox group or `Chips variant="toggle"`.
- Mutually exclusive options — use `RadioGroup`.

## Variants & decision tree

| Need | Prop |
|---|---|
| With visible text label | `label` |
| Label provided externally (e.g., a list row title) | omit `label`, use `labelledById` or `ariaLabel` |
| Helper / hint text id | `describedBy` |

## States

Off (unchecked), on (checked), focused, hover, pressed, disabled, inverse.

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `id` | `string` | — | Required. Input id. |
| `label` | `ReactNode` | — | Visible label text (renders inside `<label htmlFor>`). |
| `checked` / `defaultChecked` | `boolean` | — | Controlled / uncontrolled state. |
| `onChange` | `ChangeEventHandler` | — | Use `e.target.checked`. |
| `labelledById` | `string` | — | Use when label is rendered elsewhere; sets `aria-labelledby`. |
| `ariaLabel` | `string` | — | Use when no visible label exists. |
| `describedBy` | `string` | — | id(s) for `aria-describedby`. |
| `disabled` | `boolean` | `false` | Disable. |
| `inverse` | `boolean` | `false` | Dark-background styling. |
| `name` | `string` | — | Form submission name. |

## Usage examples

```tsx
// With visible label
<Toggle id="notif" label="Enable notifications" checked={enabled} onChange={(e) => setEnabled(e.target.checked)} />

// Inside a list row — label rendered separately
<div>
  <span id="autopay-label">Autopay</span>
  <Toggle id="autopay" labelledById="autopay-label" checked={autopay} onChange={(e) => setAutopay(e.target.checked)} />
</div>

// Disabled
<Toggle id="locked" label="Locked setting" disabled defaultChecked />
```

## Composition

Common inside `Lists` (`ListItemType.TOGGLE`), settings cards, and inline notification preferences. Toggling should produce an immediate effect; if a save action is required, use `Checkbox` instead.

## Accessibility

Either render a visible `label` or supply `ariaLabel` / `labelledById`. The toggle is a real `<input type="checkbox">`, so screen readers announce it as a checkbox with checked/unchecked state. `describedBy` adds helper-text association.

## Do / Don't

- DO apply state changes immediately on toggle.
- DO pair label and toggle visually — clicking the label flips the toggle.
- DON'T use Toggle to submit forms; that's `Checkbox` territory.
- DON'T leave a Toggle without a label, `ariaLabel`, or `labelledById`.
