Skip to content
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

Reposition the Menu on initial opening. #133

Open
Shemrock3267 opened this issue Apr 9, 2024 · 6 comments
Open

Reposition the Menu on initial opening. #133

Shemrock3267 opened this issue Apr 9, 2024 · 6 comments

Comments

@Shemrock3267
Copy link

I had an issue with custom Chip component from @mui/material in conjunction with Menu & MenuItem.
Used your demo and it worked almost fine.
Issue is that on initial opening it was slightly to the right, while if I open it for the second time it positioned well.

Screenshots:
Initial click
Screenshot 2024-04-09 at 10 40 56
Second click
Screenshot 2024-04-09 at 10 41 05

I managed to fix it via useEffect:

const popupState = usePopupState({ variant: 'popover', popupId: 'profilePopup' });
const ref = useRef<HTMLDivElement>(null);

useEffect(() => {
  // Reposition the menu when it opens for the first time
  if (popupState.isOpen) {
    popupState.setAnchorEl(ref.current);
  }
}, [popupState, popupState.isOpen]);  

Maybe you should add something like this into the library.
Cheers

@Shemrock3267
Copy link
Author

UPDATE
This fix introduces another issue:

Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.

Not sure how to fix it.

@jedwards1211
Copy link
Member

I think this will be hard to debug without seeing exactly what's happening. Do you think you could add a component that reproduces this issue to the demo app in a fork of this repo? Then i could investigate

@prma85
Copy link

prma85 commented May 10, 2024

I had the same problem, and my fix was to add the binding to the item above that had both the menu and the chip instead of just the menu.
I hope this helps

 <Box>
      <Link
        key={title}
        href={path}
        {...bindHover(popupState)}
        {...bindFocus(popupState)}
        className={active ? 'active' : ''}
      >
        <ListItemText>
          {title} {hasSubMenu && <ChevronDown viewBox='0 0 18 18' fontSize='inherit' />}
        </ListItemText>
        {hasSubMenu && <ArrowBox>
        <Fade in={popupState.isOpen} timeout={500} appear={true}>
          {<Arrow component='span' className='arrow' />}
        </Fade>
        </ArrowBox>}
      </Link>
      {hasSubMenu && (
        <>
          <CascadingMenu
            popupState={popupState}
            anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
            transformOrigin={{ vertical: 'top', horizontal: 'center' }}
            open
          >
            {items.map((item) =>
              item.items && item.items.length > 0 ? (
                <CascadingSubmenu
                  key={cleanString(item.title + 'cascading-menu')}
                  popupId={cleanString(item.title + 'cascading-menu')}
                  title={item.title}
                  TransitionComponent={Fade}
                  transitionDuration={500}
                  open
                >
                  {item.items.map((subItem) => (
                    <CascadingMenuItem key={cleanString(subItem.title)} href={subItem.path}>
                      <ListItemText primary={subItem.title} />
                    </CascadingMenuItem>
                  ))}
                </CascadingSubmenu>
              ) : (
                <CascadingMenuItem key={`${item.title}-${item.path}`}>
                  <ListItemText primary={item.title} />
                </CascadingMenuItem>
              )
            )}
          </CascadingMenu>
        </>
      )}
    </Box>

@jedwards1211
Copy link
Member

@prma85 can you share what your CascadingMenu and CascadingSubmenu implementations are?

@prma85
Copy link

prma85 commented May 11, 2024

@prma85 can you share what your CascadingMenu and CascadingSubmenu implementations are?

It is the same illustrated here https://jcoreio.github.io/material-ui-popup-state/#cascading-hover-menus

@Shemrock3267
Copy link
Author

I had the same problem, and my fix was to add the binding to the item above that had both the menu and the chip instead of just the menu. I hope this helps

 <Box>
      <Link
        key={title}
        href={path}
        {...bindHover(popupState)}
        {...bindFocus(popupState)}
        className={active ? 'active' : ''}
      >
        <ListItemText>
          {title} {hasSubMenu && <ChevronDown viewBox='0 0 18 18' fontSize='inherit' />}
        </ListItemText>
        {hasSubMenu && <ArrowBox>
        <Fade in={popupState.isOpen} timeout={500} appear={true}>
          {<Arrow component='span' className='arrow' />}
        </Fade>
        </ArrowBox>}
      </Link>
      {hasSubMenu && (
        <>
          <CascadingMenu
            popupState={popupState}
            anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
            transformOrigin={{ vertical: 'top', horizontal: 'center' }}
            open
          >
            {items.map((item) =>
              item.items && item.items.length > 0 ? (
                <CascadingSubmenu
                  key={cleanString(item.title + 'cascading-menu')}
                  popupId={cleanString(item.title + 'cascading-menu')}
                  title={item.title}
                  TransitionComponent={Fade}
                  transitionDuration={500}
                  open
                >
                  {item.items.map((subItem) => (
                    <CascadingMenuItem key={cleanString(subItem.title)} href={subItem.path}>
                      <ListItemText primary={subItem.title} />
                    </CascadingMenuItem>
                  ))}
                </CascadingSubmenu>
              ) : (
                <CascadingMenuItem key={`${item.title}-${item.path}`}>
                  <ListItemText primary={item.title} />
                </CascadingMenuItem>
              )
            )}
          </CascadingMenu>
        </>
      )}
    </Box>

From the looks of it that should work. Thanks for help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants