# Switch

A switch turns a setting on or off right away, like hiding small balances.

## When to use

- To turn one setting on or off when the change applies as soon as the switch moves, like *Hide small balances*.
- To turn on a part of a form that shows more fields, like *Early access phase*.

## When not to use

- When the change waits for a Save or Submit button, use a checkbox.
- To pick one of a few options, use a [segmented control](/components/segmented-control/).
- To start an action, like *Delete* or *Withdraw*, use a button. A switch can't ask for confirmation.

## Anatomy

## States

- **On** fills the track with the primary colour and moves the knob to the end.
- **Off** shows a grey track with the knob at the start.
- **Disabled** drops to 40% opacity in either position. Say why next to it, so people know what would turn it back on.

There is one size, 36 × 20.

## With a label

A switch always has a label. Put it before the switch, in the same row, and link it with `htmlFor` and `id` so clicking the label toggles the switch. A short hint below the label can say what the setting does.

When the whole row should toggle, as in a menu, make the row the `role="switch"` button, give it the `group/switch` class and put `SwitchTrack` inside it. Don't nest a `Switch` in another button.

## Content

- Name the setting, not its state. *Hide small balances*, not *Small balances are hidden*.
- Use sentence case and no full stop.
- Don't add On and Off text beside the switch. The track already shows the state.

## Behaviour

| Key | Action |
| --- | --- |
| <kbd>Tab</kbd> | Moves focus to the switch. |
| <kbd>Space</kbd> or <kbd>Enter</kbd> | Turns it on or off. |

Clicking the switch or its label toggles it. The knob slides with a small spring, overshooting by about 2px before it settles, and stretches toward the far end while pressed. Under reduced motion it moves without sliding or stretching. <kbd>Tab</kbd> skips disabled switches.

If the change saves to the server, move the switch at once and move it back if the save fails, with the error next to it.

## Accessibility

- The switch is a `<button role="switch">` with `aria-checked`, so screen readers announce it as on or off.
- Give it a visible label linked with `htmlFor`, or `aria-labelledby`. Use `aria-label` only when there's no visible text.
- Keyboard focus shows a 2px ring with a 2px gap (`focus/ring`), the same as the button.
- On and off differ in colour and in where the knob sits, so the state reads without colour.

## Props

| Prop | Type | Default | Notes |
| --- | --- | --- | --- |
| `checked` | `boolean` | Required | Whether the switch is on. |
| `onCheckedChange` | `(checked: boolean) => void` | Required | Called with the new value. |
| `disabled` | `boolean` | `false` | Dims the switch and takes it out of the tab order. |

Every other `<button>` prop passes through, including `id`, `aria-label` and `aria-describedby`.

`SwitchTrack` takes `checked` and draws the track and knob without a button, for rows that are the switch themselves.

## Related

- A [Button](/components/button/) starts an action instead of changing a setting.
