Monorepo for Tangled tangled.org
2

Configure Feed

Select the types of activity you want to include in your feed.

core / web / src / lib / components / ui / Tabs.svelte
2.2 kB 75 lines
1<script module lang="ts"> 2 import type { Component } from "svelte"; 3 import type { SvelteHTMLElements } from "svelte/elements"; 4 5 export interface TabDef { 6 id: string; 7 label: string; 8 href: string; 9 icon?: Component<SvelteHTMLElements["svg"]>; 10 count?: number; 11 } 12</script> 13 14<script lang="ts"> 15 import { resolve } from "$app/paths"; 16 17 interface Props { 18 tabs: TabDef[]; 19 active: string; 20 label?: string; 21 vertical?: boolean; 22 } 23 24 let { tabs, active, label, vertical = false }: Props = $props(); 25 26 const navClass = $derived( 27 vertical 28 ? "h-fit divide-y divide-border-default overflow-hidden rounded border border-border-default" 29 : "flex w-full overflow-x-auto overflow-y-hidden pl-4" 30 ); 31 32 const itemClass = (isActive: boolean) => 33 vertical 34 ? `flex items-center gap-3 px-3 py-2 text-sm no-underline hover:no-underline ${ 35 isActive 36 ? "bg-background-default text-foreground-default dark:bg-background-inset" 37 : "bg-background-inset text-foreground-muted hover:text-foreground-default dark:bg-background-default" 38 }` 39 : `relative mr-1 flex items-center rounded-t px-4 py-1 whitespace-nowrap text-foreground-default no-underline hover:no-underline ${ 40 isActive 41 ? "-mb-px bg-background-default [-webkit-text-stroke:0.3px_currentColor]" 42 : "hover:bg-background-inset" 43 }`; 44</script> 45 46<nav class={navClass} aria-label={label}> 47 {#each tabs as tab (tab.id)} 48 {@const isActive = active === tab.id} 49 {@const Glyph = tab.icon} 50 <a 51 href={tab.href.startsWith("/") ? resolve(tab.href as "/") : tab.href} 52 aria-current={isActive ? "page" : undefined} 53 class={itemClass(isActive)} 54 > 55 {#if Glyph} 56 <Glyph class={vertical ? "size-4 shrink-0" : "mr-2 h-4 w-4"} aria-hidden="true" /> 57 {/if} 58 {#if vertical} 59 {tab.label} 60 {:else} 61 <span class="flex flex-col"> 62 {tab.label} 63 <span aria-hidden="true" class="invisible h-0 overflow-hidden font-medium select-none" 64 >{tab.label}</span 65 > 66 </span> 67 {/if} 68 {#if tab.count} 69 <span class="rounded bg-background-inset px-1 text-sm {vertical ? 'ml-auto' : 'ml-1'}" 70 >{tab.count}</span 71 > 72 {/if} 73 </a> 74 {/each} 75</nav>