<script module lang="ts">
	import type { Component } from "svelte";
	import type { SvelteHTMLElements } from "svelte/elements";

	export interface SettingsNavItem {
		id: string;
		label: string;
		href: string;
		icon?: Component<SvelteHTMLElements["svg"]>;
	}
</script>

<script lang="ts">
	import { resolve } from "$app/paths";

	interface Props {
		items: SettingsNavItem[];
		active: string;
		label?: string;
	}

	let { items, active, label = "Settings" }: Props = $props();

	// Figma DS "Navigation / Button" (1009:2662) has four states across Active ×
	// Hovered. Inactive/resting is the only one with no fill and no border, so the
	// hover borders have to be added rather than recoloured — otherwise the item
	// grows by 1px on hover.
	const itemClass = (isActive: boolean) =>
		[
			"flex min-h-8 w-full items-center gap-1.5 rounded-sm border px-3 py-1.5",
			"typography-paragraph-regular text-foreground-default no-underline hover:no-underline",
			"transition-colors duration-150 ease-in-out",
			"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus",
			isActive
				? "border-border-navigation-item-active bg-background-navigation-item hover:border-border-strong hover:bg-background-muted"
				: "border-transparent hover:border-border-strong hover:bg-background-inset"
		].join(" ");
</script>

<nav
	class="flex w-full shrink-0 flex-col border-b border-border-default bg-background-navigation-frame p-2 md:w-44 md:self-stretch md:border-r md:border-b-0"
	aria-label={label}
>
	{#each items as item (item.id)}
		{@const isActive = active === item.id}
		{@const Glyph = item.icon}
		<a
			href={resolve(item.href as "/")}
			aria-current={isActive ? "page" : undefined}
			class={itemClass(isActive)}
		>
			{#if Glyph}
				<Glyph class="size-3.5 shrink-0" aria-hidden="true" />
			{/if}
			{item.label}
		</a>
	{/each}
</nav>
