react-spectrum icon indicating copy to clipboard operation
react-spectrum copied to clipboard

<FocusScope contain/> doesn't work when rendered into an iframe

Open chungwu opened this issue 1 year ago โ€ข 1 comments

๐Ÿ› Bug Report

When rendering something containing <FocusScope contain/> into an iframe, FocusScope has trouble detecting the newly-focused element and goes into an infinite focusing loop.

Here's a repro: https://codesandbox.io/s/react-aria-focusscope-in-iframe-0e6fkj?file=/src/App.tsx

You can focus on one input in the iframe, and as long as you focus on another input, FocusScope will keep switching focus between the two.

The issue seems to be that in FocusScope.tsx, onBlur, it is checking if the newly-focused element is within the focus scope, and if not, returns the focus to the previously-focused node. Unfortunately it is assuming that document.activeElement is the newly-focused element instead of using e.relatedTarget, and document refers to the parent frame and not the child frame, so it incorrectly tries to restore focus to the previously-focused input.

๐Ÿค” Expected Behavior

<FocusScope/> continues working in an iframe.

๐Ÿ˜ฏ Current Behavior

<FocusScope/> cannot detect focused element across iframes.

๐Ÿ’ Possible Solution

It's possible here to look for activeElement in all the iframes until you find one, instead of directly relying on document.activeElement. But then, I'm not sure if this is even a use case that react-aria is trying to allow ๐Ÿ˜… I see many direct references to document in the react-aria code, so they'll all probably break in some way when used across iframes.

๐Ÿ”ฆ Context

In Plasmic, we're allowing users to register React components that we then use to render in another iframe. This happens when those registered components use <FocusScope contain/>.

๐Ÿ’ป Code Sample

https://codesandbox.io/s/react-aria-focusscope-in-iframe-0e6fkj?file=/src/App.tsx

๐ŸŒ Your Environment

Software Version(s)
@react-aria/focus 3.6.1

๐Ÿงข Your Company/Team

Plasmic

chungwu avatar Jul 27 '22 20:07 chungwu

Thanks for the sandbox, definitely not ideal. I forget exactly why I made this change, perhaps we could use e.relatedTarget instead of document.activeElement

Perhaps we can use the ownerDocument containing the FocusScope instead

LFDanLu avatar Jul 28 '22 19:07 LFDanLu

I have a potential solution for this and would like to submit a RFC @LFDanLu

slye-stripe avatar Sep 13 '23 13:09 slye-stripe

Sounds good, thanks! I'll bring it to the teams attention.

LFDanLu avatar Sep 13 '23 16:09 LFDanLu

This appears to have been fixed, I can't reproduce with latest https://codesandbox.io/p/sandbox/react-aria-focusscope-in-iframe-forked-ds3vwm Thanks @slye-stripe, I'm guessing one of your PRs fixed it!

snowystinger avatar Dec 23 '23 04:12 snowystinger