Skip to content

Switch

Terminal window
$ npx shadcn@latest add https://lacodda.github.io/dowel/r/switch.json
See it liveOff, on, and disabled, with and without words.→

The difference from Checkbox is not how it looks, and getting it wrong is the commonest mistake in the pair. A checkbox is an answer collected now and submitted later, with the rest of the form. A switch is a setting that applies the moment it moves.

If there is a Save button, it is a Checkbox. If the change is the action, it is a Switch.

Put a switch in a form behind a Save button and the reader cannot tell whether anything happened: they flipped it, and nothing said so.

<Switch defaultChecked>Notify me</Switch>

It reports its state, not only its position. The role is switch and aria-checked follows it — which matters more than it looks, because under reduced motion the theme drops the slide and the position is all that changes on screen.

The track carries the accent when on, and it is the only colour in the control, so a column of settings reads as a list of on-and-off rather than a field of decoration.

A switch with no words is a light with no caption. Leave them out only where the meaning is genuinely in the context, and then name it:

<Switch aria-label="Notify me" />

Props

Read from the types in ui/switch.tsx, the file a product copies - so the description of each prop is also what an editor shows over it there.

PropTypeDefault
childrenReactNodeThe words next to the switch. A switch with no label is a light with no caption - give aria-label if the meaning is genuinely in the context.
checkedbooleanWhether the switch is on, when the caller owns the state. Pair it with onCheckedChange.
defaultCheckedbooleanWhether the switch starts on, when it manages its own state.
onCheckedChange(checked: boolean) => voidTold the new state when the switch is flipped.
disabledbooleanThe switch cannot be flipped; it and its label dim.
requiredbooleanMarks the switch as required for a form.
readOnlybooleanThe state shows but cannot be changed by the reader.
namestringThe field name submitted with a form.
aria-labelstringNames the switch for a screen reader when it has no children.
classNamestring

Accessibility

The examples on the stand, through axe 4.14.0 in a browser, in both themes, against WCAG 2.2 A and AA and axe's best practices: 18 rules applied and passed, and none failed. The accessibility report has every item.

History

Each release that changed ui/switch.tsx - the file a product copies - newest first.

  1. v0.41.0
    • docs read every props table from the component's types ee3b159
  2. v0.33.0breaking
    • feat no-raw-button and no-arbitrary-scale ac7a11a
  3. v0.16.0
    • feat a field, and the three ways of choosing 7df746d