Skip to content

Commit 82fdf1e

Browse files
committed
fix: improve draggable functionality and enhance drop handling in horizontal scroll
1 parent 39dbde2 commit 82fdf1e

File tree

2 files changed

+35
-24
lines changed

2 files changed

+35
-24
lines changed

src/lib/actions/draggable.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ export function draggable<T>(node: HTMLElement, options: DraggableOptions<T>) {
1212
const draggingClass = (options.attributes?.draggingClass || DEFAULT_DRAGGING_CLASS).split(' ');
1313
let initialX: number;
1414
let initialY: number;
15-
15+
1616
function isInteractiveElement(target: HTMLElement): boolean {
1717
if (!options.interactive) return false;
18-
18+
1919
// Check if the target or its parents match any of the interactive selectors
20-
return options.interactive.some(selector =>
21-
target.matches(selector) || target.closest(selector)
20+
return options.interactive.some(
21+
(selector) => target.matches(selector) || target.closest(selector)
2222
);
2323
}
2424

@@ -56,7 +56,7 @@ export function draggable<T>(node: HTMLElement, options: DraggableOptions<T>) {
5656

5757
function handlePointerDown(event: PointerEvent) {
5858
if (options.disabled) return;
59-
59+
6060
// If the target is an interactive element, don't start dragging
6161
if (isInteractiveElement(event.target as HTMLElement)) {
6262
return;

src/routes/horizontal-scroll/+page.svelte

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@
1717
]);
1818
1919
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');
2223
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+
}
2528
}
2629
</script>
2730

@@ -34,38 +37,46 @@
3437
<div class="flex gap-4 overflow-x-auto p-4">
3538
{#each images as image, index (image.id)}
3639
<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"
3946
animate:flip={{ duration: 200 }}
47+
in:fade={{ duration: 150 }}
48+
out:fade={{ duration: 150 }}
4049
>
4150
<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"
5053
>
5154
<img
5255
src={image.url}
5356
alt=""
5457
class="h-full w-full object-cover transition-transform duration-700
55-
group-hover:scale-105"
58+
group-hover:scale-105"
5659
/>
57-
<!-- ... existing overlay code ... -->
5860
</div>
5961

60-
<!-- Added position indicator -->
6162
<div
6263
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"
6566
>
6667
{index + 1}
6768
</div>
6869
</div>
6970
{/each}
7071
</div>
7172
</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

Comments
 (0)