Tessina UI
Tessina UI
GitHubIntroduction
InstallationUsageTheming
Components
ButtonIconButtonLinkSpinnerBadgeAvatarStatusChipShortcutSkeletonSurfaceProgressMeterRating
LabelFieldFieldsetCheckboxRadioSwitchSliderSelectComboboxSearchTextareaNumberFieldDate PickerTime PickerOTP InputFile UploadCalendar
AlertBannerToastTooltip
TabsAccordionCollapsibleBreadcrumbPaginationStepperSegmentedControlButtonGroupToggleButtonToggleGroupToolbarNavigation MenuMenubarBottom NavSidebar
Split ButtonFABDropdown MenuContextMenuCommandPopoverHoverCard
ContainerStackFlexGridAspectRatioSpacerCardCarouselDividerScroll Area
Table
ChatBubblePromptInputCodeBlock
ModalAlertDialogDrawerAction SheetTop Header MobileTop Header DesktopEmptyStateForm
Contributing
ComponentsNavigation Blocks

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>

Showcase

All variants, sizes, orientations, icon combinations, and states:

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

Stepper

Numeric quantity control with increment and decrement buttons. Two layout variants (pill and floating), five sizes, full intent palette, min/max/step, disabled/readOnly states, and LTR/RTL support.

ButtonGroup

A group of pill buttons inside a rounded pill container, supporting horizontal and vertical orientations with configurable gap

On this page

PlaygroundInstallationUsageShowcaseAPI ReferenceSegmentedControl PropsSegmentedControlItem PropsVariantsSizesControlled vs UncontrolledAccessibility