Something went wrong. Try again.
Monorepo for Tangled
Something went wrong. Try again.
Svelte
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115<script module lang="ts"> import type { RecentItemData } from "$lib/components/timeline/types";
/** the unresolved app path a recent row points at */ export const recentPath = (item: RecentItemData): string => { switch (item.kind) { case "repo": return `/${item.ownerHandle}/${item.name}`; case "issue": return `/${item.ownerHandle}/${item.repoName}/issues/${item.issueId}`; case "pull": return `/${item.ownerHandle}/${item.repoName}/pulls/${item.pullId}`; } };</script>
<script lang="ts"> import { resolve } from "$app/paths"; import Ban from "$icon/ban"; import CircleDot from "$icon/circle-dot"; import GitMerge from "$icon/git-merge"; import GitPullRequest from "$icon/git-pull-request"; import GitPullRequestClosed from "$icon/git-pull-request-closed"; import { tv } from "tailwind-variants"; import Avatar from "$lib/components/ui/Avatar.svelte"; import TimeAgo from "$lib/components/ui/TimeAgo.svelte";
let { item }: { item: RecentItemData } = $props();
const badgeColor = tv({ base: "text-foreground-subtle", variants: { kind: { repo: "", issue: "", pull: "" }, open: { true: "", false: "" }, state: { open: "", merged: "", closed: "" } }, compoundVariants: [ { kind: "issue", open: true, class: "text-foreground-success" }, { kind: "pull", state: "open", class: "text-foreground-success" }, { kind: "pull", state: "merged", class: "text-foreground-info" }, { kind: "pull", state: "closed", class: "text-foreground-muted" } ] });
// issue and pull rows put a circled glyph where a repo row puts an avatar. // merged uses the info colour the pull pills already use, not the appview's // raw purple, which this design system has no token for. const badge = $derived.by(() => { switch (item.kind) { case "issue": return { Icon: item.open ? CircleDot : Ban, color: badgeColor({ kind: "issue", open: item.open }) }; case "pull": return { Icon: item.state === "open" ? GitPullRequest : item.state === "merged" ? GitMerge : GitPullRequestClosed, color: badgeColor({ kind: "pull", state: item.state }) }; default: return { Icon: CircleDot, color: badgeColor({ kind: "repo" }) }; } });</script>
<a href={resolve(recentPath(item) as "/")} class="relative grid grid-cols-[1.75rem_1fr_auto] grid-rows-2 gap-x-sm overflow-hidden px-md py-sm typography-paragraph-small no-underline hover:bg-background-subtle/50 hover:no-underline"> {#if item.kind === "repo"} <span class="relative z-10 col-start-1 row-span-2 row-start-1 self-center"> <Avatar did={item.ownerDid} handle={item.ownerHandle} size="large" class="size-7" /> </span> <span class="col-start-2 row-span-2 row-start-1 self-center truncate font-medium text-foreground-default" > {item.ownerHandle}/{item.name} </span> <TimeAgo value={item.visited} class="col-start-3 row-span-2 row-start-1 shrink-0 self-center text-foreground-subtle" /> {:else} <span class="relative z-10 col-start-1 row-span-2 row-start-1 flex size-7 shrink-0 items-center justify-center self-center rounded-full border border-border-default bg-background-default {badge.color}" > <badge.Icon class="size-3.5" aria-hidden="true" /> </span> <span class="col-start-2 row-start-1 truncate text-foreground-default">{item.title}</span> <span class="col-start-2 row-start-2 truncate text-foreground-subtle"> {item.ownerHandle}/{item.repoName} </span> <TimeAgo value={item.visited} class="col-start-3 row-start-1 shrink-0 self-center text-foreground-subtle" /> {/if}</a>