├── .eslintrc.json
├── .gitignore
├── README.md
├── jsconfig.json
├── next.config.js
├── package-lock.json
├── package.json
├── public
├── favicon.ico
├── logo.jpg
├── next.svg
├── thirteen.svg
└── vercel.svg
└── src
├── components
├── BaseLayout.js
└── Sidebar.js
├── context
└── SidebarContext.js
├── pages
├── _app.js
├── about.js
├── contact.js
├── index.js
└── mails.js
└── styles
└── globals.css
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | /node_modules
3 | /.pnp
4 | .pnp.js
5 |
6 | # testing
7 | /coverage
8 |
9 | # next.js
10 | /.next/
11 | /out/
12 |
13 | # production
14 | /build
15 |
16 | # misc
17 | .DS_Store
18 | *.pem
19 |
20 | # debug
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 | .pnpm-debug.log*
25 |
26 | # local env files
27 | .env*.local
28 |
29 | # vercel
30 | .vercel
31 |
32 | # typescript
33 | *.tsbuildinfo
34 | next-env.d.ts
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # collapsible-sidebar-in-nextjs
2 | Build collapsible-sidebar-in-nextjs
3 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "paths": {
5 | "@/*": ["./src/*"]
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | reactStrictMode: true,
4 | }
5 |
6 | module.exports = nextConfig
7 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "collapsiable-sidebar",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@next/font": "13.1.4",
13 | "eslint": "8.32.0",
14 | "eslint-config-next": "13.1.4",
15 | "next": "13.1.4",
16 | "react": "18.2.0",
17 | "react-dom": "18.2.0",
18 | "react-icons": "^4.7.1"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MdUsmanAnsari/collapsible-sidebar-in-nextjs/0a6c56e0bcb4babd040747ccce98d3954eb15db7/public/favicon.ico
--------------------------------------------------------------------------------
/public/logo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MdUsmanAnsari/collapsible-sidebar-in-nextjs/0a6c56e0bcb4babd040747ccce98d3954eb15db7/public/logo.jpg
--------------------------------------------------------------------------------
/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/thirteen.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/BaseLayout.js:
--------------------------------------------------------------------------------
1 | import Sidebar from "./Sidebar";
2 |
3 | const BaseLayout = ({ children }) => {
4 | return (
5 |
6 |
7 | {children};
8 |
9 | );
10 | };
11 |
12 | export default BaseLayout;
13 |
--------------------------------------------------------------------------------
/src/components/Sidebar.js:
--------------------------------------------------------------------------------
1 | import Image from "next/image";
2 | import { AiOutlineHome } from "react-icons/ai";
3 | import { BsPeople } from "react-icons/bs";
4 | import { TiContacts } from "react-icons/ti";
5 | import { FiMail } from "react-icons/fi";
6 | import { MdKeyboardArrowLeft, MdKeyboardArrowRight } from "react-icons/md";
7 | import Link from "next/link";
8 | import { useContext } from "react";
9 | import { SidebarContext } from "@/context/SidebarContext";
10 | import { useRouter } from "next/router";
11 |
12 | const sidebarItems = [
13 | {
14 | name: "Home",
15 | href: "/",
16 | icon: AiOutlineHome,
17 | },
18 | {
19 | name: "About",
20 | href: "/about",
21 | icon: BsPeople,
22 | },
23 | {
24 | name: "Mails",
25 | href: "/mails",
26 | icon: FiMail,
27 | },
28 | {
29 | name: "Contact",
30 | href: "/contact",
31 | icon: TiContacts,
32 | },
33 | ];
34 |
35 | const Sidebar = () => {
36 | const router = useRouter();
37 | const { isCollapsed, toggleSidebarcollapse } = useContext(SidebarContext);
38 |
39 | return (
40 |
41 |
44 |
75 |
76 | );
77 | };
78 |
79 | export default Sidebar;
80 |
--------------------------------------------------------------------------------
/src/context/SidebarContext.js:
--------------------------------------------------------------------------------
1 | import { createContext, useState } from "react";
2 |
3 | const initialValue = { isCollapsed: false };
4 |
5 | const SidebarContext = createContext(initialValue);
6 |
7 | const SidebarProvider = ({ children }) => {
8 | const [isCollapsed, setCollapse] = useState(false);
9 |
10 | const toggleSidebarcollapse = () => {
11 | setCollapse((prevState) => !prevState);
12 | };
13 |
14 | return (
15 |
16 | {children}
17 |
18 | );
19 | };
20 |
21 | export { SidebarContext, SidebarProvider };
22 |
--------------------------------------------------------------------------------
/src/pages/_app.js:
--------------------------------------------------------------------------------
1 | import { SidebarProvider } from "@/context/SidebarContext";
2 | import "@/styles/globals.css";
3 |
4 | export default function App({ Component, pageProps }) {
5 | return (
6 |
7 |
8 |
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/src/pages/about.js:
--------------------------------------------------------------------------------
1 | import BaseLayout from "@/components/BaseLayout";
2 |
3 | const About = () => {
4 | return About Page;
5 | };
6 |
7 | export default About;
8 |
--------------------------------------------------------------------------------
/src/pages/contact.js:
--------------------------------------------------------------------------------
1 | import BaseLayout from "@/components/BaseLayout";
2 |
3 | const Contact = () => {
4 | return Contact Page;
5 | };
6 |
7 | export default Contact;
8 |
--------------------------------------------------------------------------------
/src/pages/index.js:
--------------------------------------------------------------------------------
1 | import BaseLayout from "../components/BaseLayout";
2 |
3 | const Home = () => {
4 | return Dashboard;
5 | };
6 |
7 | export default Home;
8 |
--------------------------------------------------------------------------------
/src/pages/mails.js:
--------------------------------------------------------------------------------
1 | import BaseLayout from "@/components/BaseLayout";
2 |
3 | const Mails = () => {
4 | return Mails Page;
5 | };
6 |
7 | export default Mails;
8 |
--------------------------------------------------------------------------------
/src/styles/globals.css:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Roboto:wght@300;400&display=swap");
2 |
3 | :root {
4 | --color-bg: #fff;
5 | --color-border: #e5e7eb;
6 | --color-sidebar-item: #f3f4f6;
7 | }
8 |
9 | * {
10 | padding: 0;
11 | margin: 0;
12 | box-sizing: border-box;
13 | }
14 |
15 | body {
16 | background-color: #eee;
17 | font-family: "Roboto", sans-serif;
18 | }
19 |
20 | .layout {
21 | display: flex;
22 | height: 100vh;
23 | position: relative;
24 | gap: 2rem;
25 | }
26 |
27 | .layout__main-content {
28 | flex-grow: 1;
29 | }
30 |
31 | .sidebar__wrapper {
32 | position: relative;
33 | }
34 |
35 | .sidebar {
36 | width: 17rem;
37 | height: 100%;
38 | background-color: var(--color-bg);
39 | padding: 1rem;
40 | transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.1);
41 | overflow: hidden;
42 | }
43 |
44 | .sidebar__top {
45 | width: max-content;
46 | display: flex;
47 | align-items: center;
48 | gap: 1rem;
49 | padding-bottom: 1rem;
50 | margin-bottom: 1rem;
51 | border-bottom: 1px solid var(--color-border);
52 | }
53 |
54 | .sidebar__logo {
55 | width: 3.5rem;
56 | height: 3.5rem;
57 | object-fit: contain;
58 | border-radius: 1rem;
59 | }
60 |
61 | .sidebar__logo-name {
62 | font-size: 1.2rem;
63 | font-weight: 600;
64 | }
65 |
66 | .sidebar__list {
67 | list-style: none;
68 | }
69 |
70 | .sidebar__link {
71 | display: inline-block;
72 | font-size: 1rem;
73 | text-decoration: none;
74 | color: #000;
75 | padding: 0.8rem 1rem;
76 | display: flex;
77 | background-color: var(--color-sidebar-item);
78 | margin-bottom: 1rem;
79 | border-radius: 0.8rem;
80 | }
81 |
82 | .sidebar__link--active {
83 | color: #fff;
84 | background-color: #10b981;
85 | }
86 |
87 | .sidebar__icon {
88 | display: inline-block;
89 | font-size: 1.2rem;
90 | }
91 |
92 | .sidebar__name {
93 | margin-left: 0.5rem;
94 | }
95 |
96 | [data-collapse="true"] {
97 | width: 5.3rem;
98 | }
99 |
100 | [data-collapse="true"] .sidebar__name,
101 | [data-collapse="true"] .sidebar__logo-name {
102 | display: none;
103 | }
104 |
105 | .btn {
106 | position: absolute;
107 | right: 0;
108 | top: 4.7rem;
109 | border: none;
110 | background-color: var(--color-bg);
111 | width: 1.5rem;
112 | height: 1.5rem;
113 | border: 1px solid var(--color-border);
114 | border-radius: 50%;
115 | display: flex;
116 | justify-content: center;
117 | align-items: center;
118 | cursor: pointer;
119 | transform: translateX(50%);
120 | font-size: 1.1rem;
121 | }
122 |
--------------------------------------------------------------------------------