-
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
DropdownMenuV2: prevent default on Escape key presses #55962
Conversation
@@ -181,7 +181,13 @@ const UnconnectedDropdownMenu = ( | |||
children, | |||
shift, | |||
modal = true, | |||
hideOnEscape = true, | |||
hideOnEscape = ( event ) => { |
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.
IMO, since we're just passing down this prop and it's ariakit that is handling the ESCAPE key, I think the ideal fix would have to be done in ariakit directly
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'm fine with a fix here for now, but maybe this could benefit more users.
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.
@diegohaz maybe you can share some perspective as to why this is not the case in ariakit
?
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 can't remember any discussion about hideOnEscape
and fullscreen mode in particular, so there's likely no specific reason. It seems it just hasn't been considered yet.
But there's an issue with fullscreen and portal: ariakit/ariakit#865
0d19ff6
to
897f3fc
Compare
// Pressing Escape can cause unexpected consequences (ie. exiting | ||
// full screen mode on MacOs, close parent modals...). | ||
event.preventDefault(); | ||
event.stopPropagation(); |
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.
Is there any particular reason to stop propagation?
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.
Without it, I thought that, when a DropdownMenu is rendered inside a Modal, pressing Escape would close the DropdownMenu and the parent modal.
That was my impression because, when talking to Diego, I seem to remember him suggesting this change specifically for when a DropdownMenu is rendered inside a Modal.
But I just tested without it, and things seem to work well.
Flaky tests detected in 897f3fc. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/6813741126
|
* DropdownMenuV2: prevent ESC key presses from propagating outside of the component by default * CHANGELOG * Storybook control improvements * Don't expose 'hideOnEscape' prop, keep internal * Memoize wrapperProps * Remove stopPropagation
What?
This PR changes the default behaviour of the new experimental
DropdownMenu
component so that the keyboard event related to pressing theEscape
key is default prevented.Why?
As pointed out in #55625 (comment), pressing the
Escape
key to close the dropdown menu can have unintended consequences (like, for example, causing a browser on MacOs to exit full screen mode).How?
Instead of using a boolean for the
hideOnEscape
prop, we can use a callback function that accepts theevent
object. We can then callpreventDefault()
on it.Also, note that this PR only changes the default behaviour of the component. Folks wishing to have the keyboard event bubbling up can simply pass a different value for the prop.
Testing Instructions
npm run storybook:dev
document.addEventListener('keydown', (e) => console.log(e.key, e.defaultPrevented))
Escape true
. When pressing the escape key when the menu is closed, the console output should beEscape false
.