fix(desktop): restore overflow-anchor:none on live scroll containers

useAnchoredScroll is meant to be the single owner of scrollTop, but both
live scroll containers had lost the [overflow-anchor:none] class (it
survived only on the thread loading skeleton, which never scrolls). With
it gone, Chromium's native scroll-anchoring heuristic re-engaged and
applied its own scrollTop correction on prepend — picking its own anchor
element — while the hook applied a second scrollBy correction on top. When
the two anchors diverged the corrections stacked, producing the residual
jiggle that survived the single-owner rewrite.

Restoring the class on both live containers (MessageTimeline timeline +
MessageThreadPanel body) hands scroll ownership back to the hook alone.

This is a real-wheel-only symptom: native scroll anchoring barely fires
under synthetic scrollTop= writes, so the headless suite stayed green
while a manual macOS scroll pass surfaced it. scroll-history e2e 6/6,
tsc clean.

Co-authored-by: Tyler Longwell <tlongwell@squareup.com>
Signed-off-by: Tyler Longwell <tlongwell@squareup.com>
This commit is contained in:
npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d
2026-06-18 12:56:40 -04:00
co-authored by Tyler Longwell
parent 0f32f49045
commit 2a56e08eb9
2 changed files with 2 additions and 2 deletions
@@ -383,7 +383,7 @@ export function MessageThreadPanel({
const threadScrollRegion = (
<div
className={cn(
"min-h-0 flex-1 overflow-y-auto overflow-x-hidden overscroll-contain pb-24",
"min-h-0 flex-1 overflow-y-auto overflow-x-hidden overscroll-contain pb-24 [overflow-anchor:none]",
isSplitLayout && auxiliaryPanelContentPaddingClass,
!isSplitLayout && !isFloatingOverlay && "pt-[4.75rem]",
)}
@@ -307,7 +307,7 @@ const MessageTimelineBase = React.forwardRef<
) : null}
<div
className={cn(
"absolute inset-0 overflow-y-auto overflow-x-hidden overscroll-contain px-2 pt-1",
"absolute inset-0 overflow-y-auto overflow-x-hidden overscroll-contain px-2 pt-1 [overflow-anchor:none]",
hasComposerOverlay ? "pb-24" : "pb-4",
)}
data-scroll-restoration-id={scrollRestorationId}