Switch
A tactile toggle for settings that take effect immediately.
togglesettings
Preview
Switch preview
Live · keyboard ready
When to use
- Settings that take effect as soon as they are flipped, like notifications.
- Settings lists where each row is one on and off preference.
When not to use
- Use checkbox when the choice waits for a submit button.
- Use segmented-control for a choice between named options.
- Use theme-switch for a light and dark toggle.
shadcn CLI
Also installs (1)
- manicat-foundation
Manual install(+)
registry.jsonjson
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "switch",
"type": "registry:ui",
"title": "Switch",
"description": "A tactile toggle for settings that take effect immediately.",
"categories": [
"inputs"
],
"dependencies": [
"@radix-ui/react-switch",
"motion"
],
"registryDependencies": [
"https://manicat.viraza.net/r/manicat-foundation.json"
],
"files": [
{
"path": "registry/components/switch/switch.tsx",
"type": "registry:component",
"target": "@components/manicat/switch/switch.tsx"
},
{
"path": "registry/components/switch/switch.module.css",
"type": "registry:component",
"target": "@components/manicat/switch/switch.module.css"
}
],
"docs": "Docs and live preview: https://uiarc.dev/components/switch",
"meta": {
"tier": "free",
"kind": "component",
"docs": "https://manicat.viraza.net/components/switch",
"markdown": "https://uiarc.dev/components/switch/markdown",
"tags": [
"toggle",
"settings"
]
}
}Usage
Install the component, then copy this into your app. Change the content and the props to fit your screen.
example.tsxtsx
"use client";
import { useState } from "react";
import { Switch } from "@/components/manicat/switch/switch";
export function SwitchExample() {
const [checked, setChecked] = useState(true);
return (
<div className="grid gap-3">
<Switch label="Reduced motion" checked={checked} onCheckedChange={setChecked} />
<Switch label="Always on" />
</div>
);
}
Examples
Real screens rather than isolated props. Switch to Code to copy a whole example into your project.
Notification settings A settings card where each row pairs a label with a switch, and the master switch gates the others.
Notification settings
A settings card where each row pairs a label with a switch, and the master switch gates the others. preview
Live · keyboard ready
notification-settings-a-settings-card-where-each-row-pairs-a-label-with-a-switch-and-the-master-switch-gates-the-others-.tsxtsx
"use client";
import { useState } from "react";
import { Switch } from "@/components/manicat/switch/switch";
export function SwitchSettingsExample() {
const [enabled, setEnabled] = useState(true);
const [mentions, setMentions] = useState(true);
const [digest, setDigest] = useState(false);
return (
<div className="grid w-full max-w-sm gap-4 rounded-[var(--radius-panel)] border border-(color:--border) bg-(--surface) p-5">
<Switch label="Push notifications" checked={enabled} onCheckedChange={setEnabled} />
<div className="grid gap-3 border-t border-(color:--border) pt-4">
<Switch label="Mentions and replies" checked={enabled && mentions} onCheckedChange={setMentions} disabled={!enabled} />
<Switch label="Weekly digest" checked={enabled && digest} onCheckedChange={setDigest} disabled={!enabled} />
</div>
</div>
);
}
Keyboard interactions
| Keys | Action |
|---|---|
| Space / Enter | Toggles the switch. Holding Space stretches the thumb until release. |
Accessibility
- Radix renders a button with role="switch" and aria-checked.
- The label prop becomes aria-label unless one is passed; icon-only usage needs an aria-label.
Motion
- Pressing stretches the thumb toward the other side like a held finger; releasing sends it across on a snappy spring.
- Reduced motion removes the stretch and moves the thumb instantly; CSS transitions are also disabled.
Responsive behavior
- The switch is inline and keeps a control-height minimum, so the whole label is a touch target.
- Hover styles apply only on fine pointers; touch gets the press stretch.
Performance
- Motion is CSS transitions on the track and thumb, with no observers or per-frame work.
Notes for AI
- Use for settings that take effect immediately. Use checkbox for choices confirmed by a submit button.
- Exported both as a named and a default export.
- Pass name to submit with a form through Radix's hidden input.