Content switcher
Choosing · researchedA row of connected buttons where exactly one is active, swapping the view of the same content or setting a choice.
molecule · also called Segmented control, Segmented, Segmented button · contains button
Each block is the real component from that system’s own package, in an isolated frame. They are live: hover, focus and press them. Frames are drawn on white so systems compare on one ground, and a font a system licenses only for its own site (GOV.UK’s Transport) falls back to what the system itself specifies.
Ant Design
Segmented native: partly antd 6.6.5- Variants
- default, round
- Sizes
- large, medium, small
- States documented
- disabled
- Accessibility guidance
- no
Renders a radiogroup of native visually-hidden input[type=radio] in labels (via @rc-component/segmented), one active at a time.
2 corrected on re-read
- builds_on_native: "yes" → "partly" Root div role=radiogroup with native input type=radio per item, same pattern as Radio.Group
- states_documented: null → ["disabled"] Segmented API: disabled for whole control and per item
Carbon
Content switcher native: partly @carbon/react 1.117.0- Variants
- high contrast, low contrast, with icons
- Sizes
- sm, md, lg
- States documented
- hover, focus, disabled
- Accessibility guidance
- yes
Each Switch is a button with role=tab inside the container (React source), so segments are announced as tabs; selectionMode automatic or manual. Index entries (Content switcher, Switch) correct.
2 corrected on re-read
- variants: null → ["high contrast","low contrast","with icons"] Usage 'Modifiers': high and low contrast, content switcher with icons
- urls: {"docs_url":"https://carbondesignsystem.com/components/content-switcher/usage/","code_url":"https://github.com/carbon-design-system/carbon/tree/main/packages/react/src/components/ContentSwitcher"} → {"docs_url":"https://www.carbondesignsystem.com/building-blocks/core/components/content-switcher/guidelines","code_url":"https://github.com/carbon-design-system/carbon/tree/main/packages/react/src/components/ContentSwitcher"} docs 200 after redirect to https://www.carbondesignsystem.com/building-blocks/core/components/content-switcher/guidelines; code URL 200
GOV.UK
Checked: component index (https://design-system.service.gov.uk/components/ , 37 components), patterns index, styles index, repo tree src/govuk/components and objects, and installed govuk-frontend 6.5.1 components directory. No segmented control or button-toggle component. Tabs component swaps panels of content but renders links/tabs, not a connected button row (mapped separately to tabs).
Material Web
Agree with index. Experimental labs code in the 2.5.0 package, no docs page. Set is a div role=group; each segment renders a native button with aria-pressed. multiselect property switches single to multiple selection. Roadmap lists Segmented button as not built. Newer unpublished GB button group (main only) has selection=single|multiple too.
2 corrected on re-read
- present: "ships" → "absent" labs-only: Absent as shipped: labs/segmentedbuttonset + segmentedbutton (div role=group; native button aria-pressed) is experimental labs code in 2.5.0 with no d
- urls: {"docs_url":null,"code_url":"https://github.com/material-components/material-web/tree/main/labs/segmentedbuttonset"} → {"docs_url":null,"code_url":null} no URLs for absent rows; repo tree API 1808 entries, not truncated
· code ↗
Primer
SegmentedControl native: partly @primer/react 38.40.1- Variants
- default, subtle
- Sizes
- small, medium
- States documented
- disabled, loading
- Accessibility guidance
- yes
Primer React. Selects one of several buttons; can collapse to an ActionMenu dropdown at narrow widths (variant responsive values hideLabels/dropdown). Status ready.
1 corrected on re-read
- states_documented: null → ["disabled","loading"] SegmentedControl.Action props: disabled, loading
Spectrum
Segmented control native: partly- Variants
- —
- Sizes
- —
- States documented
- default, hover, active, focus, disabled
- Accessibility guidance
- no
Docs from the rsp page (items 2 to 5, selected state, vertical option); implementation is React Spectrum S2 only, built on React Aria ToggleButtonGroup and ToggleButton (real button elements in a group). No SWC element or spectrum-css component; installed SWC 1.12.4 has none (sp-action-group in SWC 1st-gen with selects is the nearest, and is not installed). The accessibility fragment is the generic Button keyboard table.
1 corrected on re-read
- a11y_documented: "yes" → "no" rsp accessibility fragment is the Button keyboard table (identical to rsp button fragment), not about this component
USWDS
Button group (segmented) variant native: yes @uswds/uswds 3.14.0- Variants
- segmented (usa-button-group--segmented)
- Sizes
- —
- States documented
- default
- Accessibility guidance
- yes
Index said not shipped. The Segmented button group on the Button group page is a row of joined buttons (example Map/Hybrid/Satellite), but docs and template ship no selected-state logic or aria-pressed; it is styling only. Variant of Button group, not a separate component.
Platform facts
Anatomy
- switcher container — No source names it; APG Tabs calls the set a 'tab list' (role tablist), APG Radio Group a 'radiogroup'.
- segment — APG Tabs: 'tab' elements; APG Radio Group: radio buttons. Which applies depends on whether the switcher shows different panels or sets a value.
The seven states
| default | One segment is selected (APG: aria-selected on a tab, aria-checked on a radio). |
|---|---|
| hover | Pointer-only CSS state; not defined by APG or HTML. |
| focus | APG Tabs: Tab moves focus to the active tab; arrows move among tabs. |
| active | Pressed state while the pointer or key is down; CSS :active. Not defined by APG. |
| disabled | Inference: APG Tabs and Radio Group pages contain no mention of disabled (grepped 2026-10-05); the native disabled attribute exists on input type=radio and button. aria-disabled would be the author's choice. |
| error | n/a — Not defined. |
| loading | n/a — Not defined. |
Every cell was read twice, the second time from raw sources by a separate pass. 8 of 35 fields changed on the second read — open any “corrected” note to see what it said before.