A sheet from the bottom edge that answers the flick rather than the distance, with three places to stop.
The prompt18,746 characters
Add the "Drawer" 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 Drawer, from the source below.
2. It needs nothing beyond 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-4
--ink-rgb
--on-ink
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.
5. IF YOU CHANGE IT, GO ALL THE WAY. This block is
built for every state its object can really be
in — empty, one, full, refused, undone, pressed
twice, interrupted halfway — and not only the one
the demo opens on. Adapt it and the same standard
holds: work out that list before you write, and
build the whole of it. Never settle for the
minimum that makes the screenshot right. A
component somebody has to come back and finish is
the thing this was written to replace.
6. AVATARS is a stub
— notboring's own pictures are not licensed to
travel. Point it at this project's images, or
leave the placeholder and tell me.
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.
--- Drawer.tsx ---
import { useEffect, useRef, useState } from "react";
/* ══ Drawer ═══════════════════════════════════════════════
A sheet that comes up from the bottom edge and answers the
flick rather than the distance.
WHERE YOU LET GO IS NOT THE QUESTION — HOW YOU LET GO IS.
Nearly every drawer decides by position: past half it
opens, short of half it closes. That is wrong in the one
case people actually do, which is the fast short flick — a
quick shove downward from the top of the sheet is
unmistakably "put this away", and a position rule sends it
back up because the finger only traveled forty pixels. The
speed at the moment of release is read here, and anything
past 0.55 px/ms decides on its own; only a slow release
falls back to the nearest of the three places the sheet
can be.
THREE PLACES, AND THE TOP ONE IS THE TOP. Shut, a peek that
shows the head and what is under it, and full — and full is
ten pixels off the ceiling, not seventy. A sheet you drag
to the top of its screen and which stops well short of it
is a sheet that is broken, whatever the number was supposed
to mean. Ten is the sliver of page that says there is a
The rest — the source and its comments — is what the plan opens.