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.
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"
/>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 dock | Tiles swell with their distance from the pointer and make room for each other. |
|---|---|
| Tab | Enter the dock. It is one stop, landing on the tile used last, which swells as if hovered. |
| Arrow keys | Move along the dock: left and right on a horizontal dock, up and down on a vertical one. |
| Home / End | Jump to the first or the last tile. |
| Enter / Space | Open the item. The tile hops when bounce is on. |
Read from the component's own type, so this cannot drift from what it accepts.
| Prop | Type | Default | Description |
|---|---|---|---|
items* | DockItem[] | — | |
magnification | number | — | Largest scale a tile reaches right under the pointer. @defaultValue 1.8 |
distance | number | — | 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" |
bounceOnClick | boolean | — | A short hop when an item is pressed. @defaultValue true |
tone | "muted" | "outline" | "ghost" | "muted" | |
size | "sm" | "default" | "lg" | "default" | |
aria-label | string | "Dock" | |
className | string | — |