Switch
Toggle switch component with multiple sizes built on HeadlessUI
Switch
A toggle component built on HeadlessUI that provides an accessible on/off control. Supports multiple sizes, controlled and uncontrolled modes, and integrates seamlessly with forms.
Installation
import { Switch } from '@geckoui/geckoui';Basic Usage
import { useState } from 'react';
function Example() {
const [enabled, setEnabled] = useState(false);
return (
<Switch checked={enabled} onChange={setEnabled} />
);
}Props API
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | - | Controlled checked state |
onChange | (checked: boolean) => void | - | Callback when state changes |
size | 'sm' | 'md' | 'md' | Size of the switch |
className | string | - | CSS class for the switch container |
thumbClassName | string | - | CSS class for the switch thumb |
disabled | boolean | false | Disable the switch |
defaultChecked | boolean | - | Initial checked state (uncontrolled) |
Examples
Sizes
<div className="flex flex-col gap-4">
<Switch size="sm" checked={enabled} onChange={setEnabled} />
<Switch size="md" checked={enabled} onChange={setEnabled} />
</div>Settings Panel
function SettingsPanel() {
const [settings, setSettings] = 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">Email Notifications</div>
<div className="text-sm text-gray-500">Receive email updates</div>
</div>
<Switch
checked={settings.notifications}
onChange={(checked) =>
setSettings({ ...settings, notifications: checked })
}
/>
</div>
{/* More settings... */}
</div>
);
}Disabled State
<div className="flex gap-4">
<Switch checked disabled />
<Switch disabled />
</div>Uncontrolled with Default Value
<Switch defaultChecked={true} />Keyboard Navigation
The switch supports keyboard interaction:
- Space or Enter: Toggle the switch
- Tab: Move focus to next element
- Shift + Tab: Move focus to previous element
Note: The Enter key is prevented from default form submission behavior.
Module Augmentation
The Switch component supports TypeScript module augmentation, allowing you to add custom sizes with full type safety.
Live Example
This documentation site demonstrates module augmentation with a custom lg size:
Step 1: TypeScript Declaration
Create a declaration file (e.g., gecko.d.ts) in your project:
import "@geckoui/geckoui";
declare module "@geckoui/geckoui" {
interface SwitchSizeMap {
lg: unknown;
}
}Step 2: Add CSS Styles
Add the corresponding styles to your global CSS/SCSS file. You need to define both the container size and the thumb element:
.GeckoUISwitch {
&--size-lg {
@apply h-8 w-14;
}
&__thumb {
&--size-lg {
@apply w-6 translate-x-0.5 group-data-[checked]:translate-x-3.5;
}
}
}Step 3: Use Your Custom Size
<Switch size="lg" checked={enabled} onChange={setEnabled} />Accessibility
- Built on HeadlessUI for WCAG compliance
- Proper ARIA attributes automatically applied
- Fully keyboard navigable
- Focus visible for keyboard users
- Works with screen readers
- Disabled state properly communicated
Styling
The component uses BEM-style class names:
GeckoUISwitch- Main containerGeckoUISwitch--size-{sm|md}- Size modifiersGeckoUISwitch__thumb- Toggle thumb elementGeckoUISwitch__thumb--size-{sm|md}- Thumb size modifiers
The switch also supports HeadlessUI data attributes:
data-[checked]- Applied when checkeddata-[disabled]- Applied when disabled
Dependencies
This component uses @headlessui/react for accessibility and behavior.