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 / repo / TreeHeader.svelte
2.3 kB 76 lines
1<script lang="ts"> 2 import { resolve } from "$app/paths"; 3 import type { TreeEntrySummary } from "./types"; 4 5 interface Props { 6 ownerHandle: string; 7 repoName: string; 8 ref: string; 9 path: string; 10 entries: TreeEntrySummary[]; 11 } 12 13 let { ownerHandle, repoName, ref, path, entries }: Props = $props(); 14 15 const base = $derived(`/${ownerHandle}/${repoName}`); 16 const encodedRef = $derived(encodeURIComponent(ref)); 17 18 const crumbs = $derived.by(() => { 19 const parts = path.split("/").filter(Boolean); 20 return [ 21 { name: repoName, href: `${base}/tree/${encodedRef}`, last: parts.length === 0 }, 22 ...parts.map((name, index) => ({ 23 name, 24 href: `${base}/tree/${encodedRef}/${parts.slice(0, index + 1).join("/")}`, 25 last: index === parts.length - 1 26 })) 27 ]; 28 }); 29 30 const folders = $derived( 31 entries.filter((entry) => entry.kind === "directory" || entry.kind === "submodule").length 32 ); 33 const files = $derived(entries.length - folders); 34 const plural = (count: number, noun: string) => `${count} ${noun}${count === 1 ? "" : "s"}`; 35</script> 36 37<div class="mb-3 flex items-center justify-between gap-2 text-sm"> 38 <div class="flex min-w-0 items-center gap-3"> 39 <div 40 class="flex w-fit items-center gap-1 overflow-x-auto rounded border border-border-default bg-background-inset p-2 whitespace-nowrap" 41 > 42 {#each crumbs as crumb (crumb.href)} 43 {#if crumb.last} 44 <span class="text-foreground-default" aria-current="page">{crumb.name}</span> 45 {:else} 46 <a 47 href={resolve(crumb.href as "/")} 48 class="text-foreground-muted no-underline hover:underline">{crumb.name}</a 49 > 50 <span class="text-foreground-muted" aria-hidden="true">/</span> 51 {/if} 52 {/each} 53 </div> 54 55 <div class="flex items-center gap-2 text-foreground-muted"> 56 {#if folders > 0} 57 <span>{plural(folders, "folder")}</span> 58 {/if} 59 {#if folders > 0 && files > 0} 60 <span aria-hidden="true">&middot;</span> 61 {/if} 62 {#if files > 0} 63 <span>{plural(files, "file")}</span> 64 {/if} 65 </div> 66 </div> 67 68 <div 69 class="hidden w-fit items-center gap-1 rounded border border-border-default bg-background-inset p-2 whitespace-nowrap text-foreground-muted md:flex" 70 > 71 at <a 72 href={resolve(`${base}/tree/${encodedRef}` as "/")} 73 class="text-foreground-default no-underline hover:underline">{ref}</a 74 > 75 </div> 76</div>