Documentation Index
Fetch the complete documentation index at: https://mintlify.com/mui/base-ui/llms.txt
Use this file to discover all available pages before exploring further.
A toggle switch for binary on/off states.
import { Switch } from '@base-ui/react/switch';
Anatomy
The Switch component consists of two parts:
Switch.Root - The switch control itself
Switch.Thumb - The draggable thumb element
Basic Usage
<Switch.Root>
<Switch.Thumb />
</Switch.Root>
Key Features
- Controlled and uncontrolled modes
- Accessible with proper ARIA attributes
- Works seamlessly with Field and Form components
- Custom render props
- Support for read-only and disabled states
Key Props
checked
Type: boolean
Whether the switch is currently active. Use with onCheckedChange for controlled mode.
const [checked, setChecked] = React.useState(false);
<Switch.Root checked={checked} onCheckedChange={setChecked}>
<Switch.Thumb />
</Switch.Root>
defaultChecked
Type: boolean
Default: false
Whether the switch is initially active. Use for uncontrolled mode.
<Switch.Root defaultChecked>
<Switch.Thumb />
</Switch.Root>
onCheckedChange
Type: (checked: boolean, eventDetails: ChangeEventDetails) => void
Event handler called when the switch is activated or deactivated.
<Switch.Root onCheckedChange={(checked) => console.log('Switch:', checked)}>
<Switch.Thumb />
</Switch.Root>
disabled
Type: boolean
Default: false
Whether the component should ignore user interaction.
<Switch.Root disabled>
<Switch.Thumb />
</Switch.Root>
readOnly
Type: boolean
Default: false
Whether the user should be unable to activate or deactivate the switch.
required
Type: boolean
Default: false
Whether the user must activate the switch before submitting a form.
Type: string
Identifies the field when a form is submitted.
Type: string
The value submitted with the form when the switch is on.
uncheckedValue
Type: string
The value submitted with the form when the switch is off.
inputRef
Type: React.Ref<HTMLInputElement>
A ref to access the hidden input element.
Styling
<Switch.Root className="relative w-11 h-6 rounded-full bg-gray-200 data-[checked]:bg-blue-500 transition-colors">
<Switch.Thumb className="absolute left-0.5 top-0.5 w-5 h-5 rounded-full bg-white shadow-md transition-transform data-[checked]:translate-x-5" />
</Switch.Root>
<Switch.Root className={styles.root}>
<Switch.Thumb className={styles.thumb} />
</Switch.Root>
.root {
position: relative;
width: 2.75rem;
height: 1.5rem;
border-radius: 9999px;
background-color: #e5e7eb;
transition: background-color 0.2s;
}
.root[data-checked] {
background-color: #3b82f6;
}
.root[data-disabled] {
opacity: 0.5;
cursor: not-allowed;
}
.thumb {
position: absolute;
left: 0.125rem;
top: 0.125rem;
width: 1.25rem;
height: 1.25rem;
border-radius: 50%;
background-color: white;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
transition: transform 0.2s;
}
.thumb[data-checked] {
transform: translateX(1.25rem);
}
Common Patterns
With Label
import { Field } from '@base-ui/react/switch';
<Field.Root>
<div className="flex items-center justify-between">
<Field.Label>Enable notifications</Field.Label>
<Switch.Root name="notifications">
<Switch.Thumb />
</Switch.Root>
</div>
</Field.Root>
Settings List
function SettingsList() {
const [settings, setSettings] = React.useState({
notifications: true,
darkMode: false,
analytics: true,
});
return (
<div className="space-y-4">
<div className="flex items-center justify-between">
<div>
<div className="font-medium">Push Notifications</div>
<div className="text-sm text-gray-500">Receive push notifications</div>
</div>
<Switch.Root
checked={settings.notifications}
onCheckedChange={(checked) =>
setSettings({ ...settings, notifications: checked })
}
>
<Switch.Thumb />
</Switch.Root>
</div>
<div className="flex items-center justify-between">
<div>
<div className="font-medium">Dark Mode</div>
<div className="text-sm text-gray-500">Use dark theme</div>
</div>
<Switch.Root
checked={settings.darkMode}
onCheckedChange={(checked) =>
setSettings({ ...settings, darkMode: checked })
}
>
<Switch.Thumb />
</Switch.Root>
</div>
</div>
);
}
With Icons
<Switch.Root className="relative w-14 h-7 rounded-full bg-gray-200 data-[checked]:bg-blue-500">
<Switch.Thumb className="absolute left-1 top-1 w-5 h-5 rounded-full bg-white flex items-center justify-center transition-transform data-[checked]:translate-x-7">
<svg className="w-3 h-3" fill="currentColor">
<path d="M12 2.25a.75.75 0 01.75.75v2.25a.75.75 0 01-1.5 0V3a.75.75 0 01.75-.75zM7.5 12a4.5 4.5 0 119 0 4.5 4.5 0 01-9 0z" />
</svg>
</Switch.Thumb>
</Switch.Root>
Form Integration
import { Form, Field } from '@base-ui/react/switch';
<Form.Root>
<Field.Root name="terms" required>
<div className="flex items-center gap-3">
<Switch.Root>
<Switch.Thumb />
</Switch.Root>
<Field.Label>
I agree to the terms and conditions
</Field.Label>
</div>
<Field.Error />
</Field.Root>
</Form.Root>
Color Variants
function ColoredSwitch() {
const [checked, setChecked] = React.useState(false);
return (
<Switch.Root
checked={checked}
onCheckedChange={setChecked}
className="relative w-11 h-6 rounded-full bg-gray-200 data-[checked]:bg-green-500"
>
<Switch.Thumb className="absolute left-0.5 top-0.5 w-5 h-5 rounded-full bg-white shadow transition-transform data-[checked]:translate-x-5" />
</Switch.Root>
);
}