Material UI is a Material Design library made for React.
It’s a set of React components that have Material Design styles.
In this article, we’ll look at how to add drawers to Material UI.
Responsive Drawer
We can make a responsive drawer by adding some media queries to show and hide the drawer.
For example, we can write:
import React from "react";
import PropTypes from "prop-types";
import AppBar from "@material-ui/core/AppBar";
import CssBaseline from "@material-ui/core/CssBaseline";
import Divider from "@material-ui/core/Divider";
import Drawer from "@material-ui/core/Drawer";
import Hidden from "@material-ui/core/Hidden";
import IconButton from "@material-ui/core/IconButton";
import InboxIcon from "@material-ui/icons/MoveToInbox";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import ListItemText from "@material-ui/core/ListItemText";
import MailIcon from "@material-ui/icons/Mail";
import MenuIcon from "@material-ui/icons/Menu";
import Toolbar from "@material-ui/core/Toolbar";
import Typography from "@material-ui/core/Typography";
import { makeStyles, useTheme } from "@material-ui/core/styles";
const drawerWidth = 240;
const useStyles = makeStyles(theme => ({
root: {
display: "flex"
},
drawer: {
[theme.breakpoints.up("sm")]: {
width: drawerWidth,
flexShrink: 0
}
},
appBar: {
[theme.breakpoints.up("sm")]: {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: drawerWidth
}
},
menuButton: {
marginRight: theme.spacing(2),
[theme.breakpoints.up("sm")]: {
display: "none"
}
},
toolbar: theme.mixins.toolbar,
drawerPaper: {
width: drawerWidth
},
content: {
flexGrow: 1,
padding: theme.spacing(3)
}
}));
export default function App(props) {
const { window } = props;
const classes = useStyles();
const theme = useTheme();
const [mobileOpen, setMobileOpen] = React.useState(false);
const handleDrawerToggle = () => {
setMobileOpen(!mobileOpen);
};
const drawer = (
<div>
<div className={classes.toolbar} />
<List>
<ListItem button key="home">
<ListItemIcon>
<MailIcon />
</ListItemIcon>
<ListItemText primary="home" />
</ListItem>
</List>
</div>
);
const container =
window !== undefined ? () => window().document.body : undefined;
return (
<div className={classes.root}>
<CssBaseline />
<AppBar position="fixed" className={classes.appBar}>
<Toolbar>
<IconButton
color="inherit"
edge="start"
onClick={handleDrawerToggle}
className={classes.menuButton}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" noWrap>
Responsive drawer
</Typography>
</Toolbar>
</AppBar>
<nav className={classes.drawer}>
<Hidden smUp implementation="css">
<Drawer
container={container}
variant="temporary"
open={mobileOpen}
onClose={handleDrawerToggle}
classes={{
paper: classes.drawerPaper
}}
ModalProps={{
keepMounted: true
}}
>
{drawer}
</Drawer>
</Hidden>
<Hidden xsDown implementation="css">
<Drawer
classes={{
paper: classes.drawerPaper
}}
variant="permanent"
open
>
{drawer}
</Drawer>
</Hidden>
</nav>
<main className={classes.content}>
<div className={classes.toolbar} />
<Typography paragraph>Lorem ipsum dolor sit amet</Typography>
<Typography paragraph>
Consequat mauris nunc congue nisi vitae suscipit.
</Typography>
</main>
</div>
);
}
We use the Hidden
component to display items with the given breakpoints.
We keep the drawer always open if the screen meets the breakpoint sm
or up.
Otherwise, we show a menu with a button to open the drawer.
The main content is in the main
element.
AppBar
has the top bar which is always shown.
We have the mobileOpen
state to track the open state.
It’s set as the value of the open
prop.
Persistent Drawer
We can add a persistent drawer to show always show a button to open the drawer.
For example, we can write:
import React from "react";
import clsx from "clsx";
import { makeStyles, useTheme } from "@material-ui/core/styles";
import Drawer from "@material-ui/core/Drawer";
import CssBaseline from "@material-ui/core/CssBaseline";
import AppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar";
import List from "@material-ui/core/List";
import Typography from "@material-ui/core/Typography";
import Divider from "@material-ui/core/Divider";
import IconButton from "@material-ui/core/IconButton";
import MenuIcon from "@material-ui/icons/Menu";
import ChevronLeftIcon from "@material-ui/icons/ChevronLeft";
import ChevronRightIcon from "@material-ui/icons/ChevronRight";
import ListItem from "@material-ui/core/ListItem";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import ListItemText from "@material-ui/core/ListItemText";
import InboxIcon from "@material-ui/icons/MoveToInbox";
import MailIcon from "@material-ui/icons/Mail";
export default function App() {
const [open, setOpen] = React.useState(false);
const handleDrawerOpen = () => {
setOpen(true);
};
const handleDrawerClose = () => {
setOpen(false);
};
return (
<div>
<CssBaseline />
<AppBar position="fixed">
<Toolbar>
<IconButton color="inherit" onClick={handleDrawerOpen} edge="start">
<MenuIcon />
</IconButton>
<Typography variant="h6" noWrap>
Persistent drawer
</Typography>
</Toolbar>
</AppBar>
<Drawer variant="persistent" anchor="left" open={open}>
<List>
<ListItem button key="home">
<ListItemIcon>
<MailIcon />
</ListItemIcon>
<ListItemText primary="home" />
</ListItem>
<ListItem button key="close" onClick={handleDrawerClose}>
<ListItemText primary="close" />
</ListItem>
</List>
</Drawer>
<main style={{ marginTop: 50 }}>
<Typography paragraph>Lorem ipsum dolor sit amet</Typography>
<Typography paragraph>
Consequat mauris nunc congue nisi vitae suscipit
</Typography>
</main>
</div>
);
}
to create an app bar with a drawer that has the close button on the drawer.
We have the variant
set to persistent
to keep it always open unless we click close in the list item text.
The close button is at:
<ListItem button key="close" onClick={handleDrawerClose}>
<ListItemText primary="close" />
</ListItem>
Conclusion
We can create a drawers in various ways.
We can make the drawer responsive or persistent.