How to create a Responsive Sidebar with dropdown menu in React JS?
A sidebar is an important element of a website’s design since it allows users to quickly visit any section within a site.
Preview of final output:
Prerequisite:
Approach to Create Responsive Sidebar with Dropdown :
- Create a navigation bar with a hamburger menu with items routed to different pages using react-router-dom.
- Use icons from the react-icons for the menu and dropdown.
- Use styled components to create components with custom css and styles.
Steps to Create React Application:
Step 1: Initialize the react app using this command in the terminal.
npx create-react-app react-sidebar-dropdown
Step 2: Move to the project directory.
cd react-sidebar-dropdown
Step 3: Install the dependencies required in this project by typing the given command in the terminal.
npm i react-router-dom --save styled-components --save react-icons
Project Structure:
The updated dependencies in package.json file.
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.12.0",
"react-router-dom": "^6.20.0",
"react-scripts": "5.0.1",
"styled-components": "^6.1.1",
"web-vitals": "^2.1.4"
}
Example: This example demostrates how to create a responsive sidebar menu using the react-router-dom and styled-components package.
Javascript
// Filename - App.js import "./App.css" ; import Sidebar from "./components/Sidebar" ; import { BrowserRouter as Router, Routes, Route, } from "react-router-dom" ; import { AboutUs, OurAim, OurVision, } from "./pages/AboutUs" ; import { Services, ServicesOne, ServicesTwo, ServicesThree, } from "./pages/Services" ; import { Events, EventsOne, EventsTwo, } from "./pages/Events" ; import Contact from "./pages/ContactUs" ; import Support from "./pages/Support" ; function App() { return ( <Router> <Sidebar /> <Routes> <Route path= "/about-us" element={<AboutUs />} /> <Route path= "/about-us/aim" element={<OurAim />} /> <Route path= "/about-us/vision" element={<OurVision />} /> <Route path= "/services" element={<Services />} /> <Route path= "/services/services1" element={<ServicesOne />} /> <Route path= "/services/services2" element={<ServicesTwo />} /> <Route path= "/services/services3" element={<ServicesThree />} /> <Route path= "/contact" element={<Contact />} /> <Route path= "/events" element={<Events />} /> <Route path= "/events/events1" element={<EventsOne />} /> <Route path= "/events/events2" element={<EventsTwo />} /> <Route path= "/support" element={<Support />} /> </Routes> </Router> ); } export default App; |
Javascript
// Filename - components/Sidebar.js import React, { useState } from "react" ; import styled from "styled-components" ; import { Link } from "react-router-dom" ; import * as FaIcons from "react-icons/fa" ; import * as AiIcons from "react-icons/ai" ; import { SidebarData } from "./SidebarData" ; import SubMenu from "./SubMenu" ; import { IconContext } from "react-icons/lib" ; const Nav = styled.div` background: #15171c; height: 80px; display: flex; justify-content: flex-start; align-items: center; `; const NavIcon = styled(Link)` margin-left: 2rem; font-size: 2rem; height: 80px; display: flex; justify-content: flex-start; align-items: center; `; const SidebarNav = styled.nav` background: #15171c; width: 250px; height: 100vh; display: flex; justify-content: center; position: fixed; top: 0; left: ${({ sidebar }) => (sidebar ? "0" : "-100%" )}; transition: 350ms; z-index: 10; `; const SidebarWrap = styled.div` width: 100%; `; const Sidebar = () => { const [sidebar, setSidebar] = useState( false ); const showSidebar = () => setSidebar(!sidebar); return ( <> <IconContext.Provider value={{ color: "#fff" }}> <Nav> <NavIcon to= "#" > <FaIcons.FaBars onClick={showSidebar} /> </NavIcon> <h1 style={{ textAlign: "center" , marginLeft: "200px" , color: "green" , }} > w3wiki </h1> </Nav> <SidebarNav sidebar={sidebar}> <SidebarWrap> <NavIcon to= "#" > <AiIcons.AiOutlineClose onClick={showSidebar} /> </NavIcon> {SidebarData.map((item, index) => { return ( <SubMenu item={item} key={index} /> ); })} </SidebarWrap> </SidebarNav> </IconContext.Provider> </> ); }; export default Sidebar; |
Javascript
// Filename - components/SidebarData.js import React from "react" ; import * as FaIcons from "react-icons/fa" ; import * as AiIcons from "react-icons/ai" ; import * as IoIcons from "react-icons/io" ; import * as RiIcons from "react-icons/ri" ; export const SidebarData = [ { title: "About Us" , path: "/about-us" , icon: <AiIcons.AiFillHome />, iconClosed: <RiIcons.RiArrowDownSFill />, iconOpened: <RiIcons.RiArrowUpSFill />, subNav: [ { title: "Our Aim" , path: "/about-us/aim" , icon: <IoIcons.IoIosPaper />, }, { title: "Our Vision" , path: "/about-us/vision" , icon: <IoIcons.IoIosPaper />, }, ], }, { title: "Services" , path: "/services" , icon: <IoIcons.IoIosPaper />, iconClosed: <RiIcons.RiArrowDownSFill />, iconOpened: <RiIcons.RiArrowUpSFill />, subNav: [ { title: "Service 1" , path: "/services/services1" , icon: <IoIcons.IoIosPaper />, cName: "sub-nav" , }, { title: "Service 2" , path: "/services/services2" , icon: <IoIcons.IoIosPaper />, cName: "sub-nav" , }, { title: "Service 3" , path: "/services/services3" , icon: <IoIcons.IoIosPaper />, }, ], }, { title: "Contact" , path: "/contact" , icon: <FaIcons.FaPhone />, }, { title: "Events" , path: "/events" , icon: <FaIcons.FaEnvelopeOpenText />, iconClosed: <RiIcons.RiArrowDownSFill />, iconOpened: <RiIcons.RiArrowUpSFill />, subNav: [ { title: "Event 1" , path: "/events/events1" , icon: <IoIcons.IoIosPaper />, }, { title: "Event 2" , path: "/events/events2" , icon: <IoIcons.IoIosPaper />, }, ], }, { title: "Support" , path: "/support" , icon: <IoIcons.IoMdHelpCircle />, }, ]; |
Javascript
// Filename - components/SubMenu.js import React, { useState } from "react" ; import { Link } from "react-router-dom" ; import styled from "styled-components" ; const SidebarLink = styled(Link)` display: flex; color: #e1e9fc; justify-content: space-between; align-items: center; padding: 20px; list-style: none; height: 60px; text-decoration: none; font-size: 18px; &:hover { background: #252831; border-left: 4px solid green; cursor: pointer; } `; const SidebarLabel = styled.span` margin-left: 16px; `; const DropdownLink = styled(Link)` background: #252831; height: 60px; padding-left: 3rem; display: flex; align-items: center; text-decoration: none; color: #f5f5f5; font-size: 18px; &:hover { background: green; cursor: pointer; } `; const SubMenu = ({ item }) => { const [subnav, setSubnav] = useState( false ); const showSubnav = () => setSubnav(!subnav); return ( <> <SidebarLink to={item.path} onClick={item.subNav && showSubnav} > <div> {item.icon} <SidebarLabel> {item.title} </SidebarLabel> </div> <div> {item.subNav && subnav ? item.iconOpened : item.subNav ? item.iconClosed : null } </div> </SidebarLink> {subnav && item.subNav.map((item, index) => { return ( <DropdownLink to={item.path} key={index} > {item.icon} <SidebarLabel> {item.title} </SidebarLabel> </DropdownLink> ); })} </> ); }; export default SubMenu; |
Javascript
// Filename - pages/AboutUs.js import React from "react" ; export const AboutUs = () => { return ( <div className= "home" > <h1>w3wiki About us</h1> </div> ); }; export const OurAim = () => { return ( <div className= "home" > <h1>w3wiki Aim</h1> </div> ); }; export const OurVision = () => { return ( <div className= "home" > <h1>w3wiki Vision</h1> </div> ); }; |
Javascript
// Filename - pages/ContactUs.js import React from "react" ; const Contact = () => { return ( <div className= "contact" > <h1>w3wiki Contact us</h1> </div> ); }; export default Contact; |
Javascript
// Filename - pages/Events.js import React from "react" ; export const Events = () => { return ( <div className= "events" > <h1>w3wiki Events</h1> </div> ); }; export const EventsOne = () => { return ( <div className= "events" > <h1>w3wiki Event1</h1> </div> ); }; export const EventsTwo = () => { return ( <div className= "events" > <h1>w3wiki Event2</h1> </div> ); }; |
Javascript
// Filename - pages/Support.js import React from "react" ; const Support = () => { return ( <div className= "support" > <h1>w3wiki Support us</h1> </div> ); }; export default Support; |
Javascript
// Filename - pages/Services.js import React from "react" ; export const Services = () => { return ( <div className= "services" > <h1>w3wiki Services</h1> </div> ); }; export const ServicesOne = () => { return ( <div className= "services" > <h1>w3wiki Service1</h1> </div> ); }; export const ServicesTwo = () => { return ( <div className= "services" > <h1>w3wiki Service2</h1> </div> ); }; export const ServicesThree = () => { return ( <div className= "services" > <h1>w3wiki Service3</h1> </div> ); }; |
CSS
/* Filename: App.css */ * { box-sizing: border-box; margin : 0 ; padding : 0 ; } .home, .services, .reports, .contact, .events, .support { display : flex; margin-left : 260px ; font-size : 2 rem; } |
Steps to Run the Project: Save all files and start the server by using the below command in your PowerShell terminal or IDE’s terminal.
npm start
Output: This output will be visible on the http://localhost:3000/ on the browser window.
Contact Us