Skip to content

fix: stop Escape focus restore from closing the app-mode menu#822

Merged
cursor[bot] merged 2 commits into
mainfrom
cursor/fix-mode-menu-escape-focus-race-828c
Jul 18, 2026
Merged

fix: stop Escape focus restore from closing the app-mode menu#822
cursor[bot] merged 2 commits into
mainfrom
cursor/fix-mode-menu-escape-focus-race-828c

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Summary

  • Fixes a Production UI flake where Escape from the scope popover deferred a focus restore onto "Open answer options", which stole focus while the app-mode menu was opening and dismissed the menu via onBlur before the Documents item was visible.
  • Adds restoreFocusUnlessMoved() so Escape/scope-close restore is skipped when focus already moved (for example into the mode menu).
  • Hardens the smoke helper to wait for a visible scope popover to hide before opening the mode menu (fail-closed on timeout), and adds a focused unit test for the restore guard.

Verification

  • npm run test -- tests/restore-focus-unless-moved.dom.test.tsx (3 passed)
  • Focused Chromium: tests/ui-smoke.spec.ts for dashboard defers source and administration requests until their surfaces open and document search mode lists matching documents (2 passed; 6/6 stress reruns of the formerly flaky test)
  • UI verification not run: targeted Playwright path covers the regression; hosted Production UI required for the gate

Risk and rollout

  • Risk: low — focus-restore guard on dismissable layers plus a smoke wait; no clinical/data path changes
  • Rollback: revert this squash merge
  • Provider or production effects: None

Clinical Governance Preflight

  • Source-backed claims still require linked source verification before clinical use
  • No patient-identifiable document workflow was introduced or expanded without explicit governance approval
  • Supabase target remains Clinical KB Database (sjrfecxgysukkwxsowpy)
  • Service-role keys and private document access remain server-only
  • Demo/synthetic content remains clearly separated from real clinical sources
  • Source metadata, review status, and outdated/unknown-source behavior remain conservative
  • Deployment classification/TGA SaMD impact was checked when clinical decision-support behavior changed

Notes

Open in Web Open in Cursor 

Summary by CodeRabbit

  • Bug Fixes

    • Improved focus restoration when closing search scope controls or pressing Escape.
    • Prevented focus from being unexpectedly redirected when users have moved to another control or opened the app mode menu.
    • Reduced interaction conflicts when switching document search modes.
  • Tests

    • Added coverage for focus restoration and scenarios where restoration should be skipped.

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Focus restoration

Layer / File(s) Summary
Guarded focus helper and Escape integration
src/components/use-dismissable-layer.ts, tests/restore-focus-unless-moved.dom.test.tsx
restoreFocusUnlessMoved conditionally restores focus without overriding app-mode menu focus or focus moved to another control. Escape handling and DOM tests use the guarded behavior.
Scope close integration and smoke synchronization
src/components/clinical-dashboard/master-search-header.tsx, tests/ui-smoke.spec.ts
Scope UI close paths use guarded focus restoration, and the smoke helper waits for the scope popover to become hidden before opening the app-mode menu.

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

Suggested reviewers: claude, copilot

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Title check ✅ Passed The title clearly matches the PR’s main fix: preventing Escape focus restore from closing the app-mode menu.
Description check ✅ Passed The description follows the template with Summary, Verification, Risk and rollout, Clinical Governance Preflight, and Notes.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/fix-mode-menu-escape-focus-race-828c

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

@supabase

supabase Bot commented Jul 18, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project sjrfecxgysukkwxsowpy because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@cursor
cursor Bot marked this pull request as ready for review July 18, 2026 06:53
@cursor
cursor Bot enabled auto-merge (squash) July 18, 2026 06:53

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/ui-smoke.spec.ts`:
- Around line 166-171: Remove the catch that suppresses failures from the
scope-command-popover wait in the deferred focus restore flow. Let waitFor({
state: "hidden", timeout: uiAssertionTimeoutMs }) fail when the popover remains
visible, so opening the mode menu only occurs after the dismissal precondition
succeeds.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 68cee0a8-6428-48d8-9e43-8c8944253ae9

📥 Commits

Reviewing files that changed from the base of the PR and between 77ab4a6 and f0febf2.

📒 Files selected for processing (4)
  • src/components/clinical-dashboard/master-search-header.tsx
  • src/components/use-dismissable-layer.ts
  • tests/restore-focus-unless-moved.dom.test.tsx
  • tests/ui-smoke.spec.ts

Comment thread tests/ui-smoke.spec.ts Outdated
cursoragent and others added 2 commits July 18, 2026 07:01
Scope dismiss deferred a focus restore onto the answer-options trigger.
When a mode-menu open landed in the same frame window, that restore stole
focus, blur-dismissed the menu, and flaked the Documents mode switch in
Production UI CI. Skip restore when the mode menu is open or focus already
moved, and wait for the scope popover to hide before opening the menu.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Only wait for the scope popover when it is visible, and let that wait
throw if dismissal times out so the mode-menu open cannot recreate the
Escape focus-restore race.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
@cursor
cursor Bot force-pushed the cursor/fix-mode-menu-escape-focus-race-828c branch from f0febf2 to 2b8ddb8 Compare July 18, 2026 07:01
@cursor
cursor Bot merged commit 39c4bdc into main Jul 18, 2026
16 checks passed
@cursor
cursor Bot deleted the cursor/fix-mode-menu-escape-focus-race-828c branch July 18, 2026 07:08
cursor Bot pushed a commit that referenced this pull request Jul 18, 2026
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
BigSimmo added a commit that referenced this pull request Jul 18, 2026
* fix: stop Escape focus restore from closing the app-mode menu

Scope dismiss deferred a focus restore onto the answer-options trigger.
When a mode-menu open landed in the same frame window, that restore stole
focus, blur-dismissed the menu, and flaked the Documents mode switch in
Production UI CI. Skip restore when the mode menu is open or focus already
moved, and wait for the scope popover to hide before opening the menu.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>

* fix(test): fail closed when scope popover does not dismiss

Only wait for the scope popover when it is visible, and let that wait
throw if dismissal times out so the mode-menu open cannot recreate the
Escape focus-restore race.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants