-
Notifications
You must be signed in to change notification settings - Fork 15
fix(container-menu)!: improves logic for returning focus to trigger #659
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this approach. To reiterate what we discussed, we agreed that deferring trigger focus didn't make sense as consumers can't (and shouldn't) control this behavior anyway. It also leaves room for folks to refocus another element in response to menu closing without affecting screen reader announcements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quick status comment:
Flo and I met offline to go over the current approach and how we can maybe improve focus behavior between controlled and uncontrolled instances of isExpanded
. Currently, this PR will only synchronously focus the button if isExpanded
is uncontrolled.
Instead, we think there could be an opportunity here to give more direct trigger focus control through the use of a new parameter, which would also slightly change how Menu
works in controlled scenarios by requiring consumers to focus their buttons when isExpanded
is false
.
To-be-discussed at tomorrow's meeting of the minds to get team consensus. 🧐
packages/menu/src/useMenu.ts
Outdated
@@ -272,22 +278,32 @@ export const useMenu = <T extends HTMLElement = HTMLElement, M extends HTMLEleme | |||
event.stopPropagation(); | |||
|
|||
const changeType = StateChangeTypes.TriggerClick; | |||
const nextIsExpanded = !controlledIsExpanded; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually think the code below reads better if we use !controlledIsExpanded
. I confused nextisExpanded
as referring to the next
/ nested menu state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love how well the new direction cleaned up with the code!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (KEYS.ESCAPE === key) { | ||
focusTriggerRef.current = true; | ||
} | ||
// TODO: Investigate why focus goes to body instead of next interactive element on TAB keydown. Meanwhile, returning focus to trigger. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are the current results of this investigation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The mystery prevails. 🤔
I verified that returnFocusToTrigger
is only called once on TAB keypress. ✅
The browser first sets the activeElement
to body
. Pressing TAB once more sets the focus to the next interactive element. That implies the placement in the tab sequence isn't reset. I created a JIRA task to revisit.
Description
Improve the logic for returning focus to trigger. Adds optional
restoreFocus
prop to manager focus return to trigger.💥 BREAKING CHANGE:
A new
restoreFocus
prop has been added. By defaultrestoreFocus
istrue
and will return the focus to the trigger on menu item selection,ESC
/TAB
key press, and clicking outside the menu dropdown. User who need to keep the dropdown open on selection must setrestoreFocus={false}
and manually handle the focus return.Detail
onChange
callback. Now, when a menu item triggers Garden's Modal open, the focus will automatically be restored to the menu trigger after the modal has closed.Screen.Recording.2024-08-29.at.10.19.34.AM.mov
restoreFocus
prop which defaults totrue
. Disabling it gives users more flexibility with managing focus return to the trigger. See demo Story in docs: demo restoreFocus with controlled menu [ DO NOT MERGE! ] #661.Checklist
npm start
)