fix(cmux-next): no focus ring after clicking away from a menu
Summary
After opening a composer menu with the mouse (Reasoning, Computer, any ui/Menu) and clicking away, the chip kept a focus ring. Base UI returned focus to the trigger, and WebKit drew that programmatic focus as keyboard focus because a menu row had just been focused by script. #21395 (in the current nightly) made the rings keyboard-only in CSS but did not cover this return.
MenuPopup now passes a default finalFocus. A pointer close (a press outside, or a mouse pick) puts focus back where it was when the menu opened, normally the prompt, else on the trigger with focusVisible: false. Keyboard closes still return to the trigger with its ring, Escape included. Base UI 1.8 reports the interaction that opened the menu as the close type, so the popup also records whether a key was pressed in it. If focus has already moved outside the popup when Base UI asks (it asks after the close fade), for example into another chip's picker opened by the same press, it stays there. A menu opened through the controlled open prop records its opener too. Menus with an explicit finalFocus, and submenus, are unchanged.
Testing
test/menu-pointer-close-focus.test.ts(new, Chromium and WebKit): a press outside the open Reasoning or Computer menu leaves no ring; a mouse pick returns focus to the prompt with no chip ring; Escape after a mouse open still puts a ringed focus on the chip; pressing Model while the Reasoning menu is open keeps the model picker open with focus inside it (probed green in WebKit and Chromium). Committed before the fix. Red/green from a headless WebKit probe on the New Tab gallery stage: after a click away, the chip matched:focus-visiblewith a drawn outline before and drew none after; Escape still left the chip focused and:focus-visible. The suite itself was not run locally (cosmic-gray load ~300 timed out Vite warm-up); CI's browser lane runs it.bunx tsc --noEmit,vp fmt --checkandvp lintclean.
Changelog
Fixed: Clicking away from a composer menu no longer leaves a focus ring on its chip
Proof
Headless WebKit on the gallery stage agent-pane.new-tab / reasoning-chip, dark, 2x.

🤖 Generated with Claude Code