Toggle
A switch control for binary on/off states. Renders with the switch ARIA role for correct screen reader semantics.
Preview
Sizes
| Size | Track width | Track height | Thumb size |
|---|---|---|---|
sm | 36 px | 20 px | 16 px |
md | 44 px | 24 px | 20 px |
Features
- Label -- optional label rendered next to the toggle. Position can be
leftorright. - Disabled -- reduces opacity to 50% and prevents interaction.
- Spring easing -- the thumb uses the spring easing curve for a tactile feel.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | false | Whether the toggle is on |
onChange | (checked: boolean) => void | -- | Called when the state changes |
size | 'sm' | 'md' | 'md' | Toggle dimensions |
label | string | -- | Visible label text |
labelPosition | 'left' | 'right' | 'right' | Which side the label appears on |
disabled | boolean | false | Disables the toggle |
className | string | -- | Additional CSS classes |
Code example
React
tsx
import { useState } from 'react';
import { Toggle } from '@thepace/lexicon/components';
function NotificationSettings() {
const [email, setEmail] = useState(true);
const [sms, setSms] = useState(false);
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-4)' }}>
<Toggle
checked={email}
onChange={setEmail}
label="Email notifications"
/>
<Toggle
checked={sms}
onChange={setSms}
label="SMS notifications"
size="sm"
/>
<Toggle
checked={false}
label="Push notifications"
disabled
/>
</div>
);
}Vanilla HTML
html
<label class="lex-toggle">
<button
class="lex-toggle__track lex-toggle__track--on"
role="switch"
aria-checked="true"
aria-label="Email notifications"
>
<span class="lex-toggle__thumb"></span>
</button>
<span class="lex-toggle__label">Email notifications</span>
</label>
<label class="lex-toggle lex-toggle--sm">
<button
class="lex-toggle__track"
role="switch"
aria-checked="false"
aria-label="SMS notifications"
>
<span class="lex-toggle__thumb"></span>
</button>
<span class="lex-toggle__label">SMS notifications</span>
</label>CSS class reference
| Class | Purpose |
|---|---|
.lex-toggle | Wrapper (flex container with label) |
.lex-toggle--sm | Small size |
.lex-toggle--md | Medium size (default) |
.lex-toggle--disabled | Disabled state |
.lex-toggle__track | The track (pill-shaped background) |
.lex-toggle__track--on | Active/on state |
.lex-toggle__thumb | The sliding circle |
.lex-toggle__label | Label text |
Accessibility
- Uses
role="switch"witharia-checkedreflecting the current state. - When a
labelprop is provided, it is linked viaaria-labelledby. Without a label, providearia-labeldirectly. - The toggle is focusable and activates on
SpaceorEnter. - When
disabled,aria-disabled="true"is set and interaction is suppressed. - The focus ring uses
--border-focusfor clear keyboard navigation visibility.