-
Notifications
You must be signed in to change notification settings - Fork 63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Doesn't seem to work in other documents #539
Comments
You're welcome! 🙂 It's quite possible there are some things the code isn't handling. I had another look at the code, and I found one case where it's not respecting the When you say it doesn't work, have you checked your console for errors? If you're hitting the issue above, you might have exceptions in the console from line 68, and that would cause the trap not to function properly. If not, then something else is going on.
Just a thought here, and probably wouldn't change anything, but
So your code is more like Also, what is Another idea is to put the trap in the other document. For example, if you're using this for a modal window of some kind, put the trap in that modal component, and create it only when that modal is created, instead of keeping it "alive" outside of it and trying to activate it only when the modal is visible. |
No errors.
Indeed I am storing it in a variable: const document = useMemo(() => menu?.ownerDocument, [menu])
If it was a ref, it would be
The trap is in the other document. It wraps a div whose document is the document I'm passing to focusTrapOptions: const [menu, setMenu] = useState<HTMLDivElement | null>(null)
const document = useMemo(() => menu?.ownerDocument, [menu])
// a small amount of other stuff but you get the point...
return <FocusTrap active={menu !== null} focusTrapOptions={{document}}>
<div ref={setMenu} {...otherProps}>
{children}
</div>
</FocusTrap> The only reason active is |
Code was accessing `document` global instead of first checking for the `focusTrapOptions.document` setting.
Code was accessing `document` global instead of first checking for the `focusTrapOptions.document` setting.
OK, then what do you mean when you say it's "not working"? Is it that the trap activates, and traps focus within the child document, but you can still click on elements outside (in the host document)? That's a limitation of having the trap work on a child document. Also, just to check everything, you should be using focus-trap-react v8.8.0 or greater. That's the version that added support for the focus-trap |
No. I can still use tab and shift+tab to navigate through other elements in the focus trap's document. I'm aware of the limitations of different contexts and that you can't trap focus in one window to another window. That's not what I'm referring to. To be perfectly clear when I say it's "not working" I mean there are no observable effects other than the keyboard focus being fully capable of leaving the focus trap in the document in which it's active. No console errors, nothing like that, it just... doesn't work. I'm aware of how annoying it can be to receive a bug report like this but when I say doesn't work, I quite literally mean that I have no other information than that.
Just installed it a couple days ago. Using version 8.8.2. |
Right, not much to go on then... Are you able to debug into focus-trap-react.js to try and see where the problem is? If your node_modules tree isn't read-only, you could at least add console statements in focus-trap-react.js and then see what parts of the code get executed at runtime and which don't. That might shed some light on things. |
The Chrome debugger has code coverage so I can just use that. (It shows timings on the left for lines that got executed) Could be a couple days though, I'll keep you posted. In the meantime I can provide a codesandbox that reproduces the issue? |
Take your time. A repro always helps, for sure! |
Huh. Actually it seems specifying |
Yeah, that's because specifying document seems to have fixed it in the codesandbox for whatever reason. By any chance did your commit make it to npm already? I've taken my application into the debugger and verified that active is true and the document is correct and that the focus trap is activated via |
Wrong document here. The issue seems to be that the focus trap is created before The reason the CodeSandbox demo works is because the document variable has already been initialized when the focus trap first gets switched on. The solution would be to only call setupFocusTrap once the |
So something like |
And there's no way you can change your code to delay the inclusion of the focus trap component to when the document has stabilized? Like don't render the trap until you have the document you need... |
Because this is kind of a big change to the way it's currently working. |
This... is impossible? Like, my component doesn't know where it's mounted until it's been mounted.
It's not. It's highly unlikely people are relying on when the document field is read from the options. If anything this fixes a bug, where the focus trap reads the options before they are ready. |
That's true. Then rendering with
I'll give this some thought. It's a significant change in terms of when the trap gets created. I'll have to check focus-trap to see if creating the trap triggers any events for which you might expect a callback in one of the options, in which case, you wouldn't get the callback at the same time anymore. If that turns out to be a problem, then another option might be to promote the |
Either that or make it so that I don't have to specify the |
@LoganDark Can you check if #546 will fix your issue? |
I did consider this, but if you give the trap more than one container, which doc do we use (I guess they should all be from the same document, but still), and more, if the container elements are updated while the trap is active, we'd have to check for a change in the doc again and then remove/re-add all the listeners... Just seems like too risky when there seems to be a simpler solution, which I hope I have in #546. |
Definitely seems like it. |
OK, I'll merge it and publish it. Hopefully it addresses your issue. |
It'll be published imminently in 8.9.0. |
@all-contributors add @LoganDark for bug |
I've put up a pull request to add @LoganDark! 🎉 |
I appreciate the effort you have put into making the focus trap library work in iframes and child windows, but unfortunately it seems like maybe the React version is not prepared for this?
I'm using the FocusTrap like
<FocusTrap active={element !== null} focusTrapOptions={{document}}>
, wheredocument
is the document of the child window (derived fromelement.ownerDocument
), but the focus trap still isn't trapping focus. When the same component is used in the main document, it works just fine.Do you know what could be the cause of the issue?
The text was updated successfully, but these errors were encountered: