JeremieLeblanc
JeremieLeblanc

Reputation: 21

How to close both nested Material-ui popovers on button click or click away

I have nested popovers from Material-ui to create a menu with sub-menus. When I click one of the menu options I would like all of the popovers to close. Similarly, I would like all of the popovers to close on click away instead of having to click away multiple times to close them one at a time.

This would be a little simpler if I kept all of the code within one component, but I need to be able to reuse this code, so I prefer to keep it separated like it currently is. I have tried to change the handle functions to the parent component to no avail.

I have created a CodeSanbox example of my code: https://codesandbox.io/embed/friendly-sunset-dznur

I'm not sure how to make the popovers close when I click a menu item, but at the very least I would expect both popovers to close on click away.

Upvotes: 2

Views: 3158

Answers (1)

alvinsj
alvinsj

Reputation: 875

I had a quick try here: https://codesandbox.io/s/nostalgic-davinci-fd61v.

I would think you are trying to achieve:

  1. Composition with the menus, e.g. DropdownMenu > SideMenu > MenuItem.
  2. Making it reusable and clean APIs.

The below approach would be something I would try:

Example 1: Inject props to children

const childrenWithNewProps = React.Children.map(props.children, child =>
  React.cloneElement(child, { onClose: handleClose })
);

Alternatively, a less pretty solution will be making the children as function, e.g. children({onClose}), but this will make the onClose explicit and repetitive.

Example 2: children as function

// children({onClose})
<DropdownMenu>
  {({onClose}) => {
    return <Fragment>
      <SideMenu onClose={onClose}>
        <MenuItem onClose={onClose}/>
        <MenuItem onClose={onClose}/>
      </SideMenu>
    </Fragment>
  }}
</DropdownMenu>

Upvotes: 1

Related Questions