Skip to content

fix(web): composer menu chevrons open while the composer is resting - #17111

Open
NikaCholadze wants to merge 1 commit into
pingdotgg:mainfrom
NikaCholadze:fix/compact-send-menu-trigger
Open

NikaCholadze wants to merge 1 commit into
pingdotgg:mainfrom
NikaCholadze:fix/compact-send-menu-trigger

Conversation

@NikaCholadze

Copy link
Copy Markdown

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 preserveComposerFocusOnPointerDown is true, both menu triggers call preventDefault() on pointerdown to keep focus in the editor. After a cancelled pointerdown, Chromium skips the compatibility mousedown and mouseup and only fires click. Base UI's MenuTrigger opens on mousedown, and it ignores the following mouse click on 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 on click.

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 mousedown instead of pointerdown. Cancelling mousedown still stops the button from taking focus, so the editor keeps focus and the composer stays resting. Base UI's own onMouseDown handler still runs, so the menu opens. Every other button keeps the pointerdown guard, because they act on click.

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.

    • Before (main): three clicks, aria-expanded stayed false and no menu items were rendered.
    • After: one click, aria-expanded="true", the menu showed "Send with full history (147k tokens)", and the composer stayed resting (50px).
    • The timeline is blurred in both screenshots because it contains private conversation content.
    Before After
    Before: chevron click does nothing while the composer rests After: the menu opens with "Send with full history"
  • Focused test. ComposerPrimaryActions.menus.test.tsx presses each trigger with Chromium's event order (cancelled pointerdown, so no mousedown/mouseup, but click still fires) against the real Base UI menu. It asserts that the menu opens and the item handler runs once. Both cases fail on main (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 lint and vp fmt are clean on both files.

  • Not checked:

    • I did not click "Send with full history" in the dev client, because that starts a real provider turn. That path is unchanged: the item already calls onSendWithFullHistory, which reaches ChatView.onSend with keepFullHistory set.
    • I did not test the mobile-width layout in a real client, Safari or Firefox.

Done with Claude Opus 5.5 in Claude Code (via T3 Code).

🤖 Generated with Claude Code

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>
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Oct 8, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Oct 8, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at b54b999

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:

  • Diff unchanged. Approvability was decided on eligibility alone.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Oct 8, 2026

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f4da2b1a-287c-42bf-8079-0f823ea3c6f2
📥 Commits

Reviewing files that changed from the base of the PR and between 30cc788 and b54b999.

📒 Files selected for processing (2)
  • apps/web/src/components/chat/ComposerPrimaryActions.menus.test.tsx
  • apps/web/src/components/chat/ComposerPrimaryActions.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

Menu triggers now use mousedown cancellation when composer focus preservation is enabled. Tests cover opening both menus with a mouse, selecting an item, and checking that its handler runs once.

Changes

Composer menu focus handling

Layer / File(s) Summary
Menu trigger focus handling
apps/web/src/components/chat/ComposerPrimaryActions.tsx, apps/web/src/components/chat/ComposerPrimaryActions.menus.test.tsx
Menu triggers use separate focus props that cancel mousedown when focus preservation is enabled. Tests simulate mouse interaction with both menus and verify that selecting an item calls its handler once.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: juliusmarminge

Merge Risk: 🔵 Low · up to b54b9

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)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main fix: menu chevrons now open when the composer is resting.
Description check ✅ Passed The description includes the problem, reproduction steps, technical cause, change, scope justification, verification results, screenshots, limitations, and agent attribution. It satisfies the reposito…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@juliusmarminge juliusmarminge added the macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews label Oct 11, 2026 — with ChatGPT Codex Connector
@macroscopeapp
macroscopeapp Bot dismissed their stale review October 11, 2026 06:21

Dismissing prior approval to re-evaluate b54b999

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews size:S 10-29 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants