-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Navigation block: Don't close submenu when it has focus #52177
Navigation block: Don't close submenu when it has focus #52177
Conversation
// If focus is outside modal, and in the document, close menu | ||
// event.target === The element losing focus | ||
// event.relatedTarget === The element receiving focus (if any) | ||
// When focusout is outsite the document, | ||
// `window.document.activeElement` doesn't change. | ||
if ( | ||
selectors.core.navigation.menuOpenBy( store ).click && |
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.
We shouldn't be careful about not calling closeMenu
multiple times even if the menu is closed. If anything, we should make the side effects that happen when the menu is closed (inside the closeMenu
function) more declarative so they only trigger when the status changes.
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 I am not mistaken, I added that check because the focusout
event was triggered in the children, so it is being called each time we change focus over the elements of the submenu.
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 think that works fine now with the new implementation, doesn't it?
Size Change: +25 B (0%) Total Size: 1.42 MB
ℹ️ View Unchanged
|
This may have already been present, but I found an odd bug.
Screen.Recording.2023-06-30.at.3.32.03.PM.mov |
You're right. It feels weird not to flush the "Opened because it has focus" status when you are actively trying to close the menu. I've pushed a fix, let me know if it feels better now! |
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 left a few comments. I think the only required change is that the fix is not working with the Page List block, which I believe should be an easy fix.
if ( $w->next_tag( | ||
array( | ||
'tag_name' => 'UL', | ||
'class_name' => 'wp-block-navigation-submenu', |
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.
Right now, the fix doesn't work with the Page list block. It seems it doesn't have the wp-block-navigation-submenu
. I believe we should either check the class wp-block-navigation__submenu-container
or don't check any class. But I guess the first one should be safer.
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.
Good catch. Changed.
// If focus is outside modal, and in the document, close menu | ||
// event.target === The element losing focus | ||
// event.relatedTarget === The element receiving focus (if any) | ||
// When focusout is outsite the document, | ||
// `window.document.activeElement` doesn't change. | ||
if ( | ||
selectors.core.navigation.menuOpenBy( store ).click && |
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 I am not mistaken, I added that check because the focusout
event was triggered in the children, so it is being called each time we change focus over the elements of the submenu.
'class_name' => 'wp-block-navigation-submenu', | ||
) | ||
) ) { | ||
$w->set_attribute( 'data-wp-on--focusin', 'actions.core.navigation.openMenuOnFocus' ); |
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 same as focusout
, the focusin
event is propagated to all the focusable children. This means that the action is called each time the focus is changed between the submenu elements. Not sure if it is a problem, but we are calling that action more times than needed. Should we add a check in the action or is it okay?
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 think it's ok. I think openMenu
and closeMenu
should be more declarative, and calling them multiple times should be ok.
9ea3bc9
to
93bc1e2
Compare
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.
Looks great now! 🙂 I've tested it and it seems to work with both navigation submenus and pages.
Awesome. Thank you, Mario 🎉 @jeryj, I'm going to merge this now but feel free to get back to me if you think something can still be improved. |
What?
This PR builds on top of #52170 because it includes changes that only work with the modified logic of that PR.
Don't close the submenu when it has been focused because the mouse was hovering.
Why?
It's an edge case, but it shouldn't happen.
Spotted by @jeryj in Slack.
How?
Adding a new
focusin
handler that adds a"focus"
prop to the"submenuOpenedBy"
object and prevents the menu from closing until"focus"
is removed on thefocusout
handler.Testing Instructions
tab
keypressesScreenshots or screencast
Before
Screen.Capture.on.2023-06-30.at.15-44-56.mp4
After
Screen.Capture.on.2023-06-30.at.15-42-52.mp4