Skip to content
WANCRAFT

D.13Navigation & Menus

Interactive Dock

A navigation dock whose tiles rise and grow as the pointer approaches.

UpdatedReactMotionTailwindadvanced

Overview

Interactive Dock measures the pointer's distance to every tile and maps it to size through a spring, so neighbouring tiles swell in a smooth wave and rise above a fixed-height rail. Tooltips appear on hover and on keyboard focus, arrow keys move between items, and keyboard focus magnifies like the pointer. On touch screens and with reduced motion it becomes a compact, horizontally scrollable bar with visible labels.

01Installation

Method 01 · Registry

CLI verified

Uses the shadcn CLI in a project initialised with shadcn init. Installs the file to components/ui/interactive-dock.tsx and adds its dependencies.

npx shadcn@latest add https://wancraft.my/r/interactive-dock.json

Method 02 · Copy and paste

  1. 1. Install the dependencies below.
  2. 2. Copy the source from the Code tab into components/ui/interactive-dock.tsx.
  3. 3. Import it and adjust props.
npm install motion
Dependencies
motion
Peer
react ≥ 18, tailwindcss ≥ 4
Added
1 Oct 2026
Updated
13 Oct 2026

02Usage

The default configuration. Change properties above to generate a tailored example in the Usage tab.

example.tsx
import { InteractiveDock, type DockItem } from "@/components/ui/interactive-dock";
import { Home, Search, Inbox, Settings } from "lucide-react";

export function InteractiveDockExample() {
  const items: DockItem[] = [
    { label: "Home", icon: <Home />, href: "/", active: true },
    { label: "Search", icon: <Search />, href: "/search" },
    { label: "Inbox", icon: <Inbox />, href: "/inbox" },
    { label: "Settings", icon: <Settings />, href: "/settings" },
  ];

  return (
    <InteractiveDock items={items} />
  );
}

03Props

PropTypeDefaultDescription
itemsDockItem[]—{ label: string; icon: ReactNode; href?: string; onClick?: (e) => void; active?: boolean }. Items with href render links, others render buttons.
magnificationnumber1.7Scale of the tile directly under the pointer.
distancenumber140Distance in px from the pointer over which tiles are magnified.
sizenumber44Resting tile size in px.
spring{ stiffness: number; damping: number; mass: number }{ stiffness: 320, damping: 24, mass: 0.4 }Spring used to settle tile sizes.
accentstring"#FF7448"Colour of the active indicator and focus ring.
indicator"dot" | "bar""dot"Shape of the active indicator.
labelstring"Dock"Accessible name of the <nav> landmark.
...propsHTMLAttributes—Native attributes are forwarded to the <nav>.

04Features

  • 01Distance-based magnification driven by motion values — no React state on pointer move
  • 02Tiles rise above a fixed-height rail, so surrounding layout never moves vertically
  • 03Tooltips with index labels on hover and keyboard focus
  • 04Arrow keys, Home and End move focus; keyboard focus magnifies too
  • 05Touch / reduced-motion alternative: compact scrollable bar with visible labels
motion · springinput · pointerinput · hoverinput · keyboardinput · focusinput · click

05Accessibility

  • Rendered as a <nav> landmark with a list; items are real links or buttons with aria-label.
  • The active item has aria-current ("page" for links).
  • Tooltips are decorative duplicates of the accessible name and are aria-hidden.
  • Visible focus ring in the accent colour; magnification is disabled with prefers-reduced-motion.

06Limitations

  • Magnification changes tile widths, so the dock's total width grows while hovered — leave horizontal room around it.