SegmentedControl
Mutually-exclusive choice rendered as a horizontal group of buttons. Use for view-mode toggles, density selectors, time-range pickers — anywhere a small fixed set of options needs to surface inline. For binary on/off, use a Toggle. For longer / searchable lists, use Combobox or Listbox.
Basic
html
<SegmentedControl v-model="value" :options="options" />ts
const options = [
{ label: 'List', value: 'list' },
{ label: 'Grid', value: 'grid' },
{ label: 'Map', value: 'map' },
]Sizes
html
<SegmentedControl v-model="value" :options="options" size="sm" />
<SegmentedControl v-model="value" :options="options" size="md" />Variants
The variant changes the active-segment color treatment.
html
<SegmentedControl v-model="value" :options="options" variant="primary" />
<SegmentedControl v-model="value" :options="options" variant="secondary" />
<SegmentedControl v-model="value" :options="options" variant="tertiary" />Disabled options
Mark individual options as disabled to render them inert. The user can still see them — they just can't be selected.
html
<SegmentedControl v-model="range" :options="rangeOptions" />ts
const rangeOptions = [
{ label: 'Day', value: 'day' },
{ label: 'Week', value: 'week' },
{ label: 'Month', value: 'month' },
{ label: 'Custom', value: 'custom', disabled: true },
]Custom option content
Use the option slot to render anything inside each segment — icons + labels, badges, etc. The slot receives the full option object.
html
<SegmentedControl v-model="value" :options="options">
<template #option="{ option }">
<span class="inline-flex items-center gap-1.5">
<Icon :name="option.icon" :size="16" />
{{ option.label }}
</span>
</template>
</SegmentedControl>Props
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | string | number | required | Selected value. Use v-model. |
options | { label: string; value: string | number; disabled?: boolean }[] | required | Segment options. |
size | 'sm' | 'md' | 'md' | Segment height + typography. |
variant | 'primary' | 'secondary' | 'tertiary' | 'primary' | Active-segment color treatment. |
Slots
| Slot | Slot props | Description |
|---|---|---|
option | { option } | Override the default label rendering for every segment. |
Events
| Event | Description |
|---|---|
update:modelValue | Emitted when the user selects a different option. |
Accessibility
The wrapper has role="group" with aria-label="Segmented control". Each segment is a real <button> with aria-pressed reflecting the selected state, and disabled honored.