portfolio-webpage/src/components/Header.astro

181 lines
7.0 KiB
Plaintext

---
import { Image } from "astro:assets";
import { SITE, LINKS } from "@/consts";
import { cn } from "@/lib/utils";
import Container from "@/components/Container.astro";
import { Icon } from "astro-icon/components";
import pictureOfMe from "@/images/me.jpg";
const { pathname } = Astro.url;
const subpath = pathname.match(/[^/]+/g);
---
<header id="header" class="fixed top-0 w-full h-16 z-50">
<Container size="md">
<div
class="relative h-full w-full flex flex-row justify-between items-center"
>
<div class="flex gap-1 font-semibold">
<a
href="/"
class="flex gap-1 text-current hover:text-black dark:hover:text-white transition-colors duration-300 ease-in-out"
>
<Image
src={pictureOfMe}
loading="eager"
alt="Me"
class="size-6 fill-current rounded-lg mr-2"
quality="low"
/>
<div class="font-departure font-bold">
{SITE.TITLE}
</div>
</a>
</div>
<div>
<nav
class="hidden md:flex items-center justify-center text-sm gap-1"
>
{
LINKS.map((LINK) => (
<a
href={LINK.HREF}
class={cn(
"h-8 rounded-xl px-3 text-current font-departure",
"flex items-center justify-center",
"transition-colors duration-300 ease-in-out",
pathname === LINK.HREF ||
"/" + subpath?.[0] + "/" === LINK.HREF
? "bg-black dark:bg-white text-white dark:text-black"
: "hover:bg-black/5 dark:hover:bg-white/20 hover:text-black dark:hover:text-white",
)}
>
{LINK.TEXT}
</a>
))
}
</nav>
</div>
<div class="buttons flex gap-1">
<a
href="/search/"
aria-label="Search blog posts and projects"
class={cn(
"hidden md:flex",
"size-9 rounded-full p-2 items-center justify-center text-center",
"bg-transparent hover:bg-black/5 dark:hover:bg-white/20",
"stroke-current hover:stroke-black hover:dark:stroke-white",
"border border-black/10 dark:border-white/25",
"transition-colors duration-300 ease-in-out",
pathname === "/search/" ||
"/" + subpath?.[0] === "/search/"
? "pointer-events-none bg-black dark:bg-white text-white dark:text-black"
: "",
)}
>
<Icon name="pixelarticons:search" class:list="text-xl" />
</a>
<a
href="/rss.xml"
target="_blank"
aria-label="Rss feed"
class={cn(
"hidden md:flex",
"size-9 rounded-full p-2 items-center justify-center text-center",
"bg-transparent hover:bg-black/5 dark:hover:bg-white/20",
"stroke-current hover:stroke-black hover:dark:stroke-white",
"border border-black/10 dark:border-white/25",
"transition-colors duration-300 ease-in-out active:opacity-1!",
)}
>
<Icon name="pixelarticons:rss" class:list="text-xl" />
</a>
<button
id="header-theme-button"
aria-label="Toggle light and dark theme"
class={cn(
"hidden md:flex",
"size-9 rounded-full p-2 items-center justify-center text-center",
"bg-transparent hover:bg-black/5 dark:hover:bg-white/20",
"stroke-current hover:stroke-black hover:dark:stroke-white",
"border border-black/10 dark:border-white/25",
"transition-colors duration-300 ease-in-out",
)}
>
<Icon
name="pixelarticons:sun"
class:list={"text-xl block dark:hidden"}
/>
<Icon
name="pixelarticons:moon"
class:list={"text-xl hidden dark:block"}
/>
</button>
<button
id="header-drawer-button"
aria-label={`Toggle drawer open and closed`}
class={cn(
"flex md:hidden",
"size-9 rounded-full p-2 items-center justify-center text-center",
"bg-transparent hover:bg-black/5 dark:hover:bg-white/20",
"stroke-current hover:stroke-black hover:dark:stroke-white",
"border border-black/10 dark:border-white/25",
"transition-colors duration-300 ease-in-out",
)}
>
<div id="drawer-open">
<Icon name="pixelarticons:menu" class:list="text-xl" />
</div>
<div id="drawer-close">
<Icon
name="pixelarticons:chevron-up"
class:list="text-xl"
/>
</div>
</button>
</div>
</div>
</Container>
</header>
<style>
#header-drawer-button > #drawer-open {
@apply block;
}
#header-drawer-button > #drawer-close {
@apply hidden;
}
#header-drawer-button.open > #drawer-open {
@apply hidden;
}
#header-drawer-button.open > #drawer-close {
@apply block;
}
</style>
<script is:inline>
function toggleDrawer() {
const drawer = document.getElementById("drawer");
const drawerButton = document.getElementById("header-drawer-button");
drawer?.classList.toggle("open");
drawerButton?.classList.toggle("open");
}
function initializeDrawerButton() {
const drawerButton = document.getElementById("header-drawer-button");
drawerButton?.addEventListener("click", toggleDrawer);
}
document.addEventListener("astro:after-swap", initializeDrawerButton);
initializeDrawerButton();
</script>