From 6377d810783f239c2795306b9120d7bc5dae3791 Mon Sep 17 00:00:00 2001 From: Houtan Rocky Date: Mon, 22 Apr 2024 23:03:59 +0330 Subject: [PATCH 1/2] Add holdDelay property to delay dragging --- packages/core/src/index.ts | 34 ++++++++++++++++++++ packages/svelte/demo/src/routes/+page.svelte | 1 + 2 files changed, 35 insertions(+) diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 65b84dd7..0e9d17a7 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -224,6 +224,14 @@ export type DragOptions = { * Fires when dragging ends */ onDragEnd?: (data: DragEventData) => void; + + /** + * Time in milliseconds a user must hold before dragging starts. + * This can help prevent accidental drags. + * + * @default 0ms + */ + holdDelay?: number; }; const enum DEFAULT_CLASS { @@ -267,6 +275,7 @@ export const draggable = (node: HTMLElement, options: DragOptions = {}) => { onDragStart, onDrag, onDragEnd, + holdDelay = 0, } = options; let active = false; @@ -373,11 +382,26 @@ export const draggable = (node: HTMLElement, options: DragOptions = {}) => { return inverseScale; }; + let holdTimeout: number | undefined; + let draggingAllowed = false; + function dragStart(e: PointerEvent) { if (disabled) return; if (e.button === 2) return; + // Start the hold delay timer + if (holdDelay > 0) { + holdTimeout = window.setTimeout(() => { + draggingAllowed = true; + fireSvelteDragStartEvent(); + }, holdDelay); + } else { + draggingAllowed = true; + fireSvelteDragStartEvent(); + } + + activePointers.add(e.pointerId); if (ignoreMultitouch && activePointers.size > 1) return e.preventDefault(); @@ -438,6 +462,14 @@ export const draggable = (node: HTMLElement, options: DragOptions = {}) => { } function dragEnd(e: PointerEvent) { + if (holdTimeout) { + clearTimeout(holdTimeout); + } + + if (!draggingAllowed) return; + + draggingAllowed = false; + activePointers.delete(e.pointerId); if (!active) return; @@ -459,6 +491,8 @@ export const draggable = (node: HTMLElement, options: DragOptions = {}) => { } function drag(e: PointerEvent) { + if (!draggingAllowed) return; + if (!active || (ignoreMultitouch && activePointers.size > 1)) return; if (recomputeBounds.drag) computedBounds = computeBoundRect(bounds, node); diff --git a/packages/svelte/demo/src/routes/+page.svelte b/packages/svelte/demo/src/routes/+page.svelte index 9627afd4..2935942d 100644 --- a/packages/svelte/demo/src/routes/+page.svelte +++ b/packages/svelte/demo/src/routes/+page.svelte @@ -170,6 +170,7 @@ progressX.set(offsetX); progressY.set(offsetY); }, + holdDelay: 200 }} class="box" > From e5dca8782103ab96453efa6707e5774ea0ecb49b Mon Sep 17 00:00:00 2001 From: Houtan Rocky Date: Tue, 23 Apr 2024 15:14:51 +0330 Subject: [PATCH 2/2] Default holdDelay to 100ms --- packages/core/src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 0e9d17a7..839b79c7 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -229,7 +229,7 @@ export type DragOptions = { * Time in milliseconds a user must hold before dragging starts. * This can help prevent accidental drags. * - * @default 0ms + * @default 100ms */ holdDelay?: number; }; @@ -275,7 +275,7 @@ export const draggable = (node: HTMLElement, options: DragOptions = {}) => { onDragStart, onDrag, onDragEnd, - holdDelay = 0, + holdDelay = 100, } = options; let active = false;