# SegmentedControl

- Page: https://jiguang132.com/resources/astryx/docs/segmented-control
- Resource: Astryx (https://jiguang132.com/resources/astryx.md)
- All guides: https://jiguang132.com/resources/astryx/docs.md

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.

## Installation

```bash
npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0
```

Requires React 19+, base CSS and a Theme provider. See [Setup](/resources/astryx/docs/getting-started).

## Segmented Control

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.

| Prop | Type | Default | Description |
|---|---|---|---|
| value * | string |  | The currently selected value (controlled). |
| onChange * | (value: string) => void |  | Callback fired when a segment is selected. |
| label * | string |  | Accessible label for the radio group (used as aria-label, never rendered visually). |
| size | 'sm' \| 'md' \| 'lg' | 'md' | Size variant for the control. |
| layout | 'hug' \| 'fill' | 'hug' | Layout mode. hug (default) sizes segments to content, capped at the container width (segment labels truncate when it is too narrow); fill stretches them equally to fill the container. |
| isDisabled | boolean | false | Whether the entire control is disabled. |
| disabledMessage | string |  | 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. |
| children * | ReactNode |  | SegmentedControlItem children. |
| xstyle | StyleXStyles |  | StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value: not an inline style object like style={{}}. |

### Usage guidance

- 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.
- Avoid: 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.
- Avoid: 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.
- Avoid: 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.

### In a narrow card

```tsx
import {useState} from 'react';
import {Card} from '@astryxdesign/core/Card';
import {Heading} from '@astryxdesign/core/Heading';
import {
  SegmentedControl,
  SegmentedControlItem,
} from '@astryxdesign/core/SegmentedControl';
import {Text} from '@astryxdesign/core/Text';
import {VStack} from '@astryxdesign/core/VStack';

const SUMMARY = {
  overview: '4 projects, 2 due this week.',
  activity: '18 updates since Monday.',
  members: '12 members, 3 pending invites.',
  billing: 'Next invoice on October 1.',
};

// Inside a VStack the default hug layout keeps its content width; it does not
// stretch to the card. When the card is narrower than the control (a 320px
// phone column), the control caps at the card width and each label truncates
// with an ellipsis instead of running past the card edge. The full label stays
// each segment's accessible name. Keep labels short for phone widths.
function WorkspaceCard() {
  const [view, setView] = useState('overview');
  return (
    <Card maxWidth={480}>
      <VStack gap={3}>
        <Heading level={3}>Team workspace</Heading>
        <SegmentedControl label="Workspace view" value={view} onChange={setView}>
          <SegmentedControlItem value="overview" label="Overview" />
          <SegmentedControlItem value="activity" label="Activity" />
          <SegmentedControlItem value="members" label="Members" />
          <SegmentedControlItem value="billing" label="Billing" />
        </SegmentedControl>
        <Text color="secondary">{SUMMARY[view]}</Text>
      </VStack>
    </Card>
  );
}
```

### Theming API

```json
{
  "targets": [
    {
      "className": "astryx-segmented-control",
      "visualProps": [
        "size"
      ]
    },
    {
      "className": "astryx-segmented-control-item",
      "visualProps": [
        "size"
      ],
      "states": [
        "selected",
        "disabled"
      ]
    }
  ],
  "vars": [
    {
      "name": "--_segmented-control-radius",
      "description": "Border radius of the segmented control",
      "default": "var(--radius-element)",
      "private": true
    },
    {
      "name": "--_segmented-control-padding",
      "description": "Inner padding of the segmented control",
      "default": "var(--spacing-0-5)",
      "private": true
    }
  ],
  "derived": [
    {
      "property": "borderRadius",
      "vars": [
        "--_segmented-control-radius"
      ]
    },
    {
      "property": "padding",
      "vars": [
        "--_segmented-control-padding"
      ]
    }
  ]
}
```

## SegmentedControlItem



### Accessibility

- **Text label**: 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. — 4.5:1
- **Essential icon**: 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. — 3:1
- **Selected state indicator**: The selected background must reach 3:1 only when users need it to tell selected from unselected. Label color and weight also show selection. — 3:1 if relied upon
- **Visible control boundary**: The control edge or segment borders need at least 3:1 contrast when users need them to see the choices. — 3:1 if needed
- **Keyboard focus indicator**: The focus outline must have at least 3:1 contrast with the area around the segment. Check it on the track and selected background. — 3:1
- **Disabled appearance**: Disabled controls do not need to meet these contrast ratios. — Not required

### Anatomy

- **Control**: Container for the mutually exclusive segment choices.
- **Segment**: Individual choice within the control.
- **Label**: Visible text identifying a segment when its label is not hidden.
- **Icon**: Optional caller-supplied icon shown inside a segment.

## Segmented Control Item

Individual segment item rendering as a radio button within the segmented control.

| Prop | Type | Default | Description |
|---|---|---|---|
| value * | string |  | Unique value for this segment, matched against the parent value. |
| label * | string |  | Accessible label for this segment. Rendered as visible text unless isLabelHidden is true. |
| isLabelHidden | boolean | false | Whether the label is visually hidden. When true, only the icon is displayed and label is used as aria-label. |
| icon | ReactNode |  | Icon element displayed before the label. |
| isDisabled | boolean | false | Whether this individual item is disabled. |


## Examples

- Segmented Control Item: Segmented control items with text labels and icons, including a disabled item.
- Segmented Control: 
- SegmentedControl — Disabled Item: Segmented control with an individually disabled option for unavailable choices.
- SegmentedControl — Fill Layout: Segmented control that stretches segments equally to fill the available width, useful for fixed-width containers.
- SegmentedControl — Icon Only: Compact segmented control with hidden labels, showing only icons for space-constrained layouts.
- SegmentedControlItem — Basic: Label-only options inside a SegmentedControl. Each item declares a value; the parent control holds the selected value and change handler.
- SegmentedControl — With Icons: Segmented control with icon and label pairs for a view mode switcher.

---

Index of all JGuang resources: https://jiguang132.com/llms.txt
