0

This post shows how to orient a Menu (popover) below it's parent item using anchorEl. However I would like to know if there's an easy way to offset the menu to exactly below the appbar while maintaining horizontal alignment to the parent button.

Current:

achorEl positioning

Desired:

desired Positioning

Sandbox

joshp
  • 706
  • 5
  • 22
  • It is definitely possible with pure CSS, though depends on your element hierarchy. I.e. if the menu is positioned absolute or relative and the parent(or in this case, I'm guessing the app bar) has a defined 'position' property. Then you you can move the menu either without affecting you layout by declaring 'bottom : - 100%', or 'transform: translate' by an equal, positive amount.. Both move the element by its own exact size only in different directions... the crusial part is to have set a position property on the parent elements. and if you wish to alter the layout use the margin or padding – zergski Feb 24 '21 at 02:56

1 Answers1

0

Well, I'm not sure it's the best solution, but I ended up having to modify the JSX element tree, creating a styled wrapper div:

const appBarHeightCSS = css`
  min-height: 56px;
  @media (min-width: 0px) and (orientation: landscape) {
    min-height: 48px;
  }
  @media (min-width: 600px) {
    min-height: 64px;
  }
`;

const StyledButtonContainerDiv = styled.div`
  ${appBarHeightCSS}
  display: flex;
  justify-content: center;
  align-items: center;
  color: ${theme.palette.grey['400']};
`;

and passing the div element via ref

const accountButtonDiv = React.useRef<HTMLDivElement | null>();

...

<StyledButtonContainerDiv ref={accountButtonDiv}>
  <ToolbarButton
    anchorRef={accountButtonDiv}
    Menu={AccountMenu}
    aria-label="account of current user"
    aria-controls="primary-search-account-menu"
    aria-haspopup="true"
   >
     <AccountCircle />
</ToolbarButton>

...

to the custom ToolbarButton component

export default function ToolbarButton(props): JSX.Element {
  const { anchorRef, Menu, badgeContent, children, ...defaultProps } = props;

  const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);

  const handleMenuOpen = () => {
    setAnchorEl(anchorRef.current);
  };

  return (
    <>
      <IconButton {...defaultProps} onClick={handleMenuOpen} color="inherit">
        <Badge badgeContent={badgeContent} color="secondary">
          {children}
        </Badge>
      </IconButton>
      <Menu anchorEl={anchorEl} setAnchorEl={setAnchorEl} />
    </>
  );
}
joshp
  • 706
  • 5
  • 22