Dock

macOS-style animated dock with Gaussian neighbor icon magnification driven by spring physics.

Installation

File Structure

dock.tsx

Usage

import { Dock } from "@/components/unlumen-ui/dock";

const items = [
  { icon: "🌐", label: "Browser" },
  { icon: "📁", label: "Files", href: "/files" },
];

<Dock items={items} />;

Custom magnification

<Dock
  items={items}
  magnification={3}
  distance={120}
  springOptions={{ stiffness: 400, damping: 25 }}
/>

API Reference

Dock

PropTypeDefaultDescription
itemsDockItem[]-Array of dock items to render.
magnification?number2.2Maximum scale factor applied to the icon directly under the cursor.
distance?number100Pixel radius from the cursor within which neighbor icons are magnified.
iconSize?number48Base icon size in pixels (width & height).
gap?number12Gap between icons in pixels.
alwaysShowLabels?booleanfalseWhen true, labels are always visible beneath icons instead of appearing only on hover.
springOptions?SpringOptions{ stiffness: 300, damping: 22, mass: 0.5 }Motion spring options for the scale animation.
className?string-Extra classes on the dock container.

DockItem

PropTypeDefaultDescription
iconReact.ReactNode-Icon content — emoji, image, or any React node.
labelstring-Tooltip text shown above the icon on hover.
href?string-If provided, the item renders as an anchor tag.
onClick?() => void-Click handler (used when href is not set).

Notes

  • Magnification uses a Gaussian bell curve: scale = (magnification − 1) × exp(−d² / (2 × distance²)) + 1, so icons taper smoothly from the cursor outward.
  • Each icon's scale is independently driven by a useSpring on a useTransform of the shared mouseX MotionValue — no re-renders during animation.
  • The dock uses origin-bottom so icons scale upward from their base, matching macOS behavior.
  • Tooltips animate with a 150ms ease-in/out on hover.
  • The dock container has backdrop-blur-md applied — ensure there's a background element behind it for the blur to be visible.

Keep in mind

Most components on this site are inspired by or recreated from existing work across the web. I'm not here to take credit; just to learn, experiment, and sometimes push things a bit further. If something looks familiar and I forgot to mention you, reach out and I'll fix that right away.