This repository has no description
0

Configure Feed

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

core / web / src / lib / components / ui / Tabs.svelte
2.4 kB 76 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 overlapBottom?: boolean; 23 } 24 25 let { tabs, active, label, vertical = false, overlapBottom = false }: Props = $props(); 26 27 const navClass = $derived( 28 vertical 29 ? "h-fit divide-y divide-border-default overflow-hidden rounded border border-border-default" 30 : "relative z-10 flex w-full overflow-x-auto overflow-y-hidden pl-4" 31 ); 32 33 const itemClass = (isActive: boolean) => 34 vertical 35 ? `flex items-center gap-3 px-3 py-2 text-sm no-underline hover:no-underline ${ 36 isActive 37 ? "bg-background-default text-foreground-default dark:bg-background-inset" 38 : "bg-background-inset text-foreground-muted hover:text-foreground-default dark:bg-background-default" 39 }` 40 : `relative mr-1 flex items-center rounded-t px-4 pt-1 pb-[5px] whitespace-nowrap text-foreground-default no-underline hover:no-underline ${ 41 isActive 42 ? "border border-b-0 border-border-default bg-background-default [-webkit-text-stroke:0.3px_currentColor]" 43 : "border border-b-0 border-transparent hover:bg-background-muted hover:dark:bg-background-subtle/50" 44 }`; 45</script> 46 47<nav class={[navClass, overlapBottom && "-mb-px"]} aria-label={label}> 48 {#each tabs as tab (tab.id)} 49 {@const isActive = active === tab.id} 50 {@const Glyph = tab.icon} 51 <a 52 href={tab.href.startsWith("/") ? resolve(tab.href as "/") : tab.href} 53 aria-current={isActive ? "page" : undefined} 54 class={itemClass(isActive)} 55 > 56 {#if Glyph} 57 <Glyph class={vertical ? "size-4 shrink-0" : "mr-2 size-4 "} aria-hidden="true" /> 58 {/if} 59 {#if vertical} 60 {tab.label} 61 {:else} 62 <span class="flex flex-col"> 63 {tab.label} 64 <span aria-hidden="true" class="invisible h-0 overflow-hidden font-medium select-none" 65 >{tab.label}</span 66 > 67 </span> 68 {/if} 69 {#if tab.count} 70 <span class="rounded-sm bg-background-inset px-1 text-sm {vertical ? 'ml-auto' : 'ml-1'}" 71 >{tab.count}</span 72 > 73 {/if} 74 </a> 75 {/each} 76</nav>