atmo.rsvp
1<script lang="ts">
2 // @ts-nocheck
3 import { designs, resolveAccentColor } from './thumbnails/designs';
4 import { tick } from 'svelte';
5
6 let {
7 name = '',
8 dateStr = '',
9 accent = '',
10 seed = 1,
11 selected = $bindable<string | null>(null),
12 onselect
13 }: {
14 name?: string;
15 dateStr?: string;
16 accent?: string;
17 seed?: number;
18 selected?: string | null;
19 onselect?: () => void;
20 } = $props();
21
22 const presetKeys = Object.keys(designs);
23 const previewSize = 200;
24
25 let containerEl: HTMLDivElement | undefined = $state(undefined);
26
27 function renderAll() {
28 if (!containerEl) return;
29 const color = resolveAccentColor(accent);
30 const canvases = containerEl.querySelectorAll<HTMLCanvasElement>('canvas');
31 canvases.forEach((canvas) => {
32 const key = canvas.dataset.key!;
33 const ctx = canvas.getContext('2d');
34 if (!ctx) return;
35 canvas.width = previewSize;
36 canvas.height = previewSize;
37 designs[key](ctx, previewSize, previewSize, name || 'Event', dateStr, seed, color);
38 });
39 }
40
41 $effect(() => {
42 void name;
43 void dateStr;
44 void accent;
45 void seed;
46 void containerEl;
47 tick().then(renderAll);
48 });
49</script>
50
51<div class="flex flex-col gap-3">
52 <p class="text-base-500 dark:text-base-400 text-xs font-medium">Preset thumbnails</p>
53 <div class="grid grid-cols-3 gap-2" bind:this={containerEl}>
54 {#each presetKeys as key}
55 <button
56 type="button"
57 class="aspect-square cursor-pointer overflow-hidden rounded-xl border-2 transition-colors
58 {selected === key
59 ? 'border-accent-500'
60 : 'border-base-200 dark:border-base-700 hover:border-accent-400 dark:hover:border-accent-500'}"
61 onclick={() => { selected = key; onselect?.(); }}
62 >
63 <canvas data-key={key} class="h-full w-full"></canvas>
64 </button>
65 {/each}
66 </div>
67</div>