Switch
An immediate on/off pill with a sliding knob
Sync settings
Sync this workspaceApplies on every machine you sign in to.
Sync on metered networksUses data on a phone hotspot.
Reduce motionCuts animation across the app.
Syncing on unmetered networks only.
Installation
npx shadcn@latest add @sudokw/primitives-switchimport { Switch } from "@gpuixui/primitives";Usage
import { Switch } from "@gpuixui/primitives";
import { useState } from "react";
export const Theme = () => {
const [dark, setDark] = useState(false);
return (
<Switch
checked={dark}
label="Dark theme"
onCheckedChange={setDark}
/>
);
};Composition
Switch
└── SwitchThumbAPI reference
Switch
| Prop | Type | Default | Consequence |
|---|---|---|---|
checked | boolean | — | controlled state; omit to let the switch keep its own |
defaultChecked | boolean | false | initial state when uncontrolled |
onCheckedChange | (next: boolean) => void | none | the next boolean, only when it changed |
onChange | (next: boolean) => void | none | deprecated alias for onCheckedChange; the new name wins when both are passed |
children | ReactNode | none | a glyph on the knob |
disabled | boolean | false | refuses pointer and keys and leaves the tab order |
invalid | boolean | false | an off pill takes the destructive edge |
size | "sm" | "md" | "lg" | "md" | the pill's height from iconSize; the band stays 24px |
accent | "primary" | "destructive" | "primary" | the checked fill and the knob's on-colour |
label | string | none | the accessible name; a visible Label does not supply it |
description | string | none | announced help (aria-description); wins over a tooltip's text |
reducedMotion | boolean | the provider's preference (false when none) | the knob lands on its position instead of sliding there; the slide is the timing table's fast level (160 ms) on its standard curve; the prop wins |
style | StateStyle<SwitchState> | — | resolved against the live state and merged last |
className | string | — | joined after the recipe, so it wins conflicts |
testId | string | — | stable locator |
ref / aria-id / onLayout | host address | none | the press band is the addressed element: focus it, measure it, and name it for automation |
onMouseEnter / onMouseLeave / aria-description | the tooltip trigger pair and its words | none | forwarded to the press band, so a switch can be a Tooltip trigger; the tip's words land on the same help channel |
onClick / onKeyDown / onKeyUp / onFocus / onBlur | host handlers | none | composed with the switch's own; yours runs first |
SwitchThumb
| Prop | Type | Default | Consequence |
|---|---|---|---|
children | ReactNode | the plain filled knob | a glyph on the knob |
className | string | — | compiled through the recipe, joined after the thumb's rules |
style | StyleDesc | — | merged last |
Keyboard
- EnterSpace
- toggles the switch
read from Switch.tsx
Edit this page on GitHubapps/docs/content/docs/components/switch.mdx