In this article, we will learn how to show an active menu item in the MUI sidebar in React.
Now, let’s first create a React application with the following command.
- npx create-react-app materialUI-sidebar
Now install material-ui using the following command.
- npm install @mui/material @emotion/react @emotion/styled
- npm install @mui/material @mui/styled-engine-sc styled-components
- npm install @mui/icons-material
First, we will use the material ui sidebar to create a dashboard page.
let’s create a file called sideBar.js
in our project.
Active menu item logic is :
const sidebarImage = [ { image: '/assets/images/scanner.png', images: '/assets/images/vector.png' }, { image: '/assets/images/event.png', images: '/assets/images/event1.png' }, { image: '/assets/images/course.png', images: '/assets/images/course1.png' }, ] function App(props) { const [image, setImage] = React.useState(null) const [isActive, setIsActive] = React.useState(); const handleClickAdd = (id) => { setIsActive(id) } const drawer = ( <div> <Toolbar /> <Divider /> <List className='sideMenu'> {['Home', 'About', 'Contact'].map((text, index) => ( <ListItem key={text} component={Link} to={"/" + text} onClick={() => handleClickAdd(index)} onMouseEnter={() => setImage(index)} onMouseLeave={() => setImage(true)} disablePadding > <ListItemButton className={isActive == index ? 'active sidebarMenu' : 'black sidebarMenu'}> <ListItemIcon className='sideIcon'> {sidebarImage.map((e, sub_index) => { return ( <> <div> {(index === sub_index) ? <img src={(isActive === index ? e.images : (index !== image ? e.image : e.images))} /> : null} </div> </> ) })} </ListItemIcon> <ListItemText><div className='sideText'>{text}</div></ListItemText> </ListItemButton> </ListItem> ))} </List> </div> ); }
Now let’s create three web pages called Home.js, About.js, and Contact.js.
Filename: Home.js
import React from "react"; const Home= () => { return ( <> <div className="support"> <h1>Home</h1> </div> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p> </> ); }; export default Home;
Filename: About.js
import React from "react"; export const About = () => { return ( <> <div className="support"> <h1>About Us</h1> </div> <p> when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </p> </> ); };
Filename: Contact.js
import React from "react"; const Contact = () => { return ( <> <div className="support"> <h1>Contact us</h1> </div> <p> printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </p> </> ); }; export default Contact;
My sideBar.js
page look like this :
import * as React from 'react'; import PropTypes from 'prop-types'; import AppBar from '@mui/material/AppBar'; import Box from '@mui/material/Box'; import CssBaseline from '@mui/material/CssBaseline'; import Divider from '@mui/material/Divider'; import Drawer from '@mui/material/Drawer'; import IconButton from '@mui/material/IconButton'; import List from '@mui/material/List'; import ListItem from '@mui/material/ListItem'; import ListItemButton from '@mui/material/ListItemButton'; import ListItemIcon from '@mui/material/ListItemIcon'; import ListItemText from '@mui/material/ListItemText'; import MenuIcon from '@mui/icons-material/Menu'; import Toolbar from '@mui/material/Toolbar'; import Typography from '@mui/material/Typography'; import { Link, Outlet } from 'react-router-dom'; const drawerWidth = 240; const sidebarImage = [ { image: '/assets/images/scanner.png', images: '/assets/images/vector.png' }, { image: '/assets/images/event.png', images: '/assets/images/event1.png' }, { image: '/assets/images/course.png', images: '/assets/images/course1.png' }, ] function Sidebar(props) { const { window } = props; const [mobileOpen, setMobileOpen] = React.useState(false); const handleDrawerToggle = () => { setMobileOpen(!mobileOpen); }; const [image, setImage] = React.useState(null) const [isActive, setIsActive] = React.useState(); const handleClickAdd = (id) => { setIsActive(id) } const drawer = ( <div> <Toolbar /> <Divider /> <List className='sideMenu'> {['Home', 'About', 'Contact'].map((text, index) => ( <ListItem key={text} component={Link} to={"/" + text} onClick={() => handleClickAdd(index)} onMouseEnter={() => setImage(index)} onMouseLeave={() => setImage(true)} disablePadding > <ListItemButton className={isActive == index ? 'active sidebarMenu' : 'black sidebarMenu'}> <ListItemIcon className='sideIcon'> {sidebarImage.map((e, sub_index) => { return ( <> <div> {(index === sub_index) ? <img src={(isActive === index ? e.images : (index !== image ? e.image : e.images))} /> : null} </div> </> ) })} </ListItemIcon> <ListItemText><div className='sideText'>{text}</div></ListItemText> </ListItemButton> </ListItem> ))} </List> </div> ); const container = window !== undefined ? () => window().document.body : undefined; return ( <Box sx={{ display: 'flex' }}> <CssBaseline /> <AppBar position="fixed" sx={{ width: { sm: `calc(100% - ${drawerWidth}px)` }, ml: { sm: `${drawerWidth}px` }, }} > <Toolbar> <IconButton color="inherit" aria-label="open drawer" edge="start" onClick={handleDrawerToggle} sx={{ mr: 2, display: { sm: 'none' } }} > <MenuIcon /> </IconButton> <Typography variant="h6" noWrap component="div"> Responsive drawer </Typography> </Toolbar> </AppBar> <Box component="nav" sx={{ width: { sm: drawerWidth }, flexShrink: { sm: 0 } }} aria-label="mailbox folders"> <Drawer container={container} variant="temporary" open={mobileOpen} onClose={handleDrawerToggle} ModalProps={{ keepMounted: true }} sx={{ display: { xs: 'block', sm: 'none' }, '& .MuiDrawer-paper': { boxSizing: 'border-box', width: drawerWidth } }} > {drawer} </Drawer> <Drawer variant="permanent" sx={{ display: { xs: 'none', sm: 'block' }, '& .MuiDrawer-paper': { boxSizing: 'border-box', width: drawerWidth } }} open > {drawer} </Drawer> </Box> <Box component="main" sx={{ flexGrow: 1, p: 3, width: { sm: `calc(100% - ${drawerWidth}px)` } }}> <Toolbar /> <Outlet /> </Box> </Box> ); } Demo.propTypes = { window: PropTypes.func, }; export default Sidebar;
My app.css page look like this:
.active { background-color: #333340 !important; color: #ffffff !important; border-radius: 12px !important; } .black { color: #00000080 !important; } .sidebarMenu:hover .sideText { color: #ffffff !important; } .sidebarMenu { margin: 5px 0 !important; border-radius: 12px !important; transition: 3s; } .sidebarMenu:hover { margin: 5px 0 !important; background-color: #333340 !important; color: #ffffff !important; border-radius: 12px !important; } .sidebarMenu:hover .sideText { color: #ffffff !important; } .support { text-align: center !important; }
Output: