import { ItalicIcon } from "lucide-react"
import { Toggle } from "@/components/ui/toggle"
export default function ToggleDemo() {
return (
<Toggle aria-label="Toggle italic">
<ItalicIcon />
</Toggle>
)
}Installation
npx logic2b@latest add toggleWorking 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 "toggle" 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 toggle ``` 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/toggle.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-ui class-variance-authorityCopy into ui/toggle.tsx:
import * as React from "react"
import { Toggle as TogglePrimitive } from "radix-ui"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const toggleVariants = cva(
"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none transition-[color,box-shadow]",
{
variants: {
variant: {
default: "bg-transparent",
outline:
"border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground",
},
size: {
default: "h-9 px-2 min-w-9",
sm: "h-8 px-1.5 min-w-8",
lg: "h-10 px-2.5 min-w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
function Toggle({
className,
variant,
size,
...props
}: React.ComponentProps<typeof TogglePrimitive.Root> &
VariantProps<typeof toggleVariants>) {
return (
<TogglePrimitive.Root
data-slot="toggle"
className={cn(toggleVariants({ variant, size, className }))}
{...props}
/>
)
}
export { Toggle, toggleVariants }Usage
import { Toggle } from "@/components/ui/toggle"
<Toggle aria-label="Toggle italic">
<ItalicIcon />
</Toggle>
API
Built on Radix Toggle.Root with cva variants.
| Prop | Type | Default |
|---|---|---|
variant |
default | outline |
default |
size |
default | sm | lg |
default |
pressed |
boolean — controlled state |
— |
defaultPressed |
boolean |
— |
onPressedChange |
(pressed: boolean) => void |
— |
disabled |
boolean |
false |
Examples
Outline
import { ItalicIcon } from "lucide-react"
import { Toggle } from "@/components/ui/toggle"
export default function ToggleOutlineDemo() {
return (
<Toggle variant="outline" aria-label="Toggle italic">
<ItalicIcon />
</Toggle>
)
}With text
import { BoldIcon } from "lucide-react"
import { Toggle } from "@/components/ui/toggle"
export default function ToggleTextDemo() {
return (
<Toggle aria-label="Toggle bold" className="px-3">
<BoldIcon />
Bold
</Toggle>
)
}Sizes
import { StarIcon } from "lucide-react"
import { Toggle } from "@/components/ui/toggle"
export default function ToggleSizesDemo() {
return (
<div className="flex items-center gap-2">
<Toggle size="sm" variant="outline" aria-label="Favorite, small">
<StarIcon />
</Toggle>
<Toggle size="default" variant="outline" aria-label="Favorite, default">
<StarIcon />
</Toggle>
<Toggle size="lg" variant="outline" aria-label="Favorite, large">
<StarIcon />
</Toggle>
</div>
)
}Accessibility
- Exposes
aria-pressedso its on/off state is announced. - Toggle with
SpaceorEnterwhen focused; reachable withTab. - Icon-only toggles need an
aria-labelto provide an accessible name.