A row of 2–4 mutually exclusive choices drawn as one moving pill on a shared track — the iOS-style segmented control, and what most dashboards use to switch a view or a range without navigating anywhere. Reach for it wherever a single setting has a handful of choices that all fit on screen at once: List/Grid/Board on a file browser or project view, Day/Week/Month or 24h/7d/30d above a chart, Light/Dark/System in settings, °C/°F and km/mi on a unit preference, Monthly/Yearly on a pricing page, Newest/Oldest/Top on a feed, All/Active/Archived or Open/Closed on a list, Preview/Code on a docs example, Table/JSON/Raw on a response viewer, Chart/Table on a report, Personal/Team on a switcher, and the segmented filter at the top of a mobile screen. Common asks it answers: "segmented control", "segmented control react", "shadcn segmented control", "segmented button", "iOS segmented control react", "pill toggle", "pill switcher", "toggle switcher", "view switcher component", "list grid toggle react", "time range switcher", "date range toggle 7d 30d", "chart period selector react", "sort toggle component", "unit toggle celsius fahrenheit", "monthly yearly pricing toggle", "tabs without panels", "tabs but no content panels", "single choice button group react", "radio buttons as a button group", "radio group styled as buttons", "Ant Design Segmented equivalent", "MUI ToggleButtonGroup exclusive", "SwiftUI Picker segmented web", "shadcn tabs alternative no radix", "toggle group single selection", "sliding pill indicator react", "animated active indicator tabs", "accessible segmented control", "role radiogroup react", "aria-checked button group", "arrow keys select radio group", "roving tabindex radio", "keyboard accessible view switcher", "disabled option in a toggle group", "セグメンテッドコントロール", "切り替えボタン 3つ", "表示切り替え リスト グリッド", "期間切り替え 7日 30日", "タブだけどパネルは要らない", "ラジオボタンをボタン風に", "単一選択のボタン群", "矢印キーで選択 アクセシビリティ" — the control usually faked with a row of buttons and a useState. How it differs from the neighbours official shadcn/ui ships, measured across its whole registry today (63 items in the catalogue, 62 fetchable — questionnaire is indexed and 404s on both style tracks — and 223,287 bytes of files[].content concatenated): tabs (3,772 bytes) and toggle-group (2,309 bytes) both list radix-ui as a dependency, and button-group (2,203 bytes) depends only on cn but is a layout wrapper with no selection of its own. More to the point, the ARIA radio pattern is not in official's source to copy at all: radiogroup, role="radio", aria-checked and roving are every one of them a zero hit across all 223KB, because Radix owns that markup inside radio-group (1,450 bytes) rather than the wrapper shipping it. The word segmented does not appear once either. This is one file with no dependencies, and it is a real radio group — role=radiogroup on the track, role=radio and aria-checked on every segment — so assistive technology announces one setting with a selected option among several rather than a row of unrelated buttons. Tabs additionally owns panels and the tab/tabpanel relationship, which is the wrong contract when the choice only filters or reframes data already on the page, and a switch only covers two states. The keyboard follows the radio pattern rather than the button one: arrow keys (left/right and up/down) move and select in a single press and wrap around the ends, Home/End jump to the first and last usable segment, disabled segments are stepped over instead of trapping focus, and a roving tabindex keeps the whole group one tab stop with the selected segment as the entry point. Also: per-segment disabling as well as a whole-group disabled state, controlled or uncontrolled through a string value with onValueChange, a focus-visible ring, and shadcn tokens throughout so it follows the theme in light and dark.
pnpm dlx shadcn@latest add "https://pulld.pages.dev/r/segmented-control.json"