Segmented
A pill-shaped control for exclusive single-selection — ideal for filters and view switching.
Playground
<Segmented defaultValue="play">
<Segmented.Item value="prev">Prev</Segmented.Item>
<Segmented.Item value="play">Play</Segmented.Item>
<Segmented.Item value="next">Next</Segmented.Item>
</Segmented>Variants
defaultPill StyleoutlineBordered StyleunderlineTab StyleghostMinimal StyleSizes
Text Only
smmddefaultlg| Size | Height | H. Padding | Font | Preview |
|---|---|---|---|---|
sm | 32px | 14px | 12px | |
md | 36px | 14px | 13px | |
default | 40px | 16px | 13px | |
lg | 48px | 24px | 14px |
Icon Only (Square)
smmddefaultlg| Size | Container Height | Item Size | Icon | Preview |
|---|---|---|---|---|
sm | 32px | 24px × 24px | 14px | |
md | 36px | 28px × 28px | 16px | |
default | 40px | 32px × 32px | 16px | |
lg | 48px | 40px × 40px | 16px |
Icon + Text
smmddefaultlg| Size | Height | H. Padding | Gap | Icon | Font | Preview |
|---|---|---|---|---|---|---|
sm | 32px | 12px | 8px | 14px | 12px | |
md | 36px | 14px | 8px | 16px | 13px | |
default | 40px | 16px | 8px | 16px | 13px | |
lg | 48px | 24px | 8px | 16px | 14px |
Features
Use Cases
Notion, Linear, task management apps
Stripe, Google Analytics, dashboards
Figma, Notion, project management tools
SaaS pricing pages, subscriptions
// Status Filter — Notion, Linear style
<Segmented defaultValue="all">
<Segmented.Item value="all">All</Segmented.Item>
<Segmented.Item value="active">Active</Segmented.Item>
<Segmented.Item value="completed">Done</Segmented.Item>
</Segmented>
// Date Range Filter — Stripe, Analytics style
<Segmented defaultValue="30d">
<Segmented.Item value="7d">7d</Segmented.Item>
<Segmented.Item value="30d">30d</Segmented.Item>
<Segmented.Item value="90d">90d</Segmented.Item>
</Segmented>
// View Switch — Figma, Notion style
<Segmented defaultValue="table">
<Segmented.Item value="table">Table</Segmented.Item>
<Segmented.Item value="board">Board</Segmented.Item>
<Segmented.Item value="calendar">Calendar</Segmented.Item>
</Segmented>
// Billing Cycle — SaaS pricing style
<Segmented defaultValue="yearly">
<Segmented.Item value="monthly">Monthly</Segmented.Item>
<Segmented.Item value="yearly">Yearly</Segmented.Item>
</Segmented>States
Default
Selected item is highlighted.
Disabled
All items disabled.
Partial Disabled
Only specific items are disabled.
Many Items
Optimal for 2–5 items.
API
Component Structure
Segmented— Radix RadioGroup.ItemPropsSegment itemProps
Segmented
valueundefinedstringSelected value in controlled mode
defaultValueundefinedstringInitial selected value in uncontrolled mode
onValueChangeundefined(value: string) => voidCallback when selection changes
variant"default""default" | "outline" | "underline" | "ghost"Visual style variant (default: iOS-style, outline: bordered, underline: Stripe-style, ghost: Notion-style)
size"default""sm" | "md" | "default" | "lg"Segment size (32/36/40/48px)
radius"default""none" | "sm" | "base" | "default" | "lg" | "xl" | "2xl" | "3xl" | "full"Border radius size (6px)
fontWeight"normal""normal" | "semibold"Font weight applied to all items
disabledfalsebooleanDisables all items
| Name | Type | Default | Description |
|---|---|---|---|
value | string | undefined | Selected value in controlled mode |
defaultValue | string | undefined | Initial selected value in uncontrolled mode |
onValueChange | (value: string) => void | undefined | Callback when selection changes |
variant | "default" | "outline" | "underline" | "ghost" | "default" | Visual style variant (default: iOS-style, outline: bordered, underline: Stripe-style, ghost: Notion-style) |
size | "sm" | "md" | "default" | "lg" | "default" | Segment size (32/36/40/48px) |
radius | "none" | "sm" | "base" | "default" | "lg" | "xl" | "2xl" | "3xl" | "full" | "default" | Border radius size (6px) |
fontWeight | "normal" | "semibold" | "normal" | Font weight applied to all items |
disabled | boolean | false | Disables all items |
Segmented.Item
value—stringUnique value for the item
disabledfalsebooleanDisables this item individually
sizeinherit"sm" | "md" | "default" | "lg"Override size for this item
radiusinherit"none" | "sm" | ... | "full"Override radius for this item
contentType"text""text" | "icon-text" | "icon"Content type (icon: square, icon-text: with gap, text: standard)
| Name | Type | Default | Description |
|---|---|---|---|
value | string | — | Unique value for the item |
disabled | boolean | false | Disables this item individually |
size | "sm" | "md" | "default" | "lg" | inherit | Override size for this item |
radius | "none" | "sm" | ... | "full" | inherit | Override radius for this item |
contentType | "text" | "icon-text" | "icon" | "text" | Content type (icon: square, icon-text: with gap, text: standard) |
Customization
All items use default values based on the design system spacing rules. Customize all items at once using className on the group.
Change Horizontal Padding
className="[&>button]:px-10"Change Icon Only Width
className="[&>button]:aspect-auto [&>button]:px-5"Tip:Default values are designed to maintain component consistency. Use customization only when required for your UI.
Anatomy
Best Practices
Do
- ✓Use for 2–5 mutually exclusive options
- ✓Use for view switching within the same content area
- ✓Keep labels short and concise (1–2 words)
- ✓Best for filter and sort switching
Don't
- ✗Don't use for 6 or more options
- ✗Don't use for page navigation (→ Tabs)
- ✗Don't use when multiple selection is needed (→ ToggleGroup)
- ✗Don't use long label text
Accessibility
Keyboard Navigation
ARIA Attributes
role="radiogroup"auto-appliedrole="radio"applied to each itemaria-checkedauto-updated- Focus indicator
Segmented vs Tabs
Similar appearance, but different purpose and structure. Choose the appropriate component.
Purpose
Segmented: Value selection (filter, switch)
Tabs: Content navigation
Structure
Segmented: Standalone component
Tabs: TabList + TabPanel combination
Result
Segmented: Data change within same area
Tabs: Panel switching
Placement
Segmented: Anywhere within content
Tabs: Top of page/section
Radix Primitive
Segmented: RadioGroup
Tabs: @radix-ui/react-tabs
| Feature | Segmented | Tabs |
|---|---|---|
| Purpose | Value selection (filter, switch) | Content navigation |
| Structure | Standalone component | TabList + TabPanel combination |
| Result | Data change within same area | Panel switching |
| Placement | Anywhere within content | Top of page/section |
| Radix Primitive | RadioGroup | @radix-ui/react-tabs |
Use Segmented when changing the view within the same content area. Use Tabs when switching between different content panels.