Skip to content

Components · Forms

SegmentedControl

Single choice as a radio group with arrow keys; ToggleGroup for several on/off choices.

@rookcom/monarch-reactComponent

View switch

Usage examples

Sizes, icon-only, suffix

ToggleGroup with counts

Purpose

Picks one of a few short, mutually exclusive options shown side by side: a view (list or board), a period (monthly or yearly), a scope. ToggleGroup is the same control for several independent on/off options.

Use when

  • Two to five short options, all visible at once, and changing them updates the view immediately.
  • A compact filter set where several options can be on (ToggleGroup).

Avoid when

  • Each option shows its own panel of content: use Tabs.
  • More than five options, or long labels: use Select.
  • A single on/off setting: use Switch.

Design principles

  • One ARIA model per meaning: single choice is always a radio group, multiple choice is always toggle buttons. Never a tablist without panels.
  • One Tab stop for the whole control; arrow keys move inside it.
  • The selected option is a raised surface with a border, so selection is not shown by shade alone.
  • Labels stay short; icons help but never replace the accessible name.

API reference

import { SegmentedControl, ToggleGroup } from '@rookcom/monarch-react';
ExportKindRenderingRoot class
SegmentedControlcomponentclient.mn-segmented-control
ToggleGroupcomponentclient.mn-segmented-control

Both components take an options array of SegmentedOption and forward their ref to the group <div>.

Both are generic over the option value: value and onValueChange are typed by the options you pass.

An accessible name is required by the type: aria-label or aria-labelledby.

Generated from the TypeScript declarations of packages/react/src/components/forms/segmented-control.

Properties

SegmentedControl: value/onValueChange(value) (controlled) or defaultValue; name adds a hidden input for forms.

ToggleGroup: value/onValueChange(values) (controlled) or defaultValue, as arrays in option order.

SegmentedOption: value, label, icon, hideLabel (icon-only), count, suffix, disabled.

SegmentedControl

PropTypeDescription
options requiredreadonly SegmentedOption<T>[]
blockbooleanStretch to the container and share the width equally.
childrenReactNode
classNamestring
defaultValueT
dir"ltr" | "rtl"Text direction. Left and Right arrows follow it. Default: inherited from the page.
disabledbooleanDisable every option.
idstring
namestringSubmits the selected value with a form under this name.
onValueChange((value: T) => void)
refRef<HTMLDivElement>
requiredbooleanRequires a selection (sets aria-required).
sizeSegmentedControlSize
valueT

ToggleGroup

PropTypeDescription
options requiredreadonly SegmentedOption<T>[]
blockbooleanStretch to the container and share the width equally.
childrenReactNode
classNamestring
defaultValuereadonly T[]
dir"ltr" | "rtl"Text direction. Left and Right arrows follow it. Default: inherited from the page.
disabledbooleanDisable every option.
idstring
onValueChange((value: T[]) => void)
refRef<HTMLDivElement>
sizeSegmentedControlSize
valuereadonly T[]

Variants

PropValuesDescription
size'sm''md''lg'Control height from --mn-control-*. Default md.
block'true''false'Fill the container with equal-width options (data-block).
option.hideLabel'true''false'Icon-only option; the label stays the accessible name and the tooltip.

States

StateExposed asBehaviour
Selected / pressedaria-checked="true" or aria-pressed="true", data-state="on"Raised surface with a border and shadow, so the state is not shown by colour alone.
Hover–Text darkens to the default text colour.
Focus–Focus ring on :focus-visible.
Disabled option or groupdisabled, data-disabled, aria-disabledSkipped by arrow keys; the whole group can be disabled.

Interaction behaviour

  • SegmentedControl: clicking an option selects it. Moving with the arrow keys also selects (selection follows focus, as in a native radio group).
  • ToggleGroup: clicking or pressing Space/Enter toggles an option; arrow keys only move focus.
  • Arrow keys wrap around and skip disabled options. Left and Right follow the text direction.
  • With name, the selected value is submitted with the surrounding form.

Keyboard support

KeysAction
TabEnters the control at the selected option (or the first enabled one), then leaves it. ToggleGroup returns to the last focused option.
→ / ↓Next option (SegmentedControl: and select it).
← / ↑Previous option (SegmentedControl: and select it).
Home / EndFirst / last enabled option.
SpaceSelect (SegmentedControl) or toggle (ToggleGroup) the focused option.
EnterToggleGroup: toggle the focused option.

Accessibility

Role
radiogroup with radio items (SegmentedControl); group with toggle buttons (ToggleGroup)
Accessible name
aria-label or aria-labelledby on the group (required); each option is named by its label, plus its count.
  • Follows the WAI-ARIA APG radio group and toolbar-style roving tabindex patterns.
  • Icon-only options keep the label as visually hidden text and as a tooltip.
  • Counts are separated by a space in the accessible name: "Open 12".
  • On touch devices options are at least 44px tall.

Responsive behaviour

  • Never wider than its container: if the options do not fit, the track scrolls horizontally and the focused option scrolls into view.
  • block shares the full width equally, for example in a phone-width dialog.
  • Taller hit areas under pointer: coarse.

Theme support

  • Track, surface, border and text are Monarch tokens, so every theme and more-contrast mode applies.
  • Transitions are removed under prefers-reduced-motion: reduce; forced-colours mode outlines the selected option.

Do and don't

Do

  • Keep labels to one or two words and use the same size for all options.
  • Name the group ("View", "Billing period") with aria-label or a visible heading and aria-labelledby.
  • Use ToggleGroup when options are independent, SegmentedControl when they are exclusive.

Don't

  • Do not use it as tabs: when each option shows a panel of content, use Tabs.
  • Do not mix icon-only and labelled options in one control.
  • Do not trigger slow or destructive work on selection; arrow keys select as they move.
  • Tabs: When each option has its own panel.
  • Select: More than five options or long labels.
  • Switch: A single on/off setting.
  • FilterBar: Filters that combine search, chips and menus.

Dependencies

KindDepends on
npm packagesreact
Monarch componentsNone

Testing coverage

  • Labelled radio group with one checked radio.
  • One Tab stop on the selected option, or the first enabled one.
  • Arrow keys move and select, wrap, skip disabled options; Home/End; Up/Down.
  • Left and Right reverse in RTL.
  • Selects on click and Space; controlled mode follows the value prop only.
  • Icon-only options and counts in the accessible name; form submission through name; disabled group.
  • ToggleGroup: labelled group of toggle buttons; multi-select in option order; arrows move without toggling; Space and Enter toggle; remembers the Tab stop; controlled value.
CheckCovered
Axe in jsdomYes
Server renderingYes
Browser suitesVisual baselines: /__gallery; Cross-browser axe: /components/segmented-control

Tests: packages/react/src/components/forms/segmented-control