🐛 fix: defer scroll-to-user-message until spacer is mounted#13378
🐛 fix: defer scroll-to-user-message until spacer is mounted#13378
Conversation
The scroll that pins a user message to the top of the viewport was racing with the conversation spacer mount. When the spacer hadn't rendered yet, there wasn't enough scrollable height, so the scroll had no effect. Now `useScrollToUserMessage` accepts a `spacerActive` flag and defers the scroll until the spacer is mounted, guaranteeing the fill height is available before scrolling. https://claude.ai/code/session_016GDASpf7Rh5yN7BJTdXYwT
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c6f626c3ef
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } else { | ||
| // Defer scroll until spacer mounts and provides enough height | ||
| pendingScrollIndexRef.current = userMessageIndex; |
There was a problem hiding this comment.
Fall back to immediate scroll when spacer never mounts
Deferring to pendingScrollIndexRef whenever spacerActive is false causes auto-scroll to be skipped entirely when no spacer is needed. In useConversationSpacer, spacerActive is tied to mounted, which stays false when computed spacer height is 0 (the long user/assistant-content case), so this branch stores a pending index that is never executed. That regresses the previous behavior by preventing the user message from being pinned in conversations where the content already fills/exceeds the viewport.
Useful? React with 👍 / 👎.
The previous fix deferred scrolling entirely until spacerActive was true. This regressed the no-spacer case (content fills viewport, spacer height = 0, mounted stays false) — the scroll never fired. Now the hook always scrolls immediately on message send (preserving original behavior), and additionally fires a follow-up scroll when spacerActive transitions to true. This covers both cases: - Content fills viewport: immediate scroll works, no spacer needed - Content is short: immediate scroll may under-scroll, but the follow-up scroll after spacer mounts corrects the position https://claude.ai/code/session_016GDASpf7Rh5yN7BJTdXYwT
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## canary #13378 +/- ##
=========================================
Coverage 66.94% 66.95%
=========================================
Files 1903 1903
Lines 153684 153701 +17
Branches 15534 18387 +2853
=========================================
+ Hits 102889 102908 +19
+ Misses 50675 50673 -2
Partials 120 120
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
The scroll that pins a user message to the top of the viewport was
racing with the conversation spacer mount. When the spacer hadn't
rendered yet, there wasn't enough scrollable height, so the scroll
had no effect.
Now
useScrollToUserMessageaccepts aspacerActiveflag anddefers the scroll until the spacer is mounted, guaranteeing the
fill height is available before scrolling.
https://claude.ai/code/session_016GDASpf7Rh5yN7BJTdXYwT