Summit
ComponentsSelection

Segmented Control

A Segmented Control allows users to choose one of a few options that are displayed side by side on a track.

When to Use

  • to change what one view shows, such as the period of a chart: “6 months” or “12 months”
  • for a setting that keeps one option selected
  • for options that fit in one row

When Not to Use

  • for views that each have their own content (use Tabs)
  • for options where none or several can be on (use a Toggle Group)
  • for a choice that is submitted with a form (use a Radio Group)
  • for more options than fit in a row (use a Select)
Segmented ControlToggle GroupTabs
PurposeOne setting of a viewOptions that are each on or offViews that each have a panel
Options OnOneNone, one, or several with multipleOne
Rolesgroup of buttons with aria-pressedgroup of buttons with aria-pressedtablist, tab, and tabpanel
Arrow KeysMove focusMove focusMove focus
Enter or SpaceSelects the optionTurns the item on or offShows the tab’s panel
MarkAn indicator that slidesA muted tint and a mark that the product addsAn indicator that slides, as a tile or a line
Sizessm, default, and lgsm, default, and lgOne, 32px tall
OrientationHorizontalHorizontal or verticalHorizontal or vertical

Anatomy

ElementUsage
OptionRequired
TrackRequired
IndicatorSelected option only

One indicator slides to the selected option.

Sizes

A Segmented Control has the sm, default, and lg sizes. It is as tall as a Button of the same size, so the two line up in a row. See Sizing for where to use each height.

Behavior

SegmentedControl is built on Base UI’s Toggle Group. It keeps one option selected and moves one indicator to it.

Selection

When users click the selected option, nothing happens because SegmentedControl cancels a change that would result in an empty value. The value is an array that contains one string, as in Base UI’s Toggle Group.

Set defaultValue or value. If neither is set, no option is selected, and the indicator doesn’t appear until users click an option.

Width

The track is as wide as its options, and it doesn’t wrap or scroll. An option doesn’t shrink, and its label doesn’t wrap, so a set that is wider than its container overflows the container’s edge.

Content

StringRuleExampleCounterexample
OptionOne or two words that name the choice, not an action“Month”“Show by month”
aria-labelName what the options set“Period”“Options”

Accessibility

A Segmented Control is a group of buttons with aria-pressed, not a radiogroup or a tablist, so the arrow keys move focus and don’t select. Users press Home or End to move focus to the first or the last option, and Enter or Space to select the focused option.

A Segmented Control needs a name because options like “Week”, “Month”, and “Year” don’t tell screen reader users what they set. To provide one, set aria-label, or point aria-labelledby at a visible label.

Installation

npx shadcn@latest add @summit/segmented-control

The CLI also adds @summit/toggle.

Usage

import { SegmentedControl, SegmentedControlItem } from '@/components/ui/segmented-control';

<SegmentedControl defaultValue={['month']} aria-label="Period">
    <SegmentedControlItem value="week">Week</SegmentedControlItem>
    <SegmentedControlItem value="month">Month</SegmentedControlItem>
    <SegmentedControlItem value="year">Year</SegmentedControlItem>
</SegmentedControl>;

API Reference

PropTypeDefaultDescription
size'default' | 'sm' | 'lg''default'The height of the track and the text size of the options

Other props are passed to Base UI’s Toggle Group, except multiple and orientation, which SegmentedControl doesn’t accept. See the Base UI Toggle Group documentation for value, defaultValue, onValueChange, and disabled. SegmentedControlItem adds no props to Base UI’s Toggle. See the Base UI Toggle documentation for value.

On this page