Skip to content

Switch

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

State
JSX
<Switch checked={checked} onCheckedChange={setChecked} aria-label="Hide small balances" />
  • 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 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.
DoThe change applies as soon as the switch moves.
Don'tA switch behind a Save button. Use a checkbox when the change waits for a submit.
  1. 1Track36 × 20. Primary colour when on, grey when off.
  2. 2Knob16px. Sits at the end of the track when on.
On
Off
On, disabled
Off, disabled
  • 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.

Under $1
Only verified bidders can bid first.

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.

  • 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.
DoThe label names the setting. It reads the same whether the switch is on or off.
Don'tThe label describes the state. Once it's off, the label is wrong.
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.

  • 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.
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.

  • A Button starts an action instead of changing a setting.