your personal website on atproto - mirror
blento.app
1<script lang="ts">
2 import type { Item } from '$lib/types';
3 import { onMount, tick } from 'svelte';
4 import type { ContentComponentProps } from '../types';
5 import FluidTextCard from './FluidTextCard.svelte';
6
7 let { item = $bindable<Item>() }: ContentComponentProps = $props();
8
9 let isEditing = $state(false);
10 let inputElement: HTMLInputElement | null = $state(null);
11
12 function handleClick() {
13 if (isEditing) return;
14 isEditing = true;
15 requestAnimationFrame(() => {
16 inputElement?.focus();
17 inputElement?.select();
18 });
19 }
20
21 function handleBlur() {
22 isEditing = false;
23 }
24
25 function handleKeydown(e: KeyboardEvent) {
26 if (e.key === 'Enter' || e.key === 'Escape') {
27 isEditing = false;
28 }
29 }
30
31 let rerender = $state(0);
32 onMount(() => {
33 window.addEventListener('theme-changed', async () => {
34 // Force re-render to update FluidTextCard colors
35 await tick();
36 rerender = Math.random();
37 });
38 });
39</script>
40
41<!-- svelte-ignore a11y_no_static_element_interactions -->
42<!-- svelte-ignore a11y_click_events_have_key_events -->
43<div
44 class="relative h-full w-full cursor-text transition-colors duration-150 {isEditing
45 ? 'ring-2 ring-white/30'
46 : ''}"
47 onclick={handleClick}
48>
49 {#key item.color + '-' + rerender.toString()}
50 <FluidTextCard {item} />
51 {/key}
52
53 {#if isEditing}
54 <!-- svelte-ignore a11y_autofocus -->
55 <!-- svelte-ignore a11y_no_static_element_interactions -->
56 <!-- svelte-ignore a11y_click_events_have_key_events -->
57 <div
58 class="absolute inset-0 flex items-center justify-center bg-black/60 p-4 backdrop-blur-sm"
59 onclick={(e) => e.stopPropagation()}
60 >
61 <input
62 bind:this={inputElement}
63 bind:value={item.cardData.text}
64 onblur={handleBlur}
65 onkeydown={handleKeydown}
66 class="w-full max-w-md rounded-md border border-white/20 bg-white/10 px-4 py-3 text-center text-2xl font-bold text-white transition-colors outline-none focus:border-white/40 focus:bg-white/20"
67 placeholder="Enter text"
68 autofocus
69 />
70 </div>
71 {/if}
72</div>