fix(workspace): keep utility panel focus when the drawer opens in one commit - #972
Merged
Conversation
blove
enabled auto-merge (squash)
September 3, 2026 00:02
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
… commit Opening the tablet context surface from the rail mounts the utility panel and flips the drawer to open in the same commit. The panel focuses its own heading, then MobileNavOverlay's open effect ran focusable()[0].focus() -- a selector that excludes tabindex="-1" -- and took focus to the Close navigation button. Child passive effects run before parent ones, so the drawer always won. Dev hid this: StrictMode double-invokes effects of newly mounted components only, and the overlay stays mounted while closed, so the panel's second invocation landed last. The dev-server e2e job passed 85/85 while the deploy job's verify step against the production build failed 3/3 on the same commit, blocking refs/deploy/last-promoted from advancing. Claim initial drawer focus only when nothing inside it already holds focus. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
blove
force-pushed
the
blove/gallant-clarke-963ed0
branch
from
September 3, 2026 00:05
f8d39c8 to
7ef0dec
Compare
Contributor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
mainis currently blocked: the Deploy → Vercel job fails at "Verify deployed website" on the website e2eworkspace-shell … and restores utility focus, which stopsrefs/deploy/last-promotedfrom advancing and skips Production smoke. Every subsequent main deploy re-verifies and re-fails until this lands. First seen on c2bc3f9 (run 33684113829), still failing on df91042.This is a real production a11y regression, not a flaky assertion — the expected focus target is correct and was not loosened.
Root cause
Opening the tablet context surface (800px) from the rail's Activity button mounts
ControlPlaneUtilityPaneland flipsMobileNavOverlaytoopenin the same commit. The panel focuses its own<h2 tabindex="-1">; the overlay's open effect then ranfocusable()[0]?.focus()— a selector that explicitly excludestabindex="-1"— sending focus to the Close navigation button. React runs child passive effects before parent ones, so the drawer always won.Confirmed against the deployed site: after clicking Activity,
document.activeElementwasbutton[Close navigation]with the heading present, visible, and unfocused.Why CI's own e2e job passed on the same commit
Website — e2eruns againstnext devwith React StrictMode, which double-invokes effects of newly mounted components only.MobileNavOverlaystays mounted and returnsnullwhile closed, so its steal fires once while the fresh panel fires twice — the panel's second invocation lands last and masks the bug. A focus-event log on the dev server showed exactlyh2[Activity]→button[Close navigation]→h2[Activity]. Production has no second invocation.The fix
Claim initial drawer focus only when nothing inside the dialog already holds it. The Tab-trap registration and all other paths are untouched; when the drawer opens with no panel, focus is still on the trigger (outside the dialog), so default behavior is unchanged.
New regression tests cover the real sequence — panel mounting in the same commit that opens the drawer. The existing utility test missed this because it clicks the invoker while the drawer is already open, a commit where the overlay's state doesn't change. Both new cases fail without the fix.
Verification
Received: inactive, same locator) under production semantics, confirmed it passes with the fix and fails again with the fix reverted — the fix is causal.nx e2e website85/85 ·nx test workspace-react·nx test ui-react·nx test cockpit·nx lint workspace-react— all green.🤖 Generated with Claude Code