Switch with motion: the thumb springs across and stretches while you hold it, follows a drag (over past the middle, a rubber band past an end), and phones buzz as it switches.
$ pnpm dlx shadcn@latest add https://dashral.com/r/motion-switch.jsonInstallation
$ pnpm dlx shadcn@latest add https://dashral.com/r/motion-switch.jsonAdds components/dashral/motion/switch.tsx, the Switch it builds on (in components/dashral/), motion and the motion files every motion component shares. With the registry in your components.json:
$ pnpm dlx shadcn@latest add @dashral/motion-switchUsage
The same as Switch, imported from components/dashral/motion/: swap the import and it moves.
import { Switch } from "@/components/dashral/motion/switch"
<Switch label="Marketing emails" labelPosition="start" checked={emails} onCheckedChange={setEmails} />Examples
Settings that save
Flip a switch, or drag its thumb: Saving… then Saved pops in, and what goes with it opens beneath. Hold one down: the thumb stretches and the track gives.
Services
Each switch in the color of what it means; turned on, its dot pulses and the status under its name rises in.
Compared with Default
The thumb slides on --ease-spring.
Motion
The thumb springs across and stretches while held, the track giving under it; drag the thumb and it follows, going over past the middle and holding back like a rubber band past an end; phones buzz.
How the two editions differ in general, and which to use where: Motion.
API reference
Every prop of Switch, and every attribute of the element it renders. The Motion edition adds no props of its own.
Switch
Also takes every prop of Radix Switch(opens in a new tab).
| Prop | Type | Default |
|---|---|---|
checked / defaultChecked | boolean | — |
onCheckedChange | (checked: boolean) => void | — |
label | ReactNodeBeside the control; clicking it works the control. | — |
description | ReactNodeA hint under the label. | — |
color | "primary" | "neutral" | "info" | "success" | "warning" | "destructive" | "highlight"The color when on, ticked or picked. | "primary" |
labelPosition | "end" | "start""start" puts the label first and the switch at the far end, as in a settings row. | "end" |
error | boolean | ReactNodeA message shows under the label. | — |
classNames | { root, label, description, error, switch }Classes for each part. | — |
Motion
- The thumb springs to its side with a touch of overshoot (motion's layout animation); the track's color fades as it goes.
- Held down, the thumb stretches from 16px to 20px toward where it's headed, and settles back when you let go, wherever the pointer is.
- Drag the thumb and it follows your finger: let go past the middle and it goes over, short of it it springs back; pulled the other way or past the end it holds back like a rubber band (5px at most). The click a drag ends with isn't a second toggle.
- Held, the track gives a little (to 95%). On a phone it buzzes as it switches and gives a tick as a drag crosses the middle.
- With reduced motion the thumb simply moves: no stretch, no drag, no give.