MorphDock

A config-driven morphing navigation dock. The item row morphs compact ↔ full, and the whole pill blooms in place into a consumer-provided panel via useChromeMorph — items, badges, core/pinned flags, a trailing cluster, and a contextual action. Pure --dock tokens, reduced-motion + Esc + click-away.

Default
Command
Draggable
Expand
Orientations
Resizable
Tones

Installation

npx shadcn@latest add @byronwade/morph-dock

Props

PropTypeDefaultDescription
itemsMorphDockItem[]Nav items: id, label, icon, optional onSelect/href, active, core, pinned, badge.
expandablebooleantrueAllow compact ↔ full toggling via a chevron button.
clusterReact.ReactNodeCustom trailing slot (count + badge, env tag, search button…).
action{ label; icon; onSelect? }Contextual action pill — blooms the panel when children are present, else runs onSelect.
tone"dock" | "surface""dock"Dark dock pill (default) or light surface.
navLabelstring"Primary"Accessible name for the nav landmark.
openbooleanControlled morph open state.
onOpenChange(open: boolean) => voidOpen-state change callback.
childrenReact.ReactNodeThe panel the dock morphs into.
panelWidthnumber360Open-panel width in px.
panelHeightnumberOpen-panel height in px. Omit to size to content (bloom-down).
growHeightbooleantrueBloom width + height (default) or width-only.
placement"top" | "bottom" | "left" | "right""bottom"Which way the panel blooms from the bar.
draggablebooleanfalseDetach the open panel and drag it free by its handle (flies home on close).
resizablebooleanfalseShow a corner grip to resize the open panel; the morph box follows live.