Installation#
pnpm dlx shadcn@latest add @zui/switchThe CLI writes components/ui/switch.tsx, installs Utils, and adds @rn-primitives/switch and
class-variance-authority.
Usage#
import { useState } from 'react';
import { Switch } from '@/components/ui/switch';const [airplane, setAirplane] = useState(false);
<Switch checked={airplane} onCheckedChange={setAirplane} aria-label="Airplane mode" />;API reference#
Switch#
Takes every prop of the @rn-primitives/switch root, plus:
| Prop | Type | Default |
|---|---|---|
checked | boolean | required |
onCheckedChange | (checked: boolean) => void | required |
size | 'default' | 'sm' | 'default' |
aria-invalid | boolean | none |
Switch is controlled. Pressing it calls onCheckedChange with the new value, and it moves only once checked
follows. The thumb slides to the other end in 150ms, or jumps there when the system asks for reduced motion.
sm draws a 24px track and the default is 32px. A disabled switch is dimmed and ignores presses.
aria-invalid draws the destructive border. React Native does not announce it, so carry the error in
accessibilityHint or in a Text the user can reach.
Name it with aria-label, which iOS and Android both read. Android also reads a
Label's nativeID through aria-labelledby; iOS ignores that prop.