Switch
- Component overview: Toggle control that switches between On and Off states at a fixed size.
- Size baseline: Track 36×20px, thumb 16×16px, 2px padding on each side.
- Implementation note: The track retains the structural skeleton; visuals are controlled by design tokens.
loadingcurrently preserves the Default visual and disables interaction. - Figma spec
States
6 states: On / Off × Enabled / Disabled / Loading.
Result
Loading...
Live Editor
<div style={{ display: 'flex', gap: 32, flexWrap: 'wrap', alignItems: 'center' }}> <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}> <Switch defaultChecked aria-label="demo on" /> <span style={{ fontSize: 12, color: '#999' }}>On</span> </div> <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}> <Switch aria-label="demo off" /> <span style={{ fontSize: 12, color: '#999' }}>Off</span> </div> <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}> <Switch defaultChecked disabled aria-label="demo disabled on" /> <span style={{ fontSize: 12, color: '#999' }}>Disabled On</span> </div> <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}> <Switch disabled aria-label="demo disabled off" /> <span style={{ fontSize: 12, color: '#999' }}>Disabled Off</span> </div> <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}> <Switch defaultChecked loading aria-label="demo loading on" /> <span style={{ fontSize: 12, color: '#999' }}>Loading On</span> </div> <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}> <Switch loading aria-label="demo loading off" /> <span style={{ fontSize: 12, color: '#999' }}>Loading Off</span> </div> </div>
| State | Track color | Thumb color | Opacity |
|---|---|---|---|
| On + Enabled | Foregrounds/Toggle On#1573D1 | Foregrounds/White#FFFFFF | 100% |
| Off + Enabled | Foregrounds/Toggle Off#D6D6D6 | Foregrounds/White#FFFFFF | 100% |
| On + Disabled | Foregrounds/Toggle On#1573D1 | Foregrounds/White#FFFFFF | 60% |
| Off + Disabled | Foregrounds/Toggle Off#D6D6D6 | Foregrounds/White#FFFFFF | 60% |
| On + Loading | Foregrounds/Toggle On#1573D1 | Foregrounds/White#FFFFFF | 100% |
| Off + Loading | Foregrounds/Toggle Off#D6D6D6 | Foregrounds/White#FFFFFF | 100% |
Controlled Mode
Result
Loading...
Live Editor
function ControlledSwitch() { const [checked, setChecked] = useState(false) return ( <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}> <Switch checked={checked} onCheckedChange={setChecked} aria-label="controlled" /> <span style={{ fontSize: 14 }}>{checked ? 'On' : 'Off'}</span> </div> ) }
Size Spec
| Dimension | Value |
|---|---|
| Track width | 36px |
| Track height | 20px |
| Track border radius | 5px |
| Thumb size | 16×16px |
| Thumb border radius | Radius_5 - 2px |
| Thumb padding | 2px |
Props
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | - | Controlled checked state |
defaultChecked | boolean | false | Initial checked state (uncontrolled) |
onCheckedChange | (checked: boolean) => void | - | State change callback |
disabled | boolean | false | Disabled state (60% opacity) |
loading | boolean | false | Loading state — currently preserves Default visual and disables interaction |
aria-label | string | - | Accessibility label |