<script lang="ts" module> import { getContext, setContext } from 'svelte'; type Tab = string; type Tabs = Record<Tab, { title: string }>; class TabContext { tabs: Tabs = $state({}); current: Tab = $state(''); } export function getTabContext() { return getContext<TabContext>('tabs'); } function initTabContext() { return setContext('tabs', new TabContext()); } </script> <script lang="ts"> import { fadeFast } from '$lib/Transitions'; import type { Snippet } from 'svelte'; import { fade } from 'svelte/transition'; let { badges = {}, children }: { badges?: Record<Tab, boolean>; children?: Snippet } = $props(); const context = initTabContext(); </script> <div class="flex h-full max-h-full flex-col"> <nav> <ul class="ms-1 me-3 flex border-b-2 border-slate-700 text-sm"> {#each Object.entries(context.tabs) as [id, { title }]} <li class="-mb-0.5"> <button type="button" class:active={context.current === id} class="relative flex gap-1 p-1 px-3 hover:border-b-2 hover:border-slate-200 [&.active]:border-b-2 [&.active]:border-indigo-500" onclick={() => (context.current = id)} > {#if badges[id]} <div class="absolute top-1 right-0 h-2 w-2 rounded-full bg-emerald-400" title="There are pending changes" transition:fade={fadeFast} ></div> {/if} <span>{title}</span> </button> </li> {/each} </ul> </nav> {@render children?.()} </div>