shadcn.io is not affiliated with official shadcn/ui
Segmented Control Navbar Block for React Aria
A navbar for a meal-planning app that centres its three destinations in a tray of equal segments, each an icon, a label and a count, with one raised thumb that slides under the current one and folds to icons on a phone.
Installation
Overview
A navbar for React with React Aria whose links are a segmented control. The wordmark sits at the start and a Start free Shine Button at the end; between them, centred in the bar, a tray holds three equal segments: Plan (7 meals this week), Recipes (48 saved recipes) and Shop (12 items to buy), each with an icon, a label and a count. One raised thumb sits under the current segment; choose another and the thumb slides under it. The thumb's position is a number, not a measurement: segments are equal, so its inline start is the tray's padding plus the segment index times a segment, which works in right-to-left pages without any script. The current page is announced with aria-current="page" and the raised thumb is its mark, not colour alone. On a phone the labels and counts fold away and the wordmark shrinks to its icon, leaving three icons in the tray with the thumb kept; each segment's name and count stay in its accessible text. The bar is 56 pixels high and takes its rails and top rule from the Guides spine. It's built from Guides and Shine Button, with your theme's tokens for every colour. For apps with a small, fixed set of top-level areas where the counts matter. The counts are example data.
FAQ
How do I change the segments?
Edit SEGMENTS at the top of the file: each entry has an id, a label, an icon, an href, a count and the unit that count counts. The tray's columns and the thumb come from this array: the thumb is sized for three segments (calc((100% - 0.5rem) / 3)), so for two or four, change the 3 in THUMB too. A count is example data; feed it from your own state.
How does the thumb move?
The thumb is one absolutely placed element behind the segments. Its inline start is calc(0.25rem + var(--i) * (100% - 0.5rem) / 3), where --i is the current segment's index, set in a style attribute; a CSS transition on inset-inline-start slides it for 300 ms. The segments are equal width, so nothing needs measuring, and because it's an inline offset the thumb follows the page direction. The first render has no transition: the thumb only moves when you choose.
How does it work with a keyboard and a screen reader?
The segments are links in a nav landmark named Main, after the wordmark (a link home). Tab walks the wordmark, the three segments and Start free; Enter chooses and moves the thumb. A screen reader hears each segment's label, then its count and what it counts ("Recipes 48 saved recipes"), and the current one as the current page.
How does it work on a phone?
Below the sm breakpoint the segments show only their icon, the counts are hidden, the wordmark is just its icon and Start free is just Start, so the tray, the thumb and the action fit between the rails at 320 pixels. There is no menu button: all three destinations stay in reach. The accessible text of every segment doesn't change.
Start free renders a link when it has an href.