One tooltip, traveling between four buttons.
The prompt18,887 characters
Add the "Tooltip" 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 Tooltip, 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-3
--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.
--- Tooltip.tsx ---
import { useEffect, useId, useLayoutEffect, useRef, useState } from "react";
import { motion, useSpring } from "framer-motion";
import { Bookmark, Copy, MoreHorizontal, Share } from "lucide-react";
/* ══ Tooltip ══════════════════════════════════════════════
Four buttons, and the one tooltip they share.
ONE TOOLTIP, NOT FOUR. Give each button its own and a hand
moving along the row sees four things appear and
disappear — each one waiting out its delay, each one
fading in where the last one faded out — four
interruptions for one question. Share a single tooltip
and the first button pays the delay, after which the label
simply TRAVELS: the pill slides to the next button, grows
or shrinks to fit the next word, and the word inside it
changes. A tooltip is for being read while you move, and
one that is re-summoned at every stop cannot be.
The delay is asymmetric on purpose. 260ms to appear, so a
pointer crossing the row on its way somewhere else raises
nothing; 140ms to leave, so a pointer crossing the gap
between two buttons does not lose it and pay the delay
again at the next one.
The rest — the source and its comments — is what you are buying.