BranchSelector.tsx
Raw
1interface BranchSelectorProps {
2 repoName: string;
3 branches: string[];
4 tags?: string[];
5 currentRef: string;
6 view: "tree" | "commits" | "blob";
7 /** subpath for tree, full file path for blob */
8 path?: string;
9}
10
11export function BranchSelector({
12 repoName,
13 branches,
14 tags = [],
15 currentRef,
16 view,
17 path,
18}: BranchSelectorProps) {
19 if (branches.length === 0 && tags.length === 0) return "";
20 const isDetached =
21 !branches.includes(currentRef) && !tags.includes(currentRef);
22 const shortRef =
23 isDetached && currentRef.length > 8
24 ? currentRef.slice(0, 8)
25 : currentRef;
26 return (
27 <form
28 method="GET"
29 action={`/${repoName}/branch-switch`}
30 class="branch-selector"
31 >
32 <input type="hidden" name="view" value={view} />
33 {!!path && <input type="hidden" name="path" value={path} />}
34 <span class="branch-selector-icon">⎇</span>
35 <select name="rev" class="branch-select" data-autosubmit>
36 {isDetached && (
37 <option value={currentRef} selected safe>
38 {shortRef} (detached)
39 </option>
40 )}
41 <optgroup label="Branches">
42 {branches.map((b) => (
43 <option
44 value={b}
45 selected={b === currentRef ? true : undefined}
46 safe
47 >
48 {b}
49 </option>
50 ))}
51 </optgroup>
52 {tags.length > 0 && (
53 <optgroup label="Tags">
54 {tags.map((t) => (
55 <option
56 value={t}
57 selected={t === currentRef ? true : undefined}
58 safe
59 >
60 {t}
61 </option>
62 ))}
63 </optgroup>
64 )}
65 </select>
66 <noscript>
67 <button type="submit" class="btn btn-sm">
68 Go
69 </button>
70 </noscript>
71 </form>
72 );
73}
74