From 2078147253533becad291d2fdbd9bee34d2e1df4 Mon Sep 17 00:00:00 2001 From: Spikey Sanju Date: Fri, 13 Dec 2024 00:14:14 +0530 Subject: [PATCH] feat: add interactive elements support to draggable functionality and update version to 0.0.17 --- package.json | 2 +- src/lib/actions/draggable.ts | 29 ++++++- src/routes/+layout.svelte | 3 +- src/routes/interactive-elements/+page.svelte | 80 ++++++++++++++++++++ 4 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 src/routes/interactive-elements/+page.svelte diff --git a/package.json b/package.json index d8d7991..200f6cc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@thisux/sveltednd", - "version": "0.0.16", + "version": "0.0.17", "private": false, "description": "A lightweight, flexible drag and drop library for Svelte 5 applications.", "author": "sanju ", diff --git a/src/lib/actions/draggable.ts b/src/lib/actions/draggable.ts index 019bd02..a927221 100644 --- a/src/lib/actions/draggable.ts +++ b/src/lib/actions/draggable.ts @@ -3,8 +3,24 @@ import type { DragDropOptions, DragDropState } from '$lib/types/index.js'; const DEFAULT_DRAGGING_CLASS = 'dragging'; -export function draggable(node: HTMLElement, options: DragDropOptions) { +interface DraggableOptions extends DragDropOptions { + // Add new option for interactive selectors + interactive?: string[]; +} + +export function draggable(node: HTMLElement, options: DraggableOptions) { const draggingClass = (options.attributes?.draggingClass || DEFAULT_DRAGGING_CLASS).split(' '); + let initialX: number; + let initialY: number; + + function isInteractiveElement(target: HTMLElement): boolean { + if (!options.interactive) return false; + + // Check if the target or its parents match any of the interactive selectors + return options.interactive.some(selector => + target.matches(selector) || target.closest(selector) + ); + } function handleDragStart(event: DragEvent) { if (options.disabled) return; @@ -40,6 +56,15 @@ export function draggable(node: HTMLElement, options: DragDropOptions) { function handlePointerDown(event: PointerEvent) { if (options.disabled) return; + + // If the target is an interactive element, don't start dragging + if (isInteractiveElement(event.target as HTMLElement)) { + return; + } + + // Store initial pointer position + initialX = event.clientX; + initialY = event.clientY; dndState.isDragging = true; dndState.draggedItem = options.dragData; @@ -79,7 +104,7 @@ export function draggable(node: HTMLElement, options: DragDropOptions) { node.addEventListener('pointerup', handlePointerUp); return { - update(newOptions: DragDropOptions) { + update(newOptions: DraggableOptions) { options = newOptions; node.draggable = !options.disabled; }, diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 7d955f6..57292bc 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -11,7 +11,8 @@ { path: '/grid-sort', title: 'Grid Sort' }, { path: '/nested', title: 'Nested Containers' }, { path: '/multiple', title: 'Multiple' }, - { path: '/custom-classes', title: 'Custom Classes' } + { path: '/custom-classes', title: 'Custom Classes' }, + { path: '/interactive-elements', title: 'Interactives' } ]; const cn = (...classes: string[]) => classes.filter(Boolean).join(' '); diff --git a/src/routes/interactive-elements/+page.svelte b/src/routes/interactive-elements/+page.svelte new file mode 100644 index 0000000..1cf893e --- /dev/null +++ b/src/routes/interactive-elements/+page.svelte @@ -0,0 +1,80 @@ + + +
+
+

Interactive Draggable List

+

+ Try clicking the items or delete buttons while also being able to drag and reorder the list. +

+
+ +
+ {#each items as item, index (item.id)} +
+ + + +
+ {/each} +
+