KQ-1179 · POCKET/NAV

Pocket Nav

A navigation bar that never wraps or scrolls: a ResizeObserver reads its room and every link's natural width, and the links that no longer fit slide along the bar into a pocket at its end on the exit ease, shrinking as they go, in priority order and a cascade apart, while the links behind them close the gap on glide. The pocket takes each one with a squeeze on snap as its count rolls, links slide back out on snap as room returns, and the current page is never tucked. The bar is one tab stop whose arrows move between links and the pocket; the pocket is a menu button whose menu of tucked links opens on ArrowDown, Enter or Space, moves with arrows, Home, End and first letters, and closes on Escape or Tab with focus back on the pocket.

KQ-1179 · POCKET/NAV

Readings

Flow and pressure, last 24 hours.

9 in the bar · 0 in the pocket · window 200 px · Readings

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/pocket-nav

Props

links
{ id: string; label: string; href?: string; usage?: number }[]
default —
The links, in bar order. With href a link is an anchor; usage ranks it for priority="usage".
value / defaultValue
string
default the first link
The current link's id, controlled or initial. It carries aria-current="page" and is never tucked.
onValueChange
(id: string) => void
default —
Fires from the press, key or menu choice that made a link current.
onPocketChange
(ids: string[]) => void
default —
The links in the pocket, in bar order: once measured, then each time the set changes.
label
string
default "Main"
The navigation's accessible name.
items
number
default —
The most links the bar shows at once, 4 to 9; the rest wait in the pocket even with room to spare. Defaults to all.
priority
"order" | "usage"
default "order"
Tuck from the end of the bar backwards, or the least used links first wherever they sit.
pocket
"more" | "dots"
default "more"
A More button with a count and chevron, or a round three-dot button with a count dot.
sound
boolean
default false
A swish for each link that slides into or out of the pocket and a tick as its count moves, only while the visitor is dragging or pressing keys; a swish when the pocket opens.
disabled
boolean
default false
The links and the pocket can be read but not used.
className
string
default —
Classes for the nav, which fills its width.