Chips that land, and a field that makes room for them.
The prompt14,529 characters
Add the "Tags" 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 Tags, from the source below.
2. Install what it needs: npm i framer-motion
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-4
--ink-5
--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.
--- Tags.tsx ---
import { useEffect, useLayoutEffect, useRef, useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
/* ══ Tags ═════════════════════════════════════════════════
A field that holds words, and the words are things.
CHIPS LAND, AND THE FIELD MAKES ROOM. The common build is a
list that re-renders: type, press Enter, and the new chip is
simply there, the input a little further right than it was.
Nothing arrived; the layout changed. Here the room appears
first — the input steps aside on the same frame — and the
chip drops into it on a spring, from slightly small and
slightly low, the way a token is put down on a table. When
a chip goes it does not vanish from its slot: its width
closes and its neighbors slide up to fill the gap, so the
list is always a row of objects and never a set of positions
being recomputed.
THE FIELD'S HEIGHT IS STATED, NOT LEFT TO THE WRAP. A row of
chips that overflows to a second line makes the field a row
taller in one frame. The flow inside is measured and the box
around it is told the number, which is the same number — but
a stated height is one CSS can move between, and a derived
one is not.
The rest — the source and its comments — is what you are buying.