-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Closed
Description
🐛 Bug Report
When used inside a shadowRoot
the FocusScope
currently has some issues:
- Focused element will not be determined correctly as
document.activeElement
will refer to the parent node of the shadowRoot the currently focused element is in. The activeElement needs to be determined recursively traversing (open) shadowRoots (document.activeElement.shadowRoot.activeElement.shadowRoot.activeElement......). This leads to invalid detection whether an element is in scope and also restores focus wrongly. e.target
in focus/blur events is referring to the parent node of the shadowRoot of the focused element.e.composedPath()[0]
can be used to determine the actually focused element inside the custom element. ('composedPath' in e ? e.composedPath()[0] : e.target
)- Chrome:
TypeError: Cannot read property 'focus' of null
in theonBlur
ofuseFocusContainment
due toe.target
being null inside the rAF (not sure this is really related to custom element / shadowRoot or a general bug - Safari: Focus is looped through focusable elements
I patched this in our libs using patch-package
so I'm happy to file a PR if you'd like to support custom elements. I'm not sure how this affects other packages of the spectrum ecosystem and thus wanted to check in prior to opening a PR.
🤔 Expected Behavior
FocusRing
can be used with custom elements / shadowRoots
😯 Current Behavior
See Bug Report above
💁 Possible Solution
- Instead of
document.activeElement
useactiveElement()
function activeElement() {
let activeElement = document.activeElement;
while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement) {
activeElement = activeElement.shadowRoot.activeElement;
}
return activeElement;
}
- Instead of
e.target
use'composedPath' in e ? e.composedPath()[0] : e.target
🔦 Context
In our Microfrontend Framework we encapsulate modules inside custom elements. To escape them we use a portal-root
custom element in the body where all modals will be rendered into. Inside this we use FocusScope
to contain focus.
💻 Code Sample
https://codesandbox.io/s/vigilant-hofstadter-3wf4i?file=/src/index.js
🌍 Your Environment
Software | Version(s) |
---|---|
@react-aria/focus | 3.2.3 |
Browser | Chrome 87.0.4280.141 / Safari 14.0.2 |
Operating System | Mac OS 10.15 |
🧢 Your Company/Team
Undisclosed
🕷 Tracking Issue (optional)
n/a
shannonrothe, theomessin, alschussler, sehnemvinicius, emanuelemacri and 2 more
Metadata
Metadata
Assignees
Labels
No labels