├── src ├── react-app-env.d.ts ├── sidebars │ ├── sidebar-1 │ │ ├── logo.png │ │ ├── styles.css │ │ └── Sidebar.tsx │ ├── sidebar-2 │ │ ├── Icon.tsx │ │ ├── Button.tsx │ │ ├── useRipple.tsx │ │ ├── Sidebar.tsx │ │ ├── styles.css │ │ └── logo.svg │ ├── sidebar-8 │ │ ├── Sidebar.tsx │ │ ├── styles.css │ │ └── logo.svg │ ├── sidebar-6 │ │ ├── Sidebar.tsx │ │ ├── styles.css │ │ └── logo.svg │ ├── sidebar-9 │ │ ├── styles.css │ │ ├── Sidebar.tsx │ │ └── logo.svg │ ├── sidebar-3 │ │ ├── styles.css │ │ └── Sidebar.tsx │ ├── sidebar-10 │ │ ├── styles.css │ │ └── Sidebar.tsx │ ├── sidebar-7 │ │ ├── styles.css │ │ └── Sidebar.tsx │ ├── sidebar-4 │ │ ├── styles.css │ │ └── Sidebar.tsx │ └── sidebar-5 │ │ ├── styles.css │ │ └── Sidebar.tsx ├── concepts │ └── concept-1 │ │ ├── navbar │ │ ├── joe.png │ │ ├── Navbar.tsx │ │ ├── styles.css │ │ └── logo.svg │ │ ├── sidebar │ │ ├── Icon.tsx │ │ ├── Button.tsx │ │ ├── useRipple.tsx │ │ ├── Sidebar.tsx │ │ ├── styles.css │ │ └── logo.svg │ │ └── Concept.tsx ├── App.tsx ├── index.tsx └── index.css ├── public ├── robots.txt ├── favicon.ico ├── logo192.png ├── logo512.png ├── manifest.json └── index.html ├── .gitignore ├── tsconfig.json ├── package.json └── README.md /src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontend-joe/react-sidebars/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontend-joe/react-sidebars/HEAD/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontend-joe/react-sidebars/HEAD/public/logo512.png -------------------------------------------------------------------------------- /src/sidebars/sidebar-1/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontend-joe/react-sidebars/HEAD/src/sidebars/sidebar-1/logo.png -------------------------------------------------------------------------------- /src/concepts/concept-1/navbar/joe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontend-joe/react-sidebars/HEAD/src/concepts/concept-1/navbar/joe.png -------------------------------------------------------------------------------- /src/sidebars/sidebar-2/Icon.tsx: -------------------------------------------------------------------------------- 1 | export const Icon = ({ icon }: { icon: string }) => ( 2 | {icon} 3 | ); 4 | -------------------------------------------------------------------------------- /src/concepts/concept-1/sidebar/Icon.tsx: -------------------------------------------------------------------------------- 1 | export const Icon = ({ icon }: { icon: string }) => ( 2 | {icon} 3 | ); 4 | -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import { Sidebar as Example } from "./sidebars/sidebar-10/Sidebar"; 2 | // import { Concept as Example } from "./concepts/concept-1/Concept"; 3 | 4 | function App() { 5 | return ; 6 | } 7 | 8 | export default App; 9 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import "./index.css"; 4 | import App from "./App"; 5 | 6 | const root = ReactDOM.createRoot( 7 | document.getElementById("root") as HTMLElement 8 | ); 9 | 10 | root.render( 11 | 12 | 13 | 14 | ); 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /src/concepts/concept-1/Concept.tsx: -------------------------------------------------------------------------------- 1 | import { Sidebar } from "./sidebar/Sidebar"; 2 | import { Navbar } from "./navbar/Navbar"; 3 | import { useState } from "react"; 4 | 5 | export const Concept = () => { 6 | const [isOpen, setIsOpen] = useState(false); 7 | 8 | return ( 9 | <> 10 |
setIsOpen(false)} 12 | className={`overlay ${isOpen ? "open" : ""}`} 13 | /> 14 | 15 | 16 | 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react-jsx" 22 | }, 23 | "include": [ 24 | "src" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-sidebars", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@types/node": "^16.18.3", 7 | "@types/react": "^18.0.25", 8 | "@types/react-dom": "^18.0.8", 9 | "react": "^18.2.0", 10 | "react-dom": "^18.2.0", 11 | "react-responsive-carousel": "^3.2.23", 12 | "react-scripts": "5.0.1", 13 | "typescript": "^4.8.4" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test", 19 | "eject": "react-scripts eject" 20 | }, 21 | "eslintConfig": { 22 | "extends": [ 23 | "react-app" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-2/Button.tsx: -------------------------------------------------------------------------------- 1 | import { FC, MouseEvent } from "react"; 2 | import { createRoot } from "react-dom/client"; 3 | import { Icon } from "./Icon"; 4 | import { useRipple } from "./useRipple"; 5 | 6 | type ButtonProps = { 7 | onClick: (item: string) => void; 8 | name: string; 9 | icon?: string; 10 | isActive: boolean; 11 | }; 12 | 13 | export const Button: FC = ({ onClick, name, icon, isActive }) => { 14 | const [createRipple] = useRipple(); 15 | 16 | const handleClick = (e: MouseEvent) => { 17 | createRipple(e, name); 18 | onClick(name); 19 | }; 20 | 21 | return ( 22 | 33 | ); 34 | }; 35 | -------------------------------------------------------------------------------- /src/concepts/concept-1/sidebar/Button.tsx: -------------------------------------------------------------------------------- 1 | import { FC, MouseEvent } from "react"; 2 | import { createRoot } from "react-dom/client"; 3 | import { Icon } from "./Icon"; 4 | import { useRipple } from "./useRipple"; 5 | 6 | type ButtonProps = { 7 | onClick: (item: string) => void; 8 | name: string; 9 | icon?: string; 10 | isActive: boolean; 11 | }; 12 | 13 | export const Button: FC = ({ onClick, name, icon, isActive }) => { 14 | const [createRipple] = useRipple(); 15 | 16 | const handleClick = (e: MouseEvent) => { 17 | createRipple(e, name); 18 | onClick(name); 19 | }; 20 | 21 | return ( 22 | 33 | ); 34 | }; 35 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-2/useRipple.tsx: -------------------------------------------------------------------------------- 1 | import { FC, MouseEvent } from "react"; 2 | import { createRoot } from "react-dom/client"; 3 | 4 | type RippleProps = { 5 | top: string; 6 | left: string; 7 | }; 8 | 9 | const Ripple: FC = ({ top, left }) => ( 10 | 11 | ); 12 | 13 | const createRipple = (e: MouseEvent, name: string) => { 14 | if (!document.getElementById("ripple-shape")) { 15 | const btn: HTMLButtonElement = e?.currentTarget; 16 | const rect: DOMRect = btn.getBoundingClientRect(); 17 | const top = `${e.clientY - rect.y}px`; 18 | const left = `${e.clientX - rect.x}px`; 19 | 20 | const container = createRoot( 21 | document.getElementById(`ripple-container-${name}`)! 22 | ); 23 | 24 | container.render(); 25 | setTimeout(() => { 26 | container.unmount(); 27 | }, 1000); 28 | } 29 | }; 30 | 31 | export const useRipple = () => { 32 | return [createRipple]; 33 | }; 34 | -------------------------------------------------------------------------------- /src/concepts/concept-1/sidebar/useRipple.tsx: -------------------------------------------------------------------------------- 1 | import { FC, MouseEvent } from "react"; 2 | import { createRoot } from "react-dom/client"; 3 | 4 | type RippleProps = { 5 | top: string; 6 | left: string; 7 | }; 8 | 9 | const Ripple: FC = ({ top, left }) => ( 10 | 11 | ); 12 | 13 | const createRipple = (e: MouseEvent, name: string) => { 14 | if (!document.getElementById("ripple-shape")) { 15 | const btn: HTMLButtonElement = e?.currentTarget; 16 | const rect: DOMRect = btn.getBoundingClientRect(); 17 | const top = `${e.clientY - rect.y}px`; 18 | const left = `${e.clientX - rect.x}px`; 19 | 20 | const container = createRoot( 21 | document.getElementById(`ripple-container-${name}`)! 22 | ); 23 | 24 | container.render(); 25 | setTimeout(() => { 26 | container.unmount(); 27 | }, 1000); 28 | } 29 | }; 30 | 31 | export const useRipple = () => { 32 | return [createRipple]; 33 | }; 34 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-8/Sidebar.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | import logo from "./logo.svg"; 3 | import "./styles.css"; 4 | 5 | const navItems = ["home", "settings", "backup", "mail", "cloud", "layers"]; 6 | 7 | export const Sidebar = () => { 8 | const [isOpen, setIsOpen] = useState(false); 9 | return ( 10 | 34 | ); 35 | }; 36 | -------------------------------------------------------------------------------- /src/concepts/concept-1/navbar/Navbar.tsx: -------------------------------------------------------------------------------- 1 | import "./styles.css"; 2 | 3 | import joe from "./joe.png"; 4 | import logo from "./logo.svg"; 5 | import { Dispatch, SetStateAction } from "react"; 6 | 7 | export const Navbar = ({ 8 | setIsOpen, 9 | }: { 10 | setIsOpen: Dispatch>; 11 | }) => ( 12 | 44 | ); 45 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-6/Sidebar.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | import "./styles.css"; 3 | import logo from "./logo.svg"; 4 | 5 | const menuItems = [ 6 | "Your Work", 7 | "Activity", 8 | "Assets", 9 | "Pinned Items", 10 | "Following", 11 | "Trending", 12 | "Challenges", 13 | "Spark", 14 | ]; 15 | 16 | export const Sidebar = () => { 17 | const [isOpen, setIsOpen] = useState(false); 18 | const toggleSidebar = () => setIsOpen(!isOpen); 19 | return ( 20 | <> 21 | 47 |
48 | 49 | ); 50 | }; 51 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-9/styles.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | body { 6 | margin: 0; 7 | background: #26253e; 8 | height: 100vh; 9 | } 10 | 11 | button { 12 | background: transparent; 13 | border: 0; 14 | padding: 0; 15 | cursor: pointer; 16 | user-select: none; 17 | } 18 | 19 | .sidebar { 20 | position: absolute; 21 | overflow: hidden; 22 | top: 0; 23 | left: 0; 24 | bottom: 0; 25 | width: 260px; 26 | background: #4734d7; 27 | } 28 | 29 | .sidebar-inner { 30 | position: absolute; 31 | top: 0; 32 | left: 0; 33 | width: 260px; 34 | } 35 | 36 | .sidebar-header { 37 | display: flex; 38 | align-items: center; 39 | height: 72px; 40 | background: rgb(0 0 0 / 15%); 41 | } 42 | 43 | .sidebar-burger { 44 | width: 60px; 45 | height: 72px; 46 | display: grid; 47 | place-items: center; 48 | color: #f9f9f9; 49 | } 50 | 51 | .sidebar-logo { 52 | height: 22px; 53 | } 54 | 55 | .sidebar-menu { 56 | display: grid; 57 | padding: 10px; 58 | } 59 | 60 | .sidebar-button { 61 | display: flex; 62 | gap: 16px; 63 | align-items: center; 64 | height: 56px; 65 | width: 100%; 66 | font-family: "Poppins"; 67 | font-size: 17px; 68 | text-transform: capitalize; 69 | line-height: 1; 70 | padding: 0 10px; 71 | border-radius: 8px; 72 | color: #f9f9f9; 73 | opacity: 0.9; 74 | } 75 | 76 | .sidebar-button p { 77 | font-size: 15px; 78 | } 79 | 80 | .handle { 81 | position: absolute; 82 | z-index: 100; 83 | width: 8px; 84 | top: 0; 85 | bottom: 0; 86 | right: 0; 87 | transition: 0.3s; 88 | } 89 | 90 | .handle:hover, 91 | .handle:active { 92 | background: rgb(255 255 255 / 10%); 93 | cursor: col-resize; 94 | } 95 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-2/Sidebar.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | import "./styles.css"; 3 | import Logo from "./logo.svg"; 4 | import { Icon } from "./Icon"; 5 | import { Button } from "./Button"; 6 | 7 | const menuItems = [ 8 | { 9 | name: "Apps", 10 | icon: "apps", 11 | }, 12 | { 13 | name: "Subscriptions", 14 | icon: "subscriptions", 15 | }, 16 | { 17 | name: "Library", 18 | icon: "video_library", 19 | }, 20 | { 21 | name: "Explore", 22 | icon: "explore", 23 | }, 24 | { 25 | name: "Trending", 26 | icon: "mode_heat", 27 | }, 28 | { 29 | name: "Music", 30 | icon: "music_note", 31 | }, 32 | { 33 | name: "Watch Later", 34 | icon: "schedule", 35 | }, 36 | { 37 | name: "Settings", 38 | icon: "settings", 39 | }, 40 | { 41 | name: "Privacy", 42 | icon: "lock", 43 | }, 44 | ]; 45 | 46 | const NavHeader = () => ( 47 |
48 | 51 | 52 |
53 | ); 54 | 55 | export const Sidebar = () => { 56 | const [activeItem, setActiveItem] = useState(""); 57 | 58 | const handleClick = (item: string) => { 59 | console.log("activeItem", activeItem); 60 | setActiveItem(item !== activeItem ? item : ""); 61 | }; 62 | 63 | return ( 64 | 77 | ); 78 | }; 79 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-9/Sidebar.tsx: -------------------------------------------------------------------------------- 1 | import { useRef, useState } from "react"; 2 | import logo from "./logo.svg"; 3 | import "./styles.css"; 4 | 5 | const navItems = ["home", "settings", "backup", "mail", "cloud"]; 6 | 7 | export const Sidebar = () => { 8 | const [width, setWidth] = useState(60); 9 | const sidebarRef = useRef(null); 10 | const sidebar = sidebarRef.current; 11 | 12 | const resize = (e: any) => { 13 | let newWidth = e.clientX - sidebar?.offsetLeft!; 14 | if (newWidth < 61) newWidth = 60; 15 | if (newWidth > 259) newWidth = 260; 16 | setWidth(newWidth); 17 | }; 18 | 19 | const stopResize = () => { 20 | document.body.style.cursor = "default"; 21 | window.removeEventListener("mousemove", resize); 22 | window.removeEventListener("mouseup", stopResize); 23 | }; 24 | 25 | const initResize = () => { 26 | document.body.style.cursor = "col-resize"; 27 | window.addEventListener("mousemove", resize); 28 | window.addEventListener("mouseup", stopResize); 29 | }; 30 | 31 | return ( 32 | 51 | ); 52 | }; 53 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-8/styles.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | body { 6 | margin: 0; 7 | background: #1f1d58; 8 | } 9 | 10 | button { 11 | background: transparent; 12 | border: 0; 13 | padding: 0; 14 | cursor: pointer; 15 | } 16 | 17 | .sidebar { 18 | position: absolute; 19 | overflow: hidden; 20 | top: 0; 21 | left: 0; 22 | width: 60px; 23 | height: 100%; 24 | background: #29277a; 25 | transition: width 0.4s; 26 | } 27 | 28 | .sidebar.open { 29 | width: 260px; 30 | } 31 | 32 | .sidebar-inner { 33 | position: absolute; 34 | top: 0; 35 | left: 0; 36 | width: 260px; 37 | } 38 | 39 | .sidebar-header { 40 | display: flex; 41 | align-items: center; 42 | height: 72px; 43 | background: rgb(0 0 0 / 15%); 44 | } 45 | 46 | .sidebar-burger { 47 | width: 60px; 48 | height: 72px; 49 | display: grid; 50 | place-items: center; 51 | color: #f9f9f9; 52 | } 53 | 54 | .sidebar-logo { 55 | height: 28px; 56 | } 57 | 58 | .sidebar-menu { 59 | display: grid; 60 | padding: 10px; 61 | } 62 | 63 | .sidebar-button { 64 | display: flex; 65 | gap: 16px; 66 | align-items: center; 67 | height: 56px; 68 | width: 100%; 69 | font-family: "Poppins"; 70 | font-size: 17px; 71 | text-transform: capitalize; 72 | line-height: 1; 73 | padding: 0 10px; 74 | border-radius: 8px; 75 | color: #f9f9f9; 76 | opacity: 0.8; 77 | } 78 | 79 | .sidebar-button:hover { 80 | background: rgb(0 0 0 / 30%); 81 | opacity: 1; 82 | } 83 | 84 | .sidebar-button:hover > span { 85 | opacity: 1; 86 | } 87 | 88 | .sidebar-logo, 89 | .sidebar-button p { 90 | opacity: 0; 91 | transition: 0.3s; 92 | } 93 | 94 | .sidebar.open :is(.sidebar-button p, .sidebar-logo) { 95 | opacity: 1; 96 | } 97 | 98 | .sidebar-button > img { 99 | width: 24px; 100 | height: 24px; 101 | } 102 | 103 | .sidebar-button > span { 104 | opacity: 0.5; 105 | } 106 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-3/styles.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | body { 6 | margin: 0; 7 | background: #ededed; 8 | font-family: "Euclid Circular A"; 9 | } 10 | 11 | button { 12 | background: transparent; 13 | border: 0; 14 | padding: 0; 15 | cursor: pointer; 16 | text-align: left; 17 | } 18 | 19 | .sidebar { 20 | position: fixed; 21 | top: 0; 22 | left: 0; 23 | width: 260px; 24 | height: 100%; 25 | background: #ffffff; 26 | transition: width 0.4s; 27 | } 28 | 29 | .sidebar-header { 30 | display: flex; 31 | align-items: center; 32 | height: 72px; 33 | padding: 0 1.25rem 0 0; 34 | border-bottom: 1px solid #e1e1e1; 35 | } 36 | 37 | .sidebar .sidebar-header button { 38 | width: 64px; 39 | } 40 | 41 | .sidebar-logo { 42 | height: 20px; 43 | } 44 | 45 | .sidebar button { 46 | position: relative; 47 | display: flex; 48 | gap: 16px; 49 | align-items: center; 50 | height: 50px; 51 | width: 100%; 52 | font-family: inherit; 53 | font-size: 16px; 54 | font-weight: 400; 55 | line-height: 1; 56 | padding: 0 25px; 57 | color: #1a1a1a; 58 | } 59 | 60 | .sidebar button span:nth-child(2) { 61 | flex: 1 1 auto; 62 | } 63 | 64 | .sidebar button.active { 65 | background: #9d5bff; 66 | color: #f9f9f9; 67 | } 68 | 69 | .sub-nav button.active::before { 70 | background: #f9f9f9; 71 | } 72 | 73 | .sub-nav { 74 | overflow: hidden; 75 | /* height: 0; */ 76 | transition: 0.5s; 77 | } 78 | 79 | /* .sub-nav.open { 80 | height: 200px; 81 | } */ 82 | 83 | .sub-nav button { 84 | padding-left: 64px; 85 | } 86 | 87 | .sub-nav button::before { 88 | content: ""; 89 | position: absolute; 90 | top: 50%; 91 | left: 36px; 92 | translate: 0 -50%; 93 | width: 5px; 94 | height: 5px; 95 | border-radius: 50%; 96 | background-color: #1a1a1a; 97 | } 98 | 99 | .material-symbols-outlined { 100 | font-size: 22px; 101 | } 102 | -------------------------------------------------------------------------------- /src/concepts/concept-1/sidebar/Sidebar.tsx: -------------------------------------------------------------------------------- 1 | import { Dispatch, SetStateAction, useState } from "react"; 2 | import "./styles.css"; 3 | import Logo from "./logo.svg"; 4 | import { Icon } from "./Icon"; 5 | import { Button } from "./Button"; 6 | 7 | const menuItems = [ 8 | { 9 | name: "Apps", 10 | icon: "apps", 11 | }, 12 | { 13 | name: "Subscriptions", 14 | icon: "subscriptions", 15 | }, 16 | { 17 | name: "Library", 18 | icon: "video_library", 19 | }, 20 | { 21 | name: "Explore", 22 | icon: "explore", 23 | }, 24 | { 25 | name: "Trending", 26 | icon: "mode_heat", 27 | }, 28 | { 29 | name: "Music", 30 | icon: "music_note", 31 | }, 32 | { 33 | name: "Watch Later", 34 | icon: "schedule", 35 | }, 36 | { 37 | name: "Settings", 38 | icon: "settings", 39 | }, 40 | { 41 | name: "Privacy", 42 | icon: "lock", 43 | }, 44 | ]; 45 | 46 | const NavHeader = ({ onClick }: { onClick: VoidFunction }) => ( 47 |
48 | 51 | 52 |
53 | ); 54 | 55 | export const Sidebar = ({ 56 | isOpen, 57 | setIsOpen, 58 | }: { 59 | isOpen: boolean; 60 | setIsOpen: Dispatch>; 61 | }) => { 62 | const [activeItem, setActiveItem] = useState(""); 63 | 64 | const handleClick = (item: string) => { 65 | setActiveItem(item !== activeItem ? item : ""); 66 | }; 67 | 68 | return ( 69 | 82 | ); 83 | }; 84 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-1/styles.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | body { 6 | margin: 0; 7 | background: #202124; 8 | font-family: "Euclid Circular A"; 9 | } 10 | 11 | button { 12 | background: transparent; 13 | border: 0; 14 | padding: 0; 15 | cursor: pointer; 16 | text-align: left; 17 | } 18 | 19 | .sidebar { 20 | position: fixed; 21 | top: 0; 22 | left: 0; 23 | display: flex; 24 | flex-direction: column; 25 | width: 260px; 26 | height: 100%; 27 | background: #0f0f0f; 28 | transition: width 0.4s; 29 | } 30 | 31 | .sidebar-header { 32 | display: flex; 33 | align-items: center; 34 | height: 72px; 35 | padding: 0 1.25rem 0 0; 36 | background: rgba(0, 0, 0, 0.1); 37 | } 38 | 39 | .sidebar .sidebar-header button { 40 | width: 64px; 41 | } 42 | 43 | .sidebar-logo { 44 | height: 20px; 45 | } 46 | 47 | .sidebar-nav { 48 | flex: 1 1 auto; 49 | } 50 | 51 | .sidebar h2 { 52 | padding-left: 26px; 53 | font-size: 14px; 54 | color: rgba(255, 255, 255, 0.2); 55 | } 56 | 57 | .sidebar button { 58 | position: relative; 59 | display: flex; 60 | gap: 25px; 61 | align-items: center; 62 | height: 50px; 63 | width: 100%; 64 | font-family: inherit; 65 | font-size: 16px; 66 | font-weight: 400; 67 | line-height: 1; 68 | padding: 0 25px; 69 | color: #d4d4ea; 70 | } 71 | 72 | .sidebar button span:nth-child(2) { 73 | flex: 1 1 auto; 74 | } 75 | 76 | .sidebar button.active { 77 | background: #6a28cb; 78 | } 79 | 80 | .sub-nav { 81 | overflow: hidden; 82 | height: 0; 83 | transition: 0.5s; 84 | } 85 | 86 | .sub-nav.open { 87 | height: 200px; 88 | } 89 | 90 | .sub-nav button { 91 | padding-left: 72px; 92 | } 93 | 94 | .sub-nav button::before { 95 | content: ""; 96 | position: absolute; 97 | top: 50%; 98 | left: 36px; 99 | translate: 0 -50%; 100 | width: 5px; 101 | height: 5px; 102 | border-radius: 50%; 103 | background-color: #d4d4ea; 104 | } 105 | 106 | .material-symbols-outlined { 107 | font-size: 22px; 108 | } 109 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-2/styles.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | body { 6 | margin: 0; 7 | background: #202124; 8 | font-family: "Euclid Circular A"; 9 | } 10 | 11 | button { 12 | position: relative; 13 | overflow: hidden; 14 | height: 50px; 15 | width: 100%; 16 | font-family: inherit; 17 | font-size: 16px; 18 | font-weight: 400; 19 | padding: 0 22px; 20 | color: #d4d4ea; 21 | background: transparent; 22 | border: 0; 23 | cursor: pointer; 24 | text-align: left; 25 | } 26 | 27 | .sidebar { 28 | position: fixed; 29 | top: 0; 30 | left: 0; 31 | display: flex; 32 | flex-direction: column; 33 | width: 230px; 34 | height: 100%; 35 | background: #0f0f0f; 36 | } 37 | 38 | .sidebar-header { 39 | display: flex; 40 | align-items: center; 41 | height: 72px; 42 | padding: 0 1.25rem 0 0; 43 | background: rgba(0, 0, 0, 0.1); 44 | } 45 | 46 | .sidebar-header button { 47 | width: 64px; 48 | } 49 | 50 | .sidebar-logo { 51 | height: 20px; 52 | } 53 | 54 | button { 55 | } 56 | 57 | .button-content { 58 | position: relative; 59 | z-index: 2; 60 | display: flex; 61 | gap: 22px; 62 | align-items: center; 63 | } 64 | 65 | @keyframes active { 66 | 0%, 67 | 30% { 68 | background: transparent; 69 | } 70 | 80%, 71 | 100% { 72 | background: #2f2d32; 73 | } 74 | } 75 | 76 | .sidebar button.active { 77 | animation: active 1s forwards; 78 | } 79 | 80 | .material-symbols-outlined { 81 | font-size: 22px; 82 | } 83 | 84 | @keyframes ripple { 85 | 0% { 86 | opacity: 0; 87 | scale: 0.5; 88 | } 89 | 35% { 90 | opacity: 1; 91 | } 92 | 100% { 93 | opacity: 0; 94 | scale: 5; 95 | } 96 | } 97 | 98 | .ripple-shape { 99 | display: block; 100 | position: absolute; 101 | z-index: 1; 102 | width: 80px; 103 | height: 80px; 104 | margin-top: -40px; 105 | margin-left: -40px; 106 | border-radius: 50%; 107 | pointer-events: none; 108 | opacity: 0; 109 | background: #2f2d32; 110 | animation: ripple 1s both; 111 | } 112 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `npm start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 13 | 14 | The page will reload if you make edits.\ 15 | You will also see any lint errors in the console. 16 | 17 | ### `npm test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `npm run build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `npm run eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 35 | 36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 39 | 40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | 31 | 32 | 33 | 37 | React App 38 | 39 | 40 | 41 |
42 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-10/styles.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | body { 6 | margin: 0; 7 | background: #12131a; 8 | font-family: "Euclid Circular A"; 9 | } 10 | 11 | button { 12 | background: transparent; 13 | border: 0; 14 | padding: 0; 15 | cursor: pointer; 16 | text-align: left; 17 | } 18 | 19 | .sidebar { 20 | position: fixed; 21 | top: 0; 22 | left: 0; 23 | display: flex; 24 | flex-direction: column; 25 | gap: 8px; 26 | width: 260px; 27 | height: 100%; 28 | padding: 0 16px; 29 | background: #1d212a; 30 | border-right: 1px solid #2e303e; 31 | transition: width 0.4s; 32 | } 33 | 34 | .sidebar-header { 35 | display: flex; 36 | align-items: center; 37 | height: 72px; 38 | padding: 0 1.25rem 0 0; 39 | border-bottom: 1px solid #2e303e; 40 | color: #e1ecff; 41 | } 42 | 43 | .sidebar .sidebar-header button { 44 | width: 54px; 45 | } 46 | 47 | .sidebar-logo { 48 | height: 20px; 49 | } 50 | 51 | .sidebar button { 52 | position: relative; 53 | display: flex; 54 | gap: 16px; 55 | align-items: center; 56 | height: 50px; 57 | width: 100%; 58 | border-radius: 6px; 59 | font-family: inherit; 60 | font-size: 16px; 61 | font-weight: 400; 62 | line-height: 1; 63 | padding: 0 16px; 64 | color: #e1ecff; 65 | transition: background 0.3s; 66 | } 67 | 68 | .sidebar button span:nth-child(2) { 69 | flex: 1 1 auto; 70 | } 71 | 72 | .sidebar button:is(.active, :hover) { 73 | background: #004fee; 74 | color: #e1ecff; 75 | } 76 | 77 | .sidebar button span { 78 | transition: 0.3s; 79 | } 80 | 81 | .sidebar button.active > span:nth-child(3) { 82 | rotate: -180deg; 83 | } 84 | 85 | .sidebar button:not(.active):hover { 86 | background: #2e303e; 87 | } 88 | 89 | .sub-nav button.active::before { 90 | background: #e1ecff; 91 | } 92 | 93 | .sub-nav { 94 | overflow: hidden; 95 | /* height: 0; */ 96 | transition: 0.5s; 97 | } 98 | 99 | /* .sub-nav.open { 100 | height: 200px; 101 | } */ 102 | 103 | .sub-nav button { 104 | padding-left: 54px; 105 | } 106 | 107 | .sub-nav button::before { 108 | content: ""; 109 | position: absolute; 110 | top: 50%; 111 | left: 25px; 112 | translate: 0 -50%; 113 | width: 5px; 114 | height: 5px; 115 | border-radius: 50%; 116 | background-color: #e1ecff; 117 | } 118 | 119 | .material-symbols-outlined { 120 | font-size: 22px; 121 | } 122 | -------------------------------------------------------------------------------- /src/concepts/concept-1/sidebar/styles.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | body { 6 | margin: 0; 7 | background: #202124; 8 | font-family: "Euclid Circular A"; 9 | } 10 | 11 | .sidebar button { 12 | position: relative; 13 | overflow: hidden; 14 | height: 50px; 15 | width: 100%; 16 | font-family: inherit; 17 | font-size: 17px; 18 | font-weight: 400; 19 | padding: 0 22px; 20 | color: #d4d4ea; 21 | background: transparent; 22 | border: 0; 23 | cursor: pointer; 24 | text-align: left; 25 | } 26 | 27 | .sidebar { 28 | position: fixed; 29 | z-index: 3; 30 | top: 0; 31 | left: 0; 32 | display: flex; 33 | flex-direction: column; 34 | width: 230px; 35 | height: 100%; 36 | background: #000000; 37 | translate: -100% 0; 38 | transition: 0.3s; 39 | } 40 | 41 | .sidebar.open { 42 | translate: 0 0; 43 | } 44 | 45 | .sidebar-header { 46 | display: flex; 47 | align-items: center; 48 | height: 72px; 49 | padding: 0 1.25rem 0 0; 50 | background: rgba(0, 0, 0, 0.1); 51 | } 52 | 53 | .sidebar-header button { 54 | width: 64px; 55 | } 56 | 57 | .sidebar-logo { 58 | height: 20px; 59 | } 60 | 61 | .button-content { 62 | position: relative; 63 | z-index: 2; 64 | display: flex; 65 | gap: 22px; 66 | align-items: center; 67 | } 68 | 69 | @keyframes active { 70 | 0%, 71 | 30% { 72 | background: transparent; 73 | } 74 | 80%, 75 | 100% { 76 | background: #2f2d32; 77 | } 78 | } 79 | 80 | .sidebar button.active { 81 | animation: active 1s forwards; 82 | } 83 | 84 | .overlay { 85 | position: fixed; 86 | z-index: 2; 87 | top: 0; 88 | left: 0; 89 | width: 100%; 90 | height: 100%; 91 | background: rgb(0 0 0 / 40%); 92 | visibility: hidden; 93 | opacity: 0; 94 | transition: 0.3s; 95 | } 96 | 97 | .overlay.open { 98 | visibility: visible; 99 | opacity: 1; 100 | } 101 | 102 | @keyframes ripple { 103 | 0% { 104 | opacity: 0; 105 | scale: 0.5; 106 | } 107 | 35% { 108 | opacity: 1; 109 | } 110 | 100% { 111 | opacity: 0; 112 | scale: 5; 113 | } 114 | } 115 | 116 | .ripple-shape { 117 | display: block; 118 | position: absolute; 119 | z-index: 1; 120 | width: 80px; 121 | height: 80px; 122 | margin-top: -40px; 123 | margin-left: -40px; 124 | border-radius: 50%; 125 | pointer-events: none; 126 | opacity: 0; 127 | background: #2f2d32; 128 | animation: ripple 1s both; 129 | } 130 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-6/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #131417 !important; 3 | font-family: "Lato", sans-serif; 4 | } 5 | 6 | * { 7 | box-sizing: border-box; 8 | } 9 | 10 | button { 11 | display: flex; 12 | align-items: center; 13 | gap: 10px; 14 | background: transparent; 15 | border: 0; 16 | padding: 0; 17 | cursor: pointer; 18 | text-align: left; 19 | font-family: inherit; 20 | font-size: 16px; 21 | color: #f9f9f9; 22 | } 23 | 24 | @keyframes border { 25 | 100% { 26 | translate: 0 8px; 27 | } 28 | } 29 | 30 | .sidebar, 31 | .sidebar-border { 32 | transition: 0.4s; 33 | } 34 | 35 | .sidebar { 36 | position: fixed; 37 | z-index: 1; 38 | top: 0; 39 | left: 0; 40 | display: flex; 41 | flex-direction: column; 42 | width: 190px; 43 | height: 100%; 44 | translate: -190px 0; 45 | box-shadow: 2px 0 5px rgb(0 0 0 / 20%); 46 | } 47 | 48 | .sidebar-border { 49 | position: fixed; 50 | top: -10px; 51 | left: 0; 52 | width: 12px; 53 | height: calc(100% + 20px); 54 | background: repeating-linear-gradient( 55 | 45deg, 56 | #3d414b 0px 3px, 57 | #22252b 3px 6px 58 | ); 59 | animation: border 0.25s infinite linear; 60 | animation-play-state: paused; 61 | } 62 | 63 | .sidebar-border:hover { 64 | animation-play-state: running; 65 | } 66 | 67 | .sidebar.open { 68 | translate: 0; 69 | background: #1e1f26; 70 | } 71 | 72 | .sidebar.open ~ .sidebar-border { 73 | opacity: 0; 74 | } 75 | 76 | .sidebar > img { 77 | flex: 0 0 auto; 78 | margin: 20px; 79 | } 80 | 81 | .create-label { 82 | font-weight: 700; 83 | font-size: 12px; 84 | color: #868ca0; 85 | margin: 0 20px 8px; 86 | } 87 | 88 | .create { 89 | position: relative; 90 | overflow: hidden; 91 | border-radius: 4px; 92 | margin: 0 20px 16px; 93 | padding: 8px 0; 94 | background: #2c303a; 95 | } 96 | 97 | .create::before { 98 | content: ""; 99 | display: block; 100 | position: absolute; 101 | top: 0; 102 | left: 0; 103 | width: 100%; 104 | height: 4px; 105 | background: linear-gradient( 106 | 70deg, 107 | rgb(14, 190, 255), 108 | rgb(255, 221, 64), 109 | rgb(174, 99, 228), 110 | rgb(71, 207, 115) 111 | ); 112 | } 113 | 114 | .create-button { 115 | height: 40px; 116 | padding: 0 8px; 117 | } 118 | 119 | .create-button:first-child { 120 | border-bottom: 1px solid #1e1f26; 121 | } 122 | 123 | .create-button span:first-child { 124 | color: #717790; 125 | } 126 | 127 | .create-button span:nth-child(3) { 128 | margin-left: auto; 129 | } 130 | 131 | .sidebar > nav > button { 132 | height: 44px; 133 | padding: 0 20px; 134 | } 135 | 136 | .sidebar-toggle { 137 | position: absolute; 138 | top: 20px; 139 | right: -30px; 140 | display: grid; 141 | place-items: center; 142 | width: 30px; 143 | height: 30px; 144 | background: #4e5261; 145 | border-top-right-radius: 3px; 146 | border-bottom-right-radius: 3px; 147 | color: #f9f9f9; 148 | font-size: 22px; 149 | } 150 | -------------------------------------------------------------------------------- /src/concepts/concept-1/navbar/styles.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | body { 6 | background: #202124; 7 | font-family: Roboto; 8 | } 9 | 10 | .navbar button { 11 | position: relative; 12 | display: grid; 13 | place-items: center; 14 | width: 40px; 15 | height: 72px; 16 | border: 0; 17 | padding: 0; 18 | background: transparent; 19 | color: #ffffff; 20 | cursor: pointer; 21 | } 22 | 23 | .badge { 24 | position: absolute; 25 | top: 20px; 26 | right: 6px; 27 | display: grid; 28 | place-items: center; 29 | width: 16px; 30 | height: 12px; 31 | border-radius: 6px; 32 | background: red; 33 | font-size: 8px; 34 | font-weight: 500; 35 | font-family: Roboto; 36 | } 37 | 38 | .navbar .burger { 39 | width: 72px; 40 | } 41 | 42 | .navbar { 43 | position: fixed; 44 | z-index: 1; 45 | top: 0; 46 | left: 0; 47 | width: 100%; 48 | height: 72px; 49 | display: flex; 50 | align-items: center; 51 | justify-content: flex-end; 52 | background: #121212; 53 | } 54 | 55 | .logo { 56 | display: flex; 57 | align-items: center; 58 | gap: 8px; 59 | width: 88px; 60 | padding-right: 10px; 61 | } 62 | 63 | @media (width >= 500px) { 64 | .logo { 65 | margin-bottom: 0; 66 | } 67 | } 68 | 69 | .logo img { 70 | height: 20px; 71 | } 72 | 73 | .center { 74 | flex: 0 0 auto; 75 | display: flex; 76 | align-items: center; 77 | gap: 10px; 78 | margin: 0 auto; 79 | color: #888989; 80 | } 81 | 82 | .center button { 83 | display: none; 84 | background: #222222; 85 | height: 40px; 86 | border-radius: 50%; 87 | font-size: 20px; 88 | } 89 | 90 | @media (width >= 500px) { 91 | .center button { 92 | display: block; 93 | } 94 | } 95 | 96 | .search { 97 | position: relative; 98 | display: none; 99 | } 100 | 101 | @media (width >= 500px) { 102 | .search { 103 | display: block; 104 | } 105 | } 106 | 107 | .search button { 108 | position: absolute; 109 | top: 50%; 110 | right: 1px; 111 | translate: 0 -50%; 112 | z-index: 1; 113 | font-size: 20px; 114 | width: 60px; 115 | height: 42px; 116 | border-radius: 0; 117 | border-top-right-radius: 20px; 118 | border-bottom-right-radius: 20px; 119 | background: #222222; 120 | } 121 | 122 | .search input { 123 | flex: 1 1 auto; 124 | height: 44px; 125 | width: 25vw; 126 | padding-left: 16px; 127 | padding-right: 60px; 128 | font-size: 16px; 129 | border: 1px solid #303030; 130 | border-radius: 22px; 131 | background: #121212; 132 | color: inherit; 133 | font-family: inherit; 134 | font-weight: 400; 135 | outline: none; 136 | } 137 | 138 | @media (width >= 650px) { 139 | .search input { 140 | width: 240px; 141 | } 142 | } 143 | 144 | @media (width >= 850px) { 145 | .search input { 146 | width: 30vw; 147 | } 148 | } 149 | 150 | .navbar nav { 151 | display: flex; 152 | align-items: center; 153 | padding-right: 20px; 154 | } 155 | 156 | .navbar nav img { 157 | flex: 0 32px; 158 | width: 32px; 159 | height: 32px; 160 | margin-left: 8px; 161 | border-radius: 50%; 162 | } 163 | 164 | @media (width >= 500px) { 165 | .navbar nav button:is(:nth-child(1), :nth-child(2)) { 166 | display: none; 167 | } 168 | } 169 | 170 | @media (width < 400px) { 171 | .navbar nav button:is(:nth-child(2), :nth-child(4)) { 172 | display: none; 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-8/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-7/styles.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | :root { 6 | --tab-width: 260px; 7 | } 8 | 9 | body { 10 | margin: 0; 11 | background: #f2f1f4; 12 | font-family: "Euclid Circular A"; 13 | } 14 | 15 | button { 16 | background: transparent; 17 | border: 0; 18 | padding: 0; 19 | cursor: pointer; 20 | text-align: left; 21 | } 22 | 23 | .sidebar { 24 | position: fixed; 25 | top: 0; 26 | left: 0; 27 | width: 260px; 28 | height: 100%; 29 | padding: 0 20px; 30 | background: #fff; 31 | box-shadow: -2px 0 24px rgb(0 0 0 / 6%); 32 | transition: width 0.4s; 33 | } 34 | 35 | .tabs { 36 | position: relative; 37 | display: flex; 38 | align-items: center; 39 | height: 72px; 40 | border-bottom: 1px solid rgb(0 0 0 / 10%); 41 | margin-bottom: 16px; 42 | } 43 | 44 | .tabs button { 45 | flex: 1 1 auto; 46 | display: grid; 47 | place-items: center; 48 | opacity: 0.6; 49 | color: #756f7d; 50 | } 51 | 52 | .tabs button.active { 53 | opacity: 1; 54 | } 55 | 56 | .tabs .underline { 57 | position: absolute; 58 | left: 0; 59 | bottom: -3px; 60 | width: 33.33%; 61 | height: 4px; 62 | border-radius: 2px; 63 | background: #8b50e3; 64 | transition: 0.3s; 65 | } 66 | 67 | .sidebar button { 68 | position: relative; 69 | display: flex; 70 | gap: 16px; 71 | align-items: center; 72 | height: 50px; 73 | width: 100%; 74 | font-family: inherit; 75 | font-size: 16px; 76 | font-weight: 400; 77 | line-height: 1; 78 | padding: 0 25px; 79 | color: #4d4953; 80 | } 81 | 82 | .material-symbols-outlined { 83 | font-size: 22px; 84 | } 85 | 86 | form button, 87 | form input { 88 | border: 0; 89 | padding: 12px 0; 90 | height: 60px; 91 | background: transparent; 92 | font-family: inherit; 93 | font-size: 14px; 94 | outline: none; 95 | } 96 | 97 | form { 98 | flex: 1 1 auto; 99 | min-width: 0; 100 | margin: 0; 101 | padding: 16px 16px; 102 | display: grid; 103 | gap: 16px; 104 | width: 100%; 105 | } 106 | 107 | .textbox { 108 | position: relative; 109 | } 110 | 111 | .textbox span { 112 | position: absolute; 113 | top: 50%; 114 | translate: 0 -50%; 115 | left: 16px; 116 | font-size: 20px; 117 | pointer-events: none; 118 | color: rgb(0 0 0 / 40%); 119 | } 120 | 121 | .textbox input { 122 | padding: 0 24px 0 46px; 123 | border-radius: 6px; 124 | border: 2px solid rgb(0 0 0 / 10%); 125 | color: rgb(0 0 0 / 96%); 126 | height: 50px; 127 | width: 190px; 128 | } 129 | 130 | .row { 131 | display: flex; 132 | justify-content: space-between; 133 | margin-bottom: 10px; 134 | width: 100%; 135 | } 136 | 137 | .switch-label { 138 | font-size: 14px; 139 | color: rgb(0 0 0 / 60%); 140 | } 141 | 142 | .switch { 143 | display: inline-block; 144 | } 145 | 146 | .switch input { 147 | display: none; 148 | } 149 | 150 | .switch label { 151 | display: block; 152 | width: 40px; 153 | height: 20px; 154 | padding: 2px; 155 | border-radius: 15px; 156 | border: 2px solid #7e8382; 157 | cursor: pointer; 158 | transition: 0.3s; 159 | } 160 | 161 | .switch label::after { 162 | content: ""; 163 | display: inherit; 164 | width: 12px; 165 | height: 12px; 166 | border-radius: 12px; 167 | background: #7e8382; 168 | transition: 0.3s; 169 | } 170 | 171 | .switch input:checked ~ label { 172 | border-color: #8b50e3; 173 | } 174 | 175 | .switch input:checked ~ label::after { 176 | translate: 20px 0; 177 | background: #8b50e3; 178 | } 179 | 180 | .switch input:disabled ~ label { 181 | opacity: 0.35; 182 | cursor: not-allowed; 183 | } 184 | 185 | .switch.square label, 186 | .switch.square label::after { 187 | border-radius: 0; 188 | } 189 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-1/Sidebar.tsx: -------------------------------------------------------------------------------- 1 | import { FC, useState } from "react"; 2 | import "./styles.css"; 3 | import Logo from "./logo.png"; 4 | 5 | const menuItems = [ 6 | { 7 | name: "Apps", 8 | icon: "apps", 9 | }, 10 | { 11 | name: "Subscriptions", 12 | icon: "subscriptions", 13 | }, 14 | { 15 | name: "Library", 16 | icon: "video_library", 17 | }, 18 | { 19 | name: "Explore", 20 | icon: "explore", 21 | items: ["Movies", "Live", "Gaming", "News"], 22 | }, 23 | { 24 | name: "Settings", 25 | icon: "settings", 26 | items: ["History", "Help", "Feedback", "Reports"], 27 | }, 28 | { 29 | name: "Trending", 30 | icon: "mode_heat", 31 | }, 32 | { 33 | name: "Music", 34 | icon: "music_note", 35 | }, 36 | { 37 | name: "Watch Later", 38 | icon: "schedule", 39 | }, 40 | ]; 41 | 42 | const Icon = ({ icon }: { icon: string }) => ( 43 | {icon} 44 | ); 45 | 46 | const NavHeader = () => ( 47 |
48 | 51 | 52 |
53 | ); 54 | 55 | type ButtonProps = { 56 | onClick: (item: string) => void; 57 | name: string; 58 | icon?: string; 59 | isActive: boolean; 60 | hasSubNav?: boolean; 61 | }; 62 | 63 | const NavButton: FC = ({ 64 | onClick, 65 | name, 66 | icon, 67 | isActive, 68 | hasSubNav, 69 | }) => ( 70 | 79 | ); 80 | 81 | export const Sidebar = () => { 82 | const [activeItem, setActiveItem] = useState(""); 83 | 84 | const handleClick = (item: string) => { 85 | console.log("activeItem", activeItem); 86 | setActiveItem(item !== activeItem ? item : ""); 87 | }; 88 | 89 | const isSubNavOpen = (item: string, items: string[]) => 90 | items.some((i) => i === activeItem) || item === activeItem; 91 | 92 | return ( 93 | 135 | ); 136 | }; 137 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-4/styles.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | :root { 6 | --tab-width: 260px; 7 | } 8 | 9 | body { 10 | margin: 0; 11 | background: #2a262c; 12 | font-family: "Euclid Circular A"; 13 | } 14 | 15 | button { 16 | background: transparent; 17 | border: 0; 18 | padding: 0; 19 | cursor: pointer; 20 | text-align: left; 21 | } 22 | 23 | .sidebar { 24 | position: fixed; 25 | top: 0; 26 | left: 0; 27 | display: flex; 28 | flex-direction: column; 29 | width: var(--tab-width); 30 | height: 100%; 31 | background: #121114; 32 | transition: width 0.4s; 33 | } 34 | 35 | header { 36 | position: relative; 37 | display: flex; 38 | align-items: center; 39 | height: 72px; 40 | border-bottom: 1px solid rgb(225 225 225 / 10%); 41 | margin-bottom: 16px; 42 | } 43 | 44 | .sidebar .sidebar-header button { 45 | flex: 1 1 auto; 46 | display: grid; 47 | place-items: center; 48 | opacity: 0.5; 49 | } 50 | 51 | .sidebar button .material-symbols-outlined { 52 | color: #9c9c9c; 53 | } 54 | 55 | .sidebar .sidebar-header button.active { 56 | opacity: 1; 57 | } 58 | 59 | header .underline { 60 | position: absolute; 61 | left: 0; 62 | bottom: 0; 63 | width: 33.33%; 64 | height: 3px; 65 | background: #9d5bff; 66 | transition: 0.3s; 67 | } 68 | 69 | .sidebar button { 70 | position: relative; 71 | display: flex; 72 | gap: 16px; 73 | align-items: center; 74 | height: 50px; 75 | width: 100%; 76 | font-family: inherit; 77 | font-size: 16px; 78 | font-weight: 400; 79 | line-height: 1; 80 | padding: 0 25px; 81 | color: #f9f9f9; 82 | } 83 | 84 | .material-symbols-outlined { 85 | font-size: 22px; 86 | } 87 | 88 | .tabs { 89 | flex: 1 1 auto; 90 | position: relative; 91 | overflow: hidden; 92 | } 93 | 94 | .tabs > div { 95 | position: absolute; 96 | top: 0; 97 | left: 0; 98 | transition: 0.3s; 99 | display: flex; 100 | } 101 | 102 | .tabs > div > div { 103 | width: var(--tab-width); 104 | } 105 | 106 | form button, 107 | form input { 108 | border: 0; 109 | padding: 16px; 110 | width: 100%; 111 | height: 60px; 112 | background: transparent; 113 | font-family: inherit; 114 | font-size: 14px; 115 | outline: none; 116 | } 117 | 118 | form { 119 | margin: 0; 120 | display: grid; 121 | padding: 10px 32px; 122 | gap: 16px; 123 | } 124 | 125 | .textbox { 126 | position: relative; 127 | } 128 | 129 | .textbox span { 130 | position: absolute; 131 | top: 50%; 132 | translate: 0 -50%; 133 | left: 16px; 134 | font-size: 20px; 135 | pointer-events: none; 136 | color: rgb(255 255 255 / 40%); 137 | } 138 | 139 | .textbox input { 140 | padding: 0 24px 0 46px; 141 | border-radius: 6px; 142 | border: 2px solid rgb(225 225 225 / 10%); 143 | color: rgb(255 255 255 / 96%); 144 | height: 50px; 145 | } 146 | 147 | .row { 148 | display: flex; 149 | justify-content: space-between; 150 | margin-bottom: 10px; 151 | } 152 | 153 | .switch-label { 154 | font-size: 14px; 155 | color: rgb(225 225 225 / 60%); 156 | } 157 | 158 | .switch { 159 | display: inline-block; 160 | } 161 | 162 | .switch input { 163 | display: none; 164 | } 165 | 166 | .switch label { 167 | display: block; 168 | width: 40px; 169 | height: 20px; 170 | padding: 2px; 171 | border-radius: 15px; 172 | border: 2px solid #7e8382; 173 | cursor: pointer; 174 | transition: 0.3s; 175 | } 176 | 177 | .switch label::after { 178 | content: ""; 179 | display: inherit; 180 | width: 12px; 181 | height: 12px; 182 | border-radius: 12px; 183 | background: #7e8382; 184 | transition: 0.3s; 185 | } 186 | 187 | .switch input:checked ~ label { 188 | border-color: #25c89c; 189 | } 190 | 191 | .switch input:checked ~ label::after { 192 | translate: 20px 0; 193 | background: #25c89c; 194 | } 195 | 196 | .switch input:disabled ~ label { 197 | opacity: 0.35; 198 | cursor: not-allowed; 199 | } 200 | 201 | .switch.square label, 202 | .switch.square label::after { 203 | border-radius: 0; 204 | } 205 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-10/Sidebar.tsx: -------------------------------------------------------------------------------- 1 | import { FC, useRef, useState } from "react"; 2 | import "./styles.css"; 3 | 4 | const menuItems = [ 5 | { 6 | name: "Home", 7 | icon: "home", 8 | }, 9 | { 10 | name: "Settings", 11 | icon: "settings", 12 | items: ["Display", "Editor", "Theme", "Interface"], 13 | }, 14 | { 15 | name: "Create", 16 | icon: "add_box", 17 | items: ["Article", "Document", "Report"], 18 | }, 19 | { 20 | name: "Account", 21 | icon: "lock", 22 | items: ["Dashboard", "Logout"], 23 | }, 24 | { 25 | name: "Products", 26 | icon: "inventory_2", 27 | }, 28 | { 29 | name: "Favourites", 30 | icon: "favorite", 31 | }, 32 | ]; 33 | 34 | type Item = { 35 | name: string; 36 | icon: string; 37 | items: string[]; 38 | }; 39 | 40 | const Icon = ({ icon }: { icon: string }) => ( 41 | {icon} 42 | ); 43 | 44 | const NavHeader = () => ( 45 |
46 | 49 | Admin 50 |
51 | ); 52 | 53 | type ButtonProps = { 54 | onClick: (item: string) => void; 55 | name: string; 56 | icon?: string; 57 | isActive: boolean; 58 | hasSubNav?: boolean; 59 | }; 60 | 61 | const NavButton: FC = ({ 62 | onClick, 63 | name, 64 | icon, 65 | isActive, 66 | hasSubNav, 67 | }) => ( 68 | 77 | ); 78 | 79 | type SubMenuProps = { 80 | item: Item; 81 | activeItem: string; 82 | handleClick: (args0: string) => void; 83 | }; 84 | 85 | const SubMenu: FC = ({ item, activeItem, handleClick }) => { 86 | const navRef = useRef(null); 87 | 88 | const isSubNavOpen = (item: string, items: string[]) => 89 | items.some((i) => i === activeItem) || item === activeItem; 90 | 91 | return ( 92 |
100 |
101 | {item?.items.map((subItem) => ( 102 | 107 | ))} 108 |
109 |
110 | ); 111 | }; 112 | 113 | export const Sidebar = () => { 114 | const [activeItem, setActiveItem] = useState(""); 115 | 116 | const handleClick = (item: string) => { 117 | console.log("activeItem", activeItem); 118 | setActiveItem(item !== activeItem ? item : ""); 119 | }; 120 | 121 | return ( 122 | 154 | ); 155 | }; 156 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-9/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-3/Sidebar.tsx: -------------------------------------------------------------------------------- 1 | import { FC, useEffect, useRef, useState } from "react"; 2 | import "./styles.css"; 3 | import Logo from "./logo.png"; 4 | 5 | const menuItems = [ 6 | { 7 | name: "Home", 8 | icon: "home", 9 | }, 10 | { 11 | name: "Settings", 12 | icon: "settings", 13 | items: ["Display", "Editor", "Theme", "Interface"], 14 | }, 15 | { 16 | name: "Create", 17 | icon: "add_box", 18 | items: ["Article", "Document", "Report"], 19 | }, 20 | { 21 | name: "Account", 22 | icon: "lock", 23 | items: ["Dashboard", "Logout"], 24 | }, 25 | { 26 | name: "Products", 27 | icon: "inventory_2", 28 | }, 29 | { 30 | name: "Favourites", 31 | icon: "favorite", 32 | }, 33 | { 34 | name: "Search", 35 | icon: "search", 36 | }, 37 | { 38 | name: "Users", 39 | icon: "person", 40 | }, 41 | ]; 42 | 43 | type Item = { 44 | name: string; 45 | icon: string; 46 | items: string[]; 47 | }; 48 | 49 | const Icon = ({ icon }: { icon: string }) => ( 50 | {icon} 51 | ); 52 | 53 | const NavHeader = () => ( 54 |
55 | 58 | Admin 59 |
60 | ); 61 | 62 | type ButtonProps = { 63 | onClick: (item: string) => void; 64 | name: string; 65 | icon?: string; 66 | isActive: boolean; 67 | hasSubNav?: boolean; 68 | }; 69 | 70 | const NavButton: FC = ({ 71 | onClick, 72 | name, 73 | icon, 74 | isActive, 75 | hasSubNav, 76 | }) => ( 77 | 86 | ); 87 | 88 | type SubMenuProps = { 89 | item: Item; 90 | activeItem: string; 91 | handleClick: (args0: string) => void; 92 | }; 93 | 94 | const SubMenu: FC = ({ item, activeItem, handleClick }) => { 95 | const navRef = useRef(null); 96 | 97 | const isSubNavOpen = (item: string, items: string[]) => 98 | items.some((i) => i === activeItem) || item === activeItem; 99 | 100 | return ( 101 |
109 |
110 | {item?.items.map((subItem) => ( 111 | 116 | ))} 117 |
118 |
119 | ); 120 | }; 121 | 122 | export const Sidebar = () => { 123 | const [activeItem, setActiveItem] = useState(""); 124 | 125 | const handleClick = (item: string) => { 126 | console.log("activeItem", activeItem); 127 | setActiveItem(item !== activeItem ? item : ""); 128 | }; 129 | 130 | return ( 131 | 163 | ); 164 | }; 165 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-5/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #1b192d !important; 3 | } 4 | 5 | * { 6 | box-sizing: border-box; 7 | } 8 | 9 | :root { 10 | --tab-width: 260px; 11 | } 12 | 13 | body { 14 | margin: 0; 15 | background: #2a262c; 16 | font-family: "Euclid Circular A"; 17 | } 18 | 19 | button { 20 | background: transparent; 21 | border: 0; 22 | padding: 0; 23 | cursor: pointer; 24 | text-align: left; 25 | } 26 | 27 | .sidebar { 28 | position: fixed; 29 | top: 0; 30 | left: 0; 31 | width: var(--tab-width); 32 | height: 100%; 33 | background: #0a0910; 34 | transition: width 0.4s; 35 | } 36 | 37 | .sidebar > div { 38 | padding: 0 20px; 39 | display: flex; 40 | flex-direction: column; 41 | height: 100%; 42 | } 43 | 44 | header { 45 | position: relative; 46 | display: flex; 47 | align-items: center; 48 | height: 72px; 49 | border-bottom: 1px solid rgb(225 225 225 / 10%); 50 | margin-bottom: 16px; 51 | } 52 | 53 | .sidebar .sidebar-header button { 54 | flex: 1 1 auto; 55 | display: grid; 56 | place-items: center; 57 | opacity: 0.5; 58 | } 59 | 60 | .sidebar button .material-symbols-outlined { 61 | color: #e0e0e0; 62 | } 63 | 64 | .sidebar .sidebar-header button.active { 65 | opacity: 1; 66 | } 67 | 68 | header .underline { 69 | position: absolute; 70 | left: 0; 71 | bottom: -3px; 72 | width: 33.33%; 73 | height: 4px; 74 | border-radius: 2px; 75 | background: #ff5bab; 76 | transition: 0.3s; 77 | } 78 | 79 | .sidebar button { 80 | position: relative; 81 | display: flex; 82 | gap: 16px; 83 | align-items: center; 84 | height: 50px; 85 | width: 100%; 86 | font-family: inherit; 87 | font-size: 16px; 88 | font-weight: 400; 89 | line-height: 1; 90 | padding: 0 25px; 91 | color: #f9f9f9; 92 | } 93 | 94 | .material-symbols-outlined { 95 | font-size: 22px; 96 | } 97 | 98 | .tabs { 99 | flex: 1 1 auto; 100 | position: relative; 101 | overflow: hidden; 102 | } 103 | 104 | .tabs > div { 105 | position: absolute; 106 | top: 0; 107 | left: 0; 108 | transition: 0.3s; 109 | display: flex; 110 | opacity: 0; 111 | width: 100%; 112 | visibility: hidden; 113 | translate: 0 20px; 114 | transition: 0.3s; 115 | } 116 | 117 | .tabs > div.active { 118 | opacity: 1; 119 | visibility: visible; 120 | translate: 0; 121 | } 122 | 123 | .tabs > div > div { 124 | display: grid; 125 | width: 100%; 126 | } 127 | 128 | form button, 129 | form input { 130 | border: 0; 131 | padding: 12px 0; 132 | height: 60px; 133 | background: transparent; 134 | font-family: inherit; 135 | font-size: 14px; 136 | outline: none; 137 | } 138 | 139 | form { 140 | flex: 1 1 auto; 141 | min-width: 0; 142 | margin: 0; 143 | padding: 16px 16px; 144 | display: grid; 145 | gap: 16px; 146 | width: 100%; 147 | } 148 | 149 | .textbox { 150 | position: relative; 151 | } 152 | 153 | .textbox span { 154 | position: absolute; 155 | top: 50%; 156 | translate: 0 -50%; 157 | left: 16px; 158 | font-size: 20px; 159 | pointer-events: none; 160 | color: rgb(255 255 255 / 40%); 161 | } 162 | 163 | .textbox input { 164 | padding: 0 24px 0 46px; 165 | border-radius: 6px; 166 | border: 2px solid rgb(225 225 225 / 10%); 167 | color: rgb(255 255 255 / 96%); 168 | height: 50px; 169 | width: 190px; 170 | } 171 | 172 | .row { 173 | display: flex; 174 | justify-content: space-between; 175 | margin-bottom: 10px; 176 | width: 100%; 177 | } 178 | 179 | .switch-label { 180 | font-size: 14px; 181 | color: rgb(225 225 225 / 60%); 182 | } 183 | 184 | .switch { 185 | display: inline-block; 186 | } 187 | 188 | .switch input { 189 | display: none; 190 | } 191 | 192 | .switch label { 193 | display: block; 194 | width: 40px; 195 | height: 20px; 196 | padding: 2px; 197 | border-radius: 15px; 198 | border: 2px solid #7e8382; 199 | cursor: pointer; 200 | transition: 0.3s; 201 | } 202 | 203 | .switch label::after { 204 | content: ""; 205 | display: inherit; 206 | width: 12px; 207 | height: 12px; 208 | border-radius: 12px; 209 | background: #7e8382; 210 | transition: 0.3s; 211 | } 212 | 213 | .switch input:checked ~ label { 214 | border-color: #ff5bab; 215 | } 216 | 217 | .switch input:checked ~ label::after { 218 | translate: 20px 0; 219 | background: #ff5bab; 220 | } 221 | 222 | .switch input:disabled ~ label { 223 | opacity: 0.35; 224 | cursor: not-allowed; 225 | } 226 | 227 | .switch.square label, 228 | .switch.square label::after { 229 | border-radius: 0; 230 | } 231 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-7/Sidebar.tsx: -------------------------------------------------------------------------------- 1 | import { FC, useState } from "react"; 2 | import "./styles.css"; 3 | 4 | import "react-responsive-carousel/lib/styles/carousel.min.css"; 5 | import { Carousel as ReactCarousel } from "react-responsive-carousel"; 6 | 7 | const menuItems = [ 8 | { 9 | name: "Home", 10 | icon: "home", 11 | }, 12 | { 13 | name: "Apps", 14 | icon: "dashboard", 15 | }, 16 | { 17 | name: "Create", 18 | icon: "add_box", 19 | }, 20 | { 21 | name: "Favourites", 22 | icon: "favorite", 23 | }, 24 | ]; 25 | 26 | const Icon = ({ icon }: { icon: string }) => ( 27 | {icon} 28 | ); 29 | 30 | const tabs = ["menu", "lock", "settings"]; 31 | 32 | type NavProps = { 33 | activeTab: number; 34 | onTabClicked: (tab: number) => void; 35 | }; 36 | 37 | const Nav: FC = ({ activeTab, onTabClicked }) => ( 38 |
39 | {tabs.map((tab, index) => ( 40 | 48 | ))} 49 |
55 |
56 | ); 57 | 58 | type ButtonProps = { 59 | name: string; 60 | icon?: string; 61 | }; 62 | 63 | const NavButton: FC = ({ name, icon }) => ( 64 | 68 | ); 69 | 70 | export const Sidebar = () => { 71 | const [activeTab, setActiveTab] = useState(0); 72 | 73 | const handleTabClicked = (index: number) => setActiveTab(index); 74 | 75 | return ( 76 | 142 | ); 143 | }; 144 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-4/Sidebar.tsx: -------------------------------------------------------------------------------- 1 | import { FC, useEffect, useRef, useState } from "react"; 2 | import "./styles.css"; 3 | import Logo from "./logo.png"; 4 | 5 | const menuItems = [ 6 | { 7 | name: "Home", 8 | icon: "home", 9 | }, 10 | { 11 | name: "Apps", 12 | icon: "apps", 13 | }, 14 | { 15 | name: "Create", 16 | icon: "add_box", 17 | }, 18 | { 19 | name: "Profile", 20 | icon: "person", 21 | }, 22 | { 23 | name: "Products", 24 | icon: "inventory_2", 25 | }, 26 | { 27 | name: "Favourites", 28 | icon: "favorite", 29 | }, 30 | { 31 | name: "Search", 32 | icon: "search", 33 | }, 34 | { 35 | name: "Users", 36 | icon: "person", 37 | }, 38 | ]; 39 | 40 | const Icon = ({ icon }: { icon: string }) => ( 41 | {icon} 42 | ); 43 | 44 | const tabs = ["menu", "lock", "settings"]; 45 | 46 | type HeaderProps = { 47 | activeTab: number; 48 | onTabClicked: (tab: number) => void; 49 | }; 50 | 51 | const NavHeader: FC = ({ activeTab, onTabClicked }) => ( 52 |
53 | {tabs.map((tab, index) => ( 54 | 62 | ))} 63 |
69 |
70 | ); 71 | 72 | type ButtonProps = { 73 | name: string; 74 | icon?: string; 75 | }; 76 | 77 | const NavButton: FC = ({ name, icon }) => ( 78 | 82 | ); 83 | 84 | export const Sidebar = () => { 85 | const [activeTab, setActiveTab] = useState(0); 86 | 87 | const handleTabClicked = (tab: number) => { 88 | setActiveTab(tab); 89 | }; 90 | 91 | return ( 92 | 154 | ); 155 | }; 156 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-5/Sidebar.tsx: -------------------------------------------------------------------------------- 1 | import { FC, ReactNode, useState } from "react"; 2 | import "./styles.css"; 3 | 4 | const menuItems = [ 5 | { 6 | name: "Home", 7 | icon: "home", 8 | }, 9 | { 10 | name: "Apps", 11 | icon: "apps", 12 | }, 13 | { 14 | name: "Create", 15 | icon: "add_box", 16 | }, 17 | { 18 | name: "Profile", 19 | icon: "person", 20 | }, 21 | { 22 | name: "Products", 23 | icon: "inventory_2", 24 | }, 25 | { 26 | name: "Favourites", 27 | icon: "favorite", 28 | }, 29 | { 30 | name: "Search", 31 | icon: "search", 32 | }, 33 | { 34 | name: "Users", 35 | icon: "person", 36 | }, 37 | ]; 38 | 39 | const Icon = ({ icon }: { icon: string }) => ( 40 | {icon} 41 | ); 42 | 43 | const tabs = ["menu", "lock", "settings"]; 44 | 45 | type HeaderProps = { 46 | activeTab: number; 47 | onTabClicked: (tab: number) => void; 48 | }; 49 | 50 | const NavHeader: FC = ({ activeTab, onTabClicked }) => ( 51 |
52 | {tabs.map((tab, index) => ( 53 | 61 | ))} 62 |
68 |
69 | ); 70 | 71 | type ButtonProps = { 72 | name: string; 73 | icon?: string; 74 | }; 75 | 76 | const NavButton: FC = ({ name, icon }) => ( 77 | 81 | ); 82 | 83 | const Tab = ({ 84 | children, 85 | isActive, 86 | }: { 87 | children: ReactNode; 88 | isActive: boolean; 89 | }) => { 90 | return
{children}
; 91 | }; 92 | 93 | export const Sidebar = () => { 94 | const [activeTab, setActiveTab] = useState(0); 95 | 96 | const handleTabClicked = (tab: number) => { 97 | setActiveTab(tab); 98 | }; 99 | 100 | return ( 101 | 162 | ); 163 | }; 164 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-2/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/concepts/concept-1/navbar/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/concepts/concept-1/sidebar/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/sidebars/sidebar-6/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | --------------------------------------------------------------------------------