shadcn.io is not affiliated with official shadcn/ui
Icon-Only Navbar Block for React Aria
An icon-only navbar for a messaging app: six destinations in square cells on shared hairlines, each named by a tooltip, with unread dots and a Show labels toggle that widens the cells to reveal the words.
Installation
Overview
An icon-only navbar for React with React Aria, the bar for apps whose destinations are well known and should take no room. It's a 48-pixel strip on the page's rails with a wordmark cell and six destination cells (Home, Search, Messages, Alerts, Settings and Profile), each 48 pixels square on shared hairlines that meet the top rule with a plus mark. Every cell is a link named by its tooltip on hover and keyboard focus and by its own text, the current one tinted with a stroke on the bar's bottom edge, and Messages and Alerts carry a dot and a spoken count until you open them. From the md breakpoint a Show labels toggle at the end widens the cells with a transition of the grid's columns and reveals the words beside the icons, and the tooltips step aside because the words say it. On a phone the six cells share the bar's width, icons only, and the toggle is gone. The bar is a plain list of links with no keyboard hint, unlike the action dock of a toolbar. It's built from Tooltip, Toggle and Guides, with your theme's tokens for every colour. For messaging, social and dashboard apps with a handful of destinations the users already know.
FAQ
How is each icon named?
Twice: every cell holds its label as text that's folded to nothing until the toggle is on (so it's the link's accessible name at all times, in its own language), and a tooltip shows the same word on hover and keyboard focus. The wordmark cell is named Glyphrail home. The current destination has aria-current="page": it's tinted and a foreground stroke lies on the bar's bottom edge, so the mark isn't colour alone.
Each link is a React Aria Link inside a tooltip trigger, switched off with isDisabled while the words show.
How does the Show labels toggle work?
The toggle is a pressed button (aria-pressed) whose state sits on the bar as data-labels. From md, pressing it switches the list's columns from six 3 rem tracks to six 5.25 rem tracks over 300 ms and unfolds each word beside its icon, so the cells widen and nothing else moves; the bar stays 48 pixels tall. Below md there's no room for the words, so the toggle is hidden and the six cells share the bar's width. With reduced motion the cells change width at once.
How do the unread dots work?
unread on a destination is its count: Messages starts at 3 and Alerts at 1. A small foreground dot sits on the icon (never a red one) and a visually hidden ", 3 unread" follows the name, so a screen reader hears "Messages, 3 unread". Opening a destination marks it current and reads what waited there, which removes its dot; the block keeps this in state, so wire your own counts in.
How do I add or remove a destination?
Edit DESTINATIONS at the top of the file: an icon, an id, a label and an optional unread each. The grid has six columns (grid-cols-6 on a phone and repeat(6, …) from sm): change the 6 in those three classes when the count changes, and check that the widened bar still fits the md width.
How does it work with a keyboard?
Tab moves through the wordmark, the six links and the toggle; each link shows its tooltip on focus, Enter follows it and Space presses the toggle. Every link points at #: point them at your routes and derive the current one from your router instead of the block's state.