# ToggleGroup A segmented control: several options, one strip. - Group: Forms - Import: `import { ToggleGroup } from '@misoto22/folio'` - Page: https://ui.misoto22.com/components/toggle-group/ - Related: tabs, radio-group ## When to reach for it It changes a VALUE. Something that switches panels is Tabs. ## Anatomy - **Strip** (required) — The bordered pill holding the segments, w-fit as well as inline-flex — without it a flex or grid parent stretches the strip to the widest sibling and leaves dead space after the last segment. - **Travelling pill** — The --accent block behind the selection, on single-value groups only and only once it has measured a selected segment. It moves rather than cross-fading, so the eye follows one thing. - **Segment** (required) — A button at --control-h-sm. In a single group it changes ink only and lets the pill behind it do the filling; in a multiple group it fills itself, because there is nothing travelling. - **Segment content** — children, in a gap-2 row. There is no iconOnly path here the way Button has one, so an icon with no words is a segment with no name. ## Best practices ### Do - Give a single-value group a defaultValue or a value. The pill appears only after it has measured a selected segment, so a group that starts empty is a bare strip with nothing marked in it. - Name the strip. Inside a Field its label does it, through aria-labelledby — the root is a div, so there is nothing for htmlFor to bind to — and standing alone it needs its own aria-label, which with type="single" is what a radiogroup is announced by. - Give an icon-only segment its own aria-label: nothing strips the text or supplies a name for you here, so a strip of three glyphs announces three unnamed buttons. ### Don’t - type="single" has radio semantics but not radio behaviour: pressing the selected segment deselects it and commits an empty string, so a view switcher built on it can be switched off into no view at all. - Segments are --control-h-sm — 36px comfortable, 30px under data-density="compact" — which is below the 44px pointer floor (WCAG 2.5.5). A strip meant for a thumb needs its own height. - Do not put six options in it. The strip neither wraps nor scrolls, so past about five segments it simply runs out past its container, and that is a Select or a Combobox anyway. - A Field’s required marks a single-value strip and leaves a multiple-value one unmarked: that one is a role="toolbar", which takes no aria-required at all, so on type="multiple" the asterisk is the whole of the marking. ## Accessibility - type="single" gets radio semantics; type="multiple" gets independent toggles. Choosing wrong tells a screen reader that picking one option unpicks the others. ## Keyboard - Tab — Moves into the strip — one stop for the group. - ← / → — Moves between segments. - Enter / Space — Toggles the focused segment. ## ToggleGroup A segmented control: several options, one strip. `type="single"` is a choice — Radix gives it radio semantics, and it is the right shape for a view switcher or a density setting. `type="multiple"` is a set of independent toggles, which is a different thing announced differently; choosing the wrong one is how a "filter by tag" control ends up telling a screen reader that picking one tag unpicks the others. The two look different on purpose. A single-value strip moves ONE filled pill between its options, so the eye follows a thing travelling; a multiple-value strip fills each pressed option separately, because there is no single selection to travel. Two people looking at a screenshot should be able to tell which kind they are looking at, and before this they could not. Distinct from `Tabs`, which switches PANELS and owns a tabpanel relationship. A toggle group changes a value. Inside a `Field` the strip takes its name from that label, by pointing back at it — the root is a div, and `