diff options
Diffstat (limited to 'frontend/src/lib/tabs/Tabs.svelte')
-rw-r--r-- | frontend/src/lib/tabs/Tabs.svelte | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/frontend/src/lib/tabs/Tabs.svelte b/frontend/src/lib/tabs/Tabs.svelte index 09cdbdd..59b3220 100644 --- a/frontend/src/lib/tabs/Tabs.svelte +++ b/frontend/src/lib/tabs/Tabs.svelte @@ -1,28 +1,50 @@ +<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 { getTabContext } from '$lib/Tabs'; import { fadeFast } from '$lib/Transitions'; + import type { Snippet } from 'svelte'; import { fade } from 'svelte/transition'; - const context = getTabContext(); + 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="me-3 flex border-b-2 border-slate-700 text-sm"> - {#each Object.entries($context.tabs) as [id, { title, badge }]} + <ul class="ms-1 me-3 flex border-b-2 border-slate-700 text-sm"> + {#each Object.entries(context.tabs) as [id, { title }] (id)} <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" - on:click={() => ($context.current = id)} + class:active={context.current === id} + class="relative flex gap-1 p-1 px-3 hover:border-b-2 hover:border-slate-200 focus-visible:border-b-2 focus-visible:!border-slate-200 focus-visible:outline-hidden [&.active]:border-b-2 [&.active]:border-indigo-500" + onclick={() => (context.current = id)} > - {#if badge} + {#if badges[id]} <div - class="absolute right-0 top-1 h-2 w-2 rounded-full bg-emerald-400" + 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> @@ -30,11 +52,5 @@ {/each} </ul> </nav> - <slot /> + {@render children?.()} </div> - -<style lang="postcss"> - button.active { - @apply border-b-2 border-indigo-500; - } -</style> |