SegmentedControl
Pre-alphaThe registry and the CLI are not published yet.Roadmap

SegmentedControl

iOS-style segmented selector with a sliding indicator.

Activity
DayWeekMonthYear
AVERAGE

7,842 steps

Installation

npx axiom add segmented-control
pnpm dlx axiom add segmented-control
yarn dlx axiom add segmented-control
bun x axiom add segmented-control

Installs: react-native-reanimated, react-native-worklets, react-native-gesture-handler.

Selection, measurement and the draggable indicator live in use-segmented-control.ts, shared by every styling variant. Colors come from segmentedControl.default.{default,selected,disabled}.{track,indicator,border,foreground} in the component tokens.

Usage

import { SegmentedControl } from "@/components/ui/segmented-control";

<SegmentedControl
	options={["List", "Grid"]}
	value={layout}
	onValueChange={setLayout}
/>;

Props

PropTypeDefaultDescription
optionsArray<string | SegmentOption>The segments. A string is used as both value and label. SegmentOption is { value, label?, icon?, accessibilityLabel?, disabled? }.
valuestringValue of the selected segment.
defaultValuestringfirst optionInitial selection when the control manages its own state.
onValueChange(value: string) => voidCalled when the user picks another segment.
size'md' | 'lg''md'Minimum height: 32 or 40pt. Grows with larger system text.
fullWidthbooleantrueStretches to the parent width with equal segments. false sizes it to its content.
disabledbooleanfalseDisables the whole control.
styleStyleProp<ViewStyle>Extra styles for the track.

The indicator slides on the UI thread with Reanimated and can be dragged from one segment to another. Keep it to 2–5 short options: past that, labels get truncated.

Use cases

Switching the view of the same data

The segments change how the content is shown, not what it is. Icons are enough when they are standard.

Photos

<SegmentedControl
	fullWidth={false}
	options={[
		{ value: "list", icon: "menu", accessibilityLabel: "List" },
		{ value: "grid", icon: "grid", accessibilityLabel: "Grid" },
	]}
	value={layout}
	onValueChange={setLayout}
/>

Filtering a list in place

A short list of states above the content. Changing segment filters the list below without navigating.

Orders

AllActiveDelivered
#10482 · 3 itemsArriving tomorrow

Shipped

#10477 · 1 itemPreparing

Paid

<SegmentedControl options={['All', 'Active', 'Delivered']} value={status} onValueChange={setStatus} />
<FlatList data={orders.filter(byStatus(status))} renderItem={renderOrder} />

Setting with few options

A compact alternative to radios for 2–3 values that the user compares at a glance.

Appearance

Light

Dark

Auto
Auto follows the system setting.
<SegmentedControl
	size="lg"
	options={[
		{ value: "light", label: "Light", icon: "sun" },
		{ value: "dark", label: "Dark", icon: "moon" },
		{ value: "system", label: "Auto" },
	]}
	value={scheme}
	onValueChange={setScheme}
/>