Segmented

Chooses between a few options side by side, like Grid or List.

Examples

Chart period

WeekMonthYear

Send or request

SendRequest

Billing period

MonthlyYearly

Sizes

  • GridListTimeline

    sm

  • GridListTimeline

    mddefault

Fill

  • GridListTimeline

    falsedefault

  • GridListTimeline

    true

States

  • GridListTimeline

    rest

  • GridListTimeline

    hover

  • GridListTimeline

    focus-visible

  • GridListTimeline

    disabled item

  • GridListTimeline

    disabled

Usage

When to use it
Use
A view or mode switch: Grid or List, Monthly or Yearly.
Use
A short setting where seeing every option helps: Week, Month or Year.
Not for
The choice switches panels of content. Use Tabs.
Not for
More than five options. Use Select.
Not for
Each option needs a line of explanation. Use Radio.
Not for
Any number of options may be on. Use Chip.

Rules

7 rules
Must
Set defaultValue or value so one segment is always chosen. Because the group starts empty, so no pill shows and the view it sets has no value.
Must
Pass aria-label to Segmented when there is no visible heading. Because the track is a radio group, and unnamed a reader hears "Grid, radio" with no question.
Must
Read the choice with onValueChange(value: string), not the Base UI details object. Because Segmented passes only the value string, so a second details argument is undefined.
Should
Write one or two words in sentence case, all the same kind.
Must
Keep two to five segments; use Select beyond that. Because segments never wrap, so past five the labels truncate to a few letters on a phone.
Should
Use fill on a phone; labels truncate rather than wrap.
Never
Build a view switch with Tabs; Segmented sets a value, Tabs switch panels. Because Tabs announce a tab and a panel per item, and a view switch has one panel.

Accessibility

4 checks
Segmented is a radio group: Tab enters once, arrows move and choose, and the group needs a name.
The white pill on the grey track is about 1.1:1, so the chosen segment also takes the stronger text color.
Forced colors paints the chosen segment Highlight and HighlightText.
The track is 32 or 40px tall, under 44px; fill gives wider targets.

Edge cases

6 edge cases
Long labels
Segments never wrap; once the track fills its container the labels truncate. Shorten them or use Select.
Narrow container
Three segments need about 230px; below that the labels truncate. Use fill or fewer segments.
Right to left
Segments run right to left and arrows follow the reading direction.
No items
An empty grey pill; never render it.
Zoom 200%
Segments widen and the track keeps its height.
Reduced motion
Colors change at once; there is no sliding pill.

API

6 props
size
'sm' | 'md' default 'md'
fill
boolean default false
value, defaultValue
string
onValueChange
(value: string) => void
SegmentedItem value
string default required
disabled
boolean default false

Tokens

14 tokens
--surface-2
#efeeea
--radius-control
999px
--control-sm
32px
--control-md
40px
--fg-2
#4a4943
--fg
#0f0f0d
--raised
#ffffff
--shadow-card
0 1px 2px rgb(var(--shadow-ink) / 0.06), 0 1px 1px rgb(var(--shadow-ink) / 0.04)
--fg-disabled
#a6a49b
--ring
var(--accent-line)
--line-focus
2px
--focus-offset
2px
--dur-fast
140ms
--ease-out
cubic-bezier(0.16, 1, 0.3, 1)

Install

For your coding agent

GitHub

Please star me pookie

141

A new design system every week

Leave your email before you copy the prompt.