material-components-web-react
material-components-web-react copied to clipboard
Menu click away
I am implementing a secondary menu into list items. To avoid triggering the list primary action, I have to stop click propagation from the secondary action button. This has the side effect of preventing menu close because menu listens for a body click to close.
I don't think body click is reliable because stopping propagation is so common.
I can think of two alternatives:
- Showing an invisible element behind the menu and in front of the body to intercept all clicks (side effect is that body is completely non-responsive)
- Hiding on blur (side effect is that menus would close more often - like on switching tabs/apps)
I tried to add an invisible layer as a child of Menu
but it only accepts a single MenuList
so I am now adding the layer via portal. Before I go too far along this route, I want to know if this is a problem that should be solved in this library. How do other components (Dialog/Drawer) handle click away?
After a little research, I see suggestions to cancel event handlers with preventDefault instead of stopPropagation. This allows bubbling but allows handlers to ignore events by checking defaultPrevented
.
If ripple ignored events with defaultPrevented
this would solve my use case. Is this consistent though? Why should a ripple ignore defaultPrevented
but a menu click away handler doesn't...?
I solved this in my case by attaching mousedown listeners on body
. These get called before the react event listeners (attached to document
) and let me close the menu before the event propagation is stopped in the react listeners.