Switch
Toggle switch component with multiple sizes, built on a native checkbox
You are reading the v1 docs. v2 renamed several props and replaced GeckoUIPortal with GeckoUIProvider. Read this page in v2.
Live examples are only rendered in the v2 docs.
Switch
A toggle component built on a native checkbox 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
A custom lg size created using module augmentation:
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 {
&[data-size="lg"] {
@apply h-8 w-14;
}
&__thumb[data-size="lg"] {
@apply w-6 translate-x-0.5;
}
// The checked position is a separate rule, because the state lives on the input
&:has(input:checked) &__thumb[data-size="lg"] {
@apply translate-x-7;
}
}Step 3: Use Your Custom Size
<Switch size="lg" checked={enabled} onChange={setEnabled} />Accessibility
- Renders a native
<input type="checkbox">withrole="switch", so the state is announced correctly - 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 class names with data attributes:
GeckoUISwitch- Main containerGeckoUISwitch[data-size="sm|md"]- Size modifiersGeckoUISwitch__thumb- Toggle thumb elementGeckoUISwitch__thumb[data-size="sm|md"]- Thumb size modifiers
Checked and disabled live on the hidden input rather than on a data attribute, so target them through the container:
.GeckoUISwitch:has(input:checked) { /* on */ }
.GeckoUISwitch:has(input:disabled) { /* off limits */ }
.GeckoUISwitch:has(input:focus-visible) { /* keyboard focus */ }