Dock Magnify

About this component

Dock Magnify

A dock of app tiles that swells under the pointer the way a desktop dock does: each tile's scale follows a cosine falloff from the pointer, eased every frame and written straight to a CSS variable, so moving along it costs no React renders. Neighbours make room as tiles grow, so nothing clips, and the tiles grow away from the edge the dock sits on (bottom, top, left or right). Labels show beside the hovered tile, a pressed tile hops, and running dots, badges, images, tinted icon tiles and separators are all built in. The dock is one tab stop with arrow keys, and a keyboard-focused tile swells as if hovered; reduced motion keeps every tile at rest.

Usage

The import and the props worth knowing about, in one place.

import { CalendarDays, Mail, Music } from "lucide-react";
import { DockMagnify } from "@/components/beste/component/dock-magnify";

<DockMagnify
  items={[
    { id: "music", label: "Music", icon: Music, tint: "#fb3c5b", running: true },
    { id: "mail", label: "Mail", icon: Mail, tint: "#3b82f6", badge: 12, href: "/mail" },
    { id: "divider", separator: true },
    { id: "calendar", label: "Calendar", icon: CalendarDays, onClick: () => console.log("Open the calendar") },
  ]}
  magnification={2}     // largest scale under the pointer
  distance={160}        // px the swell reaches either side
  side="left"           // "bottom" (default) | "top" | "left" | "right"
  tone="outline"        // "muted" (default) | "outline" | "ghost"
  size="lg"             // "sm" | "default" | "lg"
/>

Keyboard and gestures

Every one of these is in the component already. They are listed because a props table cannot mention a gesture, so nothing else on this page can tell you they exist.

Move the pointer along the dockTiles swell with their distance from the pointer and make room for each other.
TabEnter the dock. It is one stop, landing on the tile used last, which swells as if hovered.
Arrow keysMove along the dock: left and right on a horizontal dock, up and down on a vertical one.
Home / EndJump to the first or the last tile.
Enter / SpaceOpen the item. The tile hops when bounce is on.

Props

Read from the component's own type, so this cannot drift from what it accepts.

PropTypeDefaultDescription
items*DockItem[]—
magnificationnumber—Largest scale a tile reaches right under the pointer. @defaultValue 1.8
distancenumber—How far the swell reaches either side of the pointer, in px. @defaultValue 140
side"bottom" | "top" | "left" | "right"—Edge the dock sits on. Tiles grow away from it and labels show on the far side. @defaultValue "bottom"
bounceOnClickboolean—A short hop when an item is pressed. @defaultValue true
tone"muted" | "outline" | "ghost""muted"
size"sm" | "default" | "lg""default"
aria-labelstring"Dock"
classNamestring—