Switch
Switches toggle a single setting on or off. Use a switch when the change takes effect immediately — settings panels, feature flags, row-level toggles. For form choices that only apply on submit, use a checkbox.
Examples
Default (small)
Sizes
States
Controlled
Settings list
Overview
Built on Base UI Switch. Two sizes (small, medium), uses the brand color for the checked state, and supports the full set of native form attributes via BaseSwitch.Root.
import { Switch } from "@rogo-technologies/ui/switch";
<Switch defaultChecked aria-label="Push notifications" />;Usage
Controlled
const [enabled, setEnabled] = useState(false);
<Switch checked={enabled} onCheckedChange={setEnabled} aria-label="Notifications" />;With a label
Use a <label htmlFor> paired with id on the switch so clicking the label toggles the switch — this is the accessible pattern and what screen readers expect.
<div className="flex items-center gap-2">
<Switch id="notifications" defaultChecked />
<label htmlFor="notifications">Push notifications</label>
</div>If you don't render a visible label, pass aria-label instead.
Inside dropdown items
Switch works as a right-slot control in DropdownMenuItem.suffix. Pair with closeOnClick={false} so toggling doesn't dismiss the menu, and mirror the toggle via onSelect so clicking the row counts too. See the Dropdown Menu / Toggle switches example.
Sizes
small is the default (16×28). medium (20×36) is better when the switch is a primary affordance on a settings row rather than a trailing control.
<Switch size="small" />
<Switch size="medium" />Disabled
<Switch disabled />
<Switch disabled defaultChecked />Accessibility
- Keyboard:
SpaceorEntertoggles when focused. - Focus ring is visible on keyboard focus.
- Always pair with a visible
<label>(viahtmlFor/id) or passaria-label. - The checked state is announced as "on"/"off" to screen readers via the underlying
role="switch".
When to use
- ✅ Immediate-effect toggles — feature flags, "dark mode", "Wi-Fi", notification preferences.
- ✅ Settings rows where the change applies on click.
- ❌ Form fields where the value applies on submit — use a
Checkbox. - ❌ Mutually exclusive options — use a
RadioGroup.
API
Switch
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | — | Controlled checked state. |
defaultChecked | boolean | false | Initial checked state for uncontrolled usage. |
onCheckedChange | (checked: boolean) => void | — | Callback when the checked state changes. |
size | "small" | "medium" | "small" | Visual size. |
disabled | boolean | false | Disables the switch. |
name | string | — | Name attribute for form submission. |
value | string | "on" | Value attribute for form submission. |
required | boolean | false | Marks the switch as required. |
id | string | — | Associates the switch with a <label>. |
Guidelines
Do
- Pair the switch with a visible label whenever possible
- Apply the change the moment the switch is flipped (immediate effect)
- Use
smallsize in lists; reach formediumwhen the switch is the row's primary control - Use
aria-labelif there's no visible label
Don't
- Don't use a switch for a form field that only commits on submit — use a checkbox
- Don't use a switch for one-of-many choices — use a radio group
- Don't disable a switch without context — explain via tooltip or helper text
- Don't put two switches next to each other without labels — they read as ambiguous