Files
website/src/lib/components/MainNav.svelte
2025-05-10 17:20:12 +05:30

75 lines
2.4 KiB
Svelte

<script lang="ts" context="module">
import type { Component } from 'svelte';
export type NavLink = {
label: string;
href?: string;
showBadge?: boolean;
submenu?: Component<{ label: string }>;
mobileSubmenu?: Component<{ label: string }>;
};
</script>
<script lang="ts">
import { classNames } from '$lib/utils/classnames';
import { trackEvent } from '$lib/actions/analytics';
export let initialized = false;
export let links: NavLink[] = [];
</script>
<nav class="web-main-header-nav" aria-label="Main">
<ul class="web-main-header-nav-list flex items-center">
{#each links as link}
<li class="web-main-header-nav-item text-primary hover:text-accent">
{#if link.submenu}
<div
class="web-main-header-nav-item-button"
aria-haspopup="true"
aria-expanded="false"
aria-controls="submenu"
data-submenu-button
>
<svelte:component this={link.submenu} label={link.label} />
</div>
{:else}
<a
class={classNames(
'data-[badge]:after:animate-scale-in data-[badge]:relative data-[badge]:after:absolute data-[badge]:after:size-1.5 data-[badge]:after:translate-full data-[badge]:after:rounded-full'
)}
href={link.href}
data-initialized={initialized ? '' : undefined}
data-badge={link.showBadge ? '' : undefined}
onclick={() => trackEvent(`main-nav-${link.label.toLowerCase()}-nav-click`)}
>{link.label}
</a>
{/if}
</li>
{/each}
</ul>
</nav>
<style>
[data-badge] {
position: relative;
&::after {
content: '';
position: absolute;
background-color: hsl(var(--color-accent));
border-radius: 100%;
width: 0.375rem;
height: 0.375rem;
inset-block-start: -2px;
inset-inline-end: -4px;
translate: 100%;
}
&:not([data-initialized])::after {
animation: scale-in 0.2s ease-out;
}
}
</style>