ToggleGroup
Pressed-state buttons grouped as a segmented control, single or multiple selection, plus a standalone Toggle.
Code
import { Toggle, ToggleGroup } from "@fadymondy/nasaq/web";export function ViewMode() { return ( <ToggleGroup defaultValue={["list"]} aria-label="View mode"> <Toggle value="list">List</Toggle> <Toggle value="grid">Grid</Toggle> </ToggleGroup> );}Actions · beta
Live examples and controls: ToggleGroup in the lab.
Install
npx shadcn@latest add https://docs.nasaqui.com/r/toggle-group.jsonA row of buttons that each hold a pressed state. With the default single selection it is a segmented control
(list / grid view, text alignment). With multiple several items can be pressed at once (bold, italic). Toggle
alone is a single pressed-state button (star, pin). Built on Base UI Toggle and ToggleGroup.
When to use
- Choosing a view mode, alignment or density from two to five short options.
- Formatting toolbars where each option is independent (
multiple).
When not to use
- Switching between panels of content: use
Tabs. - A choice that is submitted with a form and needs descriptions: use
RadioGroup. - Filtering by category with many chips: use
ChipGroup. - An immediate on/off setting: use
Switch.
Import
import { Toggle, ToggleGroup } from "@fadymondy/nasaq/web";Quick start
import { Toggle, ToggleGroup } from "@fadymondy/nasaq/web";
export function ViewMode() {
return (
<ToggleGroup defaultValue={["list"]} aria-label="View mode">
<Toggle value="list">List</Toggle>
<Toggle value="grid">Grid</Toggle>
</ToggleGroup>
);
}Anatomy
<ToggleGroup> data-slot="toggle-group" data-variant="segmented | outline"
└─ <Toggle> data-slot="toggle" data-pressed when onAPI
ToggleGroup (ToggleGroupProps)
All Base UI ToggleGroup props, plus:
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "segmented" | "outline" | "segmented" | Tinted track with a raised pressed item, or joined bordered buttons. |
multiple | boolean | false | Allow several pressed items. |
value / defaultValue | readonly string[] | none | Values of the pressed items. Always an array, even in single mode. |
onValueChange | (value: string[], eventDetails) => void | none | Called when the pressed set changes. |
orientation | "horizontal" | "vertical" | "horizontal" | Arrow key axis. |
loopFocus | boolean | true | Wrap focus at the ends. |
disabled | boolean | false | Disable every item. |
Toggle
All Base UI Toggle props: value (its id inside a group), pressed / defaultPressed, onPressedChange, disabled.
Outside a group it renders as an outline button.
Examples
Multiple selection with icons (icon-only items need aria-label):
import { Toggle, ToggleGroup } from "@fadymondy/nasaq/web";
import { Bold, Italic } from "lucide-react";
export function Format() {
return (
<ToggleGroup multiple variant="outline" aria-label="Formatting">
<Toggle value="bold" aria-label="Bold"><Bold /></Toggle>
<Toggle value="italic" aria-label="Italic"><Italic /></Toggle>
</ToggleGroup>
);
}Controlled, in Arabic:
import { useState } from "react";
import { Toggle, ToggleGroup } from "@fadymondy/nasaq/web";
export function ViewModeAr() {
const [value, setValue] = useState<string[]>(["list"]);
return (
<ToggleGroup value={value} onValueChange={setValue} aria-label="طريقة العرض">
<Toggle value="list">قائمة</Toggle>
<Toggle value="grid">شبكة</Toggle>
</ToggleGroup>
);
}Accessibility
| Key | Action |
|---|---|
| Tab | Moves focus into the group, then out. |
| Arrow keys | Move between items. In RTL, ArrowLeft moves to the next item. |
| Space / Enter | Toggles the focused item. |
- The group has
role="group"; items exposearia-pressed. Name the group witharia-labeland localise it. - In single mode, pressing the pressed item again unpresses it and gives an empty array; guard in
onValueChangeif one must always stay selected.
RTL & i18n
Items are laid out in reading order, so the first item sits at the inline start. The outline variant rounds the inline-start and inline-end corners with logical classes.
Styling & tokens
bg-secondary track, bg-card pressed item, bg-nq-selected and border-primary for pressed outline items,
text-muted-foreground idle text, focus ring nq-focus. State attributes: data-pressed, data-disabled.
className merges onto both parts.
Do / Don't
- Do keep labels to one or two words.
- Don't use it for page navigation.
Related
tabs, radio-group, chip-group, button.
Lab
https://docs.nasaqui.com/?path=/docs/components-actions-toggle-group--docs
ThemeSwitcher
Theme (light / dark / system) and language controls - a segmented switcher, a one-icon light/dark toggle with a click, a language dropdown, and menu-item variants for embedding in other menus.
ViewToggle
Switches how a collection is shown (table, grid, board, list or calendar), with one view always pressed and optional persistence in localStorage.