This Banner is For Sale !!
Get your ad here for a week in 20$ only and get upto 15k traffic Daily!!!

Build A Responsive Sidebar with React and Styled Components




Why does Sidebar / Navbar exist?

Navigation is essentially the most best strategy to undergo the web site. The navigation hyperlinks may be displayed both in Sidebar or Navbar. Each companies are broadly utilized by a lot of the web sites.



What is going to we be constructing?

On this article, we will probably be constructing a easy but responsive sidebar, step-by-step utilizing ReactJS, styled-components, and React Router DOM as our main dependencies. This sidebar will probably be absolutely responsive on all units, a demo of which is present here.

Professional: We can even be studying one of many folder constructions on this react app.



Stipulations

Earlier than diving into coding this element, you should be sure to have good data of:

  • HTML, CSS, JavaScript
  • ReactJS
  • Styled-components
  • React Router DOM

Furthermore, you additionally want have:

  • NodeJS (Steady model)
  • NPM and / or Yarn



Constructing the element

In Command Immediate, navigate to the listing the place you want to create the mission and kind:



1. Set up the React App

# With npm
npx create-react-app react-sidebar

# With yarn
yarn create react-app react-sidebar
Enter fullscreen mode

Exit fullscreen mode

the place react-sidebar is the mission listing identify. Now open this mission listing in your favourite code editor. I will probably be utilizing Visual Studio Code.

Now, preserve index.js, App.js and App.css and delete the opposite recordsdata / folders inside src folder. This can clear up a lot of the react app.

Inside public folder, preserve index.html file and delete all different recordsdata / folders.



2. Add the packages to the react app

Set up Materials UI Icons, React Router DOM, styled-components. Run the next command to get them put in on our react app:

# With npm
npm set up @mui/icons-materials @mui/materials @emotion/styled @emotion/react react-router-dom styled-parts

# With yarn
yarn add @mui/materials @emotion/react @emotion/styled react-router-dom styled-parts
Enter fullscreen mode

Exit fullscreen mode

Let’s join the entire app with react-router-dom in order that its features / parts can be utilized in all places. Change the code in src/index.js with the next:

// src/index.js
import React from "react";
import { BrowserRouter } from "react-router-dom";
import ReactDOM from "react-dom/shopper";
import App from "./App";

const root = ReactDOM.createRoot(doc.getElementById("root"));
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>
);
Enter fullscreen mode

Exit fullscreen mode

Before everything, we have to use react-router-dom to create hyperlinks to completely different pages inside our app. So, we have to join the entire app with its guardian element which is BrowserRouter. This can give us entry to make use of virtually all the parts, the mentioned package deal has to supply.

To take action, at first, we import the guardian element and wrap the App element contained in the guardian element. This App element covers our entire app and we will use React Router wherever inside our app.

Run the app in your browser utilizing npm begin or yarn begin and head to localhost:3000 to view the modifications.

Now, let’s create the routes / pages utilizing react-router-dom. Change the code in src/App.js with the next code:

// src/App.js
import { Routes, Route } from "react-router-dom";
import { DynamicItem, Sidebar, dummyData } from "./parts";
import "./App.css";

perform App() {
  return (
    <div id="most important">
      <Sidebar>
        <Routes>
          <Route path="/" ingredient={<DynamicItem web page="homepage" />} />
          {dummyData &&
            dummyData.map((merchandise, index) => (
              <Route
                key={index}
                path={merchandise.path}
                ingredient={<DynamicItem web page={merchandise.identify} />}
              />
            ))}
        </Routes>
      </Sidebar>
    </div>
  );
}

export default App;
Enter fullscreen mode

Exit fullscreen mode

Right here, we’re importing Routes, Route from react-router-dom which is able to assist us create pages inside our app. We’re additionally importing the Sidebar element, which we will probably be creating after someday, dummyData, some random knowledge which incorporates path to our pages, DynamicItem, a dummy web page which shows the web page identify as we navigate to it.

Subsequent factor, we have to do is use the Sidebar element. This element will probably be such that it’ll settle for youngsters as props in order that it’s seen in all places as we navigate between the pages. Proper after that, we have to add Routes element, a container which covers our pages / routes as we create them in order that the app is aware of this can be a routes container and it incorporates pages.

Now, the one factor we have to do is add the routes we wish. We all know that dummyData incorporates the paths to the pages, we will map via the information to get them, and use Route element for every of the trail. The Route element accepts two properties, path, the place the route will probably be navigating to, and ingredient, which is a element that will probably be rendered in that web page / route.

Now, we have to add the essential styling to our app. These kinds solely outline the format of our app. Change the code in src/App.css with the next code:

Observe: We are able to additionally create among the styling utilizing styled-components. You are able to do the styling nonetheless you want, however right here, I’ve used css for fundamental styling.

/* src/App.css */
* {
  margin: 0;
  padding: 0;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  define: none;
  border: none;
  text-decoration: none;

  font-family: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI",
    "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
    sans-serif;
}

#most important {
  width: 100%;
  peak: 100%;
  show: flex;
  flex-direction: row;
}

.btn {
  margin: 1rem 1rem 0 0;
  padding: 0.25rem 0.5rem;
  show: flex;
  hole: 0.25rem;
  align-items: middle;
  justify-content: middle;
  background: clear;
  define: none;
  border: 1px stable #808080;
  border-radius: 3px;
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
  -ms-border-radius: 3px;
  -o-border-radius: 3px;
  cursor: pointer;
  transition: all 0.2s ease-in-out;
  -webkit-transition: all 0.2s ease-in-out;
  -moz-transition: all 0.2s ease-in-out;
  -ms-transition: all 0.2s ease-in-out;
  -o-transition: all 0.2s ease-in-out;
}

.btn:hover {
  background-color: #e4e3e34d;
}

#web page {
  show: flex;
  align-items: middle;
  justify-content: middle;
  text-align: middle;
  text-transform: capitalize;
  font-size: 1rem;
  overflow: hidden;
}

@media display and (min-width: 468px) {
  #web page {
    font-size: 3rem;
  }

  .btn {
    padding: 0.5rem 0.75rem;
    hole: 0.5rem;
  }
}

.app__brand__text {
  font-size: 2rem;
  font-weight: 700;
  colour: #5a8dee;
  margin-left: 0.5rem;
}

/* Sidebar toggle button begins */
.outer__circle {
  place: relative;
  width: 1.5rem;
  peak: 1.5rem;
  border-radius: 50%;
  background-color: #5f97ef;
  show: flex;
  align-items: middle;
  justify-content: middle;
}

.outer__circle::after {
  place: absolute;
  high: 0.225rem;
  left: 0.215rem;
  content material: "";
  width: 1.1rem;
  peak: 1.1rem;
  border-radius: 50%;
  background-color: #fff;
}

.inner__circle {
  place: relative;
  width: 0.75rem;
  peak: 0.75rem;
  border-radius: 50%;
  background-color: #5f97ef;
  z-index: 100;
}

.inner__circle::after {
  place: absolute;
  high: 0.125rem;
  left: 0.15rem;
  content material: "";
  width: 0.5rem;
  peak: 0.5rem;
  border-radius: 50%;
  background-color: #fff;
}
/* Sidebar toggle button ends */
Enter fullscreen mode

Exit fullscreen mode

Right here, we’re resetting each type within the react app utilizing * pseudo selector to configure the entire app the best way we wish it. Furthermore, we’re additionally defining the kinds for guardian div container of app with the category identify most important. We’re additionally defining the kinds for a button which will probably be used later in DynamicItem element.

On this international kinds file, we’re manually making two circles button as an alternative of utilizing some library. This button toggles whether or not or to not show the sidebar as a complete. This might accomplished in some ways, this is only one of them.

Let’s create a file which is able to retailer the icons which will probably be utilized in our react app.

Head to src folder and create a brand new folder inside it below parts identify. Inside parts folder, create a brand new file with Icons.js identify and add the next code to it:

// src/parts/Icons.js
import HomeOutlinedIcon from "@mui/icons-material/HomeOutlined";
import WebOutlinedIcon from "@mui/icons-material/WebOutlined";
import CalendarTodayOutlinedIcon from "@mui/icons-material/CalendarTodayOutlined";
import CalendarMonthOutlinedIcon from "@mui/icons-material/CalendarMonthOutlined";
import PersonOutlineOutlinedIcon from "@mui/icons-material/PersonOutlineOutlined";
import SubjectOutlinedIcon from "@mui/icons-material/SubjectOutlined";
import GppGoodOutlinedIcon from "@mui/icons-material/GppGoodOutlined";
import AdminPanelSettingsOutlinedIcon from "@mui/icons-material/AdminPanelSettingsOutlined";
import ListAltOutlinedIcon from "@mui/icons-material/ListAltOutlined";
import InputOutlinedIcon from "@mui/icons-material/InputOutlined";

import ArrowRightOutlinedIcon from "@mui/icons-material/ArrowRightOutlined";
import ArrowBackIcon from "@mui/icons-material/ArrowBack";

export {
  HomeOutlinedIcon as HomeIcon,
  WebOutlinedIcon as LayoutIcon,
  CalendarMonthOutlinedIcon as CalendarIcon,
  PersonOutlineOutlinedIcon as UserIcon,
  SubjectOutlinedIcon as InvoiceIcon,
  GppGoodOutlinedIcon as RolesIcon,
  CalendarTodayOutlinedIcon as PagesIcon,
  AdminPanelSettingsOutlinedIcon as AuthIcon,
  ListAltOutlinedIcon as WizardIcon,
  InputOutlinedIcon as ModalIcon,
  ArrowBackIcon,
  ArrowRightOutlinedIcon as ArrowIcon,
};
Enter fullscreen mode

Exit fullscreen mode

On this file, we’re importing each icon, that we are going to be utilizing inside our app, and exporting it from a single file. This can assist us to import our icons from a single file as an alternative of utilizing a number of strains to import our icons.

Equally, we will probably be creating a brand new file inside src/parts folder below the identify Knowledge.js. This file will include our dummy knowledge that we are going to be utilizing in our app. Open Knowledge.js file and add the next code to it:

// src/parts/Knowledge.js
import {
  HomeIcon,
  LayoutIcon,
  CalendarIcon,
  InvoiceIcon,
  UserIcon,
  RolesIcon,
  PagesIcon,
  AuthIcon,
  WizardIcon,
  ModalIcon,
} from "./Icons";

export const SIDEBAR_DATA = [
  {
    id: 1,
    name: "dashboards",
    path: "dashboards",
    icon: <HomeIcon />,
  },
  {
    id: 2,
    name: "layouts",
    path: "layouts",
    icon: <LayoutIcon />,
  },
  {
    id: 3,
    name: "calendar",
    path: "calendar",
    icon: <CalendarIcon />,
  },
  {
    id: 4,
    name: "invoice",
    path: "invoice",
    icon: <InvoiceIcon />,
  },
  {
    id: 5,
    name: "users",
    path: "users",
    icon: <UserIcon />,
  },
  {
    id: 6,
    name: "roles & permissions",
    path: "roles",
    icon: <RolesIcon />,
  },
  {
    id: 7,
    name: "pages",
    path: "pages",
    icon: <PagesIcon />,
  },
  {
    id: 8,
    name: "authentication",
    path: "authentication",
    icon: <AuthIcon />,
  },
  {
    id: 9,
    name: "wizard examples",
    path: "wizard",
    icon: <WizardIcon />,
  },
  {
    id: 10,
    name: "modal examples",
    path: "modal",
    icon: <ModalIcon />,
  },
];
Enter fullscreen mode

Exit fullscreen mode

Observe that we’re importing the icons from a single file as an alternative of utilizing a number of strains to import. This fashion, we will additionally keep away from redundancy.

On this file, we’re defining an array of objects every of which incorporates knowledge for our pages, i.e. an id, identify, path, icon. That is the entire knowledge that will probably be used all through our app. Be happy to increase it as a lot as you need.

One other factor we have to do is create a centralized file which is able to export all our recordsdata, identical to Icons.js file. Create index.js file inside src/parts folder and add the next code to it:

// src/parts/index.js
export { default as Sidebar } from "./Sidebar";
export { default as SidebarItems } from "./Sidebar/SidebarItems";
export { default as DynamicItem } from "./Routes/[item]";

export { SIDEBAR_DATA as dummyData } from "./Knowledge";
Enter fullscreen mode

Exit fullscreen mode

On this file, we’re following the same process as that of Icons.js.

Observe that the recordsdata exported as default should be imported as default as effectively however the ones with out default should be imported with out it.

Now let’s create a file that may render the objects of a web page. You guessed it proper! We will probably be creating DynamicItem element. Create a folder inside src below the identify Routes and inside that folder, create a file with [item].jsx and add the next code to it:

When you’ve got labored with NextJS, you already know why we’re utilizing sq. brackets. For individuals who have no idea, you may identify it something you need, even with out the sq. brackets.

// src/parts/Routes/[item].jsx
import { Hyperlink } from "react-router-dom";
import { ArrowBackIcon } from "../Icons";

const Merchandise = (props) => {
  const { web page } = props;
  if (web page === "homepage") {
    return <div id="web page">{web page}</div>;
  } else {
    return (
      <div id="web page">
        <Hyperlink to="/">
          <button className="btn">
            <ArrowBackIcon /> Again to House
          </button>
        </Hyperlink>
        {web page}
      </div>
    );
  }
};

export default Merchandise;
Enter fullscreen mode

Exit fullscreen mode

We all know we’ve got created the routes for the pages that we wish. Now we have to make pages that will probably be rendered.

Right here we’re importing Hyperlink element from react-router-dom, a again icon from Icons.js file. We all know there isn’t a different web page / route behind it however the homepage incorporates different pages / routes. So, if the route is /, we simply must render the element, else, we additionally must render a again button that may take us again to homepage.

We’re utilizing Hyperlink element to navigate again to homepage because the web page already exists. Recall that we created routes inside src/App.js.

Now comes the principle merchandise, the sidebar element. Head to src folder and create a brand new folder inside it below the identify Sidebar and create a brand new file inside it with index.jsx identify. This would be the most important file that may eat virtually all of the recordsdata. Add the next code to it:

// src/parts/Sidebar/index.jsx
import React, { useState } from "react";

import {
  Youngsters,
  SidebarContainer,
  SidebarWrapper,
  SidebarLogoWrapper,
  SidebarLogo,
  SidebarBrand,
  SidebarToggler,
} from "./SidebarStyles";
import BrandLogo from "./BrandLogo.svg";

import { SidebarItems } from "..";

const MOBILE_VIEW = window.innerWidth < 468;

export default perform Sidebar({ youngsters }) {
  const [displaySidebar, setDisplaySidebar] = useState(!MOBILE_VIEW);

  const handleSidebarDisplay = (e) => {
    e.preventDefault();
    if (window.innerWidth > 468) {
      setDisplaySidebar(!displaySidebar);
    } else {
      setDisplaySidebar(false);
    }
  };

  return (
    <React.Fragment>
      <SidebarContainer displaySidebar={displaySidebar}>
        <SidebarWrapper>
          <SidebarLogoWrapper displaySidebar={displaySidebar}>
            {/* Emblem wrapper begins */}
            <SidebarLogo href="#">
              <span className="app-brand-logo demo">
                <img src={BrandLogo} alt="Model brand" />
              </span>
              <SidebarBrand
                displaySidebar={displaySidebar}
                className="app__brand__text"
              >
                Frest
              </SidebarBrand>
            </SidebarLogo>
            {/* Emblem wrapper ends */}
            {/* Toggle button */}
            <SidebarToggler
              displaySidebar={displaySidebar}
              onClick={handleSidebarDisplay}
            >
              <div className="outer__circle">
                <div className="inner__circle" />
              </div>
            </SidebarToggler>
          </SidebarLogoWrapper>
            {/* Render the SidebarItems element */}
          <SidebarItems displaySidebar={displaySidebar} />
        </SidebarWrapper>
      </SidebarContainer>
            {/* Render the youngsters */}
      <Youngsters displaySidebar={displaySidebar}>{youngsters}</Youngsters>
    </React.Fragment>
  );
}
Enter fullscreen mode

Exit fullscreen mode

That is the file the place we will probably be constructing Sidebar. We’re importing state supervisor useState from React to manage the view of the sidebar, kinds from one other file, will probably be created throughout the similar listing, a Brand Logo Be happy to make use of no matter brand you need, SidebarItems file that may render our objects from the information.

One other factor we’re doing right here is making a international variable that may retailer whether or not the point of view is cellular or not. If the point of view is cellular, show a portion of the sidebar in any other case, make the sidebar togglable, utilizing useState. Then we’re creating an arrow perform that may deal with whether or not or to not show the complete sidebar.

In the long run, we’re returning a React Fragment and displaying the model brand, toggle button, the sidebar objects, and the youngsters.

Observe that we’re creating the kinds utilizing styled-components that may settle for parameters and can assist us in displaying the sidebar.

Now let’s create a file that may apply all the required styling to the sidebar. Head to src/parts/Sidebar and create a brand new file below the identify SidebarStyles.js and add the next code to it:

// src/parts/Sidebar/SidebarStyles.js
import styled from "styled-components";

// Youngsters Part
export const Youngsters = styled.div`
  width: 100%;
  peak: 100%;
  margin-left: ${({ displaySidebar }) => (displaySidebar ? "15rem" : "5rem")};
  @media (max-width: 468px) {
    margin-left: 5rem;
  }
`;

export const SidebarWrapper = styled.div`
  width: 100%;
  peak: 100%;
  show: flex;
  flex-direction: column;
  font-size: 0.9rem;
`;

export const SidebarLogoWrapper = styled.div`
  padding: 0.5rem 1rem;
  margin-bottom: 1rem;
  show: flex;
  justify-content: ${({ displaySidebar }) =>
    displaySidebar ? "space-between" : "middle"};
  align-items: middle;
  @media (max-width: 468px) {
    justify-content: middle;
  }
`;

export const SidebarLogo = styled.a`
  show: flex;
  align-items: middle;
  justify-content: middle;
  @media (max-width: 468px) {
    show: none;
  }
`;

export const SidebarBrand = styled.span`
  show: ${({ displaySidebar }) => (displaySidebar ? "block" : "none")};
`;

export const SidebarToggler = styled.button`
  cursor: pointer;
  show: ${({ displaySidebar }) => (displaySidebar ? "block" : "none")};
  @media (max-width: 468px) {
    show: block;
  }
`;

// SidebarItem kinds
export const ItemsList = styled.ul`
  list-style: none;
`;

export const ItemContainer = styled.li`
  margin-top: 0.5rem;
  width: 100%;
  padding: 0.5rem 0.25rem;
  border-radius: 0.2rem;
  cursor: pointer;
  &:hover {
    background: #eaeced;
  }
  &.energetic {
    background-color: #dbe4f3;
  }
`;

export const ItemWrapper = styled.div`
  show: flex;
  align-items: middle;
  colour: #7c7788;
`;

export const ItemName = styled.span`
  margin-left: ${({ displaySidebar }) => (displaySidebar ? "0.5rem" : "0")};
  show: ${({ displaySidebar }) => (displaySidebar ? "block" : "none")};
  text-transform: capitalize;
`;

// Sidebar Container
export const SidebarContainer = styled.div`
  place: absolute;
  left: 0;
  width: ${({ displaySidebar }) => (displaySidebar ? "15rem" : "5rem")};
  peak: 100vh;
  padding: 0.75rem;
  background: #f3f4f4;
  transition: width 350ms ease;
  border-right: 1px stable #d4d8dd;
  overflow-x: hidden;
  ${({ displaySidebar }) =>
    displaySidebar && "box-shadow: 8px 0px 12px 0px rgba(0,0,0,0.1)"};
  ${ItemWrapper} {
    justify-content: ${({ displaySidebar }) => !displaySidebar && "middle"};
  }
  &:hover {
    ${({ displaySidebar }) =>
      !displaySidebar && "box-shadow: 8px 0px 12px 0px rgba(0,0,0,0.1)"};
    @media (min-width: 468px) {
      width: ${({ displaySidebar }) => !displaySidebar && "15rem"};
      ${SidebarLogoWrapper} {
        justify-content: ${({ displaySidebar }) =>
          !displaySidebar && "space-between"};
      }
      ${SidebarBrand} {
        show: ${({ displaySidebar }) => !displaySidebar && "block"};
      }
      ${SidebarToggler} {
        show: ${({ displaySidebar }) => !displaySidebar && "block"};
      }
      ${ItemWrapper} {
        justify-content: ${({ displaySidebar }) =>
          !displaySidebar && "flex-start"};
      }
      ${ItemName} {
        show: ${({ displaySidebar }) => !displaySidebar && "block"};
        margin-left: ${({ displaySidebar }) => !displaySidebar && "0.5rem"};
      }
    }
  }
  ::-webkit-scrollbar {
    width: 4px;
    peak: 3px;
  }
  ::-webkit-scrollbar-track {
    border-radius: 10px;
    background-color: clear;
  }
  ::-webkit-scrollbar-thumb {
    border-radius: 10px;
    background: #eaeced;
    &:hover {
      background: #d5e0f3;
    }
  }
  @media (max-width: 468px) {
    width: 5rem;
  }
`;
Enter fullscreen mode

Exit fullscreen mode

Right here we’re making the kinds in line with the state that we created inside Sidebar.jsx. Recall that we handed the parameters to those parts. We are able to use these params to show and conceal no matter we wish.

Observe the hierarchy. So as to management a baby element from a guardian element, the kid element should be declared earlier than the guardian element.

Now then, let’s create a file that may render all of the objects of Sidebar. Inside the identical listing, create a brand new file below the identify SidebarItems.jsx and add the next code to it:

// src/parts/Sidebar/SidebarItems.jsx
import React, { useState } from "react";
import { Hyperlink } from "react-router-dom";
import {
  ItemsList,
  ItemContainer,
  ItemWrapper,
  ItemName,
} from "./SidebarStyles";

import { dummyData } from "..";

const SidebarItems = ({ displaySidebar }) => {
  const [activeItem, setActiveItem] = useState(0);

  return (
    <ItemsList>
      {dummyData.map((itemData, index) => (
        <ItemContainer
          key={index}
          onClick={() => setActiveItem(itemData.id)}
          {/* Including energetic class when the person clicks */}
          className={itemData.id === activeItem ? "energetic" : ""}
        >
          <Hyperlink to={itemData.path}>
            <ItemWrapper>
              {itemData.icon}
              <ItemName displaySidebar={displaySidebar}>
                {itemData.identify}
              </ItemName>
            </ItemWrapper>
          </Hyperlink>
        </ItemContainer>
      ))}
    </ItemsList>
  );
};

export default SidebarItems;
Enter fullscreen mode

Exit fullscreen mode

On this file, we’re utilizing useState to handle the energetic merchandise of the sidebar, Hyperlink from React Router to redirect the person to the web page, the dummy knowledge from src/parts/index.js, and the kinds from src/parts/Sidebar/SidebarStyles.js.

Inside the principle perform, we’re creating a listing and contained in the record, we’re mapping via the dummy knowledge and rendering it utilizing the styled parts that we’ve got imported. Observe that we additionally created an energetic pseudo-selector inside SidebarStyles.js, that may type the merchandise that’s energetic. The energetic class is added to the merchandise provided that the person clicks it.

Right here, we’re additionally utilizing the Hyperlink element of React Router, for every merchandise, to navigate to the merchandise that the person clicks.

Lastly, we’ve got the next output. Play with the code nonetheless you would like and see the modifications.
image.png

This can be a easy Sidebar element. You may, nonetheless, lengthen it and make it way more wonderful nonetheless you demand it.



Sources:

  1. Live demo
  2. Source Code
  3. styled-components
  4. React Router DOM

Keep tuned with extra of my blogs on my site

That is my first weblog, so, there will probably be some errors within the script, nonetheless, the code works good. Kindly share ideas that may assist me make the articles extra organized.

The Article was Inspired from tech community site.
Contact us if this is inspired from your article and we will give you credit for it for serving the community.

This Banner is For Sale !!
Get your ad here for a week in 20$ only and get upto 10k Tech related traffic daily !!!

Leave a Reply

Your email address will not be published. Required fields are marked *

Want to Contribute to us or want to have 15k+ Audience read your Article ? Or Just want to make a strong Backlink?