- Accordion
- Agent Thinking
- Alert
- Alert Dialog
- Announcement
- Aspect Ratio
- Attachment
- Avatar
- Badge
- Breadcrumb
- Bubble
- Button
- Button Group
- Calendar
- Card
- Carousel
- Checkbox
- Checkbox Card
- Code Block
- Collapsible
- Color Picker
- Combobox
- Command
- Composer
- Composer Loader
- Context Menu
- Data Grid
- Data Table
- Date Picker
- Dialog
- Direction
- Drawer
- Dropdown Menu
- Empty
- Field
- File Upload
- Hover Card
- Input
- Input Group
- Input Otp
- Item
- Kbd
- Label
- Marker
- Menubar
- Message
- Message Scroller
- Meter
- Native Select
- Navigation Menu
- Number Field
- Pagination
- Period Switcher
- Popover
- Progress
- Questionnaire
- Radio Card
- Radio Group
- Resizable
- Reveal
- Scroll Area
- Search Field
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Social Button
- Sonner
- Spinner
- Status Dot
- Switch
- Switch Card
- Table
- Tabs
- Tag Group
- Textarea
- Theme Toggle
- Time Field
- Toggle
- Toggle Group
- Tooltip
- Trace
- Tree View
- Agent Creator 01
- Agent Limits Card 01
- Agent Progress 01
- AI Chat 01
- AI Image Generation 01
- AI Profile 01
- Alerts Card 01
- Auth Card 01
- Calendar 01
- Composer 01
- Composer Attachments 01
- Composer Panel 01
- Finance Dashboard 01
- Home Dashboard 01
- Marketing Dashboard 01
- Medical Profile 01
- Meeting Scheduler 01
- Multi Agent Chat 01
- Notification Center 01
- Patient Info Card 01
- Project Board 01
- Questionnaire 01
- Settings Modal 01
- Sidebar 01
- Stat Cards 01
- Task List 01
- Web Search 01
- Activity Rings Card 01
- Area Chart Card 01
- Bar List Card 01
- Combo Chart Card 01
- Contributions Card 01
- Earnings Chart Card 01
- Funnel Chart Card 01
- Heatmap Chart Card 01
- Line Chart Card 01
- Most Active Days Card 01
- Orders Chart Card 01
- Radar Chart Card 01
- Radial Chart Card 01
- Revenue Chart Card 01
- Sankey Chart Card 01
- Scatter Chart Card 01
- Sleep Score Card 01
- Stage Bars Card 01
- Steps Card 01
Installation
$ pnpm dlx shadcn@latest add @cobalt/toggle
Options
variant="ghost"has no resting surface. It fills with the muted surface on hover and while pressed, for toolbars and settings rows.variant="choice"is a selectable card or chip: a hairline border that turns primary, with a faint primary tint, while pressed.ToggleGroupItemtakes it too.variant="swatch"is a round colour swatch with no fill: pressed shows a ring around the child. Use it withsize="icon-sm"and a coloured dot inside.- Icon sizes
icon-xs(24px),icon-sm(32px),icon(36px) andicon-lg(40px) give a square toggle with no horizontal padding, matching Button.ToggleGroupItemtakes the same sizes.
Source
"use client";
import { Toggle as TogglePrimitive } from "@base-ui/react/toggle";
import { cva } from "class-variance-authority";
import type { VariantProps } from "class-variance-authority";
import { cn } from "cn";
const toggleVariants = cva(
"group/toggle relative isolate inline-flex shrink-0 cursor-pointer items-center justify-center gap-0.5 rounded-[10px] text-sm before:pointer-events-none before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] font-medium whitespace-nowrap text-foreground outline-none select-none [transition:background-color_150ms_ease,border-color_150ms_ease,box-shadow_150ms_ease,color_150ms_ease,scale_420ms_cubic-bezier(0.4,0,0.2,1)] focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background active:scale-[0.98] active:[transition-duration:150ms,150ms,150ms,150ms,220ms] data-disabled:pointer-events-none data-disabled:cursor-not-allowed data-disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 motion-reduce:transition-none motion-reduce:active:scale-100 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-5",
{
defaultVariants: {
size: "default",
variant: "default",
},
variants: {
size: {
default:
"h-9 min-w-9 px-2.75 has-data-[icon=inline-end]:pr-1.75 has-data-[icon=inline-start]:pl-1.75",
icon: "size-9 min-w-9 px-0",
"icon-lg": "size-10 min-w-10 px-0",
"icon-sm":
"size-8 min-w-8 rounded-[8px] px-0 [&_svg:not([class*='size-'])]:size-[18px]",
"icon-xs":
"size-6 min-w-6 rounded-[4px] px-0 [&_svg:not([class*='size-'])]:size-3.5",
lg: "h-10 min-w-10 px-2.75 has-data-[icon=inline-end]:pr-1.75 has-data-[icon=inline-start]:pl-1.75",
sm: "h-8 min-w-8 rounded-[8px] px-2.25 has-data-[icon=inline-end]:pr-1.75 has-data-[icon=inline-start]:pl-1.75 [&_svg:not([class*='size-'])]:size-[18px]",
},
variant: {
// The pressed fill, border and ring sit on the `before:` layer, which
// has no transition, so switching between toggles is instant instead
// of the old one fading out. Hover keeps its fade on the element.
default:
"bg-transparent hover:bg-muted data-pressed:before:bg-[var(--surface-strong,var(--muted))] data-pressed:text-foreground",
ghost:
"bg-transparent hover:bg-muted data-pressed:before:bg-muted data-pressed:text-foreground",
// A selectable card or chip: hairline border, primary border and tint when pressed.
choice:
"border border-border bg-transparent hover:not-data-pressed:bg-muted data-pressed:before:-inset-px data-pressed:before:border data-pressed:before:border-primary data-pressed:before:bg-primary/5 data-pressed:text-foreground",
// A round colour swatch: no fill, a ring when pressed.
swatch:
"rounded-full border-0 bg-transparent p-0 hover:bg-transparent data-pressed:before:ring-2 data-pressed:before:ring-foreground/50 data-pressed:before:ring-offset-1 data-pressed:before:ring-offset-background",
outline:
"border border-border bg-popover shadow-[shadow:var(--shadow-control,0_1px_2px_0_rgb(0_0_0/0.05))] hover:border-[var(--border-hover,var(--border))] hover:bg-[var(--surface-hover,var(--muted))] active:border-[var(--foreground-subtle,var(--border))] active:bg-[var(--surface-strong,var(--muted))] data-pressed:before:bg-[var(--surface-strong,var(--muted))] data-disabled:shadow-none",
},
},
}
);
function Toggle({
className,
variant = "default",
size = "default",
...props
}: TogglePrimitive.Props & VariantProps<typeof toggleVariants>) {
return (
<TogglePrimitive
data-slot="toggle"
className={cn(toggleVariants({ className, size, variant }))}
{...props}
/>
);
}
export { Toggle, toggleVariants }; On this page