Something went wrong. Try again.
Monorepo for Tangled
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596<script lang="ts"> import { resolve } from "$app/paths"; import File from "$icon/file"; import FileSymlink from "$icon/file-symlink"; import Folder from "$icon/folder"; import FolderInput from "$icon/folder-input"; import { subjectOf } from "$lib/api/repo"; import TimeAgo from "$lib/components/ui/TimeAgo.svelte"; import type { TreeEntrySummary } from "./types";
interface Props { ownerHandle: string; repoName: string; ref: string; entries: TreeEntrySummary[]; path?: string; withMessage?: boolean; }
let { ownerHandle, repoName, ref, entries, path = "", withMessage = false }: Props = $props();
const base = $derived(`/${ownerHandle}/${repoName}`); const encodedRef = $derived(encodeURIComponent(ref));
const linkFor = (entry: TreeEntrySummary) => { const target = path ? `${path}/${entry.name}` : entry.name; const kind = entry.kind === "directory" ? "tree" : "blob"; return `${base}/${kind}/${encodedRef}/${target}`; };
// lucide puts fill="none" on the path itself, which beats anything inherited // from the svg, so the class has to reach the path const iconClassFor = (entry: TreeEntrySummary) => entry.kind === "directory" ? "size-4 shrink-0 [&_path]:fill-current" : "size-4 shrink-0";
const iconFor = (entry: TreeEntrySummary) => { switch (entry.kind) { case "directory": return Folder; case "submodule": return FolderInput; case "symlink": return FileSymlink; default: return File; } };</script>
<!-- the divider belongs to whatever column the tree is sat in --><div class="min-w-0"> {#each entries as entry (entry.name)} {@const Glyph = iconFor(entry)} <div class={`grid items-center gap-4 py-1 ${withMessage ? "grid-cols-12" : "grid-cols-3"}`}> <a href={resolve(linkFor(entry) as "/")} class={`flex min-w-0 items-center gap-2 text-foreground-default no-underline hover:underline ${ withMessage ? "col-span-8 md:col-span-4" : "col-span-2" }`} > <Glyph class={iconClassFor(entry)} aria-hidden="true" /> <span class="truncate">{entry.name}</span> </a>
{#if withMessage} <div class="hidden min-w-0 md:col-span-6 md:block"> {#if entry.lastCommitHash && entry.lastCommitMessage} <a href={resolve(`${base}/commit/${entry.lastCommitHash}` as "/")} class="block truncate text-foreground-subtle no-underline hover:underline" > {subjectOf(entry.lastCommitMessage)} </a> {/if} </div> {/if}
<div class={`text-right text-sm text-foreground-subtle ${ withMessage ? "col-span-4 md:col-span-2" : "col-span-1" }`} > {#if entry.lastCommitHash && entry.lastCommitWhen} <a href={resolve(`${base}/commit/${entry.lastCommitHash}` as "/")} class="text-foreground-subtle no-underline hover:underline" title={entry.lastCommitMessage} > <TimeAgo value={entry.lastCommitWhen} /> </a> {/if} </div> </div> {/each}</div>