import { Label } from "@/components/ui/label"
import { Switch } from "@/components/ui/switch"
export default function SwitchDemo() {
return (
<div className="flex items-center gap-3">
<Switch id="switch-airplane-mode" />
<Label htmlFor="switch-airplane-mode">Airplane mode</Label>
</div>
)
}Installation
npx logic2b@latest add switchWorking with an AI assistant? Copy this prompt into Claude Code, Cursor or Copilot — it carries the install steps, a no-CLI fallback and a verification checklist.
Add the "switch" item from the logic2b ui registry (https://ui.logic2b.com) to this project. Follow every step and verify at the end. ## Steps 1. If the project has no `components.json` yet, set up logic2b ui first: ```bash npx logic2b@latest init ``` 2. Install the item (the CLI resolves registry dependencies automatically): ```bash npx logic2b@latest add switch ``` 3. Install any npm dependencies the command prints. ## If the CLI is not available Do it manually from the registry payload: 1. Fetch https://ui.logic2b.com/r/switch.json. 2. Write every entry in `files[]` to its mapped project path (see below). 3. Repeat (recursively) for each name in `registryDependencies`. 4. Install every package listed in `dependencies` across those payloads. ## Registry reference - Index of every item: https://ui.logic2b.com/r/index.json - Item payload (full source): https://ui.logic2b.com/r/<name>.json - Usage examples per item: https://ui.logic2b.com/r/demos/index.json → https://ui.logic2b.com/r/demos/<demo>.json - Docs index for agents: https://ui.logic2b.com/llms.txt (full docs: https://ui.logic2b.com/llms-full.txt) - Every docs page is Markdown when you append `.md` to its URL. Registry file paths map to project paths like this: - `ui/*` → `@/components/ui/*` - `blocks/<name>/*` → `@/components/*` - `charts/*` → `@/components/charts/*` - `hooks/*` → `@/hooks/*` - `lib/utils.ts` → `@/lib/utils.ts` - `theme.css` → next to the project's Tailwind entry stylesheet ## Conventions (do not break these) - Tailwind CSS v4 (CSS-first config; no tailwind.config.js needed) and React 19. - All colors go through semantic tokens (`bg-primary`, `text-muted-foreground`, `border-border`, …). Never hardcode hex/oklch values in components. - Dark mode is class-based: toggle `.dark` on `<html>`. - Icons come from lucide-react. ## Verify before finishing 1. The dev server starts and the app renders without console errors. 2. TypeScript compiles (`tsc --noEmit` or the framework's check). 3. Components use the theme: a `<Button>` shows the primary token color, and toggling `.dark` on `<html>` switches the palette.
Install the dependencies:
npm install radix-uiCopy into ui/switch.tsx:
"use client"
import * as React from "react"
import { Switch as SwitchPrimitive } from "radix-ui"
import { cn } from "@/lib/utils"
function Switch({
className,
...props
}: React.ComponentProps<typeof SwitchPrimitive.Root>) {
return (
<SwitchPrimitive.Root
data-slot="switch"
className={cn(
"peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 inline-flex h-[1.15rem] w-8 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
className
)}
{...props}
>
<SwitchPrimitive.Thumb
data-slot="switch-thumb"
className={cn(
"bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block size-4 rounded-full ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0"
)}
/>
</SwitchPrimitive.Root>
)
}
export { Switch }Usage
import { Switch } from "@/components/ui/switch"
<Switch id="airplane-mode" />
API
Built on Radix Switch.Root; forwards all of its props.
| Prop | Type | Default |
|---|---|---|
checked |
boolean — controlled state |
— |
defaultChecked |
boolean |
— |
onCheckedChange |
(checked: boolean) => void |
— |
disabled |
boolean |
false |
required |
boolean |
false |
name |
string — submitted with a form |
— |
value |
string |
on |
Examples
Controlled
import * as React from "react"
import { Label } from "@/components/ui/label"
import { Switch } from "@/components/ui/switch"
export default function SwitchControlledDemo() {
const [checked, setChecked] = React.useState(true)
return (
<div className="flex items-center gap-3">
<Switch
id="switch-notifications"
checked={checked}
onCheckedChange={setChecked}
/>
<Label htmlFor="switch-notifications">
Notifications {checked ? "on" : "off"}
</Label>
</div>
)
}Disabled
import { Label } from "@/components/ui/label"
import { Switch } from "@/components/ui/switch"
export default function SwitchDisabledDemo() {
return (
<div className="flex flex-col gap-4">
<div className="flex items-center gap-3">
<Switch id="switch-off" disabled />
<Label htmlFor="switch-off">Disabled</Label>
</div>
<div className="flex items-center gap-3">
<Switch id="switch-on" defaultChecked disabled />
<Label htmlFor="switch-on">Disabled, on</Label>
</div>
</div>
)
}Settings list
import { Label } from "@/components/ui/label"
import { Switch } from "@/components/ui/switch"
const settings = [
{ id: "marketing", label: "Marketing emails", defaultChecked: true },
{ id: "security", label: "Security alerts", defaultChecked: true },
{ id: "digest", label: "Weekly digest", defaultChecked: false },
]
export default function SwitchSettingsDemo() {
return (
<div className="flex w-[320px] flex-col gap-4">
{settings.map((setting) => (
<div key={setting.id} className="flex items-center justify-between">
<Label htmlFor={`switch-${setting.id}`}>{setting.label}</Label>
<Switch
id={`switch-${setting.id}`}
defaultChecked={setting.defaultChecked}
/>
</div>
))}
</div>
)
}Accessibility
- Renders a
switchrole element that reflects its on/off state to assistive technology. - Toggle with
SpaceorEnterwhen focused; fully reachable withTab. - Associate a
LabelviahtmlFor(or wrap the control) so the state has an accessible name.