Segment Control
Segment controls allow users to select a single option from a set of related choices. Built on Radix UI RadioGroup primitives for accessibility.
Basic Usage
import { SegmentControl } from '@/components'
<SegmentControl.Root value={value} onValueChange={setValue}>
<SegmentControl.Item value="light">
<SegmentControl.Icon><SunIcon /></SegmentControl.Icon>
<SegmentControl.Text>Light</SegmentControl.Text>
</SegmentControl.Item>
<SegmentControl.Item value="dark">
<SegmentControl.Icon><MoonIcon /></SegmentControl.Icon>
<SegmentControl.Text>Dark</SegmentControl.Text>
</SegmentControl.Item>
</SegmentControl.Root>Variants
SegmentControl supports four display variants for different use cases.
Default (Icon + Text)
Text Only
Icon Only
Rounded (Pill-shaped)
Default (Icon + Text)
Shows both icon and text label for each segment.
<SegmentControl.Root variant="default">
<SegmentControl.Item value="light">
<SegmentControl.Icon><SunIcon /></SegmentControl.Icon>
<SegmentControl.Text>Light</SegmentControl.Text>
</SegmentControl.Item>
</SegmentControl.Root>Text Only
Text-only segments for simple options.
<SegmentControl.Root variant="text">
<SegmentControl.Item value="light">
<SegmentControl.Text>Light</SegmentControl.Text>
</SegmentControl.Item>
</SegmentControl.Root>Icon Only
Compact icon-only segments for toolbars and space-constrained layouts.
<SegmentControl.Root variant="icon">
<SegmentControl.Item value="grid">
<SegmentControl.Icon><GridIcon /></SegmentControl.Icon>
</SegmentControl.Item>
</SegmentControl.Root>Rounded (Pill-shaped)
Pill-shaped segments for a softer visual appearance.
<SegmentControl.Root variant="rounded">
<SegmentControl.Item value="sun">
<SegmentControl.Icon><SunIcon /></SegmentControl.Icon>
</SegmentControl.Item>
</SegmentControl.Root>Sizes
Three sizes are available to fit different contexts.
Large (44px)
Medium (40px)
Small (36px)
<SegmentControl.Root size="lg">...</SegmentControl.Root> // 44px
<SegmentControl.Root size="md">...</SegmentControl.Root> // 40px
<SegmentControl.Root size="sm">...</SegmentControl.Root> // 36pxDisabled
Segments can be disabled either at the group level or individually.
Entire group disabled
Single item disabled
// Disable entire group
<SegmentControl.Root disabled>...</SegmentControl.Root>
// Disable single item
<SegmentControl.Item value="system" disabled>...</SegmentControl.Item>Controlled
Control the selection state externally using value and onValueChange.
const [value, setValue] = useState('grid')
<SegmentControl.Root value={value} onValueChange={setValue}>
<SegmentControl.Item value="grid">
<SegmentControl.Icon><GridIcon /></SegmentControl.Icon>
</SegmentControl.Item>
<SegmentControl.Item value="list">
<SegmentControl.Icon><ListIcon /></SegmentControl.Icon>
</SegmentControl.Item>
</SegmentControl.Root>Two Segments
Works great with just two options for binary choices.
All Variants Overview
Default variant - All sizes
All variants - Medium size
Accessibility
- Built on Radix UI RadioGroup primitive for robust accessibility
- Full keyboard support (Arrow keys to navigate, Space/Enter to select)
- Proper ARIA attributes for screen readers
- Focus states are clearly visible
- Supports
aria-labelfor group labeling
API Reference
SegmentControl.Root Props
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | - | The controlled value |
| defaultValue | string | - | The default value (uncontrolled) |
| onValueChange | (value: string) => void | - | Callback when value changes |
| variant | 'default' | 'text' | 'icon' | 'rounded' | 'default' | Visual variant |
| size | 'sm' | 'md' | 'lg' | 'lg' | Size of the control |
| disabled | boolean | false | Disable all segments |
| className | string | - | Additional CSS classes |
SegmentControl.Item Props
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | Required | The value for this segment |
| disabled | boolean | false | Disable this segment |
| className | string | - | Additional CSS classes |
SegmentControl.Icon Props
| Prop | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | Required | Icon element |
| className | string | - | Additional CSS classes |
SegmentControl.Text Props
| Prop | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | Required | Text content |
| className | string | - | Additional CSS classes |