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
3 new
Orientations
Resizable
Tones
Installation
npx shadcn@latest add @byronwade/morph-dockProps
| Prop | Type | Default | Description |
|---|---|---|---|
| items | MorphDockItem[] | — | Nav items: id, label, icon, optional onSelect/href, active, core, pinned, badge. |
| expandable | boolean | true | Allow compact ↔ full toggling via a chevron button. |
| cluster | React.ReactNode | — | Custom 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. |
| navLabel | string | "Primary" | Accessible name for the nav landmark. |
| open | boolean | — | Controlled morph open state. |
| onOpenChange | (open: boolean) => void | — | Open-state change callback. |
| children | React.ReactNode | — | The panel the dock morphs into. |
| panelWidth | number | 360 | Open-panel width in px. |
| panelHeight | number | — | Open-panel height in px. Omit to size to content (bloom-down). |
| growHeight | boolean | true | Bloom width + height (default) or width-only. |
| placement | "top" | "bottom" | "left" | "right" | "bottom" | Which way the panel blooms from the bar. |
| draggable | boolean | false | Detach the open panel and drag it free by its handle (flies home on close). |
| resizable | boolean | false | Show a corner grip to resize the open panel; the morph box follows live. |