Segmented Control

Free

4 style variants (default, pills, underline, bordered) with badge and icon support, full-width mode and two-way binding.

</>sv-segmented-control segmentedtabstoggle
import { SvSegmentedControlComponent } from '@styloviz/forms';

Demo & usage

Basic usage

Usage example — open the gallery for the full interactive demo.

An interactive demo for this component lives in the gallery.

Open live demo

More examples

Pills, full-width

example.htmlAngular
<sv-segmented-control variant="pills" [fullWidth]="true" [options]="ranges" [(ngModel)]="range" />

Swatch — size / colour picker

variant="swatch" renders labelled size chips or colour dots; mark options soldOut to disable them with a strike overlay.

example.htmlAngular
<sv-segmented-control variant="swatch" ariaLabel="Select colour" [options]="colours" [(ngModel)]="colour" />

When to use

  • Switching between 2–5 mutually exclusive views or modes (list/grid, day/week/month).
  • You want all options visible inline, like iOS-style segmented tabs.
  • For many options or page-level navigation, use Tabs.

Async states

None — this component has nothing to load, so it has no loading, empty or error state to drive.

Inputs

NameTypeDefaultDescription
optionsrequiredreadonly SegmentOption[]—The selectable segments (value + label, optional icon/badge).
valuestring (two-way)''Active segment value (two-way).
sizeSegmentedSize'md'Control size: sm, md or lg.
variantSegmentedVariant'default'Visual style: default, pills, underline or bordered.
fullWidthbooleanfalseStretch segments to fill the container width.
disabledbooleanfalseDisable the whole control.
ariaLabelstring''Accessible name for the group.
semanticsSegmentedSemantics'radiogroup'Whether this control sets a value or switches visible content.
activationSegmentedActivation'automatic'For `tablist` only: whether arrowing to a tab selects it.
errorMessagestring''Client-side validation message.
serverErrorSvServerErrornullA rejection reported by the server about this value. Self-expiring.

Outputs

EventPayload typeDescription
changedstringEmitted with the newly selected segment value.
valueChangestringEmits the new `value` whenever it changes — the output half of `[(value)]`.

Customization & theming

  • Four visual styles (default, pills, underline, bordered) in four sizes (xs–lg); optional `fullWidth`.
  • Per-segment `icon`, `badge` and `disabled` via the `options` array; name the group with `ariaLabel`.
  • Two-way bind `[(value)]` or a reactive control (CVA); listen to `(changed)`.

Best practices

  • Do: Keep segment labels short and parallel so the control stays compact.
  • Do: Limit to ~5 segments; beyond that, switch to Tabs or a Select.
  • Don't: Don't mix unrelated actions in here — it represents one exclusive choice.

Accessibility

  • A real `role="radiogroup"` of `role="radio"` segments — a single tab stop with roving focus, Arrow keys (and Home/End) to move and select, Space/Enter to select.
  • The active segment exposes `aria-checked`; pass `ariaLabel` so the group has an accessible name.
  • When the control switches visible content rather than setting a value, set `semantics="tablist"`: `role="tablist"`/`"tab"`, `aria-selected`, `aria-controls` from each option's `controls`, a stable id from `tabId` for the panel's `aria-labelledby`, and no error slot. `activation="manual"` lets the arrows move without selecting (for expensive panels); it is ignored for a radiogroup. The `swatch` variant is always a radiogroup.
  • Implements ControlValueAccessor — works with `[(ngModel)]`, `[formControl]` and `formControlName`; `formControl.disable()` disables the control.

Feedback on Segmented Control

Spotted a gap in this page, or something that didn't work as described? Comments are GitHub Discussions in the public styloviz/community repo, so posting needs a GitHub account.

Loads giscus.app and GitHub — nothing is fetched until you click.