A control that allows the user to toggle between checked and not checked.
Installation
Install the packages
Add the shadcn/ui component
Animate it
The CLI finds your shadcn/ui components through components.json, swaps their primitive imports for Animate UI's and removes the CSS animation classes Motion replaces.
Usage
Import the primitive from Animate UI instead of Radix UI. Everything else stays the same.
import { Switch } from '@animate-ui/react/primitives/radix-ui';
export function AirplaneMode() {
return (
<label className="flex items-center gap-2">
<Switch.Root>
<Switch.Thumb />
</Switch.Root>
Airplane mode
</label>
);
}Coming from the @radix-ui/react-switch package? Use the subpath: import * as SwitchPrimitive from '@animate-ui/react/primitives/radix-ui/switch'.
Animation
The motion of Animate UI v1's switch:
- Thumb, pressed: stretches toward the middle of the track, its other edge in place. Its width grows by 3/16 (a 16px thumb becomes 19px, v1's
pressedWidth) on a spring (stiffness 300, damping 25). It's the thumb's real width, so its round ends stay round. - Thumb, on a change: springs to its new side while its width springs back, on the same spring (v1's
layoutanimation). The thumb'stranslateclasses still decide where it rests (data-checked:translate-x-…): Animate UI puts it back where it was with atransformand springs it to its new place. - Root doesn't move. Its colours are the component's CSS, and v1's track changed colour at once: shadcn/ui's
transition-allon the track would fade it, so the CLI removes it. - The press is v1's: the pointer, or Enter on the keyboard. Space toggles without the stretch, and the thumb glides the same way.
- Toggling again mid-glide turns back from where the thumb is, without a jump.
- Under reduced motion, the thumb jumps to its side, without the stretch.
- shadcn/ui's
transition-transformon the thumb would tween itstranslate; the CLI removes it too (Animate UI also skips it while measuring, so a leftover class doesn't break the glide).
API Reference
Every part takes exactly the props of Radix UI's Switch. Animate UI adds the animation props below. With asChild, a part renders your element with Radix's behaviour: an asChild Root has no press stretch, an asChild Thumb no animation.
Root
Radix UI props. The Root doesn't animate itself: it tells the Thumb when it's pressed.
Thumb
Radix UI props, plus:
| Prop | Type | Default |
|---|---|---|
transition? | Transition | { type: 'spring', stiffness: 300, damping: 25 } |
AnimateUIProvider's tempo scales the spring with everything else.