Components
Toggle
A two-state button that can be turned on or off — ideal for icon controls in toolbars and inline formatting actions.
Basic usage
Wrap a Lucide icon and provide an aria-label. Click to flip between on and off. Icons without an explicit size class are set to 16px by the toggle's own base styles.
Variants
Use default for toolbar groups and outline for standalone controls that need a visible boundary. Both share the same pressed treatment — bg-accent with text-accent-foreground.
Sizes
Three sizes — sm (32px), default (36px), and lg (40px) — to match the density of the surrounding UI. Each one also sets a matching minimum width, so an icon-only toggle stays square.
States
Start a toggle in the on position with defaultPressed, or block interaction with disabled. Toggles can pair an icon with a text label.
The toggleVariants helper
The cva recipe behind the component is exported as toggleVariants from @comitor/ui. Call it to give any element the toggle's shape and state styling — an editor plugin's own button, a link, a menu item — and merge extra classes with cn. It is the same recipe ToggleGroupItem uses. Borrowing the styles means owning the semantics: set aria-pressed and the data-state attribute the pressed styles key off yourself.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'default' | 'outline' | 'default' | Visual style — transparent by default, or bordered with a shadow for standalone controls. |
size | 'default' | 'sm' | 'lg' | 'default' | Height, padding and minimum width: sm is 32px, default 36px, lg 40px. |
pressed | boolean | — | Controlled on/off state. Pair with onPressedChange. |
defaultPressed | boolean | false | Initial pressed state when uncontrolled. |
onPressedChange | (pressed: boolean) => void | — | Fires when the pressed state changes. |
disabled | boolean | false | Removes pointer events and reduces opacity to 50%. |
aria-invalid | boolean | — | Tints the focus ring and switches the border to border-destructive-ink for failed validation. |
className | string | — | Additional Tailwind classes to merge. |
...rest | Radix Toggle.Root props | — | Everything else is forwarded to the underlying button. |
Accessibility
- Built on Radix
Toggle, which exposes the on/off state to assistive tech viaaria-pressed. - Always pass an
aria-labelfor icon-only toggles so the control has an accessible name. - Fully keyboard operable — focus with Tab and flip with Enter or Space.
- A
focus-visiblering using the brand gold ring token appears on keyboard navigation and stays hidden on click. - The disabled state removes pointer events and is conveyed to the accessibility tree.
- Pressed state is carried by a real background change (
bg-accent), not by colour alone on the icon, so it survives both palettes and both themes.