Segmented control

Switch between a small set of related views.

import { SegmentedControl } from "@sagui/ui";
Markdown
Loading demo

When to use

  • Two to five short view options like Day, Week, and Month.
  • Toolbar toggles between layouts or modes that apply immediately.

When not to use

  • Use tabs when each option swaps a panel of content.
  • Use radio-group in forms or when options need descriptions.
  • Use switch for a single on and off setting.

Installation

Install the package and import the styles once. The installation guide covers the Tailwind setup.

$ npm install @sagui/ui

Usage

example.tsx
import SegmentedControl from "@sagui/ui";

export function RangeToggle() {
  const [range, setRange] = useState("week");
  return (
    <SegmentedControl
      label="Range"
      value={range}
      onValueChange={setRange}
      options={[
        { value: "day", label: "Day" },
        { value: "week", label: "Week" },
        { value: "month", label: "Month" },
      ]}
    />
  );
}

Examples

With accessories

An accessory, such as a count, renders after the label.

Loading demo

When options do not fit

The track scrolls inside its frame, fades only the edge with more to see, and keeps the selected option in view.

Loading demo

API reference

SegmentedControl

A row of toggle buttons with one selection pill that slides between them.

Prop Type Default Description
options (required) { value: string; label: string; accessory?: ReactNode }[] – Segments in order. An accessory, such as a badge, renders after the label.
value string – Selected value. Controlled.
defaultValue string First option Initial value when uncontrolled.
onValueChange (value: string) => void – Called with the chosen segment's value, from a click or the arrow, Home and End keys.
label string – aria-label for the group.
onOptionIntent (value: string) => void – Called when the pointer or focus reaches a segment before it is chosen, to start loading what it shows.
className string – Extra class on the root.

Keyboard interactions

Keys Action
Tab Moves focus into the control, onto the selected segment, and out again.
Arrow keys Select and focus the previous or next segment, wrapping at the ends.
HomeorEnd Select the first or last segment.

Accessibility

  • Renders role="group" labelled by label, with native buttons using aria-pressed for the selected segment. Only the selected segment is a tab stop.
  • The sliding pill is aria-hidden.

Motion

  • A shared layoutId pill slides to the selected segment on the morph spring, scoped per instance by a LayoutGroup.
  • Reduced motion moves the pill instantly and disables button transitions.

Responsive behavior

  • The row is inline with max-width 100% and scrolls horizontally with a hidden scrollbar when segments do not fit.
  • Segments never shrink or wrap, so keep labels short on mobile.

Performance

  • One shared layoutId pill per instance, scoped by a LayoutGroup; no observers.

Notes

  • Use for two to five short, mutually exclusive view options like time ranges or layouts. Use tabs when each option swaps a panel, and radio-group in forms.
  • Always controlled. Import it as a default export.

Also in selection controls