caliper uidocs

Switch

Free

An immediate on/off setting built on a native checkbox with role="switch", so forms, labels and reset just work.

Source packages/ui/src/switch.tsxDepends on none beyond ReactMotion 260 ms thumb · stretches on press
Notifications
Density

Installation #

terminal
pnpm dlx shadcn@latest add https://caliperui.site/r/switch.json

Adds the file to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.

Usage #

Use a switch when the change applies immediately. If the user must press Save, use a checkbox.

Wrap the whole row in a label so the text is part of the touch target.

It forwards every native input prop, including name and defaultChecked for uncontrolled forms.

notification-settings.tsx
import { Switch } from "@/components/ui/switch"

export function ReleaseNotes() {
  return (
    <label className="flex items-center justify-between">
      <span>Release notes</span>
      <Switch name="releaseNotes" defaultChecked />
    </label>
  )
}

Examples #

On, off and disabled

Disabled keeps its value visible at reduced opacity.

API reference #

Accepts every native input prop except type and role, which are fixed.

PropTypeDefaultDescription
checkedboolean—Controlled value.
defaultCheckedboolean—Uncontrolled initial value.
onChange(event) => void—Native change event.
disabledbooleanfalseNative disabled attribute.

Accessibility #

A native checkbox with role="switch" sits over the visual track, so it is announced as a switch and toggles with Space.

KeyBehaviour
TabFocuses the switch.
SpaceToggles it.

Motion #

The thumb travels 14 px on the settle curve while the track fills with ink. While pressed, the thumb stretches toward its travel and settles when released. Reduced motion jumps the thumb; the track colour and state still change.

36 × 22track · 18 px thumb
14 pxthumb travel
260 msthumb · ease-settle · 1.22× stretch on press