# Switch Component Usage
## Overview
The switch component provides a toggle control for binary settings. It's an accessible alternative to checkboxes for on/off states, commonly used for settings and preferences. Switches use the native checkbox with `role="switch"` for proper accessibility.
## JavaScript Requirements
### Required Scripts
```html
<!-- Include Basecoat CSS and JavaScript -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/basecoat-css@latest/dist/basecoat.cdn.min.css">
<script src="https://cdn.jsdelivr.net/npm/basecoat-css@latest/dist/js/basecoat.min.js" defer></script>
<script src="https://cdn.jsdelivr.net/npm/basecoat-css@latest/dist/js/switch.min.js" defer></script>
```
## HTML Structure
### Basic Switch
```html
<input type="checkbox" role="switch" class="input">
```
### Switch with Label
```html
<label class="label gap-3">
<input type="checkbox" role="switch" class="input">
Enable notifications
</label>
```
### Switch with Description
```html
<div class="flex items-center justify-between gap-4">
<div class="grid gap-1">
<label for="airplane-mode" class="label">Airplane Mode</label>
<p class="text-muted-foreground text-sm">Disable all wireless connections</p>
</div>
<input type="checkbox" role="switch" id="airplane-mode" class="input">
</div>
```
## States
### Checked/On State
```html
<input type="checkbox" role="switch" class="input" checked>
```
### Disabled State
```html
<input type="checkbox" role="switch" class="input" disabled>
<input type="checkbox" role="switch" class="input" checked disabled>
```
## Implementation Examples
### Settings Panel
```html
<div class="space-y-6">
<h3 class="text-lg font-medium">Notifications</h3>
<div class="space-y-4">
<div class="flex items-center justify-between gap-4">
<div class="grid gap-1">
<label for="push-notifications" class="label">Push Notifications</label>
<p class="text-muted-foreground text-sm">Receive push notifications on your device</p>
</div>
<input type="checkbox" role="switch" id="push-notifications" class="input" checked>
</div>
<div class="flex items-center justify-between gap-4">
<div class="grid gap-1">
<label for="email-alerts" class="label">Email Alerts</label>
<p class="text-muted-foreground text-sm">Get notified via email for important updates</p>
</div>
<input type="checkbox" role="switch" id="email-alerts" class="input">
</div>
<div class="flex items-center justify-between gap-4">
<div class="grid gap-1">
<label for="sms-alerts" class="label">SMS Alerts</label>
<p class="text-muted-foreground text-sm">Receive text messages for urgent notifications</p>
</div>
<input type="checkbox" role="switch" id="sms-alerts" class="input">
</div>
</div>
</div>
```
### Privacy Settings
```html
<form class="form space-y-6">
<h3 class="text-lg font-medium">Privacy Settings</h3>
<div class="space-y-4 border rounded-lg p-4">
<div class="flex items-center justify-between gap-4">
<div class="grid gap-1">
<label for="profile-public" class="label">Public Profile</label>
<p class="text-muted-foreground text-sm">Make your profile visible to everyone</p>
</div>
<input type="checkbox" role="switch" id="profile-public" class="input">
</div>
<hr class="border-border">
<div class="flex items-center justify-between gap-4">
<div class="grid gap-1">
<label for="show-activity" class="label">Show Activity Status</label>
<p class="text-muted-foreground text-sm">Let others see when you're online</p>
</div>
<input type="checkbox" role="switch" id="show-activity" class="input" checked>
</div>
<hr class="border-border">
<div class="flex items-center justify-between gap-4">
<div class="grid gap-1">
<label for="allow-indexing" class="label">Search Engine Indexing</label>
<p class="text-muted-foreground text-sm">Allow search engines to find your profile</p>
</div>
<input type="checkbox" role="switch" id="allow-indexing" class="input">
</div>
</div>
<button type="submit" class="btn">Save Settings</button>
</form>
```
### Feature Toggle Card
```html
<div class="card">
<header class="flex items-center justify-between">
<div>
<h3>Dark Mode</h3>
<p class="text-muted-foreground text-sm">Toggle dark mode appearance</p>
</div>
<input type="checkbox" role="switch" id="dark-mode" class="input">
</header>
</div>
```
### Compact Switch List
```html
<div class="divide-y">
<label class="flex items-center justify-between py-3 cursor-pointer">
<span>Bluetooth</span>
<input type="checkbox" role="switch" class="input" checked>
</label>
<label class="flex items-center justify-between py-3 cursor-pointer">
<span>Wi-Fi</span>
<input type="checkbox" role="switch" class="input" checked>
</label>
<label class="flex items-center justify-between py-3 cursor-pointer">
<span>Cellular</span>
<input type="checkbox" role="switch" class="input">
</label>
<label class="flex items-center justify-between py-3 cursor-pointer">
<span>Hotspot</span>
<input type="checkbox" role="switch" class="input">
</label>
</div>
```
## JavaScript Events
### Initialization Event
```javascript
document.addEventListener('basecoat:initialized', function(e) {
if (e.target.matches('[role="switch"]')) {
console.log('Switch initialized:', e.target.id);
}
});
```
### Change Event Handling
```javascript
const toggle = document.getElementById('dark-mode');
toggle.addEventListener('change', function() {
if (this.checked) {
document.documentElement.classList.add('dark');
localStorage.setItem('theme', 'dark');
} else {
document.documentElement.classList.remove('dark');
localStorage.setItem('theme', 'light');
}
});
```
### Controlled Toggle
```javascript
function setToggle(id, value) {
const toggle = document.getElementById(id);
if (toggle) {
toggle.checked = value;
// Dispatch change event for any listeners
toggle.dispatchEvent(new Event('change', { bubbles: true }));
}
}
// Usage
setToggle('notifications', true);
setToggle('marketing-emails', false);
```
## Accessibility Guidelines
### ARIA Requirements
- Use `role="switch"` on the checkbox input
- The `aria-checked` state is automatically managed by the browser
- Use `aria-label` or associated `<label>` for switch identification
- Use `aria-describedby` to link to description text
### Example with Full Accessibility
```html
<div class="flex items-center justify-between gap-4">
<div class="grid gap-1">
<label for="two-factor" class="label">Two-Factor Authentication</label>
<p id="two-factor-desc" class="text-muted-foreground text-sm">
Add an extra layer of security to your account
</p>
</div>
<input
type="checkbox"
role="switch"
id="two-factor"
class="input"
aria-describedby="two-factor-desc"
>
</div>
```
### Keyboard Navigation
- **Space**: Toggle the switch on/off
- **Enter**: Toggle the switch on/off (when focused)
- **Tab**: Move focus to/from the switch
## Best Practices
### When to Use Switches vs Checkboxes
Use switches for:
- Immediate effect toggles (settings that apply instantly)
- Binary on/off states
- Mobile-friendly interfaces
- Single options that don't require form submission
Use checkboxes for:
- Multiple selections
- Form submissions that require a save action
- Lists of options to select from
### Visual Guidelines
- Align switches consistently (typically on the right)
- Use clear, descriptive labels
- Provide descriptions for complex options
- Show the current state clearly
### Label Guidelines
- Use positive phrasing ("Enable" rather than "Disable")
- Keep labels concise
- Describe what happens when ON, not when OFF
- Place label to the left of the switch
### State Persistence
```javascript
// Load saved state on page load
document.addEventListener('DOMContentLoaded', function() {
const savedTheme = localStorage.getItem('theme');
const darkModeToggle = document.getElementById('dark-mode');
if (darkModeToggle && savedTheme === 'dark') {
darkModeToggle.checked = true;
document.documentElement.classList.add('dark');
}
});
```
## Common Patterns
### Master Toggle with Dependent Options
```html
<div class="space-y-4">
<div class="flex items-center justify-between gap-4">
<div class="grid gap-1">
<label for="notifications-master" class="label font-medium">All Notifications</label>
<p class="text-muted-foreground text-sm">Enable or disable all notifications</p>
</div>
<input type="checkbox" role="switch" id="notifications-master" class="input" checked>
</div>
<div class="ml-6 space-y-3" id="notification-options">
<div class="flex items-center justify-between gap-4">
<label for="notify-email" class="label">Email</label>
<input type="checkbox" role="switch" id="notify-email" class="input notification-option" checked>
</div>
<div class="flex items-center justify-between gap-4">
<label for="notify-push" class="label">Push</label>
<input type="checkbox" role="switch" id="notify-push" class="input notification-option" checked>
</div>
<div class="flex items-center justify-between gap-4">
<label for="notify-sms" class="label">SMS</label>
<input type="checkbox" role="switch" id="notify-sms" class="input notification-option">
</div>
</div>
</div>
<script>
const master = document.getElementById('notifications-master');
const options = document.querySelectorAll('.notification-option');
const optionsContainer = document.getElementById('notification-options');
master.addEventListener('change', function() {
optionsContainer.style.opacity = this.checked ? '1' : '0.5';
optionsContainer.style.pointerEvents = this.checked ? 'auto' : 'none';
if (!this.checked) {
options.forEach(opt => opt.checked = false);
}
});
</script>
```
### Async Toggle with Loading State
```javascript
async function handleToggle(toggle, apiEndpoint) {
const originalState = toggle.checked;
toggle.disabled = true;
try {
const response = await fetch(apiEndpoint, {
method: 'POST',
body: JSON.stringify({ enabled: toggle.checked })
});
if (!response.ok) {
throw new Error('Failed to update setting');
}
// Success - show toast
showToast('success', 'Setting Updated', 'Your preference has been saved.');
} catch (error) {
// Revert on error
toggle.checked = originalState;
showToast('error', 'Error', 'Failed to update setting. Please try again.');
} finally {
toggle.disabled = false;
}
}
```