@vielzeug/dnd 1.2.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -9
- package/dist/_touch.cjs +2 -0
- package/dist/_touch.cjs.map +1 -0
- package/dist/_touch.d.ts +12 -0
- package/dist/_touch.d.ts.map +1 -0
- package/dist/_touch.js +132 -0
- package/dist/_touch.js.map +1 -0
- package/dist/dnd.cjs +1 -1
- package/dist/dnd.cjs.map +1 -1
- package/dist/dnd.iife.js +1 -1
- package/dist/dnd.iife.js.map +1 -1
- package/dist/dnd.js +1 -1
- package/dist/dnd.js.map +1 -1
- package/dist/drop-zone.cjs +1 -1
- package/dist/drop-zone.cjs.map +1 -1
- package/dist/drop-zone.d.ts +7 -3
- package/dist/drop-zone.d.ts.map +1 -1
- package/dist/drop-zone.js +38 -26
- package/dist/drop-zone.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/sortable.cjs +1 -1
- package/dist/sortable.cjs.map +1 -1
- package/dist/sortable.d.ts +35 -1
- package/dist/sortable.d.ts.map +1 -1
- package/dist/sortable.js +165 -105
- package/dist/sortable.js.map +1 -1
- package/package.json +1 -1
- package/dist/touch.cjs +0 -2
- package/dist/touch.cjs.map +0 -1
- package/dist/touch.d.ts +0 -49
- package/dist/touch.d.ts.map +0 -1
- package/dist/touch.js +0 -124
- package/dist/touch.js.map +0 -1
package/dist/touch.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"touch.cjs","names":[],"sources":["../src/touch.ts"],"sourcesContent":["import { warn } from './_dev';\nimport { createDisposable, resolveDisabled } from './_shared';\nimport { type Disposable } from './types';\n\nexport interface TouchDragOptions {\n /**\n * Set to `true` (or mutate this same options object's field later) to pause the shim without\n * disposing it — matches `createSortable`'s/`createDropZone`'s own `disabled` option.\n */\n disabled?: boolean;\n /**\n * CSS selector identifying draggable elements. Defaults to `[draggable=\"true\"]` — the exact\n * attribute `createSortable`/`createDropZone`-managed elements already carry, so the default\n * needs no configuration for the common case of bridging touch to an existing sortable/drop zone.\n */\n draggableSelector?: string;\n /**\n * Renders a floating clone of the dragged element that follows the touch point for the\n * duration of the drag. @default true\n *\n * A native mouse-driven HTML5 drag gets this for free: the browser snapshots the dragged\n * element into its own drag image the moment `dragstart` fires, then keeps that image under\n * the cursor itself for the whole gesture — `createSortable`'s `scheduleHide()` hides the real\n * element a frame later assuming that snapshot already exists. This shim's `dragstart` is a\n * synthetic `Event`, not a real drag, so the browser never creates that image; without this\n * preview, `scheduleHide()` still hides the real element on schedule and touch users are left\n * with *no* visual feedback for the whole gesture — only an empty placeholder box moving\n * between positions — making any drop feel arbitrary regardless of where it actually lands.\n * Set to `false` to render fully custom feedback instead (e.g. toggling a class from your own\n * `dragstart`/`dragend` listeners).\n */\n showDragPreview?: boolean;\n}\n\nconst PREVIEW_Z_INDEX = 2147483647;\n\n/**\n * Floating visual stand-in for the (real, but hidden) dragged element — see `showDragPreview`'s\n * doc comment for why touch needs one at all. `cloneNode(true)` only clones light-DOM content;\n * a draggable item that renders its visible content inside a shadow root (e.g. a shadow-DOM\n * custom element) will clone as an empty shell. This mirrors the same light-DOM-only limitation\n * every `cloneNode`-based drag preview (most JS sortable libraries included) accepts in exchange\n * for never having to special-case every possible element type.\n */\nfunction createPreviewElement(source: HTMLElement): HTMLElement {\n const rect = source.getBoundingClientRect();\n const clone = source.cloneNode(true) as HTMLElement;\n\n clone.removeAttribute('id');\n clone.setAttribute('aria-hidden', 'true');\n clone.setAttribute('inert', '');\n clone.setAttribute('data-dnd-touch-preview', '');\n Object.assign(clone.style, {\n height: `${rect.height}px`,\n left: `${rect.left}px`,\n margin: '0',\n opacity: '0.85',\n pointerEvents: 'none',\n position: 'fixed',\n top: `${rect.top}px`,\n transition: 'none',\n width: `${rect.width}px`,\n zIndex: String(PREVIEW_Z_INDEX),\n });\n\n document.body.appendChild(clone);\n\n return clone;\n}\n\n// Deliberately a plain object, never a real `new DataTransfer()`. Verified directly against a\n// real Chromium build (not just jsdom): a genuine `DataTransfer` instance created outside an\n// active *native* drag operation is permanently in the spec's \"disabled mode\" — every property\n// write, `dropEffect` included, is silently ignored, and every read of it keeps returning the\n// type's default (`'none'`), no matter what's assigned. `createSortable`/`createDropZone`'s own\n// `finishSession()` reads `dropEffect === 'none'` as an explicit cancellation signal, so with a\n// real `DataTransfer` backing this shim's synthetic events, *every* commit — same-column reorder\n// or cross-column move alike — would always revert, regardless of where it was actually dropped.\n// A plain object has no such \"mode\" concept: its `dropEffect` is an ordinary, freely-settable JS\n// property, which is all `createSortable`/`createDropZone`'s handlers ever read or write on the\n// events this shim dispatches. This is also why the previous Safari-<14 fallback (which already\n// used a plain object) never exhibited this bug — it was the correct approach the whole time.\nfunction makeDataTransfer(): DataTransfer {\n return {\n dropEffect: 'move',\n effectAllowed: 'move',\n getData: () => '',\n setData() {},\n setDragImage() {},\n } as unknown as DataTransfer;\n}\n\n/**\n * Bridges touch gestures to the synthetic `DragEvent` sequence `createSortable()`/\n * `createDropZone()` already listen for. HTML5 drag-and-drop has no native touch story —\n * this translates `touchstart`/`touchmove`/`touchend`/`touchcancel` into\n * `dragstart`/`dragover`/`drop`/`dragend` on the same document, so touch devices get\n * sortable/drop-zone behavior for free with no extra wiring at each call site.\n *\n * Listens at the `document` level (matching how `createSortable`/`createDropZone` themselves\n * scope drag detection) — one instance covers the whole page. Dispose to remove all listeners.\n *\n * @example\n * ```ts\n * using touchDrag = createTouchDragShim();\n * // ...later, or via the `using` declaration above:\n * touchDrag.dispose();\n * ```\n */\nexport function createTouchDragShim(options: TouchDragOptions = {}): Disposable {\n const dt = makeDataTransfer();\n const DRAG_START_DISTANCE_PX = 6;\n\n let pendingDraggable: HTMLElement | null = null;\n let pendingStartPoint: { clientX: number; clientY: number } | null = null;\n let dragging: HTMLElement | null = null;\n let lastTarget: Element | null = null;\n\n // The preview follows the touch point via a `translate3d` delta from wherever the touch was\n // when the preview was created (`previewOrigin`), not from the element's own rect — so it never\n // \"jumps\" at drag start (the delta starts at zero regardless of exactly where inside the\n // element the user first touched).\n let previewEl: HTMLElement | null = null;\n let previewOrigin: { clientX: number; clientY: number } | null = null;\n\n function removePreview(): void {\n previewEl?.remove();\n previewEl = null;\n previewOrigin = null;\n }\n\n // Hides both the real dragged element AND the floating preview for the duration of the\n // hit-test, then restores them. Hiding `dragging` alone isn't enough: the preview sits on top\n // of everything (by design, to follow the touch point) and, since `createPreviewElement()`\n // clones the dragged element's subtree, it can carry cloned custom elements (e.g. shadow-DOM\n // components) that re-run their own setup on the clone and may set `pointer-events` on their\n // *internal* shadow content — which a `pointer-events: none` set only on the preview's light-DOM\n // root does not reliably override. Hiding it outright (rather than relying on `pointer-events`)\n // sidesteps that entirely: a hidden element is never returned by `elementFromPoint`, regardless\n // of what any of its descendants — shadow DOM included — set.\n function elementBelow(clientX: number, clientY: number): Element | null {\n const prevDraggingDisplay = dragging?.style.display ?? '';\n const prevPreviewDisplay = previewEl?.style.display ?? '';\n\n if (dragging) dragging.style.display = 'none';\n\n if (previewEl) previewEl.style.display = 'none';\n\n const below = document.elementFromPoint(clientX, clientY);\n\n if (dragging) dragging.style.display = prevDraggingDisplay;\n\n if (previewEl) previewEl.style.display = prevPreviewDisplay;\n\n return below;\n }\n\n const disposable = createDisposable(() => {\n pendingDraggable = null;\n pendingStartPoint = null;\n dragging = null;\n lastTarget = null;\n removePreview();\n });\n\n // Built on a plain `Event` rather than `new DragEvent(...)`: jsdom (and potentially other\n // non-browser DOM implementations) doesn't expose a `DragEvent` constructor at all, and\n // `createSortable`/`createDropZone`'s own handlers only ever read `type`/`clientX`/`clientY`/\n // `dataTransfer` off the event object — they never check `instanceof DragEvent` — so a patched\n // plain `Event` is indistinguishable to them and works everywhere a real `DragEvent` would.\n function dispatch(el: Element, type: string, clientX: number, clientY: number): void {\n const event = new Event(type, { bubbles: true, cancelable: true });\n\n Object.defineProperty(event, 'clientX', { configurable: true, value: clientX });\n Object.defineProperty(event, 'clientY', { configurable: true, value: clientY });\n Object.defineProperty(event, 'dataTransfer', { configurable: true, value: dt });\n el.dispatchEvent(event);\n }\n\n document.addEventListener(\n 'touchstart',\n (e: TouchEvent) => {\n if (resolveDisabled(options.disabled)) return;\n\n const touch = e.touches[0];\n\n if (!touch) return;\n\n const target = document.elementFromPoint(touch.clientX, touch.clientY) as HTMLElement | null;\n const draggable = target?.closest<HTMLElement>(options.draggableSelector ?? '[draggable=\"true\"]');\n\n if (!draggable) return;\n\n pendingDraggable = draggable;\n pendingStartPoint = { clientX: touch.clientX, clientY: touch.clientY };\n },\n { passive: false, signal: disposable.disposalSignal },\n );\n\n document.addEventListener(\n 'touchmove',\n (e: TouchEvent) => {\n const touch = e.touches[0];\n\n if (!touch) return;\n\n if (!dragging) {\n if (!pendingDraggable || !pendingStartPoint) return;\n\n const dx = touch.clientX - pendingStartPoint.clientX;\n const dy = touch.clientY - pendingStartPoint.clientY;\n const distance = Math.hypot(dx, dy);\n\n if (distance < DRAG_START_DISTANCE_PX) return;\n\n dragging = pendingDraggable;\n lastTarget = pendingDraggable;\n\n // Captured before dispatching 'dragstart': createSortable's own scheduleHide() hides\n // `dragging` a frame after that event fires, and by then its layout position may already\n // reflect the placeholder having been inserted. Reading the rect now, while it's still\n // exactly where the user picked it up, is what createPreviewElement() sizes/positions the\n // clone from.\n //\n // Wrapped in try/catch: `createPreviewElement()` clones the dragged element's whole\n // subtree, which — for a draggable item backed by custom elements — re-instantiates live\n // copies that re-run their own `connectedCallback`/setup once appended to `document.body`.\n // A best-effort *visual* feature must never be able to take down the *functional* one:\n // if any of that throws (a component assuming a page-unique id, a framework-internal\n // invariant, anything), the drag must still start normally with no preview, not silently\n // never start at all.\n if (options.showDragPreview !== false) {\n try {\n previewEl = createPreviewElement(dragging);\n previewOrigin = { clientX: touch.clientX, clientY: touch.clientY };\n } catch (err) {\n warn(`drag preview failed to render, continuing without one: ${String(err)}`);\n removePreview();\n }\n }\n\n dispatch(dragging, 'dragstart', touch.clientX, touch.clientY);\n }\n\n if (previewEl && previewOrigin) {\n const dx = touch.clientX - previewOrigin.clientX;\n const dy = touch.clientY - previewOrigin.clientY;\n\n previewEl.style.transform = `translate3d(${dx}px, ${dy}px, 0)`;\n }\n\n const below = elementBelow(touch.clientX, touch.clientY);\n\n if (below && below !== lastTarget) {\n if (lastTarget) dispatch(lastTarget, 'dragleave', touch.clientX, touch.clientY);\n\n lastTarget = below;\n }\n\n if (below) dispatch(below, 'dragover', touch.clientX, touch.clientY);\n\n pendingDraggable = null;\n pendingStartPoint = null;\n e.preventDefault();\n },\n { passive: false, signal: disposable.disposalSignal },\n );\n\n document.addEventListener(\n 'touchend',\n (e: TouchEvent) => {\n if (!dragging) {\n pendingDraggable = null;\n pendingStartPoint = null;\n\n return;\n }\n\n const touch = e.changedTouches[0];\n\n if (!touch) return;\n\n const below = elementBelow(touch.clientX, touch.clientY);\n\n if (below) dispatch(below, 'drop', touch.clientX, touch.clientY);\n\n dispatch(dragging, 'dragend', touch.clientX, touch.clientY);\n\n pendingDraggable = null;\n pendingStartPoint = null;\n dragging = null;\n lastTarget = null;\n removePreview();\n },\n { passive: true, signal: disposable.disposalSignal },\n );\n\n document.addEventListener(\n 'touchcancel',\n (e: TouchEvent) => {\n if (!dragging) {\n pendingDraggable = null;\n pendingStartPoint = null;\n\n return;\n }\n\n const touch = e.changedTouches[0];\n\n if (!touch) return;\n\n dispatch(dragging, 'dragend', touch.clientX, touch.clientY);\n pendingDraggable = null;\n pendingStartPoint = null;\n dragging = null;\n lastTarget = null;\n removePreview();\n },\n { passive: true, signal: disposable.disposalSignal },\n );\n\n return disposable;\n}\n"],"mappings":"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"}
|
package/dist/touch.d.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { type Disposable } from './types';
|
|
2
|
-
export interface TouchDragOptions {
|
|
3
|
-
/**
|
|
4
|
-
* Set to `true` (or mutate this same options object's field later) to pause the shim without
|
|
5
|
-
* disposing it — matches `createSortable`'s/`createDropZone`'s own `disabled` option.
|
|
6
|
-
*/
|
|
7
|
-
disabled?: boolean;
|
|
8
|
-
/**
|
|
9
|
-
* CSS selector identifying draggable elements. Defaults to `[draggable="true"]` — the exact
|
|
10
|
-
* attribute `createSortable`/`createDropZone`-managed elements already carry, so the default
|
|
11
|
-
* needs no configuration for the common case of bridging touch to an existing sortable/drop zone.
|
|
12
|
-
*/
|
|
13
|
-
draggableSelector?: string;
|
|
14
|
-
/**
|
|
15
|
-
* Renders a floating clone of the dragged element that follows the touch point for the
|
|
16
|
-
* duration of the drag. @default true
|
|
17
|
-
*
|
|
18
|
-
* A native mouse-driven HTML5 drag gets this for free: the browser snapshots the dragged
|
|
19
|
-
* element into its own drag image the moment `dragstart` fires, then keeps that image under
|
|
20
|
-
* the cursor itself for the whole gesture — `createSortable`'s `scheduleHide()` hides the real
|
|
21
|
-
* element a frame later assuming that snapshot already exists. This shim's `dragstart` is a
|
|
22
|
-
* synthetic `Event`, not a real drag, so the browser never creates that image; without this
|
|
23
|
-
* preview, `scheduleHide()` still hides the real element on schedule and touch users are left
|
|
24
|
-
* with *no* visual feedback for the whole gesture — only an empty placeholder box moving
|
|
25
|
-
* between positions — making any drop feel arbitrary regardless of where it actually lands.
|
|
26
|
-
* Set to `false` to render fully custom feedback instead (e.g. toggling a class from your own
|
|
27
|
-
* `dragstart`/`dragend` listeners).
|
|
28
|
-
*/
|
|
29
|
-
showDragPreview?: boolean;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Bridges touch gestures to the synthetic `DragEvent` sequence `createSortable()`/
|
|
33
|
-
* `createDropZone()` already listen for. HTML5 drag-and-drop has no native touch story —
|
|
34
|
-
* this translates `touchstart`/`touchmove`/`touchend`/`touchcancel` into
|
|
35
|
-
* `dragstart`/`dragover`/`drop`/`dragend` on the same document, so touch devices get
|
|
36
|
-
* sortable/drop-zone behavior for free with no extra wiring at each call site.
|
|
37
|
-
*
|
|
38
|
-
* Listens at the `document` level (matching how `createSortable`/`createDropZone` themselves
|
|
39
|
-
* scope drag detection) — one instance covers the whole page. Dispose to remove all listeners.
|
|
40
|
-
*
|
|
41
|
-
* @example
|
|
42
|
-
* ```ts
|
|
43
|
-
* using touchDrag = createTouchDragShim();
|
|
44
|
-
* // ...later, or via the `using` declaration above:
|
|
45
|
-
* touchDrag.dispose();
|
|
46
|
-
* ```
|
|
47
|
-
*/
|
|
48
|
-
export declare function createTouchDragShim(options?: TouchDragOptions): Disposable;
|
|
49
|
-
//# sourceMappingURL=touch.d.ts.map
|
package/dist/touch.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"touch.d.ts","sourceRoot":"","sources":["../src/touch.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;;;;;;;;;OAcG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AA4DD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,gBAAqB,GAAG,UAAU,CAqN9E"}
|
package/dist/touch.js
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import { createDisposable as e, resolveDisabled as t } from "./_shared.js";
|
|
2
|
-
import "./_dev.js";
|
|
3
|
-
//#region src/touch.ts
|
|
4
|
-
var n = 2147483647;
|
|
5
|
-
function r(e) {
|
|
6
|
-
let t = e.getBoundingClientRect(), r = e.cloneNode(!0);
|
|
7
|
-
return r.removeAttribute("id"), r.setAttribute("aria-hidden", "true"), r.setAttribute("inert", ""), r.setAttribute("data-dnd-touch-preview", ""), Object.assign(r.style, {
|
|
8
|
-
height: `${t.height}px`,
|
|
9
|
-
left: `${t.left}px`,
|
|
10
|
-
margin: "0",
|
|
11
|
-
opacity: "0.85",
|
|
12
|
-
pointerEvents: "none",
|
|
13
|
-
position: "fixed",
|
|
14
|
-
top: `${t.top}px`,
|
|
15
|
-
transition: "none",
|
|
16
|
-
width: `${t.width}px`,
|
|
17
|
-
zIndex: String(n)
|
|
18
|
-
}), document.body.appendChild(r), r;
|
|
19
|
-
}
|
|
20
|
-
function i() {
|
|
21
|
-
return {
|
|
22
|
-
dropEffect: "move",
|
|
23
|
-
effectAllowed: "move",
|
|
24
|
-
getData: () => "",
|
|
25
|
-
setData() {},
|
|
26
|
-
setDragImage() {}
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
function a(n = {}) {
|
|
30
|
-
let a = i(), o = null, s = null, c = null, l = null, u = null, d = null;
|
|
31
|
-
function f() {
|
|
32
|
-
u?.remove(), u = null, d = null;
|
|
33
|
-
}
|
|
34
|
-
function p(e, t) {
|
|
35
|
-
let n = c?.style.display ?? "", r = u?.style.display ?? "";
|
|
36
|
-
c && (c.style.display = "none"), u && (u.style.display = "none");
|
|
37
|
-
let i = document.elementFromPoint(e, t);
|
|
38
|
-
return c && (c.style.display = n), u && (u.style.display = r), i;
|
|
39
|
-
}
|
|
40
|
-
let m = e(() => {
|
|
41
|
-
o = null, s = null, c = null, l = null, f();
|
|
42
|
-
});
|
|
43
|
-
function h(e, t, n, r) {
|
|
44
|
-
let i = new Event(t, {
|
|
45
|
-
bubbles: !0,
|
|
46
|
-
cancelable: !0
|
|
47
|
-
});
|
|
48
|
-
Object.defineProperty(i, "clientX", {
|
|
49
|
-
configurable: !0,
|
|
50
|
-
value: n
|
|
51
|
-
}), Object.defineProperty(i, "clientY", {
|
|
52
|
-
configurable: !0,
|
|
53
|
-
value: r
|
|
54
|
-
}), Object.defineProperty(i, "dataTransfer", {
|
|
55
|
-
configurable: !0,
|
|
56
|
-
value: a
|
|
57
|
-
}), e.dispatchEvent(i);
|
|
58
|
-
}
|
|
59
|
-
return document.addEventListener("touchstart", (e) => {
|
|
60
|
-
if (t(n.disabled)) return;
|
|
61
|
-
let r = e.touches[0];
|
|
62
|
-
if (!r) return;
|
|
63
|
-
let i = document.elementFromPoint(r.clientX, r.clientY)?.closest(n.draggableSelector ?? "[draggable=\"true\"]");
|
|
64
|
-
i && (o = i, s = {
|
|
65
|
-
clientX: r.clientX,
|
|
66
|
-
clientY: r.clientY
|
|
67
|
-
});
|
|
68
|
-
}, {
|
|
69
|
-
passive: !1,
|
|
70
|
-
signal: m.disposalSignal
|
|
71
|
-
}), document.addEventListener("touchmove", (e) => {
|
|
72
|
-
let t = e.touches[0];
|
|
73
|
-
if (!t) return;
|
|
74
|
-
if (!c) {
|
|
75
|
-
if (!o || !s) return;
|
|
76
|
-
let e = t.clientX - s.clientX, i = t.clientY - s.clientY;
|
|
77
|
-
if (Math.hypot(e, i) < 6) return;
|
|
78
|
-
if (c = o, l = o, n.showDragPreview !== !1) try {
|
|
79
|
-
u = r(c), d = {
|
|
80
|
-
clientX: t.clientX,
|
|
81
|
-
clientY: t.clientY
|
|
82
|
-
};
|
|
83
|
-
} catch (e) {
|
|
84
|
-
`${String(e)}`, f();
|
|
85
|
-
}
|
|
86
|
-
h(c, "dragstart", t.clientX, t.clientY);
|
|
87
|
-
}
|
|
88
|
-
if (u && d) {
|
|
89
|
-
let e = t.clientX - d.clientX, n = t.clientY - d.clientY;
|
|
90
|
-
u.style.transform = `translate3d(${e}px, ${n}px, 0)`;
|
|
91
|
-
}
|
|
92
|
-
let i = p(t.clientX, t.clientY);
|
|
93
|
-
i && i !== l && (l && h(l, "dragleave", t.clientX, t.clientY), l = i), i && h(i, "dragover", t.clientX, t.clientY), o = null, s = null, e.preventDefault();
|
|
94
|
-
}, {
|
|
95
|
-
passive: !1,
|
|
96
|
-
signal: m.disposalSignal
|
|
97
|
-
}), document.addEventListener("touchend", (e) => {
|
|
98
|
-
if (!c) {
|
|
99
|
-
o = null, s = null;
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
let t = e.changedTouches[0];
|
|
103
|
-
if (!t) return;
|
|
104
|
-
let n = p(t.clientX, t.clientY);
|
|
105
|
-
n && h(n, "drop", t.clientX, t.clientY), h(c, "dragend", t.clientX, t.clientY), o = null, s = null, c = null, l = null, f();
|
|
106
|
-
}, {
|
|
107
|
-
passive: !0,
|
|
108
|
-
signal: m.disposalSignal
|
|
109
|
-
}), document.addEventListener("touchcancel", (e) => {
|
|
110
|
-
if (!c) {
|
|
111
|
-
o = null, s = null;
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
let t = e.changedTouches[0];
|
|
115
|
-
t && (h(c, "dragend", t.clientX, t.clientY), o = null, s = null, c = null, l = null, f());
|
|
116
|
-
}, {
|
|
117
|
-
passive: !0,
|
|
118
|
-
signal: m.disposalSignal
|
|
119
|
-
}), m;
|
|
120
|
-
}
|
|
121
|
-
//#endregion
|
|
122
|
-
export { a as createTouchDragShim };
|
|
123
|
-
|
|
124
|
-
//# sourceMappingURL=touch.js.map
|
package/dist/touch.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"touch.js","names":[],"sources":["../src/touch.ts"],"sourcesContent":["import { warn } from './_dev';\nimport { createDisposable, resolveDisabled } from './_shared';\nimport { type Disposable } from './types';\n\nexport interface TouchDragOptions {\n /**\n * Set to `true` (or mutate this same options object's field later) to pause the shim without\n * disposing it — matches `createSortable`'s/`createDropZone`'s own `disabled` option.\n */\n disabled?: boolean;\n /**\n * CSS selector identifying draggable elements. Defaults to `[draggable=\"true\"]` — the exact\n * attribute `createSortable`/`createDropZone`-managed elements already carry, so the default\n * needs no configuration for the common case of bridging touch to an existing sortable/drop zone.\n */\n draggableSelector?: string;\n /**\n * Renders a floating clone of the dragged element that follows the touch point for the\n * duration of the drag. @default true\n *\n * A native mouse-driven HTML5 drag gets this for free: the browser snapshots the dragged\n * element into its own drag image the moment `dragstart` fires, then keeps that image under\n * the cursor itself for the whole gesture — `createSortable`'s `scheduleHide()` hides the real\n * element a frame later assuming that snapshot already exists. This shim's `dragstart` is a\n * synthetic `Event`, not a real drag, so the browser never creates that image; without this\n * preview, `scheduleHide()` still hides the real element on schedule and touch users are left\n * with *no* visual feedback for the whole gesture — only an empty placeholder box moving\n * between positions — making any drop feel arbitrary regardless of where it actually lands.\n * Set to `false` to render fully custom feedback instead (e.g. toggling a class from your own\n * `dragstart`/`dragend` listeners).\n */\n showDragPreview?: boolean;\n}\n\nconst PREVIEW_Z_INDEX = 2147483647;\n\n/**\n * Floating visual stand-in for the (real, but hidden) dragged element — see `showDragPreview`'s\n * doc comment for why touch needs one at all. `cloneNode(true)` only clones light-DOM content;\n * a draggable item that renders its visible content inside a shadow root (e.g. a shadow-DOM\n * custom element) will clone as an empty shell. This mirrors the same light-DOM-only limitation\n * every `cloneNode`-based drag preview (most JS sortable libraries included) accepts in exchange\n * for never having to special-case every possible element type.\n */\nfunction createPreviewElement(source: HTMLElement): HTMLElement {\n const rect = source.getBoundingClientRect();\n const clone = source.cloneNode(true) as HTMLElement;\n\n clone.removeAttribute('id');\n clone.setAttribute('aria-hidden', 'true');\n clone.setAttribute('inert', '');\n clone.setAttribute('data-dnd-touch-preview', '');\n Object.assign(clone.style, {\n height: `${rect.height}px`,\n left: `${rect.left}px`,\n margin: '0',\n opacity: '0.85',\n pointerEvents: 'none',\n position: 'fixed',\n top: `${rect.top}px`,\n transition: 'none',\n width: `${rect.width}px`,\n zIndex: String(PREVIEW_Z_INDEX),\n });\n\n document.body.appendChild(clone);\n\n return clone;\n}\n\n// Deliberately a plain object, never a real `new DataTransfer()`. Verified directly against a\n// real Chromium build (not just jsdom): a genuine `DataTransfer` instance created outside an\n// active *native* drag operation is permanently in the spec's \"disabled mode\" — every property\n// write, `dropEffect` included, is silently ignored, and every read of it keeps returning the\n// type's default (`'none'`), no matter what's assigned. `createSortable`/`createDropZone`'s own\n// `finishSession()` reads `dropEffect === 'none'` as an explicit cancellation signal, so with a\n// real `DataTransfer` backing this shim's synthetic events, *every* commit — same-column reorder\n// or cross-column move alike — would always revert, regardless of where it was actually dropped.\n// A plain object has no such \"mode\" concept: its `dropEffect` is an ordinary, freely-settable JS\n// property, which is all `createSortable`/`createDropZone`'s handlers ever read or write on the\n// events this shim dispatches. This is also why the previous Safari-<14 fallback (which already\n// used a plain object) never exhibited this bug — it was the correct approach the whole time.\nfunction makeDataTransfer(): DataTransfer {\n return {\n dropEffect: 'move',\n effectAllowed: 'move',\n getData: () => '',\n setData() {},\n setDragImage() {},\n } as unknown as DataTransfer;\n}\n\n/**\n * Bridges touch gestures to the synthetic `DragEvent` sequence `createSortable()`/\n * `createDropZone()` already listen for. HTML5 drag-and-drop has no native touch story —\n * this translates `touchstart`/`touchmove`/`touchend`/`touchcancel` into\n * `dragstart`/`dragover`/`drop`/`dragend` on the same document, so touch devices get\n * sortable/drop-zone behavior for free with no extra wiring at each call site.\n *\n * Listens at the `document` level (matching how `createSortable`/`createDropZone` themselves\n * scope drag detection) — one instance covers the whole page. Dispose to remove all listeners.\n *\n * @example\n * ```ts\n * using touchDrag = createTouchDragShim();\n * // ...later, or via the `using` declaration above:\n * touchDrag.dispose();\n * ```\n */\nexport function createTouchDragShim(options: TouchDragOptions = {}): Disposable {\n const dt = makeDataTransfer();\n const DRAG_START_DISTANCE_PX = 6;\n\n let pendingDraggable: HTMLElement | null = null;\n let pendingStartPoint: { clientX: number; clientY: number } | null = null;\n let dragging: HTMLElement | null = null;\n let lastTarget: Element | null = null;\n\n // The preview follows the touch point via a `translate3d` delta from wherever the touch was\n // when the preview was created (`previewOrigin`), not from the element's own rect — so it never\n // \"jumps\" at drag start (the delta starts at zero regardless of exactly where inside the\n // element the user first touched).\n let previewEl: HTMLElement | null = null;\n let previewOrigin: { clientX: number; clientY: number } | null = null;\n\n function removePreview(): void {\n previewEl?.remove();\n previewEl = null;\n previewOrigin = null;\n }\n\n // Hides both the real dragged element AND the floating preview for the duration of the\n // hit-test, then restores them. Hiding `dragging` alone isn't enough: the preview sits on top\n // of everything (by design, to follow the touch point) and, since `createPreviewElement()`\n // clones the dragged element's subtree, it can carry cloned custom elements (e.g. shadow-DOM\n // components) that re-run their own setup on the clone and may set `pointer-events` on their\n // *internal* shadow content — which a `pointer-events: none` set only on the preview's light-DOM\n // root does not reliably override. Hiding it outright (rather than relying on `pointer-events`)\n // sidesteps that entirely: a hidden element is never returned by `elementFromPoint`, regardless\n // of what any of its descendants — shadow DOM included — set.\n function elementBelow(clientX: number, clientY: number): Element | null {\n const prevDraggingDisplay = dragging?.style.display ?? '';\n const prevPreviewDisplay = previewEl?.style.display ?? '';\n\n if (dragging) dragging.style.display = 'none';\n\n if (previewEl) previewEl.style.display = 'none';\n\n const below = document.elementFromPoint(clientX, clientY);\n\n if (dragging) dragging.style.display = prevDraggingDisplay;\n\n if (previewEl) previewEl.style.display = prevPreviewDisplay;\n\n return below;\n }\n\n const disposable = createDisposable(() => {\n pendingDraggable = null;\n pendingStartPoint = null;\n dragging = null;\n lastTarget = null;\n removePreview();\n });\n\n // Built on a plain `Event` rather than `new DragEvent(...)`: jsdom (and potentially other\n // non-browser DOM implementations) doesn't expose a `DragEvent` constructor at all, and\n // `createSortable`/`createDropZone`'s own handlers only ever read `type`/`clientX`/`clientY`/\n // `dataTransfer` off the event object — they never check `instanceof DragEvent` — so a patched\n // plain `Event` is indistinguishable to them and works everywhere a real `DragEvent` would.\n function dispatch(el: Element, type: string, clientX: number, clientY: number): void {\n const event = new Event(type, { bubbles: true, cancelable: true });\n\n Object.defineProperty(event, 'clientX', { configurable: true, value: clientX });\n Object.defineProperty(event, 'clientY', { configurable: true, value: clientY });\n Object.defineProperty(event, 'dataTransfer', { configurable: true, value: dt });\n el.dispatchEvent(event);\n }\n\n document.addEventListener(\n 'touchstart',\n (e: TouchEvent) => {\n if (resolveDisabled(options.disabled)) return;\n\n const touch = e.touches[0];\n\n if (!touch) return;\n\n const target = document.elementFromPoint(touch.clientX, touch.clientY) as HTMLElement | null;\n const draggable = target?.closest<HTMLElement>(options.draggableSelector ?? '[draggable=\"true\"]');\n\n if (!draggable) return;\n\n pendingDraggable = draggable;\n pendingStartPoint = { clientX: touch.clientX, clientY: touch.clientY };\n },\n { passive: false, signal: disposable.disposalSignal },\n );\n\n document.addEventListener(\n 'touchmove',\n (e: TouchEvent) => {\n const touch = e.touches[0];\n\n if (!touch) return;\n\n if (!dragging) {\n if (!pendingDraggable || !pendingStartPoint) return;\n\n const dx = touch.clientX - pendingStartPoint.clientX;\n const dy = touch.clientY - pendingStartPoint.clientY;\n const distance = Math.hypot(dx, dy);\n\n if (distance < DRAG_START_DISTANCE_PX) return;\n\n dragging = pendingDraggable;\n lastTarget = pendingDraggable;\n\n // Captured before dispatching 'dragstart': createSortable's own scheduleHide() hides\n // `dragging` a frame after that event fires, and by then its layout position may already\n // reflect the placeholder having been inserted. Reading the rect now, while it's still\n // exactly where the user picked it up, is what createPreviewElement() sizes/positions the\n // clone from.\n //\n // Wrapped in try/catch: `createPreviewElement()` clones the dragged element's whole\n // subtree, which — for a draggable item backed by custom elements — re-instantiates live\n // copies that re-run their own `connectedCallback`/setup once appended to `document.body`.\n // A best-effort *visual* feature must never be able to take down the *functional* one:\n // if any of that throws (a component assuming a page-unique id, a framework-internal\n // invariant, anything), the drag must still start normally with no preview, not silently\n // never start at all.\n if (options.showDragPreview !== false) {\n try {\n previewEl = createPreviewElement(dragging);\n previewOrigin = { clientX: touch.clientX, clientY: touch.clientY };\n } catch (err) {\n warn(`drag preview failed to render, continuing without one: ${String(err)}`);\n removePreview();\n }\n }\n\n dispatch(dragging, 'dragstart', touch.clientX, touch.clientY);\n }\n\n if (previewEl && previewOrigin) {\n const dx = touch.clientX - previewOrigin.clientX;\n const dy = touch.clientY - previewOrigin.clientY;\n\n previewEl.style.transform = `translate3d(${dx}px, ${dy}px, 0)`;\n }\n\n const below = elementBelow(touch.clientX, touch.clientY);\n\n if (below && below !== lastTarget) {\n if (lastTarget) dispatch(lastTarget, 'dragleave', touch.clientX, touch.clientY);\n\n lastTarget = below;\n }\n\n if (below) dispatch(below, 'dragover', touch.clientX, touch.clientY);\n\n pendingDraggable = null;\n pendingStartPoint = null;\n e.preventDefault();\n },\n { passive: false, signal: disposable.disposalSignal },\n );\n\n document.addEventListener(\n 'touchend',\n (e: TouchEvent) => {\n if (!dragging) {\n pendingDraggable = null;\n pendingStartPoint = null;\n\n return;\n }\n\n const touch = e.changedTouches[0];\n\n if (!touch) return;\n\n const below = elementBelow(touch.clientX, touch.clientY);\n\n if (below) dispatch(below, 'drop', touch.clientX, touch.clientY);\n\n dispatch(dragging, 'dragend', touch.clientX, touch.clientY);\n\n pendingDraggable = null;\n pendingStartPoint = null;\n dragging = null;\n lastTarget = null;\n removePreview();\n },\n { passive: true, signal: disposable.disposalSignal },\n );\n\n document.addEventListener(\n 'touchcancel',\n (e: TouchEvent) => {\n if (!dragging) {\n pendingDraggable = null;\n pendingStartPoint = null;\n\n return;\n }\n\n const touch = e.changedTouches[0];\n\n if (!touch) return;\n\n dispatch(dragging, 'dragend', touch.clientX, touch.clientY);\n pendingDraggable = null;\n pendingStartPoint = null;\n dragging = null;\n lastTarget = null;\n removePreview();\n },\n { passive: true, signal: disposable.disposalSignal },\n );\n\n return disposable;\n}\n"],"mappings":"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"}
|