From 563ee5699b3db95da32ce60bfca26b638413040d Mon Sep 17 00:00:00 2001 From: Rasmus Q Date: Mon, 16 Mar 2026 14:20:50 +0000 Subject: [PATCH] refactor: simplify ItemForm API using events instead of callback props --- src/lib/components/wishlist/ItemForm.svelte | 51 ++++++++++--------- src/routes/wishlist/[token]/edit/+page.svelte | 19 +++---- 2 files changed, 34 insertions(+), 36 deletions(-) diff --git a/src/lib/components/wishlist/ItemForm.svelte b/src/lib/components/wishlist/ItemForm.svelte index f66ca78..97d11ed 100644 --- a/src/lib/components/wishlist/ItemForm.svelte +++ b/src/lib/components/wishlist/ItemForm.svelte @@ -11,16 +11,19 @@ import { languageStore } from '$lib/stores/language.svelte'; import ThemeCard from '$lib/components/themes/ThemeCard.svelte'; import { getCardStyle } from '$lib/utils/colors'; + import { createEventDispatcher } from 'svelte'; + + const dispatch = createEventDispatcher<{ + success: void; + cancel: void; + colorChange: { itemId: string; color: string }; + positionChange: { itemId: string; newPosition: number }; + }>(); interface Props { item?: Item | null; mode: 'add' | 'edit'; - onSuccess?: () => void; - onCancel?: () => void; - onColorChange?: (itemId: string, color: string) => void; - currentPosition?: number; - totalItems?: number; - onPositionChange?: (newPosition: number) => void; + itemCount?: number; wishlistColor?: string | null; wishlistTheme?: string | null; } @@ -28,12 +31,7 @@ let { item = null, mode, - onSuccess, - onCancel, - onColorChange, - currentPosition = 1, - totalItems = 1, - onPositionChange, + itemCount = 1, wishlistColor = null, wishlistTheme = null }: Props = $props(); @@ -47,6 +45,7 @@ let linkUrl = $state(item?.link || ''); let imageUrl = $state(item?.imageUrl || ''); let color = $state(item?.color || null); + let position = $state(item?.order ? Number(item.order) + 1 : 1); let scrapedImages = $state([]); let isLoadingImages = $state(false); let debounceTimer: ReturnType | null = null; @@ -97,7 +96,13 @@ function handleColorChange() { if (isEdit && item) { - onColorChange?.(item.id, color || ''); + dispatch('colorChange', { itemId: item.id, color: color || '' }); + } + } + + function handlePositionChange() { + if (isEdit && item) { + dispatch('positionChange', { itemId: item.id, newPosition: position }); } } @@ -121,7 +126,7 @@ use:enhance={() => { return async ({ update }) => { await update({ reset: false }); - onSuccess?.(); + dispatch('success'); }; }} class="space-y-4" @@ -222,20 +227,16 @@ { - const newPos = parseInt((e.target as HTMLInputElement).value); - if (newPos >= 1 && newPos <= totalItems) { - onPositionChange?.(newPos); - } - }} + max={itemCount} + bind:value={position} + onchange={handlePositionChange} placeholder="1" />

- Choose where this item appears in your wishlist (1 = top, {totalItems} = bottom) + Choose where this item appears in your wishlist (1 = top, {itemCount} = bottom)

{/if} @@ -243,8 +244,8 @@
- {#if onCancel} - {/if} diff --git a/src/routes/wishlist/[token]/edit/+page.svelte b/src/routes/wishlist/[token]/edit/+page.svelte index 68143f0..ae17ad6 100644 --- a/src/routes/wishlist/[token]/edit/+page.svelte +++ b/src/routes/wishlist/[token]/edit/+page.svelte @@ -88,10 +88,8 @@ } } - async function handlePositionChange(newPosition: number) { - if (!editingItem) return; - - const currentIndex = items.findIndex((item) => item.id === editingItem.id); + async function handlePositionChange(itemId: string, newPosition: number) { + const currentIndex = items.findIndex((item) => item.id === itemId); if (currentIndex === -1) return; const newIndex = newPosition - 1; // Convert to 0-based index @@ -150,7 +148,7 @@
@@ -162,12 +160,11 @@ item.id === editingItem.id) + 1} - totalItems={items.length} - onPositionChange={handlePositionChange} + itemCount={items.length} + on:success={handleItemUpdated} + on:cancel={cancelEditing} + on:colorChange={(e) => handleColorChange(e.detail.itemId, e.detail.color)} + on:positionChange={(e) => handlePositionChange(e.detail.itemId, e.detail.newPosition)} wishlistColor={currentColor} wishlistTheme={currentTheme} />