Skip to content
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

[TrapFocus] Capture nodeToRestore via relatedTarget #26696

Merged
merged 4 commits into from
Jun 14, 2021

Conversation

eps1lon
Copy link
Member

@eps1lon eps1lon commented Jun 11, 2021

-<TrapFocus getDoc={customGetDoc} />
+<TrapFocus />

Previous implementation would break with React's planned Offscreen API (or weaker: breaks with Strict Effects in React 18) since we capture the nodeToRestore during render. However, effects might run and cleanup without render running again e.g. when no props/state/context changes but the component is hidden and revealed again.

We captured it during render because in effects other compoents might've already moved focus into the TrapFocus tree i.e. effects were too late.

What we can do instead (now that React 17 implements event.relatedTarget in IE 11) is capture the nodeToRestore when focus moves into the TrapFocus tree. We already did this but only sometimes. Probably because we already hit issues with capturing the nodeToRestore during render.

@eps1lon eps1lon added new feature New feature or request component: FocusTrap The React component. labels Jun 11, 2021
@eps1lon eps1lon added this to the React 18 milestone Jun 11, 2021
@mui-pr-bot
Copy link

mui-pr-bot commented Jun 11, 2021

Details of bundle changes (experimental)

@material-ui/lab: parsed: -0.08% 😍, gzip: -0.10% 😍

Generated by 🚫 dangerJS against 404a24c

@eps1lon eps1lon force-pushed the fix/TrapFocus/node-to-restore branch from 2574ef7 to 9241209 Compare June 11, 2021 08:28
@eps1lon eps1lon marked this pull request as ready for review June 11, 2021 08:31
@eps1lon eps1lon requested a review from oliviertassinari June 11, 2021 08:46
@@ -338,7 +316,7 @@ function Unstable_TrapFocus(props) {
};

const handleFocusSentinel = (event) => {
if (!activated.current) {
if (nodeToRestore.current === null) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This handler wasn't covered by tests. The behavior of this handler is now covered in test/e2e/fixtures/Unstable_TrapFocus/DefaultOpenLazyTrapFocus.tsx

Copy link
Member

@oliviertassinari oliviertassinari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previous implementation would break with React's planned Offscreen API (or weaker: breaks with Strict Effects in React 18) since we capture the nodeToRestore during render.

@eps1lon The changes are definitely better from the complexity and bundle size perspectives.
React 18, I fail to follow the causality. Won't a trap focus always be onscreen when active? If we had a reproduction, this would be great.


cc @mui-org/x it solve our cross-document issue: https://github.com/mui-org/material-ui-x/blob/9dd5cf94061d1733566b7b66982fae554ebcf242/packages/grid/_modules_/grid/components/panel/GridPanelWrapper.tsx#L28

@eps1lon
Copy link
Member Author

eps1lon commented Jun 14, 2021

React 18, I fail to follow the causality. Won't a trap focus always be onscreen when active? If we had a reproduction, this would be great.

Yeah, I haven't looked into if we'll ever be affected by it. But I don't think it's useful to think about it since React will have these semantics going forward.

Considering we keep existing behavior and add React 18 compat by removing code, I'm happy with this PR. Even if the change is only required for tests.

@eps1lon eps1lon merged commit aafb54a into mui:next Jun 14, 2021
@eps1lon eps1lon deleted the fix/TrapFocus/node-to-restore branch June 14, 2021 11:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change component: FocusTrap The React component. new feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants