Repository navigation
feat(session-ui): keep the code block copy button in view while scrolling - #59159
opencode-agent[bot] wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
The change works: in a scroller with a 48px sticky header, a tall code block's copy button now stays pinned 4px under the header while you scroll, where on the base it scrolls out of view (screenshots below). The new component test fails without the CSS change. The markdown, touch timeline and sticky tool group component tests pass, and tsc -b is clean.
Public API is unchanged.
One thing worth fixing: in nested scroll panels, such as the 240px-tall tool output panels, the button uses the timeline's header offset, so it ends up far below the top of the panel (see the inline comment).
|
|
||
| [data-slot="markdown-copy-button-pin"] { | ||
| position: sticky; | ||
| top: calc(var(--sticky-accordion-top, 0px) + 4px); |
There was a problem hiding this comment.
position: sticky attaches to the nearest scroll container, but --sticky-accordion-top is inherited from the timeline. Some tool outputs (list/glob/grep) render <Markdown> inside [data-component="tool-output"][data-scrollable] (max-height: 240px; overflow-y: auto). A code block there pins at the session header offset inside that small box. I reproduced the button sitting ~52px down a 240px panel, and inside an open tool group it would be ~88px. Resetting --sticky-accordion-top: 0px on that scrollable output (like session-review.css already does) should keep it at 4px there.
There was a problem hiding this comment.
The only new commit merges dev into the branch, and the PR's own changes are the same as before. The earlier point about the button sitting too far down inside nested scroll panels (like the tool output boxes) is still open. With the merge, the markdown and touch timeline component tests pass (42 tests) and tsc -b is clean. The new copy handler for text selections from dev doesn't conflict with the pinned button.
Public API is unchanged.
|
Linking the alternative I opened before the bot pointed me here: #59814. Difference in one line: this PR keeps the existing floating button and makes it stick; #59814 makes the header area a 30px sticky strip with the language name on the left and an always-visible copy button on the right. Why I went with the header strip: Your approach is less invasive (no layout change to the code block, nothing shifts) and it already has a component test, which mine does not. I am fine with either landing. If maintainers prefer the minimal pin, I will close #59814. If the label + always-visible strip is wanted, the CSS is about 20 lines and could be folded into this PR instead of being a second PR. |


Closes #53519
Long code blocks in assistant messages now keep their copy button in view while you scroll through them, so you can copy without scrolling back to the top. There's no new header strip; the button looks and sits exactly where it did before, it just stays pinned to the top-right of the visible part of the block.
How it works
inset: 0) withpointer-events: none, so selecting, scrolling and clicking the code underneath still work.--sticky-accordion-top, so in the timeline it stays under the session header, the same offset the sticky tool group headers use.Testing
markdown.spec.ts: a 120-line block in a scroller with a 32px sticky header. The button stays 4px under the header partway down, is still clickable and copies the full block, the code under its host still receives the pointer, and at the end of the block it stops 4px above the block's bottom. It fails without the CSS change.markdown.spec.ts,session-timeline-mobile.spec.ts,basic-tool.spec.tsandfile-tool.spec.tspass. The new test passed 10/10 on repeat.bun typecheck(session-ui) andbun run lint:changedare clean.Visual
Requested by: @Brendonovich (Brendan via Slack)