Toggle group
PortedToggle buttons that share one state: at most one pressed, or any number with multiple. All can be off. Arrow keys move between them. Use it for view state, such as text formatting or quick filters on a list. For a form value with exactly one choice, use the segmented RadioGroup. Give the group an aria-label, and each toggle a value.
import { TextBIcon, TextItalicIcon, TextUnderlineIcon } from "@phosphor-icons/react";
import { Toggle } from "@etched/monet/toggle";
import { ToggleGroup } from "@etched/monet/toggle-group";
export function Preview() {
return (
<ToggleGroup multiple aria-label="Text style" defaultValue={["bold"]}>
<Toggle value="bold" shape="square" aria-label="Bold" icon={<TextBIcon />} />
<Toggle value="italic" shape="square" aria-label="Italic" icon={<TextItalicIcon />} />
<Toggle value="underline" shape="square" aria-label="Underline" icon={<TextUnderlineIcon />} />
</ToggleGroup>
);
}Installation
import { ToggleGroup } from "@etched/monet/toggle-group";Examples
Several pressed
multiple: each toggle turns on and off by itself.
import { TextBIcon, TextItalicIcon, TextUnderlineIcon } from "@phosphor-icons/react";
import { Toggle } from "@etched/monet/toggle";
import { ToggleGroup } from "@etched/monet/toggle-group";
export function SeveralPressed() {
return (
<ToggleGroup multiple aria-label="Text style" defaultValue={["bold", "underline"]}>
<Toggle value="bold" shape="square" aria-label="Bold" icon={<TextBIcon />} />
<Toggle value="italic" shape="square" aria-label="Italic" icon={<TextItalicIcon />} />
<Toggle value="underline" shape="square" aria-label="Underline" icon={<TextUnderlineIcon />} />
</ToggleGroup>
);
}One at most
Without multiple, pressing a toggle releases the others. Pressing the pressed one releases it, so none can be on.
import { TextAlignCenterIcon, TextAlignLeftIcon, TextAlignRightIcon } from "@phosphor-icons/react";
import { Toggle } from "@etched/monet/toggle";
import { ToggleGroup } from "@etched/monet/toggle-group";
export function OneAtMost() {
return (
<ToggleGroup aria-label="Text alignment" defaultValue={["left"]}>
<Toggle value="left" shape="square" aria-label="Align left" icon={<TextAlignLeftIcon />} />
<Toggle value="center" shape="square" aria-label="Align center" icon={<TextAlignCenterIcon />} />
<Toggle value="right" shape="square" aria-label="Align right" icon={<TextAlignRightIcon />} />
</ToggleGroup>
);
}Quick filters
Text toggles that narrow a list. value and onValueChange hold the pressed values.
import { useState } from "react";
import { Toggle } from "@etched/monet/toggle";
import { ToggleGroup } from "@etched/monet/toggle-group";
const filters = new Map([
["unread", "Unread"],
["flagged", "Flagged"],
["mine", "Mine"],
]);
export function QuickFilters() {
const [on, setOn] = useState<string[]>(["unread"]);
return (
<div className="row">
<ToggleGroup multiple size="sm" aria-label="Filter messages" value={on} onValueChange={setOn}>
{[...filters].map(([value, label]) => (
<Toggle key={value} value={value}>
{label}
</Toggle>
))}
</ToggleGroup>
<span>{on.length ? `Showing ${on.map((value) => filters.get(value)).join(", ").toLowerCase()}` : "Showing all"}</span>
</div>
);
}Toggle group or segmented radio?
A toggle group holds view state: toggles that can all be off, or several on. A segmented RadioGroup is a form value: exactly one choice, always one chosen, sent with the form. Here, the range is one value; the columns are view state.
import { RadioGroup, RadioItem } from "@etched/monet/radio";
import { Toggle } from "@etched/monet/toggle";
import { ToggleGroup } from "@etched/monet/toggle-group";
export function ToggleGroupOrSegmentedRadio() {
return (
<div className="row" style={{ alignItems: "end", gap: "var(--et-space-6)" }}>
<RadioGroup legend="Range" appearance="segmented" defaultValue="7d">
<RadioItem value="24h" label="24h" />
<RadioItem value="7d" label="7d" />
<RadioItem value="30d" label="30d" />
</RadioGroup>
<ToggleGroup multiple aria-label="Columns" defaultValue={["owner", "site"]}>
<Toggle value="owner">Owner</Toggle>
<Toggle value="site">Site</Toggle>
<Toggle value="started">Started</Toggle>
</ToggleGroup>
</div>
);
}Accessibility
- The group is one
Tabstop.ArrowLeft/ArrowRightmove between toggles and wrap,Home/Endgo to the ends, andSpaceorEnterpresses. - A
groupnamed by itsaria-label. Each toggle is a button witharia-pressed, named by its text oraria-label. - Without
multiple, pressing one releases the others. Pressing the pressed one releases it, so none is on. - Give the group an
aria-labeland each toggle avalue. For a form value with exactly one choice, use a segmentedRadioGroup.
API reference
| Prop | Type | Default | Description |
|---|---|---|---|
| size | "sm" | "base" | "base" | Height of the toggles. In a Toolbar, the toolbar's. |
| className | string | – | Class for layout. |