add projects dropdown
All checks were successful
Test and deploy staging / staging (push) Successful in 1m48s

This commit is contained in:
2026-09-23 16:44:21 +00:00
parent 4b63e9ca11
commit 3691a85fdf
3 changed files with 131 additions and 39 deletions

View File

@@ -6,6 +6,8 @@
import { page } from '$app/state';
import { getSeo } from '$lib/seo';
import CopyButton from '$lib/components/CopyButton.svelte';
import { projects } from '$lib/projects';
import ChevronDown from 'lucide-svelte/icons/chevron-down';
import ExternalLink from 'lucide-svelte/icons/external-link';
import SiOsu from '~icons/simple-icons/osu';
import SiSteam from '~icons/simple-icons/steam';
@@ -171,13 +173,73 @@
</a>
<nav class="ml-auto hidden items-center gap-6 text-base md:flex" aria-label="Main navigation">
{#each navigation as item (item.href)}
<a
href={resolve(item.href)}
aria-current={current(item.href) ? 'page' : undefined}
class={current(item.href)
? 'text-[var(--site-text)]'
: 'text-[var(--site-muted)] hover:text-[var(--site-text)]'}>{item.label}</a
>
{#if item.href === '/projects'}
<div class="group relative">
<a
href={resolve(item.href)}
aria-current={current(item.href) ? 'page' : undefined}
aria-haspopup="true"
class="inline-flex items-center gap-1 {current(item.href)
? 'text-[var(--site-text)]'
: 'text-[var(--site-muted)] hover:text-[var(--site-text)]'}"
>{item.label}
<ChevronDown
size={14}
aria-hidden="true"
class="transition-transform group-focus-within:rotate-180 group-hover:rotate-180"
/></a
>
<div
class="invisible absolute top-full left-1/2 z-50 -translate-x-1/2 pt-3 opacity-0 transition-opacity group-focus-within:visible group-focus-within:opacity-100 group-hover:visible group-hover:opacity-100"
>
<ul
class="w-72 rounded-md border border-[var(--site-border)] bg-[var(--site-bg)] py-2 shadow-lg"
>
{#each projects as project (project.name)}
<li>
{#if project.external}
<a
href={project.href}
rel="external"
class="flex items-center justify-between gap-3 px-4 py-2 hover:bg-[var(--site-surface)] focus-visible:bg-[var(--site-surface)]"
>
<span class="min-w-0">
<span class="block text-[var(--site-text)]">{project.name}</span>
<span class="block truncate text-sm text-[var(--site-muted)]"
>{project.subtitle}</span
>
</span><ExternalLink
size={14}
aria-hidden="true"
class="shrink-0 text-[var(--site-muted)]"
/>
</a>
{:else}
<a
href={resolve(project.href)}
aria-current={current(project.href) ? 'page' : undefined}
class="block px-4 py-2 hover:bg-[var(--site-surface)] focus-visible:bg-[var(--site-surface)]"
>
<span class="block text-[var(--site-text)]">{project.name}</span>
<span class="block truncate text-sm text-[var(--site-muted)]"
>{project.subtitle}</span
>
</a>
{/if}
</li>
{/each}
</ul>
</div>
</div>
{:else}
<a
href={resolve(item.href)}
aria-current={current(item.href) ? 'page' : undefined}
class={current(item.href)
? 'text-[var(--site-text)]'
: 'text-[var(--site-muted)] hover:text-[var(--site-text)]'}>{item.label}</a
>
{/if}
{/each}
</nav>
<div class="ml-auto hidden items-center gap-5 text-base md:ml-4 md:flex">
@@ -222,6 +284,29 @@
<a href={resolve(item.href)} onclick={() => (menuOpen = false)} class="w-full py-2"
>{item.label}</a
>
{#if item.href === '/projects'}
<ul class="mb-2 flex w-full flex-col text-[var(--site-muted)]">
{#each projects as project (project.name)}
<li>
{#if project.external}
<a
href={project.href}
rel="external"
onclick={() => (menuOpen = false)}
class="inline-flex items-center gap-1 py-1.5 hover:text-[var(--site-text)]"
>{project.name} <ExternalLink size={12} aria-hidden="true" /></a
>
{:else}
<a
href={resolve(project.href)}
onclick={() => (menuOpen = false)}
class="block py-1.5 hover:text-[var(--site-text)]">{project.name}</a
>
{/if}
</li>
{/each}
</ul>
{/if}
{/each}
<div
class="mt-3 flex w-full items-center justify-center gap-5 border-t border-[var(--site-border)] pt-4"