chat: the copy buttons sit on the code block, bottom right
they were sticky at the top, which put them over the first line — and on a one-line block, which is most of them in a chat, over the whole thing. absolute bottom-right inside the surface now, with `.code-surface` given the `position: relative` it never had. that omission is why a control could end up escaping to the nearest positioned ancestor and floating below the block it belongs to. `padding-bottom` on the pre to go with the existing `padding-right`: the last line is the one they overlap now, and it needs its own room the same way the first line needed it before. the trade the old comment was worried about is real but smaller than it reads: a block taller than the viewport now has its controls at the bottom rather than the top. that is where you end up after reading it anyway, and it is a worse place to be only for a block you never scroll — which is exactly the block whose first line the old position was covering.
This commit is contained in:
@@ -108,17 +108,18 @@ export const CodeSurface = ({ code, lang = '', startLine = 1, maxLines, numbered
|
||||
style={{ '--line-digits': digits, '--line-offset': startLine - 1 } as CSSProperties}
|
||||
>
|
||||
{code && (
|
||||
// Sticky, not absolute, and first in the flow so it has a flow position to stick to. A block
|
||||
// taller than its scroll container — a live log tail, a 400-line read — used to carry its
|
||||
// controls off the top edge, so the output you most want to copy was the one whose copy button
|
||||
// you had to scroll back up to find. `h-0` keeps the row out of the vertical flow: it overlays
|
||||
// the top of the block rather than pushing it down, which is what the old `absolute` did.
|
||||
// Absolute, bottom-right, INSIDE the block — the controls belong to the code, so they sit on it
|
||||
// rather than after it. `.code-surface` is `position: relative` for this (prose.css).
|
||||
//
|
||||
// Bottom rather than top: a copy button over the FIRST line covers the thing you are most likely
|
||||
// to be reading, and on a one-line block — a single command, which is most of them here — it
|
||||
// covers the whole thing.
|
||||
//
|
||||
// Always visible, not hover-revealed: a control you have to discover by waving the pointer at it
|
||||
// is a control most people never find, and on touch there is no hover to find it with at all. Two
|
||||
// buttons rather than one with a modifier — the destination decides which you want (a terminal, or
|
||||
// someone else's markdown), and a modifier nobody can see is a feature nobody uses.
|
||||
<div className="sticky top-1.5 z-10 flex h-0 items-start justify-end gap-1.5 pr-1.5">
|
||||
<div className="absolute right-1.5 bottom-1.5 z-10 flex items-center gap-1.5">
|
||||
{lang && (
|
||||
<span className="rounded px-1 font-mono text-[10px] tracking-wide text-white/35 backdrop-blur-sm select-none">
|
||||
{lang}
|
||||
|
||||
Reference in New Issue
Block a user