[#1747] Fix aria-hidden blocked when isolating subtrees due to initial focus delay#1748
[#1747] Fix aria-hidden blocked when isolating subtrees due to initial focus delay#1748stefcameron merged 2 commits intomasterfrom
Conversation
🦋 Changeset detectedLatest commit: 8be7b5a The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
WalkthroughActivation and unpause flows were restructured to await initial focus placement before applying subtree isolation (aria-hidden/inert). addListeners now returns a Promise when delayInitialFocus is enabled; subtree isolation and onPostActivate are invoked after the initial focus has been moved. Changes
Sequence Diagram(s)mermaid Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@docs/js/no-delay.js`:
- Around line 11-18: The comment in the onPostActivate() method contains a
copy-paste artifact referencing "delay.js"; update the comment to accurately
describe this file (no-delay.js) — locate the onPostActivate function and
replace the incorrect sentence ("`no-delay.js` demo has the same check") with a
corrected description (e.g., mention this demo itself performs the check or
remove the reference) so the comment reflects the current file context.
🧹 Nitpick comments (1)
index.js (1)
1064-1089: Async finishActivation solves the Chrome warning—but fire-and-forget could mask errors.The
async finishActivationcorrectly awaitsaddListeners()before applying subtree isolation, which fixes the issue. However, on line 1089,finishActivation()is called withoutawait, meaning any errors thrown inside will become unhandled Promise rejections rather than propagating to the caller.This is probably intentional for backwards compatibility (the
activate()method returnsthissynchronously), but it's worth noting that errors inonPostActivateor other async steps won't be catchable by the caller.If error visibility is desired, consider adding a
.catch()handler:finishActivation().catch((err) => { console.error('focus-trap: error during activation:', err); });
Fixes #1747 (relates to #1575)
Also re-orders when
addListeners(), subtree isolation, andupdateObservedNodes()are called to make it consistent in all cases, always in the same order, for both activation and un-pausing.The changeset entry in this PR explains everything (copied here for convenience)...
onPostActivate()would be called before the initial focus node was focused and the trap was fully activated.setTimeout(0)) but wasn't delaying callingonPostActivate()until after that delay.isolateSubtrees='aria-hidden'option, the currently-focused node's container (a non-subtree being "disabled") would get hidden before the delay was up, resulting in Chrome preventing the effect ofaria-hiddenon that subtree with a warning in the console due to the container being hidden still containing focus (e.g. the "activate trap" button).onPostActivate()await the initial focus delay (if there is one, which is default behavior; remove it withdelayInitialFocus=false) before being applied/called.await waitFor(() => expect(initialFocusNode).toBeFocused()).onPostActivate()handler (prior to this change, that node would not be focused yet; after this change, it will be focused).PR Checklist
Please leave this checklist in your PR.
npm run demo-bundlein your branch and include the/docs/demo-bundle.jsfile that gets generated in your PR).// TEST MANUALLYcomments here) that can't be fully tested in Cypress have been manually verified.typeof document/window !== 'undefined'before using it in code that gets executed on load.npm run changesetlocally to add one, and follow the prompts).Summary by CodeRabbit
Breaking Changes
New Features
Bug Fixes
Tests
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.