Skip to content

Commit

Permalink
responsive navbar (#215)
Browse files Browse the repository at this point in the history
* started responsive navbar

* commit typing

* finish navbar

* move navbar styles to component level module

* commit module typing

* use proper color variables

* use seconds for transitions

* fix navlink order

* fix easing functions

* add css comments
  • Loading branch information
farisashai authored Mar 1, 2022
1 parent cdcdbd7 commit 7507cfe
Show file tree
Hide file tree
Showing 8 changed files with 264 additions and 295 deletions.
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
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;

.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);
}, [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}>
<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}`} />
</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

1 comment on commit 7507cfe

@vercel
Copy link

@vercel vercel bot commented on 7507cfe Mar 1, 2022

Choose a reason for hiding this comment

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

Please sign in to comment.