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 from Animate UI instead of react-aria-components: it re-exports all of React Aria, with the animated controls below. Everything else stays the same.
import { Switch } from '@animate-ui/react/primitives/react-aria';
export function AirplaneMode() {
return (
<Switch>
{({ isSelected }) => (
<>
<span className="track">
<span
data-slot="switch-thumb"
data-selected={isSelected || undefined}
/>
</span>
Airplane mode
</>
)}
</Switch>
);
}React Aria lets you render the thumb yourself. Animate UI glides the element marked data-slot="switch-thumb", which is what shadcn/ui renders: add the attribute to your own thumb.
Animation
The motion of Animate UI v1's Radix UI and Headless UI switches (v1 had no React Aria 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. Pressed means React Aria'sisPressed: the pointer, or Space and Enter on the keyboard. - 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-selected:translate-x-…): Animate UI puts it back where it was with atransformand springs it to its new place. - Switch 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. - 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). className,styleandrenderprops keep working.
API Reference
Switch takes exactly the props of React Aria's Switch, plus the props below.
| Prop | Type | Default |
|---|---|---|
transition? | Transition | { type: 'spring', stiffness: 300, damping: 25 } |
AnimateUIProvider's tempo scales the spring with everything else.