Toggle
A shadcn-style toggle component built with Ark UI primitives.
import { BoldIcon } from "lucide-react";
import { Toggle } from "@/components/ui/toggle";
const ToggleBasicDemo = () => (
<Toggle aria-label="Toggle bold" variant="outline">
<BoldIcon />
</Toggle>
);
export default ToggleBasicDemo;
Installation
npx shadcn@latest add @ark-cn/toggleInstall the dependency required by this primitive:
npm install @ark-ui/react class-variance-authorityCopy the component source into your app:
TSXcomponents/ui/toggle.tsx
"use client";
import { Toggle as TogglePrimitive } from "@ark-ui/react/toggle";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const toggleVariants = cva(
"inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-lg border font-medium text-sm outline-none transition-colors disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
{
defaultVariants: {
size: "default",
variant: "default",
},
variants: {
size: {
default: "h-9 px-3 sm:h-8",
lg: "h-10 px-3.5 sm:h-9",
sm: "h-8 px-2.5 sm:h-7",
},
variant: {
default:
"border-transparent bg-transparent text-foreground hover:bg-accent data-[state=on]:bg-primary/12 data-[state=on]:text-primary",
outline:
"border-input bg-popover text-foreground shadow-xs/5 hover:bg-accent/50 data-[state=on]:border-primary/30 data-[state=on]:bg-primary/12 data-[state=on]:text-primary",
},
},
},
);
export type ToggleProps = TogglePrimitive.RootProps &
VariantProps<typeof toggleVariants>;
export const Toggle = ({ className, size, variant, ...props }: ToggleProps) => (
<TogglePrimitive.Root
data-slot="toggle"
className={cn(toggleVariants({ className, size, variant }))}
{...props}
/>
);
export type ToggleIndicatorProps = TogglePrimitive.IndicatorProps;
export const ToggleIndicator = ({
className,
...props
}: ToggleIndicatorProps) => (
<TogglePrimitive.Indicator
data-slot="toggle-indicator"
className={cn("inline-flex items-center justify-center", className)}
{...props}
/>
);
export const ToggleContext = TogglePrimitive.Context;
export type { UseToggleProps, UseToggleReturn } from "@ark-ui/react/toggle";
export { useToggle, useToggleContext } from "@ark-ui/react/toggle";
Update import aliases to match your project setup.
Usage
import * as Toggle from "@/components/ui/toggle"Read exported parts in src/components/ui/toggle.tsx and compose the primitive according to the Ark UI pattern for this component.
Examples
Basic
import { BoldIcon } from "lucide-react";
import { Toggle } from "@/components/ui/toggle";
const ToggleBasicDemo = () => (
<Toggle aria-label="Toggle bold" variant="outline">
<BoldIcon />
</Toggle>
);
export default ToggleBasicDemo;
Controlled
Pressed: false
import { HeartIcon } from "lucide-react";
import { useState } from "react";
import { Toggle, ToggleIndicator } from "@/components/ui/toggle";
const ToggleControlledDemo = () => {
const [pressed, setPressed] = useState(false);
return (
<div className="flex items-center gap-3">
<Toggle
aria-label="Toggle favorite"
onPressedChange={setPressed}
pressed={pressed}
variant="outline"
>
<ToggleIndicator fallback={<HeartIcon />}>
<HeartIcon fill="currentColor" />
</ToggleIndicator>
</Toggle>
<p className="text-muted-foreground text-xs">
Pressed:{" "}
<span className="font-medium text-foreground">{String(pressed)}</span>
</p>
</div>
);
};
export default ToggleControlledDemo;
Disabled
import { BoldIcon } from "lucide-react";
import { Toggle } from "@/components/ui/toggle";
const ToggleDisabledDemo = () => (
<Toggle aria-label="Disabled toggle" disabled variant="outline">
<BoldIcon />
</Toggle>
);
export default ToggleDisabledDemo;
Indicator
import { HeartIcon } from "lucide-react";
import { Toggle, ToggleIndicator } from "@/components/ui/toggle";
const ToggleIndicatorDemo = () => (
<Toggle aria-label="Toggle favorite" variant="outline">
<ToggleIndicator fallback={<HeartIcon />}>
<HeartIcon fill="currentColor" />
</ToggleIndicator>
</Toggle>
);
export default ToggleIndicatorDemo;
Context
import { BoldIcon } from "lucide-react";
import { Toggle, ToggleContext } from "@/components/ui/toggle";
const ToggleContextDemo = () => (
<Toggle aria-label="Toggle bold state" variant="outline">
<BoldIcon />
<ToggleContext>
{(context) => (context.pressed ? "On" : "Off")}
</ToggleContext>
</Toggle>
);
export default ToggleContextDemo;
API reference
This component mirrors the upstream Ark UI primitive.
See the ARK UI documentation for the full API.