From 6b30a914f4588332dffed0b0771ace3ee626b3b8 Mon Sep 17 00:00:00 2001 From: Till-JS <101404291+Till-JS@users.noreply.github.com> Date: Wed, 10 Dec 2025 15:09:10 +0100 Subject: [PATCH] fix(todo): improve drag-and-drop reliability with ID-based sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use sorted task IDs instead of array reference to detect real changes from parent. Update lastTaskIds after finalize to prevent $effect from reverting local DnD state changes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../web/src/lib/components/TaskList.svelte | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/apps/todo/apps/web/src/lib/components/TaskList.svelte b/apps/todo/apps/web/src/lib/components/TaskList.svelte index 1ce2fba42..b23b5b6a2 100644 --- a/apps/todo/apps/web/src/lib/components/TaskList.svelte +++ b/apps/todo/apps/web/src/lib/components/TaskList.svelte @@ -25,14 +25,18 @@ // Local mutable state for dnd-zone let items = $state([]); - // Track last known tasks reference to detect parent updates - let lastTasksRef: Task[] | null = null; + // Create a stable key from task IDs to detect real changes + let lastTaskIds = ''; - // Sync items with tasks only when tasks array reference changes - $effect.pre(() => { - if (tasks !== lastTasksRef) { + // Sync items with tasks only when the set of task IDs changes + $effect(() => { + const currentIds = tasks + .map((t) => t.id) + .sort() + .join(','); + if (currentIds !== lastTaskIds) { items = [...tasks]; - lastTasksRef = tasks; + lastTaskIds = currentIds; } }); @@ -54,7 +58,12 @@ onTaskDrop(movedTaskId, dropTargetDate); } + // Update local state and sync lastTaskIds to prevent $effect from reverting items = newItems; + lastTaskIds = newItems + .map((t) => t.id) + .sort() + .join(','); } async function handleToggleComplete(task: Task) {