Switch

A toggle whose thumb slides with a double bounce, with hover and press states and geometry you can resize from CSS variables

import { Switch } from "@/components/ui/switch";
export default function SwitchDemo() {
return (
<label className="flex items-center gap-3 text-sm">
<Switch defaultChecked />
Airplane mode
</label>
);
}

Installation

npx shadcn@latest add https://www.deltacomponents.dev/r/switch.json

Usage

1import { Switch } from "@/components/ui/switch";
2
3<Switch defaultChecked />

It is Base UI's Switch underneath, so it carries the switch role, full keyboard support, and a form name/value for free. The thumb's travel is a keyframe sequence that plays only on a change, never on mount.

Basic

import { Switch } from "@/components/ui/switch";
export default function SwitchDemo() {
return (
<label className="flex items-center gap-3 text-sm">
<Switch defaultChecked />
Airplane mode
</label>
);
}

Controlled

Notifications are off

import { useState } from "react";
import { Switch } from "@/components/ui/switch";
export default function SwitchControlled() {
const [on, setOn] = useState(false);
return (
<div className="flex flex-col gap-3">
<Switch checked={on} onCheckedChange={setOn} />
<p className="text-sm text-muted-foreground">
Notifications are {on ? "on" : "off"}
</p>
</div>
);
}

Disabled

import { Switch } from "@/components/ui/switch";
export default function SwitchDisabled() {
return (
<div className="flex items-center gap-6">
<label className="flex items-center gap-3 text-sm">
<Switch disabled />
Off
</label>
<label className="flex items-center gap-3 text-sm">
<Switch disabled defaultChecked />
On
</label>
</div>
);
}

Resized

The whole control is drawn from a handful of CSS variables on the root, so a style sets a new size and the travel, hover pill and press squash all follow.

import type { CSSProperties } from "react";
import { Switch } from "@/components/ui/switch";
export default function SwitchResized() {
return (
<div className="flex items-center gap-6">
<Switch
defaultChecked
aria-label="Compact"
style={
{
"--switch-w": "28px",
"--switch-h": "14px",
"--switch-pad": "2.33px",
"--switch-thumb-w": "14px",
"--switch-thumb-h": "9.33px",
"--switch-press": "3px",
} as CSSProperties
}
/>
<Switch defaultChecked aria-label="Default" />
<Switch
defaultChecked
aria-label="Large"
style={
{
"--switch-w": "56px",
"--switch-h": "28px",
"--switch-pad": "4.67px",
"--switch-thumb-w": "28px",
"--switch-thumb-h": "18.67px",
} as CSSProperties
}
/>
</div>
);
}

Override Styling

Parts you hold no reference to are reachable by data-slot:

API Reference