This repository has no description
1<script lang="ts">
2 import { goto } from "$app/navigation";
3 import { resolve } from "$app/paths";
4 import GitCompare from "$icon/git-compare";
5 import Select from "$lib/components/ui/Select.svelte";
6
7 interface Props {
8 ownerHandle: string;
9 repoName: string;
10 current: string;
11 branches: string[];
12 tags: string[];
13 }
14
15 let { ownerHandle, repoName, current, branches, tags }: Props = $props();
16
17 const base = $derived(`/${ownerHandle}/${repoName}`);
18
19 const onchange = (event: Event) => {
20 const value = (event.currentTarget as HTMLSelectElement).value;
21 if (value === current) return;
22 void goto(resolve(`${base}/tree/${encodeURIComponent(value)}` as "/"));
23 };
24</script>
25
26<div class="flex min-w-0 flex-1 items-stretch gap-2">
27 <div class="max-w-32 sm:max-w-64">
28 <!-- the ref lives in the url so navigation updates it, no two way binding -->
29 <Select value={current} {onchange} aria-label="Switch branch or tag">
30 <!-- a commit sha or a ref past the knot's cap still needs a label -->
31 {#if !branches.includes(current) && !tags.includes(current)}
32 <option value={current}>{current}</option>
33 {/if}
34 <optgroup label={`Branches (${branches.length})`}>
35 {#each branches as branch (branch)}
36 <option value={branch}>{branch}</option>
37 {/each}
38 </optgroup>
39 <optgroup label={`Tags (${tags.length})`}>
40 {#each tags as tag (tag)}
41 <option value={tag}>{tag}</option>
42 {:else}
43 <option disabled>No tags found</option>
44 {/each}
45 </optgroup>
46 </Select>
47 </div>
48 <a
49 href={resolve(`${base}/compare?base=${encodeURIComponent(current)}` as "/")}
50 class="flex items-center rounded-sm border border-border-default px-2 text-foreground-muted no-underline hover:bg-background-subtle hover:no-underline"
51 title="Compare branches or tags"
52 aria-label="Compare branches or tags"
53 >
54 <GitCompare class="size-4" aria-hidden="true" />
55 </a>
56</div>