EXEPERTAI LAB

Research alpha

Time Machine
EXEPERTAI LAB
GALLERY / COLLECTION
← Browse Astryx gallery
SegmentedControl·component·@astryxdesign/core

Segmented Control

Container wrapper providing context (value, onChange, size, isDisabled) to SegmentedControlItem children.

Open in Playground @astryxdesign/core/SegmentedControl

Showcases and examples

5 documented examples

Segmented Control

SegmentedControl API entry

Preview loads on approachPreview loads on approach
Exact source · segmented-control-showcase
// Copyright (c) Meta Platforms, Inc. and affiliates.

'use client';

import {useState} from 'react';
import {
  SegmentedControl,
  SegmentedControlItem,
} from '@astryxdesign/core/SegmentedControl';

export default function SegmentedControlShowcase() {
  const [value, setValue] = useState('grid');
  return (
    <SegmentedControl value={value} onChange={setValue} label="View mode">
      <SegmentedControlItem value="grid" label="Grid" />
      <SegmentedControlItem value="list" label="List" />
      <SegmentedControlItem value="table" label="Table" />
    </SegmentedControl>
  );
}

Usage

A segmented button group that allows users to make a single selection from a small set of mutually exclusive options. Use SegmentedControl when all options should be visible at once and the selection controls a value or mode, not page navigation.

  • Use for switching between 2–5 mutually exclusive views or modes where all options should be visible.
  • Provide a descriptive label for the control to ensure the group is accessible to screen readers.
  • Use for page-level navigation; use TabList instead. TabList is a navigation component, while SegmentedControl is an input that always has exactly one selected option.
  • Use for simple on/off states; use ToggleButton instead. ToggleButton can be toggled on or off independently, while SegmentedControl enforces a single selection from a group.
  • Wrap a disabled SegmentedControl in Tooltip to explain why it is disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead.

Typed props

PropType and behavior
valuestring · required
The currently selected value (controlled).
onChange(value: string) => void · required
Callback fired when a segment is selected.
labelstring · required
Accessible label for the radio group (used as aria-label, never rendered visually).
size'sm' | 'md' | 'lg' · default 'md'
Size variant for the control.
layout'hug' | 'fill' · default 'hug'
Layout mode. hug (default) sizes segments to content; fill stretches them equally to fill the container.
isDisabledboolean · default false
Whether the entire control is disabled.
disabledMessagestring
Explains why the control is disabled. Applies to the whole-group disabled state (isDisabled), not per segment. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the control focusable via aria-disabled (selection stays blocked). Use this instead of wrapping a disabled SegmentedControl in Tooltip. Disabled controls swallow the hover events an external Tooltip needs.
childrenReactNode · required
xstyleStyleXStyles
StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value: not an inline style object like style={{}}.

Anatomy

Control · required

Container for the mutually exclusive segment choices.

Segment · required

Individual choice within the control.

Label · optional

Visible text identifying a segment when its label is not hidden.

Icon · optional

Optional caller-supplied icon shown inside a segment.

Accessibility

Text label

Color contrast · 1.4.3 Contrast (Minimum) · 4.5:1

Each label must have at least 4.5:1 contrast with its segment background. Check unselected, Hover, Pointer down, and selected colors as they appear on screen. For Hover and Pointer down, measure the final background after the overlay is applied.

States: Rest, Hover, Pointer down, Selected

Essential icon

Color contrast · 1.4.11 Non-text Contrast · 3:1

When a segment has no visible label, its icon must have at least 3:1 contrast with the segment background. An icon beside a visible label does not need its own check.

States: Icon only

Selected state indicator

Color contrast · 1.4.11 Non-text Contrast · 3:1 if relied upon

The selected background must reach 3:1 only when users need it to tell selected from unselected. Label color and weight also show selection.

States: Selected

Visible control boundary

Color contrast · 1.4.11 Non-text Contrast · 3:1 if needed

The control edge or segment borders need at least 3:1 contrast when users need them to see the choices.

States: Rest

Keyboard focus indicator

Color contrast · 1.4.11 Non-text Contrast · 3:1

The focus outline must have at least 3:1 contrast with the area around the segment. Check it on the track and selected background.

States: Focus visible

Disabled appearance

Color contrast · 1.4.3 and 1.4.11 exceptions · Not required

Disabled controls do not need to meet these contrast ratios.

States: Disabled

Theming

Targets

astryx-segmented-control

Visual props: size

astryx-segmented-control-item

Visual props: size

States: selected, disabled

Variables

--_segmented-control-radius · private

Border radius of the segmented control

Default: var(--radius-element)

--_segmented-control-padding · private

Inner padding of the segmented control

Default: var(--spacing-0-5)

Derived properties

borderRadius

Uses --_segmented-control-radius.

padding

Uses --_segmented-control-padding.