Brik Design System
Components

Segmented control

Pill-shaped toggle for switching between mutually exclusive views or modes.

SegmentedControl is a horizontal pill switcher for mutually exclusive views in the same panel — Grid / List, Monthly / Yearly, This Week / This Month. Unlike TabBar (which navigates between page sections), SegmentedControl swaps content in-place.

SegmentedControl

Use when: Toggle between 2-5 views in the same panel. Inline, compact, mutually exclusive.

Don't: Page-level navigation — that's TabBar.

<SegmentedControl items={...} />

Switch

Use when: Binary on/off setting. Settings panels, feature flags.

Don't: 3+ options — use SegmentedControl.

<Switch label="..." />

Select

Use when: One-of-many from a longer list (6+ options).

Don't: ≤5 options that fit horizontally — use SegmentedControl.

<Select options={...} />

Use it for

  • View switchers (Grid / List / Calendar)
  • Pricing toggles (Monthly / Yearly)
  • Date range selectors (Today / This Week / This Month)
  • Mode pickers in tool panels (Edit / Preview)

Import

import { SegmentedControl } from '@brikdesigns/bds';

Variants

Default

import { useState } from 'react';
const [view, setView] = useState('grid');

<SegmentedControl
  value={view}
  onChange={setView}
  items={[
    { label: 'Grid', value: 'grid' },
    { label: 'List', value: 'list' },
  ]}
/>

Sizes

  • sm — compact toolbars, dense UI
  • md — default for forms and panels
  • lg — prominent page-level toggles

Full-width

<SegmentedControl
  value={period}
  onChange={setPeriod}
  size="lg"
  fullWidth
  items={[
    { label: 'Monthly', value: 'monthly' },
    { label: 'Yearly', value: 'yearly' },
  ]}
/>

Many segments

SegmentedControl tolerates up to ~5 segments before the labels feel cramped. Beyond that, switch to Select.

<SegmentedControl
  value={range}
  onChange={setRange}
  items={[
    { label: 'Today', value: 'today' },
    { label: 'Week', value: 'week' },
    { label: 'Month', value: 'month' },
    { label: 'Quarter', value: 'quarter' },
    { label: 'Year', value: 'year' },
  ]}
/>

When not to use

Don't use SegmentedControl for page-level navigation. TabBar carries the right semantic for "navigate to a different section"; SegmentedControl is for "swap content in place." The visual treatments are similar; the navigation model is not.

  • Don't use SegmentedControl for >5 options. Long pills wrap or truncate. Use Select.
  • Don't use SegmentedControl for binary on/off. Use Switch — the affordance is correct.
  • Don't pair with conflicting selection state. SegmentedControl is single-select; for multi-select toggles use a Checkbox group or MultiSelect.

Accessibility

  • Renders a <div role="tablist"> with each segment as <button role="tab">.
  • The selected segment carries aria-selected="true"; unselected carry false.
  • Keyboard arrows move selection between segments.
  • Items can carry their own aria-label for icon-only segments.

API

PropTypeDefault
itemsSegmentItem[] (required)
valuestring
onChange(value: string) => void
size'sm' | 'md' | 'lg''md'
fullWidthbooleanfalse
disabledbooleanfalse

SegmentItem

interface SegmentItem {
  label: ReactNode;
  value: string;
  disabled?: boolean;
}

On this page