DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Michael Burrows
Michael Burrows

Posted on • Updated on • Originally published at w3collective.com

Build a React sidebar navigation component

In this tutorial we’ll be building a slide-out sidebar navigation component. Traditionally this type of navigation was implemented on mobile devices but it’s becoming common practice to use them on desktop devices.

Alt Text

We’ll be creating pages for each of the links in the navigation so you’ll also get an introduction to React Router if you haven’t already.

Let’s get started by setting up the project using the React Create App package:

npx react-create-app react-sidebar
Enter fullscreen mode Exit fullscreen mode

The only dependency required is React Router so let’s install that as well:

npm install react-router-dom
Enter fullscreen mode Exit fullscreen mode

Create a pages folder in the src directory with home.js, services.js, and contact.js files. These are just placeholder files so we can navigate between the pages in our navigation.

Inside each of the files we’ll render some simple content so we can see when the page has changed. Be sure to replace the function name and text in each file to correspond with the filename:

import React from "react";

function Home() {
  return (
    <div className="page">
      <h1>Home</h1>
      <p>This is the home page.</p>
    </div>
  );
}

export default Home;
Enter fullscreen mode Exit fullscreen mode

Next create a components folder in the src directory with a Sidebar.js and Sidebar.css file:

Inside Sidebar.js add the following imports:

import React, { useState } from "react";
import { Link } from "react-router-dom";
import "./Sidebar.css";
useState hook will be used to store the β€œactive” state of the navigation and Link is used to render the links.
Enter fullscreen mode Exit fullscreen mode

Next add a Sidebar() function as follows:

function Sidebar() {
  const [sidebar, setSidebar] = useState(false);
  const showSidebar = () => setSidebar(!sidebar);
  return (
    <nav className={sidebar ? "sidebar active" : "sidebar"}>
      <button className="hamburger" type="button" onClick={showSidebar}>
        <div></div>
      </button>
      <ul onClick={showSidebar}>
        <li><Link to="/">Home</Link></li>
        <li><Link to="/services">Services</Link></li>
        <li><Link to="/contact">Contact</Link></li>
      </ul>
    </nav>
  );
}
export default Sidebar;
Enter fullscreen mode Exit fullscreen mode

When the onClick is triggered we set the sidebar state to true which adds an active class. You’ll see later when CSS is applied that the active class shifts the position of the sidebar from offscreen to the left edge.

<Link> renders a fully accessible anchor tag which contains the URL that we'll route to the corresponding file in the pages folder.

With the sidebar component completed when can now load it into App.js and setup the routes, but first the imports:

import React from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import Home from "./pages/Home";
import Services from "./pages/Services";
import Contact from "./pages/Contact";
import Sidebar from "./components/Sidebar";
import "./App.css";
Enter fullscreen mode Exit fullscreen mode

Then edit the App() function as follows:

function App() {
  return (
    <>
      <Router>
        <Sidebar />
        <Switch>
          <Route path="/" exact component={Home} />
          <Route path="/services" component={Services} />
          <Route path="/contact" component={Contact} />
        </Switch>
      </Router>
    </>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

<Router> is the primary component of React Router that’s responsible for keeping the UI and the URL in sync. looks through all its children elements and renders the first one with a path matching the current URL.

That’s it for the JavaScript we can now add some CSS inside Sidebar.css.

First we’ll set the default position of the sidebar off-screen. Then when the active class is triggered it’s position changes to align on the left side of the browser. As the sidebar has a transition it’ll animate into position.

.sidebar {
  position: fixed;
  top: 0;
  left: -300px;
  width: 300px;
  height: 100%;
  background-color: peru;
  transition: left 300ms ease-out;
}
.sidebar.active {
  left: 0;
}
Enter fullscreen mode Exit fullscreen mode

Next some basic style for each of the links in the navigation:

.sidebar ul {
  margin: 0;
  padding: 0;
}
.sidebar li {
  list-style: none;
}
.sidebar li a {
  font-size: 18px;
  text-decoration: none;
  padding: 10px;
  display: block;
  color: #fff;
}
Enter fullscreen mode Exit fullscreen mode

A hamburger (menu) icon can be created with CSS:

.hamburger {
  border: none;
  outline: 0;
  width: 50px;
  position: absolute;
  right: -50px;
  background-color: peru;
}

.hamburger:after,
.hamburger:before,
.hamburger div {
  background-color: #fff;
  height: 5px;
  margin: 7px 0;
  border-radius: 3px;
  content: "";
  display: block;
  transition: all 300ms ease-in-out;
}
Enter fullscreen mode Exit fullscreen mode

Finally we can transform the hamburger icon into a cross icon when the sidebar is active:

.sidebar.active .hamburger:before {
  transform: translateY(12px) rotate(135deg);
}
.sidebar.active .hamburger::after {
  transform: translateY(-12px) rotate(-135deg);
}
.sidebar.active .hamburger div {
  transform: scale(0);
}
Enter fullscreen mode Exit fullscreen mode

This CSS hides the middle row of the hamburger icon and rotates the top (:before) and bottom (:after) rows to form a cross.

Top comments (1)

Collapse
 
onoshe profile image
Onoshe

Great job bro.
But is there a way you can push the page to the right(for full view of the page) when side bar is opened?

Become a Moderator Do you want us to help make DEV a better place?

Fill out this survey and help us by becoming a tag moderator here at DEV.