Currently, I am working on developing a responsive drawer in React using mui v5. In the set-up, the minimum width of the drawer is defined as 600px when it expands to full width. However, an issue arises when the screen exceeds 600px - at this point, the drawer's width decreases to 240px.
The problem occurs when the screen is larger than 600px: when the drawer is open, the page's scrollbar disappears, rendering the page unscrollable. Conversely, when the drawer is closed, the scrollbar reappears, allowing for scrolling.
To address this concern, the objective is to ensure that the scrollbar remains visible even when the drawer is opened.
Everything operates smoothly when the width is equal to or less than 600px.
To explore the code sandbox, visit this link: code sandbox
const drawerWidth = 240;
const transitionDuration = 1000; //alternative: can also leverage theme.transitions.duration
const useStyles = makeStyles(() => {
return {
menuButton: {
marginRight: (theme) => theme.spacing(2)
},
hide: {
display: "none"
},
appBar: {
zIndex: (theme) => `${theme.zIndex.drawer + 1} !important`
},
drawer: {
width: (theme) => theme.drawerWidth,
"& .MuiBackdrop-root": {
display: "none"
}
},
drawerPaper: {
width: (theme) => theme.drawerWidth,
backgroundColor: "rgba(120, 120, 120, 0.2)"
},
content: {
padding: (theme) => theme.spacing(3),
transition: (theme) =>
theme.transitions.create("margin", {
easing: theme.transitions.easing.easeOut,
duration: transitionDuration
}),
minWidth: (theme) => theme.drawerWidth,
marginLeft: (theme) => 0
},
contentShift: {
transition: (theme) =>
theme.transitions.create("margin", {
easing: theme.transitions.easing.easeOut,
duration: transitionDuration
}),
minWidth: (theme) => theme.drawerWidth,
marginLeft: (theme) => theme.drawerWidth
}
};
});
export default function App() {
const theme = useTheme();
const greaterThan375 = useMediaQuery("(min-width:600px)");
theme.drawerWidth = greaterThan375 ? drawerWidth : "100%";
const classes = useStyles(theme);
const [open, setOpen] = React.useState(greaterThan375);
useEffect(() => {
setOpen(greaterThan375);
}, [greaterThan375]);
const handleMenuClick = () => {
setOpen(!open);
};
return (
<div>
{/*fixed is default */}
<AppBar position="fixed" className={classes.appBar}>
<Toolbar>
<IconButton //hide on desktop
color="inherit"
onClick={handleMenuClick}
edge="start"
className={clsx(classes.menuButton, greaterThan375 && classes.hide)}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" noWrap>
Responsive Drawer
</Typography>
</Toolbar>
</AppBar>
<Drawer
//add full width for responsive
className={classes.drawer}
variant="temporary"
//elevation={3} only works with variant="temporary"
open={open}
transitionDuration={{
enter: transitionDuration,
exit: transitionDuration
}}
classes={{
paper: classes.drawerPaper
}}
PaperProps={{ elevation: 9 }}
>
<Toolbar />
<div>
<List>
{["Home", "Page 1", "Page 2", "Page 3"].map((text, index) => (
<ListItem button key={text}>
<ListItemIcon>
<AppsIcon />
</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
</div>
</Drawer>
<main className={clsx(classes.content, { [classes.contentShift]: open })}>
<Toolbar />
<Typography>
Dummy text for demonstration purposes.
</Typography>
</main>
</div>
);
}