diff --git a/package.json b/package.json
index 0e794b3..e254e44 100644
--- a/package.json
+++ b/package.json
@@ -4,15 +4,20 @@
"private": true,
"author": "Re:Coded",
"dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^1.2.30",
+ "@fortawesome/free-solid-svg-icons": "^5.14.0",
+ "@fortawesome/react-fontawesome": "^0.1.11",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
+ "classnames": "^2.2.6",
"framer-motion": "^2.3.0",
"prop-types": "^15.7.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.1",
+ "react-swipeable": "^5.5.1",
"tailwindcss": "^1.5.2"
},
"scripts": {
diff --git a/src/App.js b/src/App.js
index d87dcef..d9c6488 100644
--- a/src/App.js
+++ b/src/App.js
@@ -25,7 +25,7 @@ const DefaultRoutes = () => {
-
+
>
@@ -35,13 +35,15 @@ const DefaultRoutes = () => {
function App() {
return (
<>
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
>
);
}
diff --git a/src/components/Navbar/Navbar.js b/src/components/Navbar/Navbar.js
index f5efaf5..b9b4ca7 100644
--- a/src/components/Navbar/Navbar.js
+++ b/src/components/Navbar/Navbar.js
@@ -1,7 +1,30 @@
-import React from 'react';
+import React, { useState } from 'react';
+import Toolbar from './Toolbar';
+import SideNav from './SideNav';
const Navbar = () => {
- return Navbar
;
+ const [navbarOpen, setNavbarOpen] = useState(false);
+
+ const handleToggleMenuClick = () => {
+ setNavbarOpen((prevState) => !prevState);
+ };
+ const handleCloseNavbar = () => {
+ setNavbarOpen(false);
+ };
+ return (
+
+
+
+
+
+ );
};
export default Navbar;
diff --git a/src/components/Navbar/Navbar.test.js b/src/components/Navbar/Navbar.test.js
new file mode 100644
index 0000000..b188616
--- /dev/null
+++ b/src/components/Navbar/Navbar.test.js
@@ -0,0 +1,13 @@
+import React from 'react';
+import { render } from '@testing-library/react';
+import Navbar from './Navbar';
+import { BrowserRouter as Router } from 'react-router-dom';
+test('renders learn react link', () => {
+ const { getByTestId } = render(
+
+
+
+ );
+ const textElement = getByTestId('navbar');
+ expect(textElement).toBeInTheDocument();
+});
diff --git a/src/components/Navbar/SideNav.css b/src/components/Navbar/SideNav.css
new file mode 100644
index 0000000..0d2d3dd
--- /dev/null
+++ b/src/components/Navbar/SideNav.css
@@ -0,0 +1,9 @@
+.side-nav {
+ transition: transform 0.4s ease-out;
+ transform: translateX(100%);
+}
+
+.side-nav.open {
+ transform: translateX(0px);
+ box-shadow: 0px 0px 15px #232931;
+}
diff --git a/src/components/Navbar/SideNav.js b/src/components/Navbar/SideNav.js
new file mode 100644
index 0000000..6b709f8
--- /dev/null
+++ b/src/components/Navbar/SideNav.js
@@ -0,0 +1,62 @@
+import React from 'react';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faTimes } from '@fortawesome/free-solid-svg-icons';
+import './SideNav.css';
+import { Link } from 'react-router-dom';
+import { Swipeable } from 'react-swipeable';
+import PropTypes from 'prop-types';
+const SideNav = ({ navbarOpen, handleToggleMenuClick, handleCloseNavbar }) => {
+ const sideNavClasses = navbarOpen ? 'side-nav open' : 'side-nav';
+ return (
+
+
+
+ );
+};
+SideNav.propTypes = {
+ navbarOpen: PropTypes.bool.isRequired,
+ handleToggleMenuClick: PropTypes.func.isRequired,
+ handleCloseNavbar: PropTypes.func.isRequired,
+};
+export default SideNav;
diff --git a/src/components/Navbar/Toolbar.js b/src/components/Navbar/Toolbar.js
new file mode 100644
index 0000000..38eb05a
--- /dev/null
+++ b/src/components/Navbar/Toolbar.js
@@ -0,0 +1,79 @@
+import React from 'react';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faBars, faTimes } from '@fortawesome/free-solid-svg-icons';
+import { Link, useLocation } from 'react-router-dom';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+const Toolbar = ({ navbarOpen, handleToggleMenuClick }) => {
+ const location = useLocation();
+ const isDark =
+ location.pathname === '/home' || location.pathname === '/about';
+ const navLinksStyle = classNames(
+ 'px-3 py-2 flex items-center text-sm md:text-lg uppercase font-bold leading-snug',
+ {
+ 'text-secondary lg:hover:bg-primary': isDark,
+ 'text-primary lg:hover:bg-darkgray': !isDark,
+ }
+ );
+ return (
+ <>
+
+ >
+ );
+};
+
+Toolbar.propTypes = {
+ navbarOpen: PropTypes.bool.isRequired,
+ handleToggleMenuClick: PropTypes.func.isRequired,
+};
+export default Toolbar;
diff --git a/yarn.lock b/yarn.lock
index 3eeccc9..67693ab 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1134,6 +1134,44 @@
resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-10.1.0.tgz#f0950bba18819512d42f7197e56c518aa491cf18"
integrity sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==
+"@emotion/is-prop-valid@^0.8.2":
+ version "0.8.8"
+ resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a"
+ integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==
+ dependencies:
+ "@emotion/memoize" "0.7.4"
+
+"@emotion/memoize@0.7.4":
+ version "0.7.4"
+ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
+ integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
+
+"@fortawesome/fontawesome-common-types@^0.2.30":
+ version "0.2.30"
+ resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.30.tgz#2f1cc5b46bd76723be41d0013a8450c9ba92b777"
+ integrity sha512-TsRwpTuKwFNiPhk1UfKgw7zNPeV5RhNp2Uw3pws+9gDAkPGKrtjR1y2lI3SYn7+YzyfuNknflpBA1LRKjt7hMg==
+
+"@fortawesome/fontawesome-svg-core@^1.2.30":
+ version "1.2.30"
+ resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.30.tgz#f56dc6791861fe5d1af04fb8abddb94658c576db"
+ integrity sha512-E3sAXATKCSVnT17HYmZjjbcmwihrNOCkoU7dVMlasrcwiJAHxSKeZ+4WN5O+ElgO/FaYgJmASl8p9N7/B/RttA==
+ dependencies:
+ "@fortawesome/fontawesome-common-types" "^0.2.30"
+
+"@fortawesome/free-solid-svg-icons@^5.14.0":
+ version "5.14.0"
+ resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.14.0.tgz#970453f5e8c4915ad57856c3a0252ac63f6fec18"
+ integrity sha512-M933RDM8cecaKMWDSk3FRYdnzWGW7kBBlGNGfvqLVwcwhUPNj9gcw+xZMrqBdRqxnSXdl3zWzTCNNGEtFUq67Q==
+ dependencies:
+ "@fortawesome/fontawesome-common-types" "^0.2.30"
+
+"@fortawesome/react-fontawesome@^0.1.11":
+ version "0.1.11"
+ resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.11.tgz#c1a95a2bdb6a18fa97b355a563832e248bf6ef4a"
+ integrity sha512-sClfojasRifQKI0OPqTy8Ln8iIhnxR/Pv/hukBhWnBz9kQRmqi6JSH3nghlhAY7SUeIIM7B5/D2G8WjX0iepVg==
+ dependencies:
+ prop-types "^15.7.2"
+
"@fullhuman/postcss-purgecss@^2.1.2":
version "2.3.0"
resolved "https://registry.yarnpkg.com/@fullhuman/postcss-purgecss/-/postcss-purgecss-2.3.0.tgz#50a954757ec78696615d3e118e3fee2d9291882e"
@@ -1345,6 +1383,22 @@
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
+"@popmotion/easing@^1.0.1", "@popmotion/easing@^1.0.2":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/@popmotion/easing/-/easing-1.0.2.tgz#17d925c45b4bf44189e5a38038d149df42d8c0b4"
+ integrity sha512-IkdW0TNmRnWTeWI7aGQIVDbKXPWHVEYdGgd5ZR4SH/Ty/61p63jCjrPxX1XrR7IGkl08bjhJROStD7j+RKgoIw==
+
+"@popmotion/popcorn@^0.4.2":
+ version "0.4.4"
+ resolved "https://registry.yarnpkg.com/@popmotion/popcorn/-/popcorn-0.4.4.tgz#a5f906fccdff84526e3fcb892712d7d8a98d6adc"
+ integrity sha512-jYO/8319fKoNLMlY4ZJPiPu8Ea8occYwRZhxpaNn/kZsK4QG2E7XFlXZMJBsTWDw7I1i0uaqyC4zn1nwEezLzg==
+ dependencies:
+ "@popmotion/easing" "^1.0.1"
+ framesync "^4.0.1"
+ hey-listen "^1.0.8"
+ style-value-types "^3.1.7"
+ tslib "^1.10.0"
+
"@sheerun/mutationobserver-shim@^0.3.2":
version "0.3.3"
resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz#5405ee8e444ed212db44e79351f0c70a582aae25"
@@ -2966,6 +3020,11 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"
+classnames@^2.2.6:
+ version "2.2.6"
+ resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
+ integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
+
clean-css@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78"
@@ -4856,6 +4915,29 @@ fragment-cache@^0.2.1:
dependencies:
map-cache "^0.2.2"
+framer-motion@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-2.3.0.tgz#700c3d6a554c86bfa6a2d96e25f25829667cd0b4"
+ integrity sha512-zX6V5vz3joMzacqV7UpiHKUtqLMmU/YsVM6KpeRCi65KjUiymUX5O2jkpR3cCdlr1DkJ1yWUjBWY7xyiO834VA==
+ dependencies:
+ "@popmotion/easing" "^1.0.2"
+ "@popmotion/popcorn" "^0.4.2"
+ framesync "^4.0.4"
+ hey-listen "^1.0.8"
+ popmotion "9.0.0-beta-8"
+ style-value-types "^3.1.9"
+ tslib "^1.10.0"
+ optionalDependencies:
+ "@emotion/is-prop-valid" "^0.8.2"
+
+framesync@^4.0.1, framesync@^4.0.4:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/framesync/-/framesync-4.0.4.tgz#79c42c0118f26821c078570db0ff81fb863516a2"
+ integrity sha512-mdP0WvVHe0/qA62KG2LFUAOiWLng5GLpscRlwzBxu2VXOp6B8hNs5C5XlFigsMgrfDrr2YbqTsgdWZTc4RXRMQ==
+ dependencies:
+ hey-listen "^1.0.8"
+ tslib "^1.10.0"
+
fresh@0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
@@ -5202,6 +5284,11 @@ hex-color-regex@^1.1.0:
resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==
+hey-listen@^1.0.8:
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68"
+ integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==
+
history@^4.9.0:
version "4.10.1"
resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3"
@@ -7897,6 +7984,18 @@ pnp-webpack-plugin@1.6.4:
dependencies:
ts-pnp "^1.1.6"
+popmotion@9.0.0-beta-8:
+ version "9.0.0-beta-8"
+ resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-9.0.0-beta-8.tgz#f5a709f11737734e84f2a6b73f9bcf25ee30c388"
+ integrity sha512-6eQzqursPvnP7ePvdfPeY4wFHmS3OLzNP8rJRvmfFfEIfpFqrQgLsM50Gd9AOvGKJtYJOFknNG+dsnzCpgIdAA==
+ dependencies:
+ "@popmotion/easing" "^1.0.1"
+ "@popmotion/popcorn" "^0.4.2"
+ framesync "^4.0.4"
+ hey-listen "^1.0.8"
+ style-value-types "^3.1.6"
+ tslib "^1.10.0"
+
portfinder@^1.0.25:
version "1.0.26"
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.26.tgz#475658d56ca30bed72ac7f1378ed350bd1b64e70"
@@ -9017,6 +9116,13 @@ react-scripts@3.4.1:
optionalDependencies:
fsevents "2.1.2"
+react-swipeable@^5.5.1:
+ version "5.5.1"
+ resolved "https://registry.yarnpkg.com/react-swipeable/-/react-swipeable-5.5.1.tgz#48ae6182deaf62f21d4b87469b60281dbd7c4a76"
+ integrity sha512-EQObuU3Qg3JdX3WxOn5reZvOSCpU4fwpUAs+NlXSN3y+qtsO2r8VGkVnOQzmByt3BSYj9EWYdUOUfi7vaMdZZw==
+ dependencies:
+ prop-types "^15.6.2"
+
react@^16.13.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"
@@ -10189,6 +10295,14 @@ style-loader@0.23.1:
loader-utils "^1.1.0"
schema-utils "^1.0.0"
+style-value-types@^3.1.6, style-value-types@^3.1.7, style-value-types@^3.1.9:
+ version "3.1.9"
+ resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-3.1.9.tgz#faf7da660d3f284ed695cff61ea197d85b9122cc"
+ integrity sha512-050uqgB7WdvtgacoQKm+4EgKzJExVq0sieKBQQtJiU3Muh6MYcCp4T3M8+dfl6VOF2LR0NNwXBP1QYEed8DfIw==
+ dependencies:
+ hey-listen "^1.0.8"
+ tslib "^1.10.0"
+
stylehacks@^4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5"