Installation
Registry — recommended
Copies the component into your configured shadcn UI directory and installs Motion.
npx shadcn@latest add https://suluu.site/r/switch-toggle.jsonnpm package
For centralized upgrades, install the optional ESM package and configure Tailwind source detection as shown below.
pnpm add suluu motionUsage
Give every switch a stable accessible name. Use defaultChecked for local state, or pair checked with onCheckedChange when your application owns the setting. SwitchToggle renders only the control; visible labels and status text belong to your surrounding markup.
import { SwitchToggle } from "@/components/ui/switch-toggle"
export function SoundSetting() {
return (
<SwitchToggle
aria-label="Background sounds"
defaultChecked
onCheckedChange={(checked) => saveSoundSetting(checked)}
/>
)
}// app/globals.css
@import "suluu/styles.css";
@source "../node_modules/suluu/dist";
// component.tsx
import { SwitchToggle } from "suluu/switch-toggle"
export function SoundSetting() {
return <SwitchToggle aria-label="Background sounds" defaultChecked />
}Controlled state
const [enabled, setEnabled] = useState(false)
<SwitchToggle
aria-label="Background sounds"
checked={enabled}
onCheckedChange={setEnabled}
/>In context
Pair the spring switch with a persistent setting whose effect is immediate and reversible.
Product updates
A concise weekly note when something meaningful changes.
Props
SwitchToggle accepts safe native button attributes, always uses type="button", and forwards its ref to the button element.
| Prop | Type | Default | Description |
|---|---|---|---|
| checked | boolean | — | Controlled checked state. |
| defaultChecked | boolean | false | Initial uncontrolled state. |
| onCheckedChange | (checked) => void | — | Runs when a tap, key press, or drag requests a state change. |
| disabled | boolean | false | Disables every interaction. |
| className | string | — | Class name applied to the switch. |
Theming
Override these variables in your light and dark theme scopes. The registry installs the defaults automatically.
--suluu-switch-backgroundUnchecked track surface.--suluu-switch-background-checkedChecked track surface.--suluu-switch-thumbThumb surface.--suluu-switch-iconUnchecked minus icon.--suluu-switch-icon-checkedChecked check icon.--suluu-switch-ringKeyboard focus ring.--suluu-switch-offsetColor behind the focus ring offset.--suluu-switch-shadowUnchecked track depth.--suluu-switch-shadow-checkedChecked track depth and glow.--suluu-switch-thumb-shadowThumb elevation.The root exposes data-state and data-dragging for state-specific styling.
Accessibility
The spring switch is a native button with role="switch" and a live aria-checked state. Enter and Space work through native button behavior, focus remains on the control after dragging, and disabled state blocks every input path.
With reduced motion, the control keeps direct dragging but removes spring overshoot, elasticity, pill follow, squash, and path interpolation. The short state change becomes immediate.