v0.5

Switch

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

pnpm dlx @create-ui/cli add switch

Usage

import { Switch } from "@/components/ui/switch"
<Switch />

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.

Disabled

Accessibility

Built on Radix's Switch.Root, which sets role="switch" and manages aria-checked automatically.

KeyDescription
SpaceToggles the switch.
TabMoves focus to the next focusable element.
Shift+TabMoves focus to the previous focusable element.

ARIA notes:

  • Radix sets role="switch" and keeps aria-checked in 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-labelledby on the root so screen readers can announce what is being toggled.
  • The I/O symbols rendered by ioTrigger and the thumb icons rendered by thumbIcon are marked aria-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():

<Switch className="opacity-75" />

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 when ioTrigger is true).
  • data-slot="switch-thumb-icon" on each icon inside the thumb (only when thumbIcon is true).
  • data-variant="<variant>", data-size="<size>", data-shape="<shape>", data-thumb-type="<thumbType>" on the root.

Target a specific state in CSS:

[data-slot="switch"][data-variant="semantic"][data-state="checked"] {
  /* … */
}
  • 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.

Props

PropTypeDefaultDescription
checkedboolean-Controlled checked state.
defaultCheckedboolean-Uncontrolled initial checked state.
onCheckedChange(checked: boolean) => void-Callback fired when the state changes.
disabledbooleanfalsePrevents interaction and applies muted styles.
ioTriggerbooleanfalseRenders a pipe symbol when on and a circle when off, inside the track.
thumbIconbooleanfalseRenders a check icon in the thumb when on, and a close icon when off.
classNamestring-Tailwind classes merged with the component's CVA classes via cn().

Variants

VariantOptionsDefaultDescription
variant"primary" "info" "neutral" "inverse" "semantic""primary"Semantic color. semantic is red when unchecked and green when checked.
size"md" "sm" "xs""sm"Controls track height and thumb dimensions.
shape"pill" "rounded""pill"pill is fully rounded; rounded follows a stepped radius scale per size.
thumbType"short" "long""short"long widens the thumb and extends its travel distance.