Overview
The Switch component provides an accessible toggle switch with smooth animations and optional descriptions. Built on React Aria Components for full keyboard navigation and screen reader support.
Import
import { Switch } from 'stride-ds';
Basic Usage
import { Switch } from 'stride-ds';
function Example() {
return <Switch>Enable notifications</Switch>;
}
Sizes
Three size options are available:
<Switch size="sm">Small switch</Switch>
<Switch size="md">Medium switch</Switch>
<Switch size="lg">Large switch</Switch>
With Description
Add supporting text below the main label:
<Switch
description="Get notified when someone mentions you in a comment or assigns you a task."
>
Enable notifications
</Switch>
States
On/Off
<Switch>Off (default)</Switch>
<Switch isSelected>On</Switch>
Disabled
<Switch isDisabled>Disabled</Switch>
<Switch isSelected isDisabled>Disabled & On</Switch>
Props
size
'sm' | 'md' | 'lg'
default:"'md'"
Size of the switch. Affects track and thumb dimensions.
The label text for the switch.
Additional description text displayed below the label.
Whether the switch is on (controlled).
Whether the switch is initially on (uncontrolled).
Whether the switch is disabled.
onChange
(isSelected: boolean) => void
Handler called when the switch state changes.
Additional CSS classes to apply.
The value of the switch in a form.
The name of the switch in a form.
Accessibility
The Switch component is built with React Aria Components and provides:
- Keyboard Navigation: Space to toggle, Tab to move focus
- Focus Management: Clear focus indicators
- Screen Reader Support: Proper ARIA attributes including
role="switch" and aria-checked
- Label Association: Automatic association between switch and label
- State Announcements: On/off state changes are announced to screen readers
Best Practices
-
Always provide a label via
children or use aria-label:
<Switch>Enable feature</Switch>
// or
<Switch aria-label="Enable feature" />
-
Use
description for additional context:
<Switch description="This will enable advanced features">
Enable advanced mode
</Switch>
-
Use switches for immediate action toggles, not for form submission:
// Good: Immediate effect
<Switch onChange={toggleDarkMode}>Dark mode</Switch>
// Bad: Should use checkbox in a form instead
<Switch>Accept terms</Switch>
Examples
All States
<div className="flex flex-col space-y-4">
<Switch>Off</Switch>
<Switch isSelected>On</Switch>
<Switch isDisabled>Disabled</Switch>
<Switch isSelected isDisabled>Disabled & On</Switch>
</div>
All Sizes with States
<div className="flex flex-col space-y-6">
<div>
<h3 className="text-sm font-medium mb-3">Small</h3>
<div className="space-y-3">
<Switch size="sm">Dark mode</Switch>
<Switch size="sm" isSelected>Auto-save</Switch>
<Switch size="sm" isDisabled>Beta features</Switch>
</div>
</div>
<div>
<h3 className="text-sm font-medium mb-3">Medium</h3>
<div className="space-y-3">
<Switch size="md">Dark mode</Switch>
<Switch size="md" isSelected>Auto-save</Switch>
<Switch size="md" isDisabled>Beta features</Switch>
</div>
</div>
<div>
<h3 className="text-sm font-medium mb-3">Large</h3>
<div className="space-y-3">
<Switch size="lg">Dark mode</Switch>
<Switch size="lg" isSelected>Auto-save</Switch>
<Switch size="lg" isDisabled>Beta features</Switch>
</div>
</div>
</div>
Settings Panel
import { Switch } from 'stride-ds';
import { useState } from 'react';
function SettingsPanel() {
const [settings, setSettings] = useState({
notifications: true,
darkMode: false,
autoSave: true,
analytics: false,
});
return (
<div className="space-y-4">
<h3 className="text-lg font-semibold">Preferences</h3>
<Switch
isSelected={settings.notifications}
onChange={(checked) =>
setSettings({ ...settings, notifications: checked })
}
description="Receive notifications about mentions and assignments"
>
Enable notifications
</Switch>
<Switch
isSelected={settings.darkMode}
onChange={(checked) =>
setSettings({ ...settings, darkMode: checked })
}
description="Use dark theme throughout the application"
>
Dark mode
</Switch>
<Switch
isSelected={settings.autoSave}
onChange={(checked) =>
setSettings({ ...settings, autoSave: checked })
}
description="Automatically save your work every 30 seconds"
>
Auto-save
</Switch>
<Switch
isSelected={settings.analytics}
onChange={(checked) =>
setSettings({ ...settings, analytics: checked })
}
description="Help us improve by sharing anonymous usage data"
>
Analytics
</Switch>
</div>
);
}
Without Label (Icon Only)
<Switch aria-label="Toggle dark mode" />
Controlled Component
import { useState } from 'react';
import { Switch } from 'stride-ds';
function ControlledExample() {
const [isEnabled, setIsEnabled] = useState(false);
return (
<div>
<Switch
isSelected={isEnabled}
onChange={setIsEnabled}
>
Feature toggle
</Switch>
<p className="mt-4">
Status: {isEnabled ? 'Enabled' : 'Disabled'}
</p>
</div>
);
}
With Long Description
<Switch
description="This will enable the advanced notification system that includes push notifications, email alerts, and in-app notifications. You can customize these settings later in your preferences."
>
Enable advanced notification system
</Switch>
import { Switch } from 'stride-ds';
import { useState, useEffect } from 'react';
function DarkModeToggle() {
const [isDark, setIsDark] = useState(false);
useEffect(() => {
// Apply dark mode class immediately when switch changes
if (isDark) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
}, [isDark]);
return (
<Switch
isSelected={isDark}
onChange={setIsDark}
description="Toggle between light and dark theme"
>
Dark mode
</Switch>
);
}
The Switch component works with React Hook Form:
import { useForm, Controller } from 'react-hook-form';
import { Switch } from 'stride-ds';
function FormExample() {
const { control, handleSubmit } = useForm();
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="notifications"
control={control}
render={({ field }) => (
<Switch
isSelected={field.value}
onChange={field.onChange}
description="Receive email notifications"
>
Enable notifications
</Switch>
)}
/>
</form>
);
}
Differences from Checkbox
Use Switch when:
- The action takes effect immediately
- You’re toggling a system state (on/off, enabled/disabled)
- No form submission is required
Use Checkbox when:
- The action is part of a form submission
- Multiple selections are needed
- The action represents agreement or selection