Segmented Control
Segmented control allows users to select one option from a set of related choices. It features a sliding indicator animation and supports icons.
Segmented Control Playground
Segmented Control Playground
Preview
Code
List
Grid
Table
Compact
Controls
Type:
Primary
Neutral
Size:
Small
Medium
Large
Style:
Icon + Text
Icon Only
Text Only
Width:
Equal
Content
Dividers:
Off
On
Installation
You can add the segmented control component to your project manually:
1
Install the following dependencies:
npm
pnpm
yarn
bun
npm install @react-aria/focus2
Copy and paste the following code into your project.
SegmentedControl.tsx
Segment.tsx
Loading source code...
3
Update the import paths to match your project setup.
Update the import aliases (e.g. @/components, @/utils) in the copied files to match your project's path configuration.
Basic Usage
import { SegmentedControl } from '@versaui/ui/components/SegmentedControl';
import { List, GridFour, SquaresFour } from '@phosphor-icons/react';
const [view, setView] = useState('list');
// Basic segmented control
<SegmentedControl
items={[
{ id: 'day', label: 'Day' },
{ id: 'week', label: 'Week' },
{ id: 'month', label: 'Month' },
]}
selectedId={view}
onChange={setView}
/>
// With icons
<SegmentedControl
items={[
{ id: 'list', label: 'List', icon: <List /> },
{ id: 'grid', label: 'Grid', icon: <GridFour /> },
{ id: 'board', label: 'Board', icon: <SquaresFour /> },
]}
selectedId={view}
onChange={setView}
/>
// Icon only mode
<SegmentedControl
iconOnly
items={[
{ id: 'list', icon: <List /> },
{ id: 'grid', icon: <GridFour /> },
{ id: 'board', icon: <SquaresFour /> },
]}
selectedId={view}
onChange={setView}
/>
// With dividers
<SegmentedControl
showDividers
items={[
{ id: 'all', label: 'All' },
{ id: 'active', label: 'Active' },
{ id: 'archived', label: 'Archived' },
]}
selectedId={status}
onChange={setStatus}
/>
// Content width mode
<SegmentedControl
widthMode="content"
items={[
{ id: 'all', label: 'All' },
{ id: 'active', label: 'Active' },
{ id: 'archived', label: 'Archived' },
]}
selectedId={status}
onChange={setStatus}
/>
// Neutral type
<SegmentedControl
type="neutral"
items={[
{ id: 'all', label: 'All' },
{ id: 'active', label: 'Active' },
{ id: 'archived', label: 'Archived' },
]}
selectedId={status}
onChange={setStatus}
/>SegmentItem Interface
interface SegmentItem {
id: string; // Unique identifier
label?: string; // Button text
icon?: ReactNode; // Optional icon
}Accessibility
- Each segment uses
role="button"witharia-pressedto indicate selection - Keyboard activation with
EnterandSpacekeys aria-disabledindicates disabled state- Focus ring visible on keyboard navigation
SegmentedControl Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | SegmentItem[] | — | Array of segment items. |
selectedId | string | — | Currently selected segment ID. |
onChange | (id: string) => void | — | Selection change handler. |
type | 'primary' | 'neutral' | 'primary' | Color theme variant. |
size | 'small' | 'medium' | 'large' | 'medium' | Button size. |
iconOnly | boolean | false | Show only icons (no labels). |
showDividers | boolean | false | Show vertical dividers between segments. |
widthMode | 'equal' | 'content' | 'equal' | Equal distributes segments evenly across available width. Content sizes segments to fit their content. |