KQ-2108 · FAVOURITE/SHELF

Favourite Shelf

A workspace sidebar with a Favourites shelf at its top that fills by dragging any row up into it: the grabbed row lifts into a layer above the sidebar on springs.flick and follows the pointer 1:1 while a dashed ghost holds its place, and over the shelf the favourites part on springs.glide to open a gap that follows the pointer as the shelf's height glides open by a row. Let go over the gap and the row glides in with the release velocity, then lands with a short squash from a springs.recoil spring kicked by the impact; let go elsewhere and it glides home, and a favourite dragged out below the shelf comes off it. Every row is one roving list: Alt+F adds or removes a favourite with the same flight, Alt with Up or Down reorders one, Delete removes one, and the folded rail turns the shelf into a strip of icons.

KQ-2108 · FAVOURITE/SHELF

shelf 2 of 5 · Roadmap, Q4 launch · on Roadmap

Install

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

$ pnpm dlx shadcn@latest add @kinetiq/favourite-shelf

Props

shelfStyle
"tray" | "ruled" | "card"
default "tray"
How the shelf is drawn: an inset tray, hairline rules, or a raised card with an accent edge.
rowHeight
number
default 32
Every row's height, in px; the gap, the landing and the shelf's height follow it.
accent
"cobalt" | "plum" | "mint" | "ink" | string
default "cobalt"
Accent for the current page, the landing pad, the stars and the shelf meter. A name or any CSS colour.
sections
ShelfSection[]
default defaultShelfSections
The sections under the shelf, in order: { id, label }.
items
ShelfItem[]
default defaultShelfItems
Every row, in order within its section: { id, label, section, icon, count? }.
favourites / defaultFavourites
string[]
default — / defaultShelfFavourites
Item ids on the shelf in shelf order, controlled or initial.
onFavouritesChange
(ids: string[]) => void
default —
Fires with the whole new shelf after any add, remove or reorder.
onFavourite
(id: string, index: number) => void
default —
An item landed on the shelf, at this index.
onUnfavourite
(id: string) => void
default —
An item left the shelf.
onReorderFavourites
(ids: string[]) => void
default —
The shelf's order changed, by a drag or by Alt with an arrow.
limit
number
default 5
The most the shelf holds; a full shelf opens no gap and says so.
current / defaultCurrent
string
default — / "roadmap"
The open page's id, controlled or initial.
onNavigate
(id: string) => void
default —
A row was opened by a press, Enter or Space.
folded / defaultFolded
boolean
default — / false
The sidebar as a 60px rail, controlled or initial.
onFoldedChange
(folded: boolean) => void
default —
Fires from the button that folded or opened the sidebar.
workspace
string
default "Basinworks"
The workspace's name in the header.
status
"ready" | "loading" | "error"
default "ready"
Whether the sidebar's data has arrived: skeleton rows while loading, a message with Try again on error.
onRetry
() => void
default —
Try again after an error.
label
string
default —
The navigation's accessible name. Defaults to "<workspace> sidebar".
className
string
default —
Classes for the outer container.