Actions
Toggle Group
Toggle Group is exclusive segmented selection (radiogroup) with joined chrome — Segmented Control is this presentation, not a separate component.
Single selection · Size sm/md/lg · Orientation horizontal/vertical — React-first (no Figma master yet)
betaReact AvailableFigma UnavailableDocs Partial
- React last updated
- 2026-09-14
- Documentation last updated
- 2026-09-14
- Accessibility target
- WCAG 2.2 AA (target)
- Version
- 0.1.0-beta
Known open questions
- Figma master not created yet — intentional React-first CE-2 sequence.
- Multiple selection intentionally deferred; 0.1.0-beta is single-only.
Live preview
Exclusive radiogroup selection with segmented chrome. Segmented Control is this presentation — not a separate component.
Interactive
Value: list
Three options
Disabled group
Disabled item
Vertical
Purpose
Toggle Group is exclusive segmented selection with joined chrome. It is the Skrewww abstraction for what other systems call a Segmented Control — not a separate component.
Anatomy
ToggleGroup = role=radiogroup (joined outer chrome) + ToggleGroupItem children (role=radio).
Variants and states
single
When to use
Settings and toolbars where the user picks one option among a small set (List/Grid, Day/Week/Month) and the UI should read as compact joined segments.
When not to use
Peer independent actions — use Button Group. Form-field exclusive choice with radio indicators — use Radio Group. Switching content panels — use Tabs. Binary on/off — use Switch. Multi-select is not supported in 0.1.0-beta.
Accessibility
role=radiogroup with role=radio items, aria-checked, roving tabindex, arrow-key selection (automatic). Re-selecting the current value does not clear selection. Provide aria-label or aria-labelledby.
Keyboard behavior
Tab lands on the selected item (or first item if none). Arrow keys move focus and select. Home/End jump ends. Space/Enter select the focused item. Re-clicking the selected item does not clear selection.
Common mistakes
Using Button Group for exclusive selection. Creating a separate Segmented Control component. Confusing with Tabs (no panels here). Expecting multi-select.
Properties
React: value/defaultValue/onValueChange, disabled, orientation, size, aria-label, ToggleGroupItem value/disabled/children. Single selection only.
Toggle Group vs Segmented Control?
Same capability. Skrewww ships Toggle Group as the semantic component; segmented/joined appearance is the default presentation. There is no separate Segmented Control export.
Toggle Group vs Button Group?
Button Group joins independent peer actions with no selection state. Toggle Group selects exactly one value among segments.
Toggle Group vs Radio Group?
Radio Group is a form-field control with radio indicators, legend, and validation. Toggle Group is compact segmented chrome for toolbar/settings selection.
Toggle Group vs Tabs?
Tabs switch associated content panels (tablist/tabpanel). Toggle Group only selects a value — it does not own panels.
Tokens used
component/radius/controlsemantic/border/defaultsemantic/focus-ringsemantic/surface/subtle
Known limitation
React-first CE-2C — Figma pending. Multiple selection deferred. /r deferred to CE-3. Segmented Control is presentation of Toggle Group, not a second export.
Component API
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | — | Controlled selected value. Empty string means none selected yet. |
| defaultValue | string | — | Uncontrolled initial selected value. |
| onValueChange | (value: string) => void | — | Fires when the selected value changes. |
| disabled | boolean | false | Disables the entire group. |
| orientation | "horizontal" | "vertical" | "horizontal" | Layout and arrow-key orientation. |
| size | "sm" | "md" | "lg" | "md" | Segment size matching control height tokens. |
| aria-label | string | — | Accessible name for the radiogroup when no visible label exists. |
| children | ReactNode | — | ToggleGroupItem children. |
React example
Copy React example
import { useState } from "react";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/ToggleGroup";
export function Example() {
const [value, setValue] = useState("list");
return (
<ToggleGroup
aria-label="View mode"
value={value}
onValueChange={setValue}
>
<ToggleGroupItem value="list">List</ToggleGroupItem>
<ToggleGroupItem value="grid">Grid</ToggleGroupItem>
</ToggleGroup>
);
}