Material-UI: Positioning top Drawer under top App bar

Viewed 461

I would like to place a top drawer under my top app bar for navigation purposes. According to the API documentation Drawer has all the properties of the Modal component, when variant="temporary". The property "disablePortal" should lead to the desired behaviour, but it doesn't work:

The children will be under the DOM hierarchy of the parent component.

What I tried so far:

  • set disablePortal in Drawer
  • set disablePortal via ModalProps property of the Drawer
  • creat a ref and set container property of the Drawer with the current value of it

What I do not want:

  • Use Accordion in top app bar, as I think this is not the right solution
  • Tweak z-indexes
  • Use some height hacks (position drawer with the height value of top app bar)

https://mui.com/material-ui/api/drawer/

Minimal working example:

https://codesandbox.io/s/stupefied-cache-7y6qmv

import { AppBar, Box, Drawer, IconButton, Toolbar } from "@mui/material";
import MenuIcon from "@mui/icons-material/Menu";
import { useState } from "react";

export default function App() {
  const [showNavigation, setShowNavigation] = useState(false);
  return (
    <Box>
      <AppBar position="static">
        <Toolbar>
          <IconButton
            size="large"
            edge="start"
            aria-label="menu"
            onClick={() => setShowNavigation((prev) => !prev)}
          >
            <MenuIcon />
          </IconButton>
        </Toolbar>
      </AppBar>
      <Drawer
        anchor="top"
        open={showNavigation}
        onClose={() => setShowNavigation(false)}
        disablePortal
      >
        Test
      </Drawer>
    </Box>
  );
}
1 Answers

I tried this out and it worked:

import { AppBar, Box, Drawer, IconButton, Toolbar } from "@mui/material";
import MenuIcon from "@mui/icons-material/Menu";
import { makeStyles } from "@mui/styles";
import { useState } from "react";

const useStyles = makeStyles({
  root: {
    position: "relative !important",
    "& .MuiBackdrop-root": {
      position: "relative !important",
      height: "100vh"
    }
  },
  paper: {
    position: "absolute !important"
  }
});

export default function App() {
  const [showNavigation, setShowNavigation] = useState(false);
  const classes = useStyles();
  return (
    <Box>
      <AppBar position="static">
        <Toolbar>
          <IconButton
            size="large"
            edge="start"
            aria-label="menu"
            onClick={() => setShowNavigation((prev) => !prev)}
          >
            <MenuIcon />
          </IconButton>
        </Toolbar>
      </AppBar>
      <Drawer
        anchor="top"
        open={showNavigation}
        onClose={() => setShowNavigation(false)}
        disablePortal
        classes={{
          paper: classes.paper,
          root: classes.root,
        }}
      >
        Test
      </Drawer>
    </Box>
  );
}

Sandbox demo: https://codesandbox.io/s/mui-top-drawer-disableportal-bug-forked-ic8ql9?file=/src/App.js

Related