Back to catalog
Component detail entry
Forms
@vean/ui
SSegment

Segment

Segment belongs to the Forms category. Start with demos and usage, then use the API tables to finish integration and styling decisions.

Use the quick jump panel to reach overview, usage, demos, and API first, then continue through the full page.

Quick jump

Related components

If you are composing interactions in the same family, these components usually pair well together.

Segment

Overview

A linear set of two or more mutually exclusive options presented as a unified control, with a sliding indicator that follows the active option. Use it for compact segmented pickers — time ranges, view toggles, or any small set of single-choice options — where the selection should change immediately. For a set of independent two-state buttons (single or multiple), use SToggleGroup; for plain tabbed content panels, use STabs.

Usage

Features

  • 🎯 Mutually exclusive single selection — one active segment at a time, backed by useControllableState
  • 🎚 Controlled / uncontrolled — v-model and defaultValue (with type-safe generic values via T extends SegmentOptionData)
  • 🧩 Data-driven composition — pass items and let Aria SegmentCompact own iteration and indicator layout
  • ✨ Optional sliding indicator — enableIndicator (default true), fully customizable through the indicator slot
  • ⌨️ Roving focus keyboard navigation — arrow keys move between segments, loop wraps around, and arrow direction reverses in RTL
  • 🎨 6 sizes × 2 orientations × 2 shapes (square/rounded) × 2 fills (auto/full) via segmentVariants
  • 🧩 ui per-slot class overrides (root / list / trigger / indicator / indicatorContent), plus item-level disabled
  • ♿ role="tab" + aria-selected with data-state reflection, axe-clean

Component family

  • SSegment — the styled wrapper that forwards props to the Aria compact and injects segmentVariants classes
  • SegmentRoot / SegmentList / SegmentTrigger / SegmentIndicator (Aria) — domain primitives wrapping Tabs; DOM uses data-vean-segment-*
  • SegmentCompact (Aria) — data-driven composition of those primitives; import from @vean/aria/segment for unstyled usage

Demos

Basic

Icon

API

Aria Layer

6

Segment<T>

17 Props1 Emits2 Slots
Props
PropTypeDefaultDescription
class
ClassValue
—
Additional class names applied to the root element.
ui
Partial<SegmentUi>
—
Per-slot class overrides for the component.
size
ThemeSize
—
Visual size of the component.
shape
SegmentShape
—
Shape of the component.
fill
SegmentFill
—
Fill.
items
T[]
—
Items rendered by the component.
enableIndicator
boolean
—
Whether to enable indicator.
listProps
SegmentListProps
—
Properties forwarded to the list element.
triggerProps
SegmentTriggerProps
—
Properties forwarded to the trigger element.
indicatorProps
SegmentIndicatorProps
—
Properties forwarded to the indicator element.
modelValue
T['value'] | null
—
The controlled value of the tab to activate. Can be bind as `v-model`.
defaultValue
T['value'] | null
—
The value of the tab that should be active when initially rendered. Use when you do not need to control the state of the tabs
activationMode
TabsActivationMode
automatic
Whether a tab is activated automatically (on focus) or manually (on click).
unmountOnHide
boolean
`true`
When `true`, the element will be unmounted on closed state.
dir
Direction
—
The direction of navigation between items.
loop
boolean
false
Whether keyboard navigation should loop around
orientation
DataOrientation
—
The orientation of the group. Mainly so arrow navigation is done accordingly (left & right vs. up & down)
Emits
Emit NameParametersDescription
update:modelValue
Exclude<T, undefined>
Event handler called when the value changes
Slots
Slot NameParametersDescription
item
T & { selected: boolean; }
Custom content for the item slot.
indicator
—
Custom content for the indicator slot.

SegmentCompact<T>

12 Props1 Emits2 Slots
Props
PropTypeDefaultDescription
items
T[]
—
Items rendered by the component.
enableIndicator
boolean
—
Whether to enable indicator.
listProps
SegmentListProps
—
Properties forwarded to the list element.
triggerProps
SegmentTriggerProps
—
Properties forwarded to the trigger element.
indicatorProps
SegmentIndicatorProps
—
Properties forwarded to the indicator element.
modelValue
T['value'] | null
—
The controlled value of the tab to activate. Can be bind as `v-model`.
defaultValue
T['value'] | null
—
The value of the tab that should be active when initially rendered. Use when you do not need to control the state of the tabs
activationMode
TabsActivationMode
automatic
Whether a tab is activated automatically (on focus) or manually (on click).
unmountOnHide
boolean
`true`
When `true`, the element will be unmounted on closed state.
dir
Direction
—
The direction of navigation between items.
loop
boolean
false
Whether keyboard navigation should loop around
orientation
DataOrientation
—
The orientation of the group. Mainly so arrow navigation is done accordingly (left & right vs. up & down)
Emits
Emit NameParametersDescription
update:modelValue
Exclude<T, undefined>
Event handler called when the value changes
Slots
Slot NameParametersDescription
item
T & { selected: boolean; }
Custom content for the item slot.
indicator
—
Custom content for the indicator slot.

SegmentIndicator

2 Props
Props
PropTypeDefaultDescription
asChild
boolean
—
Change the default rendered element for the one passed as a child, merging their props and behavior.
as
AsTag | Component
'div'
The element or component this component should render as. Can be overwrite by `asChild`

SegmentList

SegmentRoot<T>

7 Props1 Emits
Props
PropTypeDefaultDescription
modelValue
T
—
The controlled value of the tab to activate. Can be bind as `v-model`.
defaultValue
T
—
The value of the tab that should be active when initially rendered. Use when you do not need to control the state of the tabs
activationMode
TabsActivationMode
automatic
Whether a tab is activated automatically (on focus) or manually (on click).
unmountOnHide
boolean
`true`
When `true`, the element will be unmounted on closed state.
dir
Direction
—
The direction of navigation between items.
loop
boolean
false
Whether keyboard navigation should loop around
orientation
DataOrientation
—
The orientation of the group. Mainly so arrow navigation is done accordingly (left & right vs. up & down)
Emits
Emit NameParametersDescription
update:modelValue
Exclude<T, undefined>
Event handler called when the value changes

SegmentTrigger

4 Props
Props
PropTypeDefaultDescription
value
DefinedValue
—
A unique value that associates the trigger with a content.
disabled
boolean
—
When `true`, prevents the user from interacting with the tab.
asChild
boolean
—
Change the default rendered element for the one passed as a child, merging their props and behavior.
as
AsTag | Component
'div'
The element or component this component should render as. Can be overwrite by `asChild`

Notes

Architecture and benchmark differences

SegmentCompact composes the Aria SegmentRoot/SegmentList/SegmentTrigger/SegmentIndicator primitives (each wrapping the matching Tabs part): it iterates items, forwards listProps/triggerProps/indicatorProps, and exposes item/indicator slots. SegmentTrigger keeps the Tabs ARIA pattern (role="tab" + roving focus), so loop and dir (RTL) behave identically to tabs. SSegment is a thin wrapper that only computes segmentVariants (an alias of tabsVariants) and calls provideSegmentUi. The indicator is measured asynchronously (resize observer + post-flush watch), so it appears one frame after mount. segment maps to the segmented-control pattern; the benchmark libraries express it natively except shadcn, which typically uses Tabs.

CapabilityVeanUIAnt DesignElement PlusMantineNaive UIshadcn
Aria/styled split✅—————
Single (mutually exclusive)✅✅✅✅✅—
Controlled / uncontrolled✅✅✅✅✅—
Data-driven items✅✅✅✅✅—
Sliding indicator✅✅✅✅✅—
Roving focus arrow keys✅✅✅✅——
Loop navigation✅—————
RTL-aware arrow direction✅—————
Orientation (vertical)✅——✅——
Sizes × shapes × fills✅——✅——
Item-level disabled✅✅✅✅✅—
Custom item / indicator slots✅✅✅✅✅—

Cautions

  • loop and unmountOnHide default to true; enableIndicator defaults to true. Set :enable-indicator="false" to hide the sliding indicator (active state is then reflected through data-state).
  • The indicator is positioned after an asynchronous layout measurement — it renders one frame after the active segment changes.
  • Segments use the Tabs ARIA pattern (role="tab" + aria-selected), so avoid nesting segments inside another tabs-like control.
  • defaultValue is only read on mount; subsequent changes are ignored (use v-model for external control).
  • For icon-only items, add aria-label so the segment has an accessible name.
  • unmountOnHide only matters when content panels are attached; a bare SSegment renders no content area.

FAQ

What is the difference between SSegment and SToggleGroup?

SSegment is a single mutually exclusive segmented control with a sliding indicator — exactly one option is active. SToggleGroup coordinates a set of independent toggle buttons that can be single or multiple selection, with no indicator.

How do I disable the sliding indicator?

Pass :enable-indicator="false". The selected segment is then highlighted through the data-selected style rules instead.

How do I make arrow keys wrap around?

Keep loop (default true) — focus wraps from the last segment to the first and vice versa. Disabled segments are skipped automatically.

How do I control the selected value externally?

Bind v-model for two-way control, or pass only defaultValue for uncontrolled usage. Use items to declare options; each item supports value, label, and disabled.

Can I style the indicator and items?

Yes — the indicator slot replaces the default indicator content, the item slot receives { ...item, active } for full customization, and ui.root / ui.list / ui.trigger / ui.indicator override classes per slot.

Changelog

Version history is grouped by release so you can quickly see what changed for this component across published versions.

v0.31.0

2026-08-31

Compare release

Refactor

wrap Tabs primitives and provide Segment UI

Scope: segmentAuthors: soybeanfe, cursoragentView commit2da74

v0.0.2

2025-11-18

Compare release

Feature

add SSegment component for selecting days with customizable options and integrate into home view

Scope: segmentAuthors: soybeanjsView commit31a08

Feature

add new segment examples for orientation, shape, and icon; refactor index.vue to include new demo components

Scope: segmentAuthors: soybeanjsView commiteff24

Feature

add SSegment component for selecting days with customizable options and integrate into home view

Scope: segmentAuthors: soybeanjsView commit31a08

Feature

add new segment examples for orientation, shape, and icon; refactor index.vue to include new demo components

Scope: segmentAuthors: soybeanjsView commiteff24