Repository navigation
fix(web): composer menu chevrons open while the composer is resting - #17111
NikaCholadze wants to merge 1 commit into
Conversation
The "Send options" and "Implementation actions" triggers cancelled pointerdown to keep editor focus. Chromium then skips mousedown, which is the event Base UI opens menus on, so the chevron did nothing and "Send with full history" could not be reached. Cancel mousedown instead: focus stays in the editor and the menu still opens. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a small, self-contained web UI bug fix that restores two existing menu triggers while preserving composer focus, with focused regression tests covering both affected paths. It introduces no schema, infrastructure, security, product-default, or static-analysis changes. Notes:
You can add or adjust custom eligibility rules. Learn more. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (2)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughMenu triggers now use ChangesComposer menu focus handling
Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix Suggested reviewers: Merge Risk: 🔵 Low · up to The menus now open correctly with a mouse while the composer is resting. Touch behavior on mobile was not tested in a real browser, so the editor could lose focus when a chevron is tapped. Check this on a mobile device before or shortly after merge. 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Dismissing prior approval to re-evaluate b54b999
Problem
Old Claude threads now compact before sending (#16631), and the chevron next to "Compact and send" is the only way to choose "Send with full history". In a resting composer, that chevron does nothing, so every send in an old thread compacts and the user cannot opt out. The composer rests after you type a one-line message and scroll the thread, which "Collapse composer on scroll" (on by default) does. Windows narrower than 640px take the same path.
Repro on current
main: open a Claude thread with more than 100k tokens of context that has been idle for over 70 minutes. Type one line, scroll the timeline up a little, then click the chevron. The menu does not open, however many times you click.The cause: while
preserveComposerFocusOnPointerDownis true, both menu triggers callpreventDefault()onpointerdownto keep focus in the editor. After a cancelledpointerdown, Chromium skips the compatibilitymousedownandmouseupand only firesclick. Base UI'sMenuTriggeropens onmousedown, and it ignores the following mouseclickon purpose (useClick:if (eventOption === 'mousedown' && pointerType) return). So the menu never opens. "Compact and send" still works because it is a plain button that acts onclick.Change
This is a really small fix (one file, about 10 lines) for an important problem: with it, users can again send to an old thread without compacting.
On the two menu triggers ("Send options" and "Implementation actions"), the focus guard now cancels
mousedowninstead ofpointerdown. Cancellingmousedownstill stops the button from taking focus, so the editor keeps focus and the composer stays resting. Base UI's ownonMouseDownhandler still runs, so the menu opens. Every other button keeps thepointerdownguard, because they act onclick.The "Implement" split button shares the same trigger code and had the same dead chevron, so this fixes one underlying problem in two places.
Scope and approval
There is no prior issue: this is a very small, focused fix for an obvious bug. A control that is meant to open a menu does nothing, and the fix keeps the intended behaviour (editor focus is preserved) without changing any product decision. It only touches
apps/web. It needs no contract, server or mobile change; the mobile app has no compact split button.Verification
Real client, before/after. I ran a dev server against a migrated copy of real data (
migrate-dev-db, isolated--base-dir). I opened a stale Claude thread with 147k tokens of context, typed one line and scrolled the timeline so the composer rested (form height went from 144px to 50px). Then I clicked the chevron with real mouse input in Chrome.main): three clicks,aria-expandedstayedfalseand no menu items were rendered.aria-expanded="true", the menu showed "Send with full history (147k tokens)", and the composer stayed resting (50px).Focused test.
ComposerPrimaryActions.menus.test.tsxpresses each trigger with Chromium's event order (cancelledpointerdown, so nomousedown/mouseup, butclickstill fires) against the real Base UI menu. It asserts that the menu opens and the item handler runs once. Both cases fail onmain(2 failed) and pass with the fix.vp test run src/components/chat/ComposerPrimaryActions.menus.test.tsx src/components/chat/ComposerPrimaryActions.test.tsx: 7 passed.vp lintandvp fmtare clean on both files.Not checked:
onSendWithFullHistory, which reachesChatView.onSendwithkeepFullHistoryset.Done with Claude Opus 5.5 in Claude Code (via T3 Code).
🤖 Generated with Claude Code