-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
SubMenu: Fix expanding sub menu items on touch devices #93208
SubMenu: Fix expanding sub menu items on touch devices #93208
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.
thanks for raising the issue and looking at this! 🙌
think maybe a better approach would be to change the onClick
in MenuItem
to be something like:
onClick={(event) => {
if (hasSubMenu) {
event.preventDefault();
event.stopPropagation();
}
onClick?.(event);
}}
that should stop the click event propagating up to the overlay and closing the menu.
note: this isn't perfect, if the new submenu overflows the bounds of the mobile view it will resize the whole window. but it at least unblocks people from using these submenus. i think the changes needed to properly support mobile behaviour for the Menu
and MenuItem
elements are bigger than can be delivered in a community PR 😅
const onOverlayClicked = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => { | ||
if (event.target instanceof HTMLDivElement || event.target instanceof HTMLSpanElement) { | ||
const innerText = event.target.innerText | ||
if (innerText.includes("More...")) { | ||
return | ||
} | ||
} | ||
|
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.
this is definitely too brittle i'm afraid 😬
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.
thanks for your review, bro. i will modify it.
@ashharrison90 could you please look this pr again? |
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.
This doesn't seem to quite work. We want all the use cases for the menu to support touch for submenu, so it is better if the stopPropagation is used in MenuItem
. Try the approach that @ashharrison90 suggested!
thanks for review. i have add |
The issue is still there: You have added stopPropagation only for Try adding the ash's requested changes here:
|
yep. actually this pr don't work on |
It is okay if you do it in this PR, as it will make it easier to fix the other issue :) |
ok, i will change this pr. thanks for your review. |
@tskarhed bro, i delete video-1727321713273.mp4 |
@@ -108,7 +108,8 @@ export const MenuItem = React.memo( | |||
[styles.disabled]: disabled, | |||
[styles.destructive]: destructive && !disabled, | |||
}, | |||
className | |||
className, | |||
hasSubMenu ? 'hasSubmenu' : 'noSubmenu' |
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.
Instead of using a class as a selector, you could add aria-haspopup="menu"
to the item that has a submenu and use that when selecting closest.
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.
think the changes in Menu/MenuItem
can simplify down into just modifying the onClick
- see suggestions. i think this handles all cases 🙏 thanks again for tackling this 🙇
onMouseEnter={onMouseEnter} | ||
onMouseLeave={onMouseLeave} | ||
onKeyDown={handleKeys} | ||
onTouchStart={onMouseEnter} |
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.
onTouchStart={onMouseEnter} |
@@ -108,7 +108,8 @@ export const MenuItem = React.memo( | |||
[styles.disabled]: disabled, | |||
[styles.destructive]: destructive && !disabled, | |||
}, | |||
className | |||
className, | |||
hasSubMenu ? 'hasSubmenu' : 'noSubmenu' |
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.
hasSubMenu ? 'hasSubmenu' : 'noSubmenu' |
onClick={(event) => { | ||
if (hasSubMenu && !(event.target as HTMLElement).closest('.noSubmenu')) { | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
} | ||
onClick?.(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.
onClick={(event) => { | |
if (hasSubMenu && !(event.target as HTMLElement).closest('.noSubmenu')) { | |
event.preventDefault(); | |
event.stopPropagation(); | |
} | |
onClick?.(event); | |
}} | |
onClick={(event) => { | |
if (hasSubMenu && !isSubMenuOpen) { | |
event.preventDefault(); | |
event.stopPropagation(); | |
} | |
onClick?.(event); | |
}} |
@tskarhed @ashharrison90 bros, thanks for your review. i gived a new pr. |
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.
think this looks great 👍 thanks for the contribution! 🙌
Fixes #93151
actually, i add mobile click event
onTouchStart
, and use event delegation to avoid menu is closedplease take a look @tskarhed @torkelo
https://github.com/user-attachments/assets/4ce7541c-7c5d-4d35-93bd-18ff6e960829