diff --git a/.gitignore b/.gitignore index 97e61955..1437c53f 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,3 @@ yarn-error.log* # vercel .vercel - -# autogenerated css module typings -*.module.scss.d.ts \ No newline at end of file diff --git a/pages/_app.tsx b/pages/_app.tsx index bb8d5f88..e940a065 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -8,7 +8,6 @@ import "src/components/BoardGrid/styles.scss"; import "src/components/Button/styles.scss"; import "src/components/CommunitiesGrid/styles.scss"; import "src/components/Footer/styles.scss"; -import "src/components/NavigationBar/styles.scss"; import "src/components/ScrollDownArrow/styles.scss"; import "src/components/Statistic/styles.scss"; // section css imports diff --git a/src/components/Button/styles.scss b/src/components/Button/styles.scss index 0fffacc3..1cf32561 100644 --- a/src/components/Button/styles.scss +++ b/src/components/Button/styles.scss @@ -25,5 +25,5 @@ .button:hover { opacity: 0.85; transform: translatey(-1px); - transition: 200ms; + transition: 0.2s; } diff --git a/src/components/Footer/styles.scss b/src/components/Footer/styles.scss index 3ccfddfd..862e77ce 100644 --- a/src/components/Footer/styles.scss +++ b/src/components/Footer/styles.scss @@ -123,7 +123,7 @@ cursor: pointer; color: $black; background-color: $hover-blue; - transition-duration: 200ms; + transition-duration: 0.2s; } } .vercel-btn { diff --git a/src/components/NavigationBar/Navbar.module.scss b/src/components/NavigationBar/Navbar.module.scss new file mode 100644 index 00000000..f8e11fc8 --- /dev/null +++ b/src/components/NavigationBar/Navbar.module.scss @@ -0,0 +1,181 @@ +@use "src/styles/colors" as colors; + +.navbarWrapper { + position: fixed; + top: 0; + width: 100%; + font-weight: bold; + z-index: 10; + white-space: nowrap; + + // container for fixed navbar (desktop and mobile) + .navbar { + background-color: colors.$white; + z-index: 20; + font-size: 18px; + width: 100%; + + height: 78px; + display: flex; + justify-content: space-between; + align-items: center; + + // left side of navbar is just the acm logo + .left { + height: 78px; + padding-top: 9px; + padding-bottom: 9px; + margin-left: 32px; + a { + display: flex; + flex-direction: row; + align-items: center; + text-decoration: none; + > img { + height: 60px; + margin: 0; + } + > p { + font-size: 16px; + color: colors.$black; + margin-left: 4px; + margin-bottom: 2px; + } + } + } + + // navbar right side contains all navlinks on desktop + .right { + display: flex; + flex-flow: row nowrap; + justify-content: center; + align-items: center; + + .navItem { + display: flex; + align-items: center; + text-decoration: none; + color: colors.$black; + margin-right: 32px; + } + + .loginButton { + height: 100%; + align-self: center; + + display: flex; + justify-content: center; + align-items: center; + text-decoration: none; + + height: 35px; + width: 150px; + + color: colors.$white; + background-color: colors.$black; + border-radius: 0.5em; + margin-right: 32px; + + &:hover { + opacity: 0.85; + transition: 0.3s; + } + } + } + + // toggle button for mobile menu is only visible on mobile, otherwise hidden + .toggleIcon { + position: relative; + width: 40px; + height: 20px; + margin: 0 30px; + padding: 0; + background-color: colors.$white; + + // the toggle icon is composed of two bars we can separately animate between a hamburger icon and an x icon (default is hamburger, we have .open class we can toggle to rotate into the shape of an x) + .bar1 { + width: 40px; + height: 5px; + border-radius: 2px; + background-color: colors.$black; + position: absolute; + top: 1.5px; + transition: 0.3s ease-in-out all; + + &.open { + transform: rotate(45deg); + top: 5px; + right: 0; + } + } + + .bar2 { + width: 23px; + height: 5px; + border-radius: 2px; + background-color: colors.$black; + position: absolute; + right: 0; + bottom: 1.5px; + transition: 0.3s ease-in-out all; + + &.open { + transform: rotate(-45deg); + width: 40px; + top: 5px; + right: 0; + } + } + } + } + + // menu div for links only on mobile version + .mobileNav { + width: 100vw; + background-color: colors.$white; + position: relative; + z-index: -1; + display: flex; + flex-flow: column nowrap; + justify-content: center; + align-items: center; + line-height: 300%; + transition: 0.3s ease-in-out; + // mobile menu is hidden by positioning under fixed navbar, we open it by sliding it out + margin-top: -15rem; + &.open { + margin-top: 0; + } + .navItem { + width: 100%; + text-align: center; + color: colors.$black; + transition: 0.3s ease-in-out all; + text-decoration: underline solid transparent; + &:hover { + text-decoration: underline solid currentColor; + } + } + } + + // rainbow bar is always visible below navbar, positioned to be at the bottom of the container even when mobile slides out and height changes + .rainbow { + width: 100vw; + height: 0.4em; + bottom: -0.4em; + background: linear-gradient( + 270deg, + colors.$red 0%, + colors.$orange 18.75%, + colors.$green 36.98%, + colors.$turquoise 55.73%, + colors.$blue 75%, + colors.$purple 100% + ); + } +} + +// we use this class to either hide the navlinks or mobile menu toggle based on viewport width +.hidden { + display: none; +} diff --git a/src/components/NavigationBar/Navbar.module.scss.d.ts b/src/components/NavigationBar/Navbar.module.scss.d.ts new file mode 100644 index 00000000..0841fa1f --- /dev/null +++ b/src/components/NavigationBar/Navbar.module.scss.d.ts @@ -0,0 +1,23 @@ +// AUTOGENERATED FILE -- DO NOT EDIT DIRECTLY + +declare namespace NavbarModuleScssNamespace { + export interface INavbarModuleScss { + bar1: string; + bar2: string; + hidden: string; + left: string; + loginButton: string; + mobileNav: string; + navItem: string; + navbar: string; + navbarWrapper: string; + open: string; + rainbow: string; + right: string; + toggleIcon: string; + } +} + +declare const NavbarModuleScssModule: NavbarModuleScssNamespace.INavbarModuleScss; + +export = NavbarModuleScssModule; diff --git a/src/components/NavigationBar/index.tsx b/src/components/NavigationBar/index.tsx index f2b1e828..bc5de68b 100644 --- a/src/components/NavigationBar/index.tsx +++ b/src/components/NavigationBar/index.tsx @@ -1,99 +1,78 @@ import Link from "next/link"; -import Image from "next/image"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import ACMLogo from "public/assets/ACMWhiteLogo.png"; -import CloseMenuButton from "public/assets/closemenubutton.svg"; -import MenuButtonIcon from "public/assets/menubutton.svg"; +import s from "src/components/NavigationBar/Navbar.module.scss"; +import { Size, useWindowSize } from "src/utils"; const navLinks = [ - { to: "/sponsor", text: "Sponsor" }, - { to: "/communities", text: "Communities" }, { to: "/about", text: "About Us" }, + { to: "/communities", text: "Communities" }, + { to: "/sponsor", text: "Sponsor" }, + { to: "#contact", text: "Contact" }, ]; const NavigationBar: React.FC = () => { - const [menuState, setMenuState] = useState(false); + const size: Size = useWindowSize(); + + const [menuOpen, setMenuOpen] = useState(false); + const [mobile, setMobile] = useState(false); + const toggleMenu = () => setMenuOpen(!menuOpen); + + // Switch to mobile less than 920px + useEffect(() => { + setMobile(size.width < 920); + }, [size]); - const toggleMenu = () => setMenuState(!menuState); + // If they go back to desktop size, don't keep the menu open + useEffect(() => { + if (!mobile) setMenuOpen(false); + }, [mobile]); return ( -
-
- + + Member Login + +
+ {/* Mobile Navbar Toggle */} +
- {menuState ? ( -
- - - About Us - - - Communities - - - Sponsor + {/* Mobile Menu Dropdown */} +
+ {navLinks.map((link, key) => ( + + {link.text} - - Contact - - Login -
- ) : ( -
-
- - - ACM Logo -

at UCSD

-
- - -
-
- )} + ))} + + Member Login + +
-
+ {/* Bottom Rainbow */} +
); }; diff --git a/src/components/NavigationBar/styles.scss b/src/components/NavigationBar/styles.scss deleted file mode 100644 index 2fc2c6ed..00000000 --- a/src/components/NavigationBar/styles.scss +++ /dev/null @@ -1,210 +0,0 @@ -@import "src/styles/colors.scss"; - -.navigation-bar { - height: 78px; - font-size: 18px; - font-weight: bold; - - ul { - text-decoration: none; - margin: 0 !important; - padding: 0 !important; - list-style-type: none; - height: 100%; - } - li { - display: flex; - justify-content: center; - align-items: center; - margin-bottom: 0 !important; - text-decoration: none; - list-style-type: none; - height: 100%; - margin-right: 32px; - } - - &__logo { - float: left; - height: 78px; - padding-top: 9px; - padding-bottom: 9px; - margin-left: 32px; - a { - display: flex; - flex-direction: row; - align-items: center; - text-decoration: none; - > img { - height: 60px; - margin: 0; - } - > p { - font-size: 16px; - color: $black; - margin-left: 4px; - margin-bottom: 2px; - } - } - } - - &__nav-button { - float: right; - display: flex; - align-items: center; - a { - text-decoration: none; - color: $black; - } - } - &__login { - float: right; - height: 100%; - align-self: center; - &:hover { - opacity: 0.85; - transition: 200ms; - } - a { - display: flex; - justify-content: center; - align-items: center; - text-decoration: none; - - height: 35px !important; - width: 150px; - - color: $white !important; - background-color: $black !important; - border-radius: 0.5em; - } - } - - &__nav-button--login { - float: right; - } -} -.fixed-nav { - position: fixed; - top: 0; - width: 100%; - font-weight: bold; - background-color: $white; - z-index: 2; - font-size: 18px; - height: 78px; -} -.rainbow { - width: 100vw; - height: 0.4em; - display: table; - z-index: 3; - background: linear-gradient( - 270deg, - $red 0%, - $orange 18.75%, - $green 36.98%, - $turquoise 55.73%, - $blue 75%, - $purple 100% - ); -} -.navbar-mobile-div { - display: none; -} -// Styling for menu based nav bar - -.mobile-links { - display: none; -} - -@media only screen and (max-width: 900px) { - .navigation-bar { - display: none; - } - .navbar-mobile { - margin: 0px !important; - height: 78px; - a:first-of-type { - img { - margin-bottom: 0px !important; - } - } - } - .navbar-mobile-div { - font-size: 16px; - display: block; - } - - .navbar-mobile > button { - padding: 0px 30px; - float: right; - border: none; - background-color: transparent; - outline: none; - } - - .navbar-mobile > a:first-of-type { - display: flex; - align-items: center; - float: left; - height: 60px; - margin: 9px 32px; - text-decoration: none; - img { - height: 60px; - } - > p { - color: $black; - margin: 0 0 0 4px; - } - } - .icon { - height: 78px; - } - .menuicon { - height: 20px; - width: 40px; - margin: 29px 0; - } - - .mobile-links { - z-index: 2; - display: block; - background-color: $black; - padding-top: 0.5em; - padding-bottom: 0.5em; - a { - font-size: 24px !important; - font-weight: bold; - text-decoration: underline solid transparent; - transition: text-decoration 0.2s ease; - color: $white; - padding: 0.5em; - display: block; - text-align: center; - background-color: $black; - } - a:first-of-type { - margin-top: 0.5em; - } - a:hover { - text-decoration: underline solid Currentcolor; - } - button { - position: absolute; - right: 30px; - top: 28px; - height: 40px !important; - width: 60px !important; - color: $white; - background-color: $black; - cursor: pointer; - border: none; - outline: 0; - font-size: 1.3em; - img { - float: right; - } - } - } -}