Segmented

A pill-shaped control for exclusive single-selection — ideal for filters and view switching.

4
Variants
4
Sizes
Single
Mode
Radix
Base

Playground

Preview
defaultD
Variant
Size
Radius
Weight
Content
State
<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 Style
Muted container with selected item elevated by white background and shadow — iOS/Apple style
outlineBordered Style
Bordered container with selected item on a grey background — clean border style
underlineTab Style
Selection shown by underline only — minimal tab style, similar to Stripe/GitHub
ghostMinimal Style
Transparent container with selected item showing a background — Notion/Figma style

Sizes

Text Only

sm
Height32px
H. Padding14px
Font12px
md
Height36px
H. Padding14px
Font13px
default
Height40px
H. Padding16px
Font13px
lg
Height48px
H. Padding24px
Font14px

Icon Only (Square)

sm
Container Height32px
Item24px × 24px
Icon14px
md
Container Height36px
Item28px × 28px
Icon16px
default
Container Height40px
Item32px × 32px
Icon16px
lg
Container Height48px
Item40px × 40px
Icon16px

Icon + Text

sm
Height32px
H. Padding12px
Gap8px
Icon14px
Font12px
md
Height36px
H. Padding14px
Gap8px
Icon16px
Font13px
default
Height40px
H. Padding16px
Gap8px
Icon16px
Font13px
lg
Height48px
H. Padding24px
Gap8px
Icon16px
Font14px

Features

Use Cases

Status Filter

Notion, Linear, task management apps

Date Range Filter

Stripe, Google Analytics, dashboards

View Switch

Figma, Notion, project management tools

Billing Cycle

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
.ItemProps

Props

Segmented

valueundefined
string

Selected value in controlled mode

defaultValueundefined
string

Initial selected value in uncontrolled mode

onValueChangeundefined
(value: string) => void

Callback 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

disabledfalse
boolean

Disables all items

Segmented.Item

value
string

Unique value for the item

disabledfalse
boolean

Disables 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)

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

1
2
Week
3
Month
Year
1
Root
Pill-shaped track (container)
2
Item
Individual segment (unselected)
3
Active Indicator
Sliding selection background

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

TabMove focus to group
Navigate and select between items
HomeMove to first item
EndMove to last item

ARIA Attributes

  • role="radiogroup" auto-applied
  • role="radio" applied to each item
  • aria-checked auto-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

Use Segmented when changing the view within the same content area. Use Tabs when switching between different content panels.