src/components/layout/Header.astro 3.3 K raw
1
---
2
import ThemeToggle from "../ThemeToggle.astro";
3
import { MENU_LINKS } from "@/data/constants";
4
5
const url = new URL(Astro.request.url);
6
---
7
8
<script>
9
	import { toggleClass } from "@/utils";
10
11
	document.addEventListener("DOMContentLoaded", () => {
12
		const header = document.getElementById("main-header") as HTMLElement;
13
		const toggleMenuButton = document.getElementById("toggle-navigation-menu") as HTMLButtonElement;
14
		let menuOpen = false;
15
16
		toggleMenuButton.addEventListener("click", () => {
17
			toggleClass(header, "menu-open");
18
			menuOpen = !menuOpen;
19
			toggleMenuButton.setAttribute("aria-expanded", menuOpen.toString());
20
		});
21
	});
22
</script>
23
24
<header id="main-header" class="group relative mb-28 flex items-center sm:pl-[4.5rem]">
25
	<div class="flex sm:flex-col">
26
		<a
27
			href="/"
28
			class="inline-flex items-center sm:relative sm:inline-block"
29
			aria-current={url.pathname === "/" ? "page" : false}
30
      >
31
32
      <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="mr-3 h-10 w-6 sm:absolute sm:left-[-4.5rem] sm:mr-0 sm:h-20 sm:w-12">
33
        <path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15a4.5 4.5 0 004.5 4.5H18a3.75 3.75 0 001.332-7.257 3 3 0 00-3.758-3.848 5.25 5.25 0 00-10.233 2.33A4.502 4.502 0 002.25 15z" />
34
      </svg>
35
36
			<span class="text-xl font-bold sm:text-2xl">Steve Simkins</span>
37
		</a>
38
		<nav
39
			id="navigation-menu"
40
			class="absolute -inset-x-4 top-14 hidden flex-col items-end gap-y-4 rounded-md bg-[color:var(--theme-menu-bg)] py-4 text-accent shadow backdrop-blur group-[.menu-open]:z-50 group-[.menu-open]:flex sm:static sm:z-auto sm:mt-1 sm:-ml-4 sm:flex sm:flex-row sm:items-center sm:divide-x sm:divide-dashed sm:divide-accent sm:rounded-none sm:bg-transparent sm:py-0 sm:shadow-none sm:backdrop-blur-none"
41
			aria-label="Main menu"
42
		>
43
			{
44
				MENU_LINKS.map((link) => (
45
					<a
46
						href={link.path}
47
						class="py-4 px-4 sm:py-0 sm:hover:underline"
48
						aria-current={url.pathname === link.path ? "page" : false}
49
						rel="prefetch"
50
					>
51
						{link.title}
52
					</a>
53
				))
54
			}
55
		</nav>
56
	</div>
57
	<ThemeToggle />
58
	<button
59
		id="toggle-navigation-menu"
60
		class="group relative ml-8 h-7 w-7 sm:invisible sm:hidden"
61
		type="button"
62
		aria-label="Open main menu"
63
		aria-expanded="false"
64
		aria-haspopup="menu"
65
	>
66
		<svg
67
			id="line-svg"
68
			class="absolute top-1/2 left-1/2 h-full w-full -translate-x-1/2 -translate-y-1/2 transition-all group-aria-expanded:scale-0 group-aria-expanded:opacity-0"
69
			aria-hidden="true"
70
			focusable="false"
71
			xmlns="http://www.w3.org/2000/svg"
72
			fill="none"
73
			viewBox="0 0 24 24"
74
			stroke-width="1.5"
75
			stroke="currentColor"
76
		>
77
			<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 9h16.5m-16.5 6.75h16.5"></path>
78
		</svg>
79
		<svg
80
			id="cross-svg"
81
			class="absolute top-1/2 left-1/2 h-full w-full -translate-x-1/2 -translate-y-1/2 scale-0 text-accent opacity-0 transition-all group-aria-expanded:scale-100 group-aria-expanded:opacity-100"
82
			class="text-accent"
83
			aria-hidden="true"
84
			focusable="false"
85
			xmlns="http://www.w3.org/2000/svg"
86
			fill="none"
87
			viewBox="0 0 24 24"
88
			stroke-width="1.5"
89
			stroke="currentColor"
90
		>
91
			<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path>
92
		</svg>
93
	</button>
94
</header>