Toggle control for on/off settings that commit immediately.
Description
Switch is a single-element toggle built on Radix's Switch.Root. It renders a track with a sliding thumb and commits the state change immediately on click, without a form submit step. The library adds five variant colors, three sizes, two shapes, two thumb widths, optional I/O symbols, and optional thumb icons on top of the Radix primitive.
Use it in settings panels, notification preference lists, and feature flag dashboards. Any binary setting that should take effect the moment the user flips it. It sits naturally in a labeled row, inside a card, or stacked in a list of preferences.
Don't use it inside a form that only commits on explicit submit. For that, Checkbox is the right choice; Switch implies the change is live immediately. For picking between more than two named states, use Radio or Segmented Control.
Installation
Usage
Examples
Variants
Five semantic variants: primary, info, neutral, inverse, and semantic. The semantic variant is red when unchecked and green when checked, making both states visually distinct beyond just position.
Sizes
Three sizes (md, sm, xs) scale the track height and thumb together. sm is the default.
Shape
shape="pill" (default) is fully rounded. shape="rounded" applies a stepped radius that matches the size scale.
Thumb Type
thumbType="long" widens the thumb and extends its travel distance. Useful when you want a more prominent knob or a larger touch target. Default is short.
I/O Trigger
ioTrigger renders a pipe symbol on the left when checked and a circle on the right when unchecked, inside the track. Useful when the color alone is not enough to communicate state.
Thumb Icon
thumbIcon adds a check icon to the thumb when on, and a close icon when off. Works across all thumbType values; icons scale with size.
States
disabled prevents interaction and applies muted styles to both the track and thumb, whether checked or unchecked.
Controlled
Manage state externally with checked and onCheckedChange. Use defaultChecked for the uncontrolled equivalent.
Accessibility
Built on Radix's Switch.Root, which sets role="switch" and manages aria-checked automatically.
ARIA notes:
- Radix sets
role="switch"and keepsaria-checkedin sync with the checked state. You do not need to set these manually. - Always pair the switch with a visible label or provide
aria-label/aria-labelledbyon the root so screen readers can announce what is being toggled. - The I/O symbols rendered by
ioTriggerand the thumb icons rendered bythumbIconare markedaria-hidden="true"and do not affect the accessible name. - If the toggle controls a setting that takes effect after a delay (e.g. a network request), communicate that delay in the surrounding label context, not inside the component.
Styling
Tailwind override: pass className to merge Tailwind classes via cn():
Data slots and attributes: the component sets these for CSS targeting:
data-slot="switch"on the root element.data-slot="switch-thumb"on the sliding knob.data-slot="switch-io"on each I/O indicator span (only whenioTriggeris true).data-slot="switch-thumb-icon"on each icon inside the thumb (only whenthumbIconis true).data-variant="<variant>",data-size="<size>",data-shape="<shape>",data-thumb-type="<thumbType>"on the root.
Target a specific state in CSS:
Related Components
- Checkbox: use when the toggle is part of a form that submits as a unit, or when indeterminate state is needed.
- Radio: use for mutually exclusive choices from a fixed set.
- Segmented Control: use when the user picks between more than two named options.
API Reference
Switch
Single-element toggle for binary on/off settings. Wraps Radix's Switch.Root, so all Radix Switch props (checked, onCheckedChange, defaultChecked, disabled, required, name, value, asChild) are accepted.