Client component
Segmented Control
A single-choice control styled as connected segments, the classic "view switcher". Under the styling it is a group of native radios (visually hidden), so arrow-key movement, form participation and radio semantics come from the platform, not from JavaScript re-implementations.
import { SegmentedControl } from "astralis-ui";
export function SegmentedControlDemo() {
return (
<SegmentedControl defaultValue="list" aria-label="View">
<SegmentedControl.Item value="list">List</SegmentedControl.Item>
<SegmentedControl.Item value="grid">Grid</SegmentedControl.Item>
<SegmentedControl.Item value="table">Table</SegmentedControl.Item>
</SegmentedControl>
);
}size
name
import { SegmentedControl } from "astralis-ui";
<SegmentedControl
defaultValue="week"
>
<SegmentedControl.Item value="day">Day</SegmentedControl.Item>
<SegmentedControl.Item value="week">Week</SegmentedControl.Item>
<SegmentedControl.Item value="month">Month</SegmentedControl.Item>
</SegmentedControl>
Import#
import { SegmentedControl } from "astralis-ui";Sizes#
import { SegmentedControl, VStack } from "astralis-ui";
export function SegmentedControlSizes() {
return (
<VStack gap="4" alignItems="start">
{(["sm", "md", "lg"] as const).map((size) => (
<SegmentedControl key={size} size={size} defaultValue="week" aria-label={`Range (${size})`}>
<SegmentedControl.Item value="day">Day</SegmentedControl.Item>
<SegmentedControl.Item value="week">Week</SegmentedControl.Item>
<SegmentedControl.Item value="month">Month</SegmentedControl.Item>
</SegmentedControl>
))}
</VStack>
);
}Full width#
fullWidth stretches the track and shares the width equally between segments:
import { SegmentedControl, Box } from "astralis-ui";
export function SegmentedControlFullWidth() {
return (
<Box w="full" maxW="md">
<SegmentedControl fullWidth defaultValue="preview" aria-label="Mode">
<SegmentedControl.Item value="edit">Edit</SegmentedControl.Item>
<SegmentedControl.Item value="preview">Preview</SegmentedControl.Item>
</SegmentedControl>
</Box>
);
}Segmented Control vs Tabs vs CheckableTag#
- SegmentedControl: one value from a few, radio semantics, no panels.
- Tabs: switches visible content panels.
- CheckableTag: chip-shaped multi/single select for filtering, wraps freely.
Props#
| Prop | Type | Default | Description |
|---|---|---|---|
value / defaultValue / onChange | string / string / (value: string) => void | None | Controlled / uncontrolled selection. |
size | "sm" | "md" | "lg" | "md" | Segment height and text size. |
fullWidth | boolean | false | Stretches to the container, sharing the width equally between segments. |
disabled | boolean | false | Disables every segment. |
name | string | generated | Name of the segment radios, so the choice submits with a native form. |
SegmentedControl.Item#
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | None | The value this segment represents. Required. |
children | ReactNode | None | Segment label. |
disabled | boolean | false | Disables just this segment. |
Keyboard#
The segments are native radios, so the keys are the browser's own:
| Key | Action |
|---|---|
Tab | Into the control: one tab stop, on the selected segment |
← ↑ / → ↓ | Select the previous / next segment |
Space | Select the focused segment, when none is selected yet |