File size: 2,376 Bytes
a8898de
a8647ab
a8898de
 
 
 
 
 
 
 
560169d
 
 
 
a8647ab
 
 
 
 
 
 
560169d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a8898de
 
 
 
a8647ab
a8898de
560169d
a8898de
560169d
a8898de
 
a8647ab
a8898de
 
560169d
 
 
 
 
 
 
 
 
 
 
a8647ab
a8898de
 
 
560169d
 
 
 
 
 
 
a8647ab
560169d
 
 
 
 
 
 
a8898de
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<script lang="ts">
	import { page } from '$app/state';
	import { NAV } from '$lib/data/content';
	import StampBadge from './StampBadge.svelte';
	import Icon from './Icon.svelte';

	interface Props {
		active?: string;
	}
	let { active = 'top' }: Props = $props();

	let open = $state(false);
	const close = () => (open = false);

	// On the home page the section links are plain fragments; from any other
	// route they point back to the home page's anchors. "submit" is now its own
	// route, so it always links there.
	const onHome = $derived(page.url.pathname === '/');
	const linkFor = (id: string) =>
		id === 'submit' ? '/submit' : onHome ? `#${id}` : `/#${id}`;

	// close the popout on Escape, and when the viewport grows back to the wide layout
	$effect(() => {
		if (!open) return;
		const onKey = (e: KeyboardEvent) => {
			if (e.key === 'Escape') close();
		};
		const onResize = () => {
			if (window.innerWidth > 1000) close();
		};
		window.addEventListener('keydown', onKey);
		window.addEventListener('resize', onResize);
		return () => {
			window.removeEventListener('keydown', onKey);
			window.removeEventListener('resize', onResize);
		};
	});
</script>

<nav class="nav">
	<div class="wrap nav__inner">
		<a href={onHome ? '#top' : '/'} class="nav__brand" onclick={close}>
			<StampBadge glyph="trees" accent="var(--forest)" size={32} spin={false} />
			<span class="display nav__brand-text">Build Small</span>
		</a>

		<div class="nav__links">
			{#each NAV as n (n.id)}
				<a href={linkFor(n.id)} class="nav__link" data-active={active === n.id}>{n.label}</a>
			{/each}
		</div>

		<button
			class="nav__toggle"
			aria-label={open ? 'Close menu' : 'Open menu'}
			aria-expanded={open}
			aria-controls="nav-menu"
			onclick={() => (open = !open)}
		>
			<Icon name={open ? 'close' : 'menu'} size={22} stroke="var(--ink)" />
		</button>

		<a class="btn btn--accent nav__submit" href="/submit" onclick={close}>
			Submit <Icon name="arrow" size={15} stroke="#fff" />
		</a>
	</div>

	{#if open}
		<!-- click-away scrim -->
		<button class="nav__scrim" aria-hidden="true" tabindex="-1" onclick={close}></button>
		<div class="nav__menu" id="nav-menu">
			{#each NAV as n (n.id)}
				<a
					href={linkFor(n.id)}
					class="nav__menu-link"
					data-active={active === n.id}
					onclick={close}>{n.label}</a
				>
			{/each}
		</div>
	{/if}
</nav>