Skip to Content

AI Segmented Control

Loading...

Overview

Props

Root

The container for the segmented control. Renders as a horizontal group of toggle buttons. Built on Radix UI Toggle Group with type="single".

PropTypeDefaultRequiredDescription
type"single"YesMust be "single" for one selection at a time.
valuestringNoControlled selected value. Use with onValueChange.
defaultValuestringNoUncontrolled initial selected value.
onValueChange(value: string) => voidNoCalled when the selected value changes. For controlled usage, call your state setter here (e.g. if (value) setValue(value)).
disabledbooleanfalseNoDisables the entire group.
rovingFocusbooleantrueNoEnables roving tabindex for keyboard navigation.
orientation"horizontal" | "vertical"undefinedNoLayout direction. Omit for default horizontal.
dir"ltr" | "rtl"NoDirection for layout and keyboard navigation.
loopbooleantrueNoWhether focus wraps from last item to first (and vice versa).

Root also accepts all standard HTML div attributes (e.g. className, aria-*, data-*).

Item

A single option in the segmented control. Renders as a button that can be selected.

PropTypeDefaultRequiredDescription
valuestringYesUnique value for this item. Must match a value used for controlled/uncontrolled state on Root.
disabledbooleanNoDisables this item only.

Item also accepts all standard HTML button attributes (e.g. className, aria-label, children). Use children for the label and optional icon.

Resources

Loading...

Loading...

Loading...

Loading...

Variations

Default appearance

The default segmented control provides a clean, modern interface for selecting between options.

import * as AiSegmentedControl from from '@camp/ai-segmented-control'; function MyComponent() { return ( <AiSegmentedControl.Root type="single" defaultValue="total"> <AiSegmentedControl.Item value="total">Total Contacts</AiSegmentedControl.Item> <AiSegmentedControl.Item value="active">Active</AiSegmentedControl.Item> <AiSegmentedControl.Item value="unsubscribed">Unsubscribed</AiSegmentedControl.Item> </AiSegmentedControl.Root> ); }

With Icons

Segmented controls can include icons alongside text labels for enhanced visual clarity.

import * as AiSegmentedControl from '@camp/ai-segmented-control'; import { PencilEditMedium, AiPencilEditMedium } from '@camp/icon'; function MyComponent() { return ( <AiSegmentedControl.Root type="single" defaultValue="item1"> <AiSegmentedControl.Item value="item1"> <PencilEditMedium title="Pencil Edit" /> </AiSegmentedControl.Item> <AiSegmentedControl.Item value="item2"> <AiPencilEditMedium title="AI Pencil Edit" /> </AiSegmentedControl.Item> </AiSegmentedControl.Root> ); }

Disabled state

Individual segments can be disabled to indicate unavailable options.

import * as AiSegmentedControl from '@camp/ai-segmented-control'; function MyComponent() { return ( <div style={{ display: 'flex', flexDirection: 'column', gap: '20px' }}> <div> <div style={{ marginBottom: '8px', fontSize: '14px', color: '#666' }}> All items disabled: </div> <AiSegmentedControl.Root type="single" defaultValue="total" disabled> <AiSegmentedControl.Item value="total">Total Contacts</AiSegmentedControl.Item> <AiSegmentedControl.Item value="active">Active</AiSegmentedControl.Item> <AiSegmentedControl.Item value="unsubscribed">Unsubscribed</AiSegmentedControl.Item> </AiSegmentedControl.Root> </div> <div> <div style={{ marginBottom: '8px', fontSize: '14px', color: '#666' }}> Mixed disabled states: </div> <AiSegmentedControl.Root type="single" defaultValue="total"> <AiSegmentedControl.Item value="total">Total Contacts</AiSegmentedControl.Item> <AiSegmentedControl.Item value="active" disabled> Active </AiSegmentedControl.Item> <AiSegmentedControl.Item value="unsubscribed">Unsubscribed</AiSegmentedControl.Item> </AiSegmentedControl.Root> </div> </div> ); }

Usage

Best practices

  • Use segmented controls for switching between 2-5 mutually exclusive options within the same context
  • Keep segment labels concise and clear, typically 1-3 words
  • Use icons sparingly and only when they add meaningful context
  • Ensure the selected state is visually distinct and accessible
  • Consider using segmented controls for view switching, filtering, or mode selection
  • Avoid using segmented controls for navigation that takes users out of context

Content guidelines

Segment labels should be clear, concise, and written in sentence case with no punctuation at the end. Include articles like “a” and “the” for clarity, especially for translation purposes.

Accessibility

Keyboard support

  • Use Tab to move focus into the segmented control group
  • Use Left Arrow and Right Arrow keys to navigate between segments
  • Use Space or Enter to select the focused segment
  • The component automatically handles aria-checked and role="radio" attributes
  • Screen readers announce the control as a single group with current selection

ARIA attributes

The component automatically provides proper ARIA attributes:

  • role="radiogroup" on the Root component
  • role="radio" on each Item component
  • aria-checked state management
  • Proper labeling and announcements for screen readers

Similar components

Tabs

Tabs

Allows users to switch between different views or functional aspects of an application.

Radio Button

Radio Button

Allows the user to select one option from a set.

Dropdown

Dropdown

Allows users to select an option from a dropdown menu.

Last updated on