├── .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 | --------------------------------------------------------------------------------