Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
Svelte
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123<script module lang="ts"> import { tv } from "tailwind-variants";
export const fileRow = tv({ slots: { root: "grid items-center gap-4 py-1", link: "flex min-w-0 items-center gap-2 text-foreground-default no-underline hover:underline", message: "hidden min-w-0 md:col-span-6 md:block", time: "text-right text-foreground-subtle" }, variants: { withMessage: { true: { root: "grid-cols-12", link: "col-span-8 md:col-span-4", time: "col-span-4 md:col-span-2" }, false: { root: "grid-cols-3", link: "col-span-2", time: "col-span-1" } } }, defaultVariants: { withMessage: false } });</script>
<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 { splitMessage } from "$lib/api/repo"; import { navigatingTo } from "$lib/navPulse"; import TimeAgo from "$lib/components/ui/TimeAgo.svelte"; import type { TreeEntrySummary } from "$lib/components/repo/types"; import { encodePathSegments } from "$lib/components/repo/urls";
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 row = $derived(fileRow({ withMessage }));
const linkFor = (entry: TreeEntrySummary) => { const target = path ? `${path}/${entry.name}` : entry.name; const kind = entry.kind === "directory" ? "tree" : "blob"; return `${base}/${kind}/${encodedRef}/${encodePathSegments(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)} {@const href = resolve(linkFor(entry) as "/")} <div class={row.root()} class:row-breathe={navigatingTo(href)}> <a {href} class={row.link()}> <span class="text-foreground-muted"> <Glyph class={iconClassFor(entry)} aria-hidden="true" /> </span> <span class="truncate">{entry.name}</span> </a>
{#if withMessage} <div class={row.message()}> {#if entry.lastCommitHash && entry.lastCommitMessage} <a href={resolve(`${base}/commit/${entry.lastCommitHash}` as "/")} class="block truncate text-foreground-muted no-underline hover:text-foreground-default hover:underline" > {splitMessage(entry.lastCommitMessage)[0]} </a> {/if} </div> {/if}
<div class={row.time()}> {#if entry.lastCommitHash && entry.lastCommitWhen} <a href={resolve(`${base}/commit/${entry.lastCommitHash}` as "/")} class="text-foreground-muted no-underline hover:text-foreground-default hover:underline" title={entry.lastCommitMessage} > <TimeAgo value={entry.lastCommitWhen} /> </a> {/if} </div> </div> {/each}</div>