Skip to content

Now in the official shadcn registry directory.

Start free

Switch

A binary on/off control - the checked track takes 4 semantic tones and the thumb animates on motion tokens.

form
A free styled version is available

Installation

Run the following command

npx shadcn@latest add @ai2/switch

Dependencies, the @ai2/tokens theme and the component file are installed together.

Usage

TS
import { Switch } from "@/components/ui/switch"
import { Label } from "@/components/ui/label"

<Label>
  <Switch tone="success" defaultChecked /> Auto-deploy on push
</Label>

Wrapping the switch in a Label makes the text clickable too. Both axes are optional - the default is the neutral medium switch.

Examples

Tones

The tone only shows while checked - every unchecked track uses the same neutral input color.

Sizes

Disabled

Invalid

Set aria-invalid when validation fails. The danger border and ring style is built in and matches every other ai2 form control.

Props

Switch also accepts every radix Switch prop - checked, defaultChecked, onCheckedChange and disabled included.

PropTypeDefaultDescription
tone"neutral" | "brand" | "success" | "danger""neutral"Semantic color of the checked track, mapped to theme tokens. Unchecked tracks always use the input token.
size"sm" | "md" | "lg""md"Track and thumb dimensions, including thumb travel distance.

ai2 Switch: a toggle for React with semantic tones and sizes

The ai2 Switch is a shadcn-compatible switch component for React, built on the radix-ui Switch primitive and styled with Tailwind CSS v4. It is the binary on and off control for settings screens, feature flags and preference panels, with a 4-tone by 3-size matrix from a single cva: the checked track takes a semantic color while every unchecked track stays on the neutral input token.

It ships through the shadcn registry format, so one CLI command, an MCP agent, or a copy-paste puts the source in your own project. You own the file; there is no runtime dependency on ai2 itself. The live example above is the exact component you get.

What is the ai2 Switch?

It is a two-part render behind one export: Switch wraps the radix Switch.Root track and its Switch.Thumb, so usage stays a single self-closing tag. The anatomy matches shadcn/ui exactly, extended with two cva axes: tone (neutral, brand, success, danger) and size (sm, md, lg).

The tone only colors the checked state, mapping to the primary, brand, success and danger theme tokens. The size axis scales the track, the thumb and the thumb's travel distance together, and the travel animates on the shared --motion-fast token, so a small switch and a large switch feel like the same component.

Why use it

  • Accessible by construction: The radix-ui Switch primitive renders a real button with role="switch" and aria-checked, toggles with Space and Enter, and participates in forms and labels like a native control.
  • Semantic tones: neutral for ordinary settings, brand for promoted features, success for healthy states like auto-deploy, danger for risky toggles. The unchecked track always stays neutral, so meaning attaches to the on state only.
  • Three coherent sizes: sm, md and lg scale the track, thumb and travel distance together from one cva pair, so density changes never break the geometry.
  • Motion from tokens: Both the track color and the thumb travel transition on --motion-fast with the shared easing, matching every other ai2 component.
  • Agent-readable metadata: The registry item states the tone and size matrix in plain words, so an MCP agent can find, inspect and install it without guessing.

Features

  • shadcn registry install: One command adds the component, its radix-ui dependency and the @ai2/tokens theme to your project.
  • 4 tones x 3 sizes: Twelve combinations from two cva axes, all resolved against theme tokens rather than hardcoded colors.
  • Controlled and uncontrolled state: Use defaultChecked for simple cases or drive checked and onCheckedChange from React state when other UI depends on the value.
  • Form-ready: The radix primitive supports name, value, required and disabled, and submits like a native checkbox inside a form.
  • Data attributes for styling: The track exposes data-slot="switch", data-tone and data-state, the thumb exposes data-slot="switch-thumb", so you can restyle states from CSS without forking the component.
  • Focus ring and invalid styling: Keyboard focus gets a 3px ring on the ring token, and aria-invalid switches the track to the danger border and ring, consistent with every ai2 form control.

Production tips

  • Wrap it in a Label: Putting the Switch inside an ai2 Label makes the text clickable and gives screen readers the accessible name in one move. Standalone switches need an aria-label instead.
  • Use switches for instant effects: A switch implies the change applies immediately. If the value only applies after a Save button, a checkbox communicates the deferred behavior better.
  • Reserve danger for real risk: A red checked track reads as a warning. Use tone="danger" for toggles like public access or force deploys, not for ordinary off-by-default settings.
  • Keep tone consistent per screen: Pick one tone for a settings group instead of mixing colors row by row; the tone should encode meaning, not decoration.
  • Label the setting, not the action: Prefer "Auto-deploy on push" over "Enable auto-deploy". The switch itself already communicates on and off, so the label should name the thing being controlled.

Works with the rest of ai2

The switch composes naturally with the rest of the registry. Pair it with an ai2 Label for clickable text, lay out settings rows with ai2 Field, and group related toggles inside an ai2 Card with ai2 Separator rows between sections.

When the choice is a deferred selection rather than an instant toggle, use Checkbox instead, and for one-of-many options reach for Radio Group. All three share the same tone vocabulary and token source, so mixed forms stay visually consistent in both modes.

FAQs

Get new components in your inbox

Component drops, new themes and release notes. No spam, and you can unsubscribe from any email.

© 2026 ai2 design system · MIT licensed · Built with its own components