~james/core

core/web/src/lib/components/timeline/TimelineGroup.svelte -rw-r--r-- 1.3 KiB
452f17b7 — james chore(import): snapshot james.dad.town/core at f70c71c7696a 16 hours ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<script lang="ts" generics="E extends { uri: string }">
	import type { Snippet } from "svelte";
	import type { Attachment } from "svelte/attachments";
	import TimeAgo from "#lib/components/ui/TimeAgo.svelte";
	import TimelineCard from "#lib/components/timeline/TimelineCard.svelte";
	import type { TimelineEvent } from "#lib/components/timeline/group.ts";

	let {
		title,
		items,
		row,
		trailing
	}: {
		title: Snippet;
		items: TimelineEvent<E>[];
		row: Snippet<[E]>;
		trailing?: Snippet;
	} = $props();

	const hideWhenWrapping: Attachment<HTMLElement> = (node) => {
		const header = node.parentElement!;
		const fit = () => {
			node.style.display = "none";
			const bare = header.offsetHeight;
			node.style.display = "";
			if (header.offsetHeight > bare) node.style.display = "none";
		};
		const observer = new ResizeObserver(fit);
		observer.observe(header);
		return () => observer.disconnect();
	};
</script>

<TimelineCard padded={false}>
	{#snippet header()}
		{@render title()}
		{#if trailing}
			<span class="contents" {@attach hideWhenWrapping}>{@render trailing()}</span>
		{/if}
		<TimeAgo value={items[0].eventAt} class="text-foreground-subtle" />
	{/snippet}

	<div class="divide-y divide-border-default">
		{#each items as item (item.event.uri)}
			<div class="p-sm">
				{@render row(item.event)}
			</div>
		{/each}
	</div>
</TimelineCard>