A two-state button, pressed or not, for toolbar formatting and view options.
Toggle is a real <button> with aria-pressed: quiet at rest, washed in the accent with a hairline when pressed. ghost (the default) has no edge at rest, for toolbars; outline keeps a hairline box, for a lone option such as "Show archived".
Use Switch for a setting that applies at once and reads as on or off; use Checkbox inside a form that is submitted.
Installation
npx shadcn@latest add KezLahd/rime/toggleAlso installs: base.
Usage
import { Toggle } from "@/components/ui";
<Toggle aria-label="Bold" icon={<Bold size={16} />} pressed={bold} onPressedChange={setBold} />Examples
Icon, text and disabled
API
Generated from the component's TypeScript types and JSDoc (scripts/gen-ui-registry.mjs), so it always matches the source.
Toggle
| Prop | Type | Default | Description |
|---|---|---|---|
| pressed | boolean | Controlled pressed state. Leave unset (with defaultPressed) for uncontrolled. | |
| defaultPressed | boolean | false | |
| onPressedChange | (pressed: boolean) => void | ||
| variant | "ghost" | "outline" | "ghost" | ghost (default) shows no edge at rest; outline keeps a hairline box. |
| size | "sm" | "md" | "md" | |
| icon | ReactNode | An icon before the label. An icon-only toggle needs aria-label. |
Also accepts the native attributes of AriaAttributes, ButtonHTMLAttributes, DOMAttributes, HTMLAttributes.
Theme tokens
Per-component tokens are undeclared by default, so the default shown is the fallback the CSS uses. Set one at :root (or in theme.css) to restyle every instance. Live values are read from this page, so they follow the Rime Studio.
| Token | Default | Live value |
|---|---|---|
| --toggle-height-md | var(--control-h-md) | … |
| --toggle-height-sm | var(--control-h-sm) | … |
| --toggle-ink | var(--ink-muted) | … |
| --toggle-on-bg | var(--wash-active) / var(--surface-solid) | … |
| --toggle-on-ink | var(--ink-brand) | … |
| --toggle-on-line | var(--line-brand-strong) | … |
| --toggle-radius | var(--r-md) / var(--r-sm) | … |
System tokens it reads
| Token | Default | Live value |
|---|---|---|
| --border-w | tokens.css | … |
| --control-h-md | tokens.css | … |
| --control-h-sm | tokens.css | … |
| --density | tokens.css | … |
| --dur | tokens.css | … |
| --ease | tokens.css | … |
| --focus-ring | tokens.css | … |
| --font-body | tokens.css | … |
| --ink-brand | tokens.css | … |
| --ink-disabled | tokens.css | … |
| --ink-heading | tokens.css | … |
| --ink-muted | tokens.css | … |
| --line | tokens.css | … |
| --line-brand-strong | tokens.css | … |
| --line-input | tokens.css | … |
| --r-md | tokens.css | … |
| --r-sm | tokens.css | … |
| --recess-fill | tokens.css | … |
| --rgb-white | tokens.css | … |
| --shadow-hairline-card | tokens.css | … |
| --shadow-recess | tokens.css | … |
| --surface-solid | tokens.css | … |
| --text-small | tokens.css | … |
| --wash-active | tokens.css | … |
| --wash-hover | tokens.css | … |
Accessibility
- aria-pressed carries the state, so the label must not change with it: "Bold", pressed or not pressed.
- An icon-only toggle needs aria-label.
Do and don't
Do
- Keep the label constant; the pressed state says the rest.
Don't
- Don't use a Toggle to trigger a one-off action; that is a Button.
For AI agents
This page as markdown, rendered from the same registry entry. Point an agent at it (or add .md to this page's URL), or at /llms.txt for the index.
Open toggle.mdRelated: toggle-group, switch