A frame that changes shape while the picture holds still — and shows you the part it is about to take.
The prompt10,049 characters
Add the "Aspect Ratio" 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 AspectRatio, 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-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.
--- AspectRatio.tsx ---
import { useEffect, useRef, useState } from "react";
/* ══ Aspect Ratio ═════════════════════════════════════════
A frame that changes shape, and a picture that does not
move while it does.
THE PICTURE IS NEVER SQUASHED, AND NOTHING ABOUT IT MOVES.
The whole point of a ratio box is that changing the frame
crops the image rather than distorting it, so the image is
laid out once, at the size of the tallest box this block
has — the square — and centered there for good. The frame
is a lid over it that changes shape. Nothing about the
picture's geometry depends on the ratio, so there is
nothing to keep in step: the crop is the only thing that
happens, which is the whole of what the component is.
AND IT EASES, IT DOES NOT SPRING. A frame that passes its
own height and comes back is a rectangle wobbling, and a
rectangle wobbling reads as a bug rather than as life. One
tween, quart-out, 420ms: quick off the mark, and it never
goes past the shape it is going to.
ONE NUMBER: the frame's height. The label reads off it. */
The rest — the source and its comments — is what the plan opens.