|
17 | 17 | ]); |
18 | 18 |
|
19 | 19 | function handleDrop(state: DragDropState<ImageItem>) { |
20 | | - const { draggedItem, sourceContainer, targetContainer } = state; |
21 | | - if (!targetContainer || sourceContainer === targetContainer) return; // Prevent self-placement |
| 20 | + const { draggedItem, targetContainer } = state; |
| 21 | + const dragIndex = images.findIndex((img) => img.id === draggedItem.id); |
| 22 | + const dropIndex = parseInt(targetContainer ?? '0'); |
22 | 23 |
|
23 | | - images = images.filter((img: ImageItem) => img.id !== draggedItem.id); // Remove the dragged item |
24 | | - images.splice(parseInt(targetContainer), 0, draggedItem); // Insert the dragged item at the new position |
| 24 | + if (dragIndex !== -1 && !isNaN(dropIndex)) { |
| 25 | + const [item] = images.splice(dragIndex, 1); |
| 26 | + images.splice(dropIndex, 0, item); |
| 27 | + } |
25 | 28 | } |
26 | 29 | </script> |
27 | 30 |
|
|
34 | 37 | <div class="flex gap-4 overflow-x-auto p-4"> |
35 | 38 | {#each images as image, index (image.id)} |
36 | 39 | <div |
37 | | - use:droppable={{ container: index.toString(), callbacks: { onDrop: handleDrop } }} |
38 | | - class="relative" |
| 40 | + use:draggable={{ container: index.toString(), dragData: image }} |
| 41 | + use:droppable={{ |
| 42 | + container: index.toString(), |
| 43 | + callbacks: { onDrop: handleDrop } |
| 44 | + }} |
| 45 | + class="svelte-dnd-touch-feedback relative p-4" |
39 | 46 | animate:flip={{ duration: 200 }} |
| 47 | + in:fade={{ duration: 150 }} |
| 48 | + out:fade={{ duration: 150 }} |
40 | 49 | > |
41 | 50 | <div |
42 | | - use:draggable={{ |
43 | | - container: index.toString(), |
44 | | - dragData: image |
45 | | - }} |
46 | | - in:fade={{ duration: 150 }} |
47 | | - out:fade={{ duration: 150 }} |
48 | | - class="svelte-dnd-touch-feedback group relative h-[300px] w-[200px] cursor-move overflow-hidden |
49 | | - rounded-xl transition-transform hover:scale-105" |
| 51 | + class="group relative h-[300px] w-[200px] cursor-move overflow-hidden rounded-xl |
| 52 | + transition-transform hover:scale-105" |
50 | 53 | > |
51 | 54 | <img |
52 | 55 | src={image.url} |
53 | 56 | alt="" |
54 | 57 | class="h-full w-full object-cover transition-transform duration-700 |
55 | | - group-hover:scale-105" |
| 58 | + group-hover:scale-105" |
56 | 59 | /> |
57 | | - <!-- ... existing overlay code ... --> |
58 | 60 | </div> |
59 | 61 |
|
60 | | - <!-- Added position indicator --> |
61 | 62 | <div |
62 | 63 | class="absolute -bottom-4 left-1/2 z-20 -translate-x-1/2 rounded-full bg-white/90 |
63 | | - px-4 py-1.5 text-sm font-medium text-zinc-600 backdrop-blur-sm |
64 | | - transition-all group-hover:bg-white" |
| 64 | + px-4 py-1.5 text-sm font-medium text-zinc-600 backdrop-blur-sm |
| 65 | + transition-all group-hover:bg-white" |
65 | 66 | > |
66 | 67 | {index + 1} |
67 | 68 | </div> |
68 | 69 | </div> |
69 | 70 | {/each} |
70 | 71 | </div> |
71 | 72 | </div> |
| 73 | + |
| 74 | +<style> |
| 75 | + :global(.dragging) { |
| 76 | + @apply opacity-50 shadow-lg ring-2 ring-blue-400; |
| 77 | + } |
| 78 | +
|
| 79 | + :global(.drag-over) { |
| 80 | + @apply bg-blue-50; |
| 81 | + } |
| 82 | +</style> |
0 commit comments