This repository has no description
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 px-3 py-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">·</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>