XDSSegmentedControl@xds/core · SegmentedControl
Preview coming soon
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.Best practices
| Guidance | Practices |
|---|---|
| Do | Use for switching between 2–5 mutually exclusive views or modes where all options should be visible. |
| Do | Provide a descriptive label for the control to ensure the group is accessible to screen readers. |
| Don't | Use for page-level navigation — use XDSTabList instead. TabList is a navigation component, while SegmentedControl is an input that always has exactly one selected option. |
| Don't | Use for simple on/off states — use XDSToggleButton instead. ToggleButton can be toggled on or off independently, while SegmentedControl enforces a single selection from a group. |
Import
tsimport {XDSSegmentedControl} from '@xds/core/SegmentedControl'
Props
| Prop | Type | Description |
|---|---|---|
valuerequired | string | The currently selected value (controlled). |
onChangerequired | (value: string) => void | Callback fired when a segment is selected. |
labelrequired | string | Accessible label for the radio group (used as aria-label, never rendered visually). |
childrenrequired | ReactNode | XDSSegmentedControlItem children. |
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. |
isDisabled | boolean (default: false) | Whether the entire control is disabled. |
xstyle | StyleXStyles | Additional StyleX styles for the container. |
Sub-components
SegmentedControl is a compound component with 2 sub-components.XDSSegmentedControl
Container wrapper providing context (value, onChange, size, isDisabled) to XDSSegmentedControlItem children.| Prop | Type | Description |
|---|---|---|
valuerequired | string | The currently selected value (controlled). |
onChangerequired | (value: string) => void | Callback fired when a segment is selected. |
labelrequired | string | Accessible label for the radio group (used as aria-label, never rendered visually). |
childrenrequired | ReactNode | XDSSegmentedControlItem children. |
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. |
isDisabled | boolean (default: false) | Whether the entire control is disabled. |
xstyle | StyleXStyles | Additional StyleX styles for the container. |
XDSSegmentedControlItem
Individual segment item rendering as a radio button within the segmented control.| Prop | Type | Description |
|---|---|---|
valuerequired | string | Unique value for this segment, matched against the parent value. |
labelrequired | string | Accessible label for this segment. Rendered as visible text unless isLabelHidden is true. |
isLabelHidden | boolean (default: 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 (default: false) | Whether this individual item is disabled. |
Examples
Common configurations, variations, and states.SegmentedControl — Disabled ItemSegmented control with an individually disabled option for unavailable choices.
tsx'use client';import {useState} from 'react';import {XDSSegmentedControl,XDSSegmentedControlItem,} from '@xds/core/SegmentedControl';export default function SegmentedControlDisabledItem() {const [value, setValue] = useState('hourly');return (<XDSSegmentedControlvalue={value}onChange={setValue}label="Data granularity"><XDSSegmentedControlItem value="hourly" label="Hourly" /><XDSSegmentedControlItem value="daily" label="Daily" /><XDSSegmentedControlItem value="weekly" label="Weekly" isDisabled /></XDSSegmentedControl>);}
SegmentedControl — Icon OnlyCompact segmented control with hidden labels, showing only icons for space-constrained layouts.
tsx'use client';import {useState} from 'react';import {XDSSegmentedControl,XDSSegmentedControlItem,} from '@xds/core/SegmentedControl';const GridIcon = () => (<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="7" height="7" rx="1" /><rect x="14" y="3" width="7" height="7" rx="1" /><rect x="3" y="14" width="7" height="7" rx="1" /><rect x="14" y="14" width="7" height="7" rx="1" /></svg>);const ListIcon = () => (<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" strokeLinejoin="round"><line x1="9" y1="6" x2="20" y2="6" /><line x1="9" y1="12" x2="20" y2="12" /><line x1="9" y1="18" x2="20" y2="18" /><circle cx="5" cy="6" r="1" fill="currentColor" /><circle cx="5" cy="12" r="1" fill="currentColor" /><circle cx="5" cy="18" r="1" fill="currentColor" /></svg>);export default function SegmentedControlIconOnly() {const [value, setValue] = useState('grid');return (<XDSSegmentedControlvalue={value}onChange={setValue}label="View mode"size="sm"><XDSSegmentedControlItemvalue="grid"label="Grid"isLabelHiddenicon={<GridIcon />}/><XDSSegmentedControlItemvalue="list"label="List"isLabelHiddenicon={<ListIcon />}/></XDSSegmentedControl>);}
SegmentedControl — With IconsSegmented control with icon and label pairs for a view mode switcher.
tsx'use client';import {useState} from 'react';import {XDSSegmentedControl,XDSSegmentedControlItem,} from '@xds/core/SegmentedControl';const GridIcon = () => (<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="7" height="7" rx="1" /><rect x="14" y="3" width="7" height="7" rx="1" /><rect x="3" y="14" width="7" height="7" rx="1" /><rect x="14" y="14" width="7" height="7" rx="1" /></svg>);const ListIcon = () => (<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" strokeLinejoin="round"><line x1="9" y1="6" x2="20" y2="6" /><line x1="9" y1="12" x2="20" y2="12" /><line x1="9" y1="18" x2="20" y2="18" /><circle cx="5" cy="6" r="1" fill="currentColor" /><circle cx="5" cy="12" r="1" fill="currentColor" /><circle cx="5" cy="18" r="1" fill="currentColor" /></svg>);const TableIcon = () => (<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" /><line x1="3" y1="9" x2="21" y2="9" /><line x1="3" y1="15" x2="21" y2="15" /><line x1="9" y1="3" x2="9" y2="21" /></svg>);export default function SegmentedControlWithIcons() {const [value, setValue] = useState('grid');return (<XDSSegmentedControl value={value} onChange={setValue} label="View mode"><XDSSegmentedControlItem value="grid" label="Grid" icon={<GridIcon />} /><XDSSegmentedControlItem value="list" label="List" icon={<ListIcon />} /><XDSSegmentedControlItemvalue="table"label="Table"icon={<TableIcon />}/></XDSSegmentedControl>);}
SegmentedControl \u2014 Fill LayoutSegmented control that stretches segments equally to fill the available width, useful for fixed-width containers.
tsx'use client';import {useState} from 'react';import {XDSSegmentedControl,XDSSegmentedControlItem,} from '@xds/core/SegmentedControl';export default function SegmentedControlFillLayout() {const [value, setValue] = useState('weekly');return (<div style={{width: 400}}><XDSSegmentedControlvalue={value}onChange={setValue}label="Time range"layout="fill"><XDSSegmentedControlItem value="daily" label="Daily" /><XDSSegmentedControlItem value="weekly" label="Weekly" /><XDSSegmentedControlItem value="monthly" label="Monthly" /></XDSSegmentedControl></div>);}
Showcase source
tsx'use client';import {XDSSegmentedControl,XDSSegmentedControlItem,} from '@xds/core/SegmentedControl';export default function SegmentedControlShowcase() {return (<XDSSegmentedControl value="grid" onChange={() => {}} label="View mode"><XDSSegmentedControlItem value="grid" label="Grid" /><XDSSegmentedControlItem value="list" label="List" /><XDSSegmentedControlItem value="table" label="Table" /></XDSSegmentedControl>);}