Closed majornista closed 2 years ago
We'd like to fix this with a refactor to FocusScope that takes our current Map and implements a doubly linked tree for our FocusScopes with null as the root. The reason for it being doubly-linked is that we will need to update and remove nodes in the tree, and we'll need to handle reparenting. We also need to know if something is in an ancestor or child. Having it doubly-linked should make these queries easier and these movements easier.
Right now we have a Map that vaguely implements a single direction tree, however, it can become out of date with nodes pointing to non-existent items.
There are several useful tests added in the PR that did exploration around this. They should be used to vet any future work.
๐ Bug Report
In the DialogContainer: Dialog triggered by a menu item example, a Dialog opens from a menu item, and then the menu containing the menu item closes, removing the element to which focus should be restored when the Dialog closes from the DOM. When the Dialog closes, focus is lost to the
document.body
.๐ค Expected Behavior
When a scope containing a
nodeToRestore
has been unmounted, we should restore focus to a previous `nodeToRestore, so in the Dialog triggered by a menu item example, focus should return to the ActionButton within the MenuTrigger.๐ฏ Current Behavior
When the Dialog closes, focus is lost to the
document.body
, because we do not keep track of previousnodeToRestore
s.๐ Possible Solution
Manage a stack of
nodeToRestore
elements so that when unmounting a scope, if that scopesnodeToRestore
is no longer in the DOM, we can restore focus to previousnodeToRestore
that remains in the DOM.๐ฆ Context
This is very important for keyboard and screen reader accessibility, especially with Portals in React, because when a FocusScope within a Portal unmounts with nowhere to return focus, focus is lost to the
document.body
at the end of the DOM, and a keyboard or screen reader user would have to navigate through the document to get back to where they left off.A user can explicitly manage focus within their application, when dialogs close, but that puts the burden on the developer, when it should probably be the framework's responsibility.
๐ป Code Sample
Within FocusScope:
๐ Your Environment
๐งข Your Company/Team
Adobe/Accessibility
๐ท Tracking Issue (optional)
Related issues: