Tessina UI
ConfiguratorGitHubIntroduction
InstallationUsageTheming
ComponentsAccordionAction SheetAlertAlertDialogArea ChartAspectRatioAvatarBadgeBannerBar ChartBottom NavBreadcrumbButtonButtonGroupCalendarCardCarouselChartChatBubbleCheckboxChipCodeBlockCollapsibleColor PickerComboboxCommandContainerContextMenuDate PickerDividerDrawerDropdown MenuEmptyStateFABFieldFieldsetFile UploadFile Upload 2FlexFormGridHoverCardIconButtonLabelLine ChartLinkMenubarMeterModalNavigation MenuNumberFieldOTP InputPaginationPie ChartPopoverProgressPromptInputRadar ChartRadial ChartRadioRatingScroll AreaSearchSegmentedControlSelectShortcutSidebarSkeletonSliderSpacerSpinnerSplit ButtonStackStatusStepperSurfaceSwitchTableTabsTextareaTime PickerToastToggleButtonToggleGroupToolbarTooltipTop Header DesktopTop Header Mobile
Contributing
Components

SegmentedControl

A radio-group style control where one segment is selected at a time, with outline, filled, and pill variants, horizontal and vertical orientations, and full keyboard navigation

Playground

Installation

pnpm add @tessinaui/ui

Usage

import { SegmentedControl, SegmentedControlItem } from "@tessinaui/ui";
<SegmentedControl defaultValue="week">
  <SegmentedControlItem value="day"   label="Day" />
  <SegmentedControlItem value="week"  label="Week" />
  <SegmentedControlItem value="month" label="Month" />
</SegmentedControl>

Examples

Default

The simplest usage — three labeled segments with an initial selection.

Variants

Three visual styles — outline, filled, and pill.

Sizes

Four sizes — xs, sm, md, and lg.

With Icons

Segments can pair a leadingIcon with their label.

Vertical

Stack segments by setting orientation="vertical".

Disabled

Disable a single item with disabled on the item, or the whole group with disabled on the control.

API Reference

SegmentedControl Props

PropTypeDefaultDescription
valuestring—Controlled selected value
defaultValuestring—Initial selected value for uncontrolled usage
onValueChange(value: string) => void—Callback fired when selection changes
variant"outline" | "filled" | "pill""outline"Visual style
size"xs" | "sm" | "md" | "lg""md"Size applied to all items
orientation"horizontal" | "vertical""horizontal"Layout direction
disabledbooleanfalseDisables all items in the group
dir"ltr" | "rtl""ltr"Text direction — RTL reverses layout

SegmentedControlItem Props

PropTypeDefaultDescription
valuestringrequiredUnique value identifying this item
labelstring—Visible label text
leadingIconReact.ReactNode—Icon rendered before the label
disabledbooleanfalseDisables this item individually
aria-labelstring—Accessible label (required when no visible label is provided)

Variants

VariantUnselectedSelected
outlineBorder + transparent backgroundWhite background, no border, subtle shadow
filledTransparent, muted textPrimary brand fill + on-primary text
pillTransparent, default textPrimary brand fill + on-primary text

Sizes

SizeWrapper heightUse case
xs40pxCompact toolbars
sm48pxSecondary controls
md52pxDefault, most use cases
lg52pxProminent controls with larger text

Controlled vs Uncontrolled

Controlled — manage selection state externally:

const [view, setView] = useState("week");

<SegmentedControl value={view} onValueChange={setView}>
  <SegmentedControlItem value="day"   label="Day" />
  <SegmentedControlItem value="week"  label="Week" />
  <SegmentedControlItem value="month" label="Month" />
</SegmentedControl>

Uncontrolled — let the component manage its own state:

<SegmentedControl defaultValue="week">
  <SegmentedControlItem value="day"   label="Day" />
  <SegmentedControlItem value="week"  label="Week" />
  <SegmentedControlItem value="month" label="Month" />
</SegmentedControl>

Accessibility

The SegmentedControl component:

  • Renders with role="radiogroup" on the wrapper for semantic grouping
  • Each item renders with role="radio" and aria-checked reflecting selection state
  • Keyboard navigation: Arrow keys move between items (Left/Right for horizontal, Up/Down for vertical); Home/End jump to first/last
  • Roving tabIndex: only the selected item (or first enabled item if none selected) is in the tab order
  • Disabled items are skipped during keyboard navigation
  • Touch targets ≥ 44×44px on all sizes
  • aria-label required on icon-only SegmentedControlItem elements
  • RTL fully supported via the dir prop

Search

A search input with built-in search icon, clear button, optional submit button, loading state, and full RTL support. Follows the Field component's design language with three visual variants.

Select

Keyboard-accessible dropdown select with intent variants, sizes, grouped options, leading icons, item descriptions, and label position options.

On this page

PlaygroundInstallationUsageExamplesDefaultVariantsSizesWith IconsVerticalDisabledAPI ReferenceSegmentedControl PropsSegmentedControlItem PropsVariantsSizesControlled vs UncontrolledAccessibility