Switch
A switch turns a setting on or off right away, like hiding small balances.
<Switch checked={checked} onCheckedChange={setChecked} aria-label="Hide small balances" />When to use
Section titled “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
Section titled “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.
- To start an action, like Delete or Withdraw, use a button. A switch can’t ask for confirmation.
Anatomy
Section titled “Anatomy”- 1Track36 × 20. Primary colour when on, grey when off.
- 2Knob16px. Sits at the end of the track when on.
States
Section titled “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
Section titled “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
Section titled “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
Section titled “Behaviour”| Key | Action |
|---|---|
| Tab | Moves focus to the switch. |
| Space or Enter | 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. Tab 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
Section titled “Accessibility”- The switch is a
<button role="switch">witharia-checked, so screen readers announce it as on or off. - Give it a visible label linked with
htmlFor, oraria-labelledby. Usearia-labelonly 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.
| 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
Section titled “Related”- A Button starts an action instead of changing a setting.