Icons that grow with proximity, each through its own spring.
The prompt23,937 characters
Add the "Dock" component from notboring to my project.
It is licensed for use in my projects — notboring.dev/license. Please:
1. Create the component at a sensible path for this
project, named Dock, from the source below.
2. Install what it needs: npm i framer-motion lucide-react
3. Add the CSS to the project's stylesheet.
4. THE PART THAT NEEDS YOUR JUDGMENT. The CSS reads
these custom properties and does not define them:
--card
--font-ui
--ink
--ink-2
--ink-rgb
They are notboring's design tokens. Map each one to
whatever this project already uses for the same
job — its own ink, ground, surface and UI font —
rather than defining them as new globals. If the
project has no equivalent, define it locally on
the component's own root so nothing leaks out.
Anything ending -rgb wants three bare numbers,
because the CSS builds rgba() from it.
Keep the comments. They say why the numbers are what
they are, and they are most of what makes this worth
copying rather than rewriting.
--- Dock.tsx ---
import { useEffect, useRef, useState } from "react";
import {
animate,
motion,
useMotionValue,
useMotionValueEvent,
useSpring,
useTransform,
} from "framer-motion";
import { Calendar, Camera, Mail, MessageSquare, Music, Settings, Terminal } from "lucide-react";
/* ══ Dock ═════════════════════════════════════════════════
Seven apps in a tray, and the ones near the pointer are
bigger.
SIZE IS A CONTINUOUS FUNCTION OF THE POINTER, AND EVERY
ICON READS IT THROUGH ITS OWN SPRING. Hover is a boolean,
and a tray built on it flicks from state to state as the
pointer crosses each icon's edge. This tray asks every icon
the same question on every move — how far is the pointer
from your middle — and answers with a bell: an icon starts
to grow while the pointer is still two icons away and is at
full size only when the pointer is on it. Nothing toggles.
Move the pointer a pixel and seven numbers change a little.
The rest — the source and its comments — is what you are buying.