react-native-web
react-native-web copied to clipboard
Improve the focus management of Modal component
Is there an existing request?
- [X] I have searched for this request
Describe the feature request
a concise description of the request
Supports setting the focus on the specified element when closing the Modal.
potential solutions
Add a focusAfterClosed?: ?() => HTMLElement prop
additional context
https://github.com/necolas/react-native-web/blob/e8098fd029102d7801c32c1ede792bce01808c00/packages/react-native-web/src/exports/Modal/ModalFocusTrap.js#L142-L156
The current code implements Example point 3. However, in practice, we often also need the focus to be able to return to the specified element. (Return to the trigger element is still the default behavior.) source: https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/examples/dialog/
https://user-images.githubusercontent.com/8579651/216359486-64d970cf-052b-4473-b4cd-215cdf55865c.mp4
In this case:
The expected order of focus is:
Add Delivery Address button --> Street input --> Add button --> OK button --> Add Delivery Address button
The actual order of focus is:
Add Delivery Address button --> Street input --> Add button --> OK button --> body
https://codesandbox.io/s/focus-order-djuzdk
This issue is from my comment. And the original issue #2175 has been explained in my comments. Maybe that issue could be closed as well?
this commit is trying to implement this feature. If this feature is acceptable, I would improve the docs, tests, and then submit a PR.
Is this an issue because there are 2 modals being created?
- Focus moves from App to Modal 1 to Modal 2
- Once Modal 2 is closed the logic tries to find the "trigger" from Modal 1
- Modal 1 and the last trigger were unmounted, so focus goes back to the document
Re: focusAfterClosed proposal. That would only work on RNW if we added it, because there's no equivalent prop in React Native.
Is this an issue because there are 2 modals being created?
- Focus moves from App to Modal 1 to Modal 2
- Once Modal 2 is closed the logic tries to find the "trigger" from Modal 1
- Modal 1 and the last trigger were unmounted, so focus goes back to the document
Yeah, that means we want the refocusing behavior to be controllable.
Re: focusAfterClosed proposal. That would only work on RNW if we added it, because there's no equivalent prop in React Native.
I'm also hesitant to suggest adding a prop that React native doesn't have. It seems that focus trap and refocusing behavior only exists on the web. They are very useful most of time, it's just that they really stuck us in a few scenarios, and these requirements also meet the accessibility norms.
I had another idea: export a few functions somewhere, for example, add disableTrap and setReturnFocus in the UIManager as an escape hatch. The former can help us to disable the focus trap before the user has clicked to close the current modal but it has not been unmounted. The latter can help us to specify which element we want to refocus when the current modal is closed.
The implementation may be like this: https://github.com/ntdiary/react-native-web/commit/274d344b4bfcef5a03cdf20cfd6e4503660edead Maybe it's still not a good practice for the library, but it can help us out and give users a good experience.
I fully understand that you may have to consider many factors, so here is just a discussion, and sincerely looking forward to your thoughts. Thanks again for making such a great library. 😄
Can we avoid making API changes at this stage by storing a stack of triggers, and refocusing the first that is still connected to the document?
Can we avoid making API changes at this stage by storing a stack of triggers, and refocusing the first that is still connected to the document?
Thank you for your reply, The above example is just one scenario. I'm afraid this approach can only solve limited scenarios. Perhaps we can just lower its priority first. If other people have similar needs in the future, we can then consider how to do it. : )