Skip to content

fix(ui-dialog): cancel the pending focus region activation on close - #2697

Open
matyasf wants to merge 1 commit into
masterfrom
fix_dialog_test
Open

fix(ui-dialog): cancel the pending focus region activation on close#2697
matyasf wants to merge 1 commit into
masterfrom
fix_dialog_test

Conversation

@matyasf

@matyasf matyasf commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Dialog.close() cancels any still-scheduled requestAnimationFrame region activation and clears
    _focusRegion after blurring. Without it, a Dialog closed before that frame ran (e.g. a Tray
    opened and closed within one frame, which happens when rAF callbacks land late under load)
    activated a region nothing ever blurred — its document keydown listener then ran scopeTab on
    an unrendered element, preventDefaulting every later Tab press.
  • Adds a Dialog regression test that flushes the activation frame manually after the close and
    asserts Tab still moves focus outside the Dialog.

Test Plan

  • This was the cause of the flaky Tray should handle focus properly in complex cases browser
    test. To reproduce the old failure, stub window.requestAnimationFrame to fire ~150ms late and
    run packages/ui-tray/src/Tray/__tests__/Tray.test.tsx — it fails on the first userEvent.tab()
    without this fix and passes with it.
  • Worth a manual keyboard pass on Modal/Popover/Tray/Menu: open, close, then Tab around to confirm
    focus return and tab order are unchanged.

🤖 Generated with Claude Code

@matyasf matyasf self-assigned this Aug 25, 2026
@matyasf
matyasf requested review from balzss and joyenjoyer August 25, 2026 12:41
@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://instructure.design/pr-preview/pr-2697/

Built to branch gh-pages at 2026-08-28 09:07 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

github-actions Bot pushed a commit that referenced this pull request Aug 25, 2026
@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Visual regression report

Cypress suite: ✅ Passing

Visual diff: ⚠️ Changes detected.

Status Count
Unchanged 95
Changed 1
New 0
Removed 0

Accessibility (axe): ✅ No violations.

📊 View full report — click a screenshot's ⚠ badge to see each violation boxed on the image, with the offending element named and contrast failures shown as color swatches.

Diff images (1)

badge-canvas.png — 1573 pixels differ

Baselines come from the visual-baselines branch. They refresh on every merge to master. The Cypress suite line covers the a11y and console-error assertions — a ❌ there means the suite found real issues even if the visual diff is clean.

@balzss balzss 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.

although the code looks good, the 2 visual regression test changes look interesting. the table one seems unrelated which is even weirder, but the menu one might has something to do with the changes. it looks like the dark theme now not highlights the first menu option? also the other themes are not consistent with highlighting/not-highlighting the first item. do you think it's related to this change?

github-actions Bot pushed a commit that referenced this pull request Aug 27, 2026
@matyasf

matyasf commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator Author

@balzss the 2 visual regression test changes look interesting

I've re-ran the VRT and the changes are gone..

Dialog activates its FocusRegion in a requestAnimationFrame callback. When the Dialog closed
before that frame ran (e.g. a Tray that is opened and closed within the same frame, which happens
on a loaded machine where rAF callbacks land late), close() found no region to blur and left the
frame scheduled. The callback then activated a region for an already closed Dialog, which nothing
ever blurred: componentWillUnmount only closes while open. The leaked region kept a document
keydown listener that scoped every later tab press to an element that is not rendered anymore, so
scopeTab called preventDefault and Tab stopped working.

close() now cancels any scheduled activation and clears _focusRegion after blurring.

This is what made the Tray "should handle focus properly in complex cases" browser test flaky on
CI.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
github-actions Bot pushed a commit that referenced this pull request Aug 28, 2026
@matyasf

matyasf commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator Author

VRT is flaky, now I run it again, and now it shows a change in Badge

@matyasf
matyasf requested a review from balzss August 28, 2026 11:54
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.

3 participants