Toggle Family
Use toggle family with the current published Askr packages.
@askrjs/ui/toggle0.0.13@askrjs/ui/toggle-group0.0.13@askrjs/themes/toggle0.0.13@askrjs/themes/toggle-group0.0.13
How to use toggle family
Toggle Family should use the standard themed surface unless the application is deliberately implementing its own design system on top of @askrjs/ui.
- Import the themed component from @askrjs/themes/components; use @askrjs/ui directly only when building a custom visual system.
- Keep toggle family labels, state, and application actions visible at the call site instead of styling internal DOM nodes.
- Verify keyboard behavior, focus movement or return, disabled state, and both standard themes.
import { Toggle, ToggleGroup, ToggleGroupItem } from '@askrjs/themes/components';
<Toggle pressed={bold()} onPressedChange={bold.set}>Bold</Toggle>
<ToggleGroup type="single" value={alignment()} onValueChange={alignment.set}>
<ToggleGroupItem value="left">Left</ToggleGroupItem>
<ToggleGroupItem value="center">Center</ToggleGroupItem>
</ToggleGroup>Purpose
This page covers two related but distinct primitives: `Toggle`, a single pressed/unpressed button (bold, italic, favorite-star patterns), and `ToggleGroup`, a set of toggle buttons where selecting one can affect the others — either a single-select group like alignment buttons or a multi-select group like text formatting. They share the same pressed-state model but solve different layout problems, which is why they're documented together rather than as a combined component.
Install and import
Both primitives ship from `@askrjs/ui` with their own subpaths — `@askrjs/ui/toggle` and `@askrjs/ui/toggle-group` — and matching `@askrjs/themes/toggle` and `@askrjs/themes/toggle-group` subpaths for styling. Import only the one you need; a page that just needs a single toggle button doesn't have to pull in the group's item-collection logic.
Live examples
The examples include a standalone `Toggle` for a single boolean action, a single-select `ToggleGroup` (`type="single"`) for mutually exclusive choices like text alignment, and a multi-select `ToggleGroup` (`type="multiple"`) for independent choices like bold/italic/underline stacked together.
Anatomy
`Toggle` is a standalone component with no required children structure beyond its own content. `ToggleGroup` is a root that wraps one or more `ToggleGroupItem` children, each identified by a required `value` string — the group reads its items' values to compute what's selected rather than you tracking indices.
State model
`Toggle`'s `pressed` prop is deliberately controlled-only — there's no `defaultPressed` or internal fallback, so you own the boolean and respond to `onPress`. `ToggleGroup` splits on its `type` discriminant: `type="single"` (the default) uses a string `value`/`defaultValue`/`onValueChange`, while `type="multiple"` switches all three to arrays of strings. Passing the wrong shape for the chosen `type` is a type error, not a runtime surprise.
Keyboard and accessibility
`Toggle` uses `role="button"` with `aria-pressed` and responds to both Enter and Space, and its types explicitly prohibit `onClick` in favor of `onPress` — the package's own docs note this is because `onClick` doesn't carry toggle or disabled semantics the way the pressable foundation's `onPress` does. `ToggleGroup` exposes a `loop` prop that controls whether arrow-key navigation wraps from the last item back to the first, and the group itself carries `role="group"` while each item keeps `role="button"` with `aria-pressed`.
Styling and tokens
Both components expose `data-state` (`on`/`off` for Toggle, similar semantics per item in a group) and `data-disabled` for CSS targeting, plus `data-orientation` on `ToggleGroup` so horizontal and vertical layouts can be styled independently. `@askrjs/themes` applies the shared button-like visual language here, so a themed `Toggle` looks consistent with `Button` at rest and simply adds a pressed treatment.
API
`Toggle` takes `pressed`, `onPress`, `disabled`, and the usual `asChild` escape hatch. `ToggleGroup` takes `type`, the value props matching that type, `orientation`, `loop`, and `disabled` (which cascades to disable the whole group); `ToggleGroupItem` takes its own `value`, optional `disabled`, and `asChild`, letting individual items opt out independently of the group-level flag.
Edge cases
Disabling `ToggleGroup` at the root disables every item regardless of each item's own `disabled` prop, but the reverse isn't true — you can disable individual items in an otherwise enabled group. Because `ToggleGroupItem`'s `value` is required, forgetting to set one is a compile-time error rather than something that silently breaks selection at runtime.
Related pages
For a single always-visible on/off control tied to a setting rather than a pressed visual, Switch is usually the better fit. If your toggle group is really acting as a segmented tab selector, look at Tabs instead — the visual overlap is common but the semantics differ.