Files
portfolio/src/components/Navbar.astro

142 lines
4.0 KiB
Plaintext

---
const pathName = new URL(Astro.request.url).pathname;
interface Props {
navbarDisplay: "normal" | "transparent";
}
import person from "@data/person";
import links from "@assets/menu-primary";
import ThemeSwitcher from "@components/ThemeSwitcher.astro";
const { navbarDisplay = "normal" } = Astro.props as Props;
---
<nav
class="font-header group/nav fixed top-0 right-0 left-0 z-50 uppercase"
aria-label="Primary"
transition:name="nav"
transition:animate="none"
id="nav"
data-mobile-menu="hidden"
data-transparency={navbarDisplay}
>
<div
id="navbar-lg"
class:list={[
"mx-auto border-0 border-b-1 border-solid border-b-white bg-white px-4 shadow-lg transition group-data-[mobile-menu=hidden]/nav:group-data-[transparency=transparent]/nav:border-b-gray-500 group-data-[mobile-menu=hidden]/nav:group-data-[transparency=transparent]/nav:bg-transparent dark:border-b-gray-700 dark:bg-gray-700",
"text-gray-500 dark:text-white",
"group-data-[mobile-menu=hidden]/nav:group-data-[transparency=transparent]/nav:!text-gray-500"
]}
>
<div class="flex h-12 items-center justify-between">
<!-- Logo -->
<div
class="font-header text-primary flex-shrink-0 text-2xl font-bold uppercase"
>
<a href="/" aria-label="Go home"
>{person.names.first} {person.names.last}</a
>
</div>
<!-- Desktop Menu -->
<div class="hidden space-x-6 font-medium md:flex">
<div class="text-primary">
<ThemeSwitcher />
</div>
{
links.map((link) => (
<a
href={link.href}
class:list={[
"font-header font-medium uppercase transition hover:text-gray-300",
pathName === link.href ? "text-primary" : ""
]}
aria-current={pathName === link.href ? "page" : undefined}
>
{link.label}
</a>
))
}
</div>
<!-- Mobile Menu Button -->
<div class="md:hidden">
<button id="menu-toggle" class="text-2xl focus:outline-none">
</button>
</div>
</div>
</div>
<!-- Mobile Menu -->
<div
id="mobile-menu"
class:list={[
"hidden space-y-2 bg-white px-4 pt-4 pb-4 font-medium shadow-lg transition group-data-[mobile-menu=visible]/nav:block md:hidden group-data-[mobile-menu=visible]/nav:md:hidden dark:bg-gray-600 starting:opacity-0",
"text-gray-500 dark:text-white",
"group-data-[mobile-menu=hidden]/nav:group-data-[transparency=transparent]/nav:!text-gray-500"
]}
>
{
links.map((link) => (
<a
href={link.href}
class:list={[
"block transition hover:text-gray-300",
pathName === link.href ? "text-primary" : ""
]}
aria-current={pathName === link.href ? "page" : undefined}
>
{link.label}
</a>
))
}
<div class="text-primary">
<ThemeSwitcher />
</div>
</div>
</nav>
<!-- Extra spacing for non-transparent navbar -->
<div
class:list={[
"y-0 r-0 h-12",
navbarDisplay === "transparent" ? "hidden" : "block"
]}
>
</div>
<script define:vars={{ navbarDisplay }} data-astro-rerun>
window.navbarDisplay = navbarDisplay || "normal";
</script>
<script>
let nav: HTMLElement;
let toggle: HTMLElement;
const checkScroll = () => {
nav.setAttribute(
"data-transparency",
window.scrollY === 0 && window.navbarDisplay === "transparent"
? "transparent"
: "normal"
);
};
document.addEventListener("astro:page-load", () => {
nav = document.getElementById("nav")!;
toggle = document.getElementById("menu-toggle")!;
toggle.addEventListener("click", () => {
const visible = nav.getAttribute("data-mobile-menu") === "visible";
nav.setAttribute("data-mobile-menu", visible ? "hidden" : "visible");
checkScroll();
});
checkScroll();
});
window.addEventListener("scroll", checkScroll);
</script>