Switch
Turns a setting on or off at once.
Checked
falsedefault
true
Sizes
sm
defaultdefault
States
rest
hover
held
focus-visible
on
pending
invalid
disabled
Usage
When to use it
- Use
- A setting takes effect at once, with no Save button: auto-retry, alerts, a schedule paused or running.
- Use
- A list of independent settings, each saved on its own.
- Not for
- The choice is saved with a form. Use Checkbox.
- Not for
- Two to five views of the same thing. Use Segmented control.
- Not for
- The action starts something rather than setting a state. Use Button.
Rules
6 rules
- Must
- Apply the change on onCheckedChange; never put a Switch in a form that waits for Save. Because a switch promises the change happened, so a Save button after it leaves the person unsure which one counted.
- Must
- Pass pending while the change saves, and set checked back if it fails, with the reason beside it. Because pending holds the switch read-only so a second flip cannot race the first, and a switch left on after a failed save lies.
- Must
- Name the switch with a FieldLabel in a horizontal Field, or aria-label. Because a bare switch is announced as "switch, on" with nothing to say what is on.
- Never
- Write the state into the label ("On", "Enabled") or change the label when it flips. Because the knob already shows the state and a screen reader says it, so a changing label reads as a different setting.
- Never
- Fill the track by hand, green or yellow, when on; the checked recipe already draws on. Because green is a job's done colour, and a hand-set yellow drops the ink knob, the gold edge and the light; on reads from the checked fill, its ink knob and the knob's place.
- Should
- Use size="sm" in a dense list of 32px rows, the default beside a label and description.
State order
7 states, highest first
- 1
- disabled
- 2
- pending
- 3
- invalid
- 4
- held
- 5
- focus-visible
- 6
- hover
- 7
- rest
Accessibility
4 checks
- role="switch" with aria-checked, named by its label; pending sets aria-busy and keeps focus.
- On reads from the checked fill and the ink knob at the end (12.8:1 on the yellow), not from a hue; off has a 3.5:1 edge and a 3.5:1 knob on its body.
- The hit area reaches 28px around a 20px switch.
- Announce a failed save in text beside the switch, not only by the knob moving back.
Keyboard
2 keys
- Space
- Flips the switch.
- Enter
- Flips the switch.
Edge cases
6 edge cases
- Save fails
- The caller sets checked back; the knob returns and the reason shows beside it.
- Double press while saving
- Pending makes it read-only, so the second press is ignored.
- Right to left
- The knob starts at the right and moves left when on.
- Dark theme
- On is the dark yellow tint with a yellow edge and a yellow knob.
- Forced colors
- The track draws a CanvasText edge and turns Highlight, unlit, when on; the knob is CanvasText.
- Reduced motion
- The knob cuts to its place, and the pending mark stands still.
API
5 props
checked, defaultChecked, onCheckedChangeBase UI Switchsize'sm' | 'default'default'default'pendingbooleandefaultfalsearia-invalidbooleandefaultfalsedisabled, readOnly, nameBase UI
Tokens
18 tokens
--check-off- var(--secondary-bg)
--check-off-hover- #ffffff
--well- #f4f3ee
--line-control- #8a8478
--line- #e2dfd5
--fail- #b3261e
--text-2- #55524a
--text-disabled- #a8a499
--check-bg- #ffd400
--check-edge- #d9b400
--check-mark- #161512
--primary-light- rgb(255 255 255 / 0.55)
--primary-light-hover- rgb(255 255 255 / 0.85)
--pending-cell- 3px
--dur-light- 240ms
--dur-glow- 320ms
--ease-soft- cubic-bezier(0.22, 0.8, 0.24, 1)
--focus- #7a5d00