Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

responsive navbar #215

Merged
merged 10 commits into from
Mar 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,3 @@ yarn-error.log*

# vercel
.vercel

# autogenerated css module typings
*.module.scss.d.ts
farisashai marked this conversation as resolved.
Show resolved Hide resolved
1 change: 0 additions & 1 deletion pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/components/Button/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@
.button:hover {
opacity: 0.85;
transform: translatey(-1px);
transition: 200ms;
transition: 0.2s;
}
2 changes: 1 addition & 1 deletion src/components/Footer/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
cursor: pointer;
color: $black;
background-color: $hover-blue;
transition-duration: 200ms;
transition-duration: 0.2s;
}
}
.vercel-btn {
Expand Down
181 changes: 181 additions & 0 deletions src/components/NavigationBar/Navbar.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
@use "src/styles/colors" as colors;
farisashai marked this conversation as resolved.
Show resolved Hide resolved

.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;
}
23 changes: 23 additions & 0 deletions src/components/NavigationBar/Navbar.module.scss.d.ts
Original file line number Diff line number Diff line change
@@ -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;
137 changes: 58 additions & 79 deletions src/components/NavigationBar/index.tsx
Original file line number Diff line number Diff line change
@@ -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);
farisashai marked this conversation as resolved.
Show resolved Hide resolved
}, [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 (
<div className="fixed-nav">
<div className="navigation-bar">
<ul>
<li className="navigation-bar__logo">
<Link href="/">
<a>
{/* image breaking the website right now */}
<img src={ACMLogo.src} alt="ACM Logo" />
<p>at UCSD</p>
</a>
</Link>
</li>
<li className="navigation-bar__login">
<Link href={"https://members.acmucsd.com/login"}>
<a>Member Login</a>
</Link>
</li>
<li className="navigation-bar__nav-button">
<Link href="#contact">
<a>Contact</a>
</Link>
</li>
<div className={s.navbarWrapper}>
<div className={s.navbar}>
{/* Navbar ACM Logo */}
<div className={s.left}>
<Link href="/">
<a>
<img src={ACMLogo.src} alt="ACM Logo" />
<p>at UCSD</p>
</a>
</Link>
</div>

{/* Desktop Nav Links */}
<div className={`${s.right} ${mobile && s.hidden}`}>
{navLinks.map((link, key) => (
<li key={key} className="navigation-bar__nav-button">
<Link href={link.to}>
<a>{link.text}</a>
</Link>
</li>
<Link key={key} href={link.to}>
farisashai marked this conversation as resolved.
Show resolved Hide resolved
<a className={s.navItem}>{link.text}</a>
</Link>
))}
</ul>
<Link href={"https://members.acmucsd.com/login"}>
<a className={s.loginButton}>Member Login</a>
</Link>
</div>
{/* Mobile Navbar Toggle */}
<button className={`${s.toggleIcon} ${!mobile && s.hidden}`} onClick={toggleMenu}>
<div className={`${s.bar1} ${menuOpen && s.open}`} />
<div className={`${s.bar2} ${menuOpen && s.open}`} />
Comment on lines +57 to +58
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imo probably semantically better to use an inline svg and animate that

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i tried to do this and nothing would work so i'm going to ignore for now unless anyone thinks its significant enough

</button>
</div>

{menuState ? (
<div className="mobile-links">
<button className="closebutton" onClick={toggleMenu} type="button">
<img
className="closeicon"
src={CloseMenuButton.src}
color="white"
alt="Menu Icon"
/>
</button>
<Link href="/about">
<a onClick={toggleMenu}>About Us</a>
</Link>
<Link href="/communities">
<a onClick={toggleMenu}>Communities</a>
</Link>
<Link href="/sponsor">
<a onClick={toggleMenu}>Sponsor</a>
{/* Mobile Menu Dropdown */}
<div className={`${s.mobileNav} ${menuOpen && s.open}`}>
{navLinks.map((link, key) => (
<Link key={key} href={link.to}>
<a className={`${s.navItem}`}>{link.text}</a>
</Link>
<Link href="#contact">
<a onClick={toggleMenu}>Contact</a>
</Link>
<a href="https://members.acmucsd.com/login">Login</a>
</div>
) : (
<div className="navbar-mobile-div">
<div className="navbar-mobile">
<Link href="/">
<a>
<img src={ACMLogo.src} alt="ACM Logo" />
<p>at UCSD</p>
</a>
</Link>
<button className="icon" onClick={toggleMenu} type="button">
<img
className="menuicon"
src={MenuButtonIcon.src}
alt="Menu Icon"
/>
</button>
</div>
</div>
)}
))}
<Link href={"https://members.acmucsd.com/login"}>
<a className={s.navItem}>Member Login</a>
</Link>
</div>

<div className="rainbow" />
{/* Bottom Rainbow */}
<div className={s.rainbow} />
</div>
);
};
Expand Down
Loading