├── .eslintrc.cjs ├── .gitignore ├── .prettierignore ├── .prettierrc ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── postcss.config.js ├── public └── vite.svg ├── src ├── App.jsx ├── assets │ └── react.svg ├── components │ ├── Navigation.jsx │ ├── Sidebar.jsx │ └── index.js ├── index.css └── main.jsx ├── tailwind.config.js └── vite.config.js /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | 3 | module.exports = { 4 | env: { browser: true, es2020: true }, 5 | extends: [ 6 | 'eslint:recommended', 7 | 'plugin:react/recommended', 8 | 'plugin:react/jsx-runtime', 9 | 'plugin:react-hooks/recommended', 10 | ], 11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, 12 | settings: { react: { version: '18.2' } }, 13 | plugins: ['react-refresh'], 14 | rules: { 15 | 'react-refresh/only-export-components': [ 16 | 'warn', 17 | { allowConstantExport: true }, 18 | ], 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | build 4 | src/globe/countries-110m.json 5 | src/us-cities.json -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "endOfLine": "lf", 4 | "htmlWhitespaceSensitivity": "css", 5 | "insertPragma": false, 6 | "jsxBracketSameLine": false, 7 | "jsxSingleQuote": false, 8 | "printWidth": 80, 9 | "proseWrap": "always", 10 | "quoteProps": "as-needed", 11 | "requirePragma": false, 12 | "semi": false, 13 | "singleQuote": true, 14 | "tabWidth": 2, 15 | "trailingComma": "all", 16 | "useTabs": false 17 | } 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Getting Started 2 | 3 | To get started with the project in your local development environment, follow 4 | these steps: 5 | 6 | 1. Clone the repository to your local machine. 7 | 8 | ```bash 9 | git@github.com:Yazdun/react-animated-sidebar.git 10 | ``` 11 | 12 | 2. Open the cloned folder in your preferred code editor, install the required 13 | dependencies by running the following command in the terminal: 14 | 15 | ```bash 16 | npm install 17 | ``` 18 | 19 | 3. To access the starter files for the tutorial, use the following command: 20 | 21 | ```bash 22 | git checkout starter 23 | ``` 24 | 25 | 4. Start the development server by running the following command: 26 | 27 | ```bash 28 | npm run dev 29 | ``` 30 | 31 | You are now ready to go! -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Animated Sidebar 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-animated-sidebar", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint src --ext js,jsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "framer-motion": "^10.12.18", 14 | "react": "^18.2.0", 15 | "react-dom": "^18.2.0", 16 | "react-icons": "^4.10.1", 17 | "react-use": "^17.4.0" 18 | }, 19 | "devDependencies": { 20 | "@types/react": "^18.2.14", 21 | "@types/react-dom": "^18.2.6", 22 | "@vitejs/plugin-react": "^4.0.1", 23 | "autoprefixer": "^10.4.14", 24 | "eslint": "^8.44.0", 25 | "eslint-plugin-react": "^7.32.2", 26 | "eslint-plugin-react-hooks": "^4.6.0", 27 | "eslint-plugin-react-refresh": "^0.4.1", 28 | "postcss": "^8.4.25", 29 | "tailwindcss": "^3.3.2", 30 | "vite": "^4.4.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/App.jsx: -------------------------------------------------------------------------------- 1 | import { Navigation } from './components' 2 | 3 | function App() { 4 | return ( 5 |
6 | 7 |
8 | ) 9 | } 10 | 11 | export default App 12 | -------------------------------------------------------------------------------- /src/assets/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/Navigation.jsx: -------------------------------------------------------------------------------- 1 | import { Sidebar } from './Sidebar' 2 | import { FiGithub } from 'react-icons/fi' 3 | 4 | export const Navigation = () => { 5 | return ( 6 | 19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /src/components/Sidebar.jsx: -------------------------------------------------------------------------------- 1 | import { useRef, useState } from 'react' 2 | import { GiHamburgerMenu } from 'react-icons/gi' 3 | import { AnimatePresence, motion } from 'framer-motion' 4 | import { useClickAway } from 'react-use' 5 | import { AiOutlineRollback } from 'react-icons/ai' 6 | import { BiHomeSmile, BiUser } from 'react-icons/bi' 7 | import { HiOutlineChatBubbleBottomCenterText } from 'react-icons/hi2' 8 | import { FiSettings, FiShoppingCart } from 'react-icons/fi' 9 | 10 | export const Sidebar = () => { 11 | const [open, setOpen] = useState(false) 12 | const ref = useRef(null) 13 | useClickAway(ref, () => setOpen(false)) 14 | const toggleSidebar = () => setOpen(prev => !prev) 15 | 16 | return ( 17 | <> 18 | 25 | 26 | {open && ( 27 | <> 28 | 33 | 39 |
40 | Welcome 41 | 48 |
49 | 68 |
69 | 70 | )} 71 |
72 | 73 | ) 74 | } 75 | 76 | const items = [ 77 | { title: 'Home', Icon: BiHomeSmile, href: '#' }, 78 | { title: 'About', Icon: BiUser }, 79 | { title: 'Contact', Icon: HiOutlineChatBubbleBottomCenterText, href: '#' }, 80 | { title: 'Settings', Icon: FiSettings, href: '#' }, 81 | { title: 'Shop', Icon: FiShoppingCart, href: '#' }, 82 | ] 83 | 84 | const framerSidebarBackground = { 85 | initial: { opacity: 0 }, 86 | animate: { opacity: 1 }, 87 | exit: { opacity: 0, transition: { delay: 0.2 } }, 88 | transition: { duration: 0.3 }, 89 | } 90 | 91 | const framerSidebarPanel = { 92 | initial: { x: '-100%' }, 93 | animate: { x: 0 }, 94 | exit: { x: '-100%' }, 95 | transition: { duration: 0.3 }, 96 | } 97 | 98 | const framerText = delay => { 99 | return { 100 | initial: { opacity: 0, x: -50 }, 101 | animate: { opacity: 1, x: 0 }, 102 | transition: { 103 | delay: 0.5 + delay / 10, 104 | }, 105 | } 106 | } 107 | 108 | const framerIcon = { 109 | initial: { scale: 0 }, 110 | animate: { scale: 1 }, 111 | transition: { 112 | type: 'spring', 113 | stiffness: 260, 114 | damping: 20, 115 | delay: 1.5, 116 | }, 117 | } 118 | -------------------------------------------------------------------------------- /src/components/index.js: -------------------------------------------------------------------------------- 1 | export { Navigation } from './Navigation' 2 | export { Sidebar } from './Sidebar' 3 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | body { 6 | @apply bg-zinc-900 text-zinc-200; 7 | } 8 | -------------------------------------------------------------------------------- /src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.jsx' 4 | import './index.css' 5 | 6 | ReactDOM.createRoot(document.getElementById('root')).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [], 8 | }; 9 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | --------------------------------------------------------------------------------