Toggle
Two-state button for on or off, with outline or ghost chrome and icon or label layouts.
Installation
The component is exported from @by/experience-system. Add the package with your package manager:
pnpm add @by/experience-systemIn this monorepo, depend on the workspace package (for example via workspace:* or your catalog) so imports resolve to packages/experience-system.
Composition
The exported Toggle wraps Radix Toggle.Root in a layout shell (for outline chrome). You render Toggle as a single element with children (icons, optional label text):
(shell — Experience System chrome)
└── Toggle (Radix Toggle.Root)Use segment="label" when children include visible text; use segment="icon" for icon-only toggles and set aria-label. Behavior follows Radix Toggle.
Usage
import { Toggle } from '@by/experience-system';
import { Bold, BoldFill } from '@by/icons/ui';Toggle is a client component ('use client'). Use it inside a Client Component or a dynamic import when using the Next.js App Router.
<Toggle aria-label="Bold" segment="icon" variant="outline" size="md">
<Bold className="group-data-[state=on]:hidden" />
<BoldFill className="hidden group-data-[state=on]:block" />
</Toggle>Examples
Overview
segment="label" and segment="icon" with the same bookmark pattern; variant="outline", size="md" (same preview as at the top of the page).
Sizes
sm, md, and lg with variant="outline" on each row.
Variants
outline vs ghost at md with disabled={false}.
Outlined
Ghost
API Reference
Toggle composes Radix Toggle (Toggle.Root). The tables below summarize the Radix Root props plus Experience System extensions. The root is wrapped in a div shell for outline sizing; see the shell Data attributes below. For inherited button behavior, see MDN — button.
Toggle
| Prop | Type | Default |
|---|---|---|
asChild | boolean | false |
pressed | boolean | — |
defaultPressed | boolean | — |
onPressedChange | (pressed: boolean) => void | — |
disabled | boolean | — |
variant | outline | ghost | ghost |
size | sm | md | lg | md |
segment | icon | label | icon |
dir | ltr | rtl | From ThemeProvider unless overridden |
ref | React.Ref<HTMLButtonElement> | — |
Also inherits standard button attributes where Radix forwards them (type, className, id, form props, …). Radix’s type defaults to button.
| Data attribute | Values |
|---|---|
data-slot | toggle |
data-state | on | off |
data-disabled | Present when disabled |
data-variant | outline | ghost |
data-size | sm | md | lg |
data-segment | icon | label |
Data attribute (shell div) | Values |
|---|---|
data-slot | toggle-shell |
data-orientation | horizontal |
data-variant | outline | ghost |
data-size | sm | md | lg |
Accessibility
Toggle exposes aria-pressed via the Radix primitive. Icon-only toggles must have a concise aria-label (or aria-labelledby). Do not rely on icon shape alone. See Radix Toggle — accessibility.
Keyboard interactions
| Key | Description |
|---|---|
Space | Toggles pressed state when the control is focused. |
Enter | Toggles pressed state when the control is focused. |
Source in the repo: packages/experience-system/src/components/Toggle/Toggle.tsx. Agent-oriented contracts: packages/experience-system/src/components/Toggle/Toggle.instructions.md.