material-components-web-react icon indicating copy to clipboard operation
material-components-web-react copied to clipboard

Menu click away

Open liamcmitchell-sc opened this issue 4 years ago • 2 comments

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.

Menu click away 2019-07-23 15_54_45

I don't think body click is reliable because stopping propagation is so common.

I can think of two alternatives:

  1. 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)
  2. 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?

liamcmitchell-sc avatar Jul 23 '19 14:07 liamcmitchell-sc

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...?

liamcmitchell-sc avatar Jul 23 '19 15:07 liamcmitchell-sc

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.

liamcmitchell-sc avatar Nov 07 '19 14:11 liamcmitchell-sc