svelte-dnd-action 0.9.71 → 0.9.73
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/dist/index.js +141 -46
- package/dist/index.mjs +141 -46
- package/package.json +1 -1
- package/src/helpers/styler.js +22 -5
- package/src/keyboardAction.js +43 -18
- package/src/pointerAction.js +49 -17
- package/src/wrappers/withDragHandles.js +2 -0
package/dist/index.js
CHANGED
|
@@ -1186,6 +1186,21 @@
|
|
|
1186
1186
|
function trs(property) {
|
|
1187
1187
|
return "".concat(property, " ").concat(TRANSITION_DURATION_SECONDS, "s ease");
|
|
1188
1188
|
}
|
|
1189
|
+
|
|
1190
|
+
/**
|
|
1191
|
+
* Adds the size transitions after the dragged element's initial styles have been applied.
|
|
1192
|
+
* This normally happens in a timeout to avoid a browser rendering bug, but a synchronous
|
|
1193
|
+
* first morph can happen before that timeout and needs the transitions immediately.
|
|
1194
|
+
* @param {HTMLElement} draggedEl
|
|
1195
|
+
*/
|
|
1196
|
+
function ensureMorphSizeTransitions(draggedEl) {
|
|
1197
|
+
var transitionProperties = draggedEl.style.transitionProperty.split(",").map(function (property) {
|
|
1198
|
+
return property.trim();
|
|
1199
|
+
});
|
|
1200
|
+
if (transitionProperties.includes("all")) return;
|
|
1201
|
+
if (!transitionProperties.includes("width")) draggedEl.style.transition += ", ".concat(trs("width"));
|
|
1202
|
+
if (!transitionProperties.includes("height")) draggedEl.style.transition += ", ".concat(trs("height"));
|
|
1203
|
+
}
|
|
1189
1204
|
/**
|
|
1190
1205
|
* clones the given element and applies proper styles and transitions to the dragged element
|
|
1191
1206
|
* @param {HTMLElement} originalElement
|
|
@@ -1219,7 +1234,7 @@
|
|
|
1219
1234
|
draggedEl.style.transition = "".concat(trs("top"), ", ").concat(trs("left"), ", ").concat(trs("background-color"), ", ").concat(trs("opacity"), ", ").concat(trs("color"), " ");
|
|
1220
1235
|
// this is a workaround for a strange browser bug that causes the right border to disappear when all the transitions are added at the same time
|
|
1221
1236
|
window.setTimeout(function () {
|
|
1222
|
-
return draggedEl
|
|
1237
|
+
return ensureMorphSizeTransitions(draggedEl);
|
|
1223
1238
|
}, 0);
|
|
1224
1239
|
draggedEl.style.zIndex = "9999";
|
|
1225
1240
|
draggedEl.style.cursor = "grabbing";
|
|
@@ -1242,22 +1257,26 @@
|
|
|
1242
1257
|
* @param {number} currentMouseY
|
|
1243
1258
|
*/
|
|
1244
1259
|
function morphDraggedElementToBeLike(draggedEl, copyFromEl, currentMouseX, currentMouseY) {
|
|
1260
|
+
ensureMorphSizeTransitions(draggedEl);
|
|
1245
1261
|
copyStylesFromTo(copyFromEl, draggedEl);
|
|
1246
1262
|
var newRect = copyFromEl.getBoundingClientRect();
|
|
1247
1263
|
var draggedElRect = draggedEl.getBoundingClientRect();
|
|
1264
|
+
var draggedElComputedStyle = window.getComputedStyle(draggedEl);
|
|
1265
|
+
var currentLeft = parseFloat(draggedElComputedStyle.left);
|
|
1266
|
+
var currentTop = parseFloat(draggedElComputedStyle.top);
|
|
1248
1267
|
var widthChange = newRect.width - draggedElRect.width;
|
|
1249
1268
|
var heightChange = newRect.height - draggedElRect.height;
|
|
1250
1269
|
if (widthChange || heightChange) {
|
|
1251
1270
|
var relativeDistanceOfMousePointerFromDraggedSides = {
|
|
1252
|
-
left: (currentMouseX - draggedElRect.left) / draggedElRect.width,
|
|
1253
|
-
top: (currentMouseY - draggedElRect.top) / draggedElRect.height
|
|
1271
|
+
left: draggedElRect.width ? (currentMouseX - draggedElRect.left) / draggedElRect.width : 0,
|
|
1272
|
+
top: draggedElRect.height ? (currentMouseY - draggedElRect.top) / draggedElRect.height : 0
|
|
1254
1273
|
};
|
|
1255
1274
|
if (!getFeatureFlag(FEATURE_FLAG_NAMES.USE_COMPUTED_STYLE_INSTEAD_OF_BOUNDING_RECT)) {
|
|
1256
1275
|
draggedEl.style.height = "".concat(newRect.height, "px");
|
|
1257
1276
|
draggedEl.style.width = "".concat(newRect.width, "px");
|
|
1258
1277
|
}
|
|
1259
|
-
draggedEl.style.left = "".concat(
|
|
1260
|
-
draggedEl.style.top = "".concat(
|
|
1278
|
+
draggedEl.style.left = "".concat(currentLeft - relativeDistanceOfMousePointerFromDraggedSides.left * widthChange, "px");
|
|
1279
|
+
draggedEl.style.top = "".concat(currentTop - relativeDistanceOfMousePointerFromDraggedSides.top * heightChange, "px");
|
|
1261
1280
|
}
|
|
1262
1281
|
}
|
|
1263
1282
|
|
|
@@ -1413,6 +1432,8 @@
|
|
|
1413
1432
|
var touchDragHoldTimer;
|
|
1414
1433
|
var touchHoldElapsed = false;
|
|
1415
1434
|
var useCursorForDetectionActive = false;
|
|
1435
|
+
var pendingDragOwner;
|
|
1436
|
+
var watchedDropZones = new Set();
|
|
1416
1437
|
|
|
1417
1438
|
// a map from type to a set of drop-zones
|
|
1418
1439
|
var typeToDropZones$1 = new Map();
|
|
@@ -1435,9 +1456,10 @@
|
|
|
1435
1456
|
}
|
|
1436
1457
|
}
|
|
1437
1458
|
function unregisterDropZone$1(dropZoneEl, type) {
|
|
1438
|
-
typeToDropZones$1.get(type)
|
|
1459
|
+
var dropZones = typeToDropZones$1.get(type);
|
|
1460
|
+
if (!dropZones || !dropZones["delete"](dropZoneEl)) return;
|
|
1439
1461
|
decrementActiveDropZoneCount();
|
|
1440
|
-
if (
|
|
1462
|
+
if (dropZones.size === 0) {
|
|
1441
1463
|
typeToDropZones$1["delete"](type);
|
|
1442
1464
|
}
|
|
1443
1465
|
}
|
|
@@ -1448,7 +1470,10 @@
|
|
|
1448
1470
|
return "watching dragged element";
|
|
1449
1471
|
});
|
|
1450
1472
|
var dropZones = typeToDropZones$1.get(draggedElType);
|
|
1451
|
-
|
|
1473
|
+
if (!dropZones || dropZones.size === 0) return;
|
|
1474
|
+
if (watchedDropZones.size > 0) unWatchDraggedElement();
|
|
1475
|
+
watchedDropZones = new Set(dropZones);
|
|
1476
|
+
var _iterator = _createForOfIteratorHelper(watchedDropZones),
|
|
1452
1477
|
_step;
|
|
1453
1478
|
try {
|
|
1454
1479
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
@@ -1465,11 +1490,11 @@
|
|
|
1465
1490
|
window.addEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop$1);
|
|
1466
1491
|
|
|
1467
1492
|
// it is important that we don't have an interval that is faster than the flip duration because it can cause elements to jump bach and forth
|
|
1468
|
-
var setIntervalMs = Math.max.apply(Math, _toConsumableArray(Array.from(
|
|
1493
|
+
var setIntervalMs = Math.max.apply(Math, _toConsumableArray(Array.from(watchedDropZones).map(function (dz) {
|
|
1469
1494
|
return dzToConfig$1.get(dz).dropAnimationDurationMs;
|
|
1470
1495
|
})));
|
|
1471
1496
|
var observationIntervalMs = setIntervalMs === 0 ? DISABLED_OBSERVATION_INTERVAL_MS : Math.max(setIntervalMs, MIN_OBSERVATION_INTERVAL_MS); // if setIntervalMs is 0 it goes to 20, otherwise it is max between it and min observation.
|
|
1472
|
-
multiScroller = createMultiScroller(
|
|
1497
|
+
multiScroller = createMultiScroller(watchedDropZones, function () {
|
|
1473
1498
|
return currentMousePosition;
|
|
1474
1499
|
});
|
|
1475
1500
|
// Returns reference point in document coordinates - either cursor position or element center
|
|
@@ -1481,14 +1506,13 @@
|
|
|
1481
1506
|
} : function () {
|
|
1482
1507
|
return findCenterOfElement(draggedEl);
|
|
1483
1508
|
};
|
|
1484
|
-
observe(draggedEl,
|
|
1509
|
+
observe(draggedEl, watchedDropZones, observationIntervalMs * 1.07, multiScroller, getReferencePoint);
|
|
1485
1510
|
}
|
|
1486
1511
|
function unWatchDraggedElement() {
|
|
1487
1512
|
printDebug(function () {
|
|
1488
1513
|
return "unwatching dragged element";
|
|
1489
1514
|
});
|
|
1490
|
-
var
|
|
1491
|
-
var _iterator2 = _createForOfIteratorHelper(dropZones),
|
|
1515
|
+
var _iterator2 = _createForOfIteratorHelper(watchedDropZones),
|
|
1492
1516
|
_step2;
|
|
1493
1517
|
try {
|
|
1494
1518
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
@@ -1502,6 +1526,7 @@
|
|
|
1502
1526
|
} finally {
|
|
1503
1527
|
_iterator2.f();
|
|
1504
1528
|
}
|
|
1529
|
+
watchedDropZones = new Set();
|
|
1505
1530
|
window.removeEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop$1);
|
|
1506
1531
|
// ensuring multiScroller is not already destroyed before destroying
|
|
1507
1532
|
if (multiScroller) {
|
|
@@ -1733,11 +1758,13 @@
|
|
|
1733
1758
|
window.setTimeout(callback, dropAnimationDurationMs);
|
|
1734
1759
|
}
|
|
1735
1760
|
function scheduleDZForRemovalAfterDrop(dz, destroy) {
|
|
1736
|
-
|
|
1761
|
+
var scheduledRemoval = {
|
|
1737
1762
|
dz: dz,
|
|
1738
1763
|
destroy: destroy
|
|
1739
|
-
}
|
|
1764
|
+
};
|
|
1765
|
+
scheduledForRemovalAfterDrop.push(scheduledRemoval);
|
|
1740
1766
|
window.requestAnimationFrame(function () {
|
|
1767
|
+
if (!scheduledForRemovalAfterDrop.includes(scheduledRemoval)) return;
|
|
1741
1768
|
hideElement(dz);
|
|
1742
1769
|
document.body.appendChild(dz);
|
|
1743
1770
|
});
|
|
@@ -1771,6 +1798,7 @@
|
|
|
1771
1798
|
touchDragHoldTimer = undefined;
|
|
1772
1799
|
touchHoldElapsed = false;
|
|
1773
1800
|
useCursorForDetectionActive = false;
|
|
1801
|
+
pendingDragOwner = undefined;
|
|
1774
1802
|
if (scheduledForRemovalAfterDrop.length) {
|
|
1775
1803
|
printDebug(function () {
|
|
1776
1804
|
return ["will destroy zones that were removed during drag", scheduledForRemovalAfterDrop];
|
|
@@ -1786,6 +1814,7 @@
|
|
|
1786
1814
|
}
|
|
1787
1815
|
function dndzone$2(node, options) {
|
|
1788
1816
|
var initialized = false;
|
|
1817
|
+
var destroyed = false;
|
|
1789
1818
|
var config = {
|
|
1790
1819
|
items: undefined,
|
|
1791
1820
|
type: undefined,
|
|
@@ -1833,11 +1862,17 @@
|
|
|
1833
1862
|
touchHoldElapsed = false;
|
|
1834
1863
|
}
|
|
1835
1864
|
}
|
|
1836
|
-
function
|
|
1865
|
+
function cancelPendingDrag() {
|
|
1866
|
+
if (pendingDragOwner !== node) return;
|
|
1837
1867
|
removeMaybeListeners();
|
|
1868
|
+
pendingDragOwner = undefined;
|
|
1838
1869
|
originalDragTarget = undefined;
|
|
1839
1870
|
dragStartMousePosition = undefined;
|
|
1840
1871
|
currentMousePosition = undefined;
|
|
1872
|
+
}
|
|
1873
|
+
function handleFalseAlarm(e) {
|
|
1874
|
+
if (pendingDragOwner !== node) return;
|
|
1875
|
+
cancelPendingDrag();
|
|
1841
1876
|
|
|
1842
1877
|
// dragging initiated by touch events prevents onclick from initially firing
|
|
1843
1878
|
if (e.type === "touchend") {
|
|
@@ -1850,6 +1885,7 @@
|
|
|
1850
1885
|
}
|
|
1851
1886
|
}
|
|
1852
1887
|
function handleMouseMoveMaybeDragStart(e) {
|
|
1888
|
+
if (destroyed || pendingDragOwner !== node) return;
|
|
1853
1889
|
var isTouch = !!e.touches;
|
|
1854
1890
|
var c = isTouch ? e.touches[0] : e;
|
|
1855
1891
|
// If touch drag delay is configured and not elapsed yet, allow scrolling until either
|
|
@@ -1878,7 +1914,6 @@
|
|
|
1878
1914
|
y: c.clientY
|
|
1879
1915
|
};
|
|
1880
1916
|
if (Math.abs(currentMousePosition.x - dragStartMousePosition.x) >= MIN_MOVEMENT_BEFORE_DRAG_START_PX || Math.abs(currentMousePosition.y - dragStartMousePosition.y) >= MIN_MOVEMENT_BEFORE_DRAG_START_PX) {
|
|
1881
|
-
removeMaybeListeners();
|
|
1882
1917
|
handleDragStart();
|
|
1883
1918
|
}
|
|
1884
1919
|
}
|
|
@@ -1897,9 +1932,9 @@
|
|
|
1897
1932
|
});
|
|
1898
1933
|
return;
|
|
1899
1934
|
}
|
|
1900
|
-
if (isWorkingOnPreviousDrag) {
|
|
1935
|
+
if (destroyed || isWorkingOnPreviousDrag || pendingDragOwner) {
|
|
1901
1936
|
printDebug(function () {
|
|
1902
|
-
return "cannot start a new drag before finalizing
|
|
1937
|
+
return "cannot start a new drag before finalizing the current drag or pending gesture";
|
|
1903
1938
|
});
|
|
1904
1939
|
return;
|
|
1905
1940
|
}
|
|
@@ -1909,6 +1944,7 @@
|
|
|
1909
1944
|
e.preventDefault();
|
|
1910
1945
|
}
|
|
1911
1946
|
e.stopPropagation();
|
|
1947
|
+
pendingDragOwner = node;
|
|
1912
1948
|
var c = isTouchStart ? e.touches[0] : e;
|
|
1913
1949
|
dragStartMousePosition = {
|
|
1914
1950
|
x: c.clientX,
|
|
@@ -1917,18 +1953,25 @@
|
|
|
1917
1953
|
currentMousePosition = _objectSpread2({}, dragStartMousePosition);
|
|
1918
1954
|
originalDragTarget = e.currentTarget;
|
|
1919
1955
|
if (useDelay) {
|
|
1956
|
+
var pendingTarget = originalDragTarget;
|
|
1920
1957
|
touchHoldElapsed = false;
|
|
1921
1958
|
touchDragHoldTimer = window.setTimeout(function () {
|
|
1922
|
-
// If the
|
|
1923
|
-
if (
|
|
1959
|
+
// If this action still owns the same pending gesture, transition it to a drag.
|
|
1960
|
+
if (destroyed || pendingDragOwner !== node || originalDragTarget !== pendingTarget) return;
|
|
1924
1961
|
touchHoldElapsed = true;
|
|
1925
|
-
removeMaybeListeners();
|
|
1926
1962
|
handleDragStart();
|
|
1927
1963
|
}, config.delayTouchStartMs);
|
|
1928
1964
|
}
|
|
1929
1965
|
addMaybeListeners();
|
|
1930
1966
|
}
|
|
1931
1967
|
function handleDragStart() {
|
|
1968
|
+
var _originalDragTarget;
|
|
1969
|
+
if (destroyed || pendingDragOwner !== node || isWorkingOnPreviousDrag || !((_originalDragTarget = originalDragTarget) !== null && _originalDragTarget !== void 0 && _originalDragTarget.parentElement)) {
|
|
1970
|
+
cancelPendingDrag();
|
|
1971
|
+
return;
|
|
1972
|
+
}
|
|
1973
|
+
removeMaybeListeners();
|
|
1974
|
+
pendingDragOwner = undefined;
|
|
1932
1975
|
printDebug(function () {
|
|
1933
1976
|
return ["drag start config: ".concat(toString(config)), originalDragTarget];
|
|
1934
1977
|
});
|
|
@@ -2127,11 +2170,29 @@
|
|
|
2127
2170
|
configure(newOptions);
|
|
2128
2171
|
},
|
|
2129
2172
|
destroy: function destroy() {
|
|
2173
|
+
if (destroyed) return;
|
|
2174
|
+
destroyed = true;
|
|
2175
|
+
cancelPendingDrag();
|
|
2176
|
+
var _iterator3 = _createForOfIteratorHelper(node.children),
|
|
2177
|
+
_step3;
|
|
2178
|
+
try {
|
|
2179
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
2180
|
+
var draggableEl = _step3.value;
|
|
2181
|
+
draggableEl.removeEventListener("mousedown", elToMouseDownListener.get(draggableEl));
|
|
2182
|
+
draggableEl.removeEventListener("touchstart", elToMouseDownListener.get(draggableEl));
|
|
2183
|
+
}
|
|
2184
|
+
} catch (err) {
|
|
2185
|
+
_iterator3.e(err);
|
|
2186
|
+
} finally {
|
|
2187
|
+
_iterator3.f();
|
|
2188
|
+
}
|
|
2130
2189
|
function destroyDz() {
|
|
2131
2190
|
printDebug(function () {
|
|
2132
2191
|
return "pointer dndzone will destroy";
|
|
2133
2192
|
});
|
|
2134
|
-
|
|
2193
|
+
var registeredConfig = dzToConfig$1.get(node);
|
|
2194
|
+
if (!registeredConfig) return;
|
|
2195
|
+
unregisterDropZone$1(node, registeredConfig.type);
|
|
2135
2196
|
dzToConfig$1["delete"](node);
|
|
2136
2197
|
}
|
|
2137
2198
|
if (isWorkingOnPreviousDrag && !node.closest("[".concat(ORIGINAL_DRAGGED_ITEM_MARKER_ATTRIBUTE, "]"))) {
|
|
@@ -2288,12 +2349,13 @@
|
|
|
2288
2349
|
printDebug(function () {
|
|
2289
2350
|
return "unregistering drop-zone";
|
|
2290
2351
|
});
|
|
2291
|
-
if (focusedDz === dropZoneEl) {
|
|
2352
|
+
if (isDragging && focusedDz === dropZoneEl) {
|
|
2292
2353
|
handleDrop();
|
|
2293
2354
|
}
|
|
2294
|
-
typeToDropZones.get(type)
|
|
2355
|
+
var dropZones = typeToDropZones.get(type);
|
|
2356
|
+
if (!dropZones || !dropZones["delete"](dropZoneEl)) return;
|
|
2295
2357
|
decrementActiveDropZoneCount();
|
|
2296
|
-
if (
|
|
2358
|
+
if (dropZones.size === 0) {
|
|
2297
2359
|
typeToDropZones["delete"](type);
|
|
2298
2360
|
}
|
|
2299
2361
|
if (typeToDropZones.size === 0) {
|
|
@@ -2355,17 +2417,20 @@
|
|
|
2355
2417
|
}
|
|
2356
2418
|
}
|
|
2357
2419
|
var dzFrom = focusedDz;
|
|
2420
|
+
var movedItemId = focusedItemId;
|
|
2421
|
+
focusedDz = newlyFocusedDz;
|
|
2358
2422
|
dispatchFinalizeEvent(dzFrom, originItems, {
|
|
2359
2423
|
trigger: TRIGGERS.DROPPED_INTO_ANOTHER,
|
|
2360
|
-
id:
|
|
2361
|
-
source: SOURCES.KEYBOARD
|
|
2362
|
-
});
|
|
2363
|
-
dispatchFinalizeEvent(newlyFocusedDz, targetItems, {
|
|
2364
|
-
trigger: TRIGGERS.DROPPED_INTO_ZONE,
|
|
2365
|
-
id: focusedItemId,
|
|
2424
|
+
id: movedItemId,
|
|
2366
2425
|
source: SOURCES.KEYBOARD
|
|
2367
2426
|
});
|
|
2368
|
-
|
|
2427
|
+
if (dzToConfig.has(newlyFocusedDz)) {
|
|
2428
|
+
dispatchFinalizeEvent(newlyFocusedDz, targetItems, {
|
|
2429
|
+
trigger: TRIGGERS.DROPPED_INTO_ZONE,
|
|
2430
|
+
id: movedItemId,
|
|
2431
|
+
source: SOURCES.KEYBOARD
|
|
2432
|
+
});
|
|
2433
|
+
}
|
|
2369
2434
|
}
|
|
2370
2435
|
function triggerAllDzsUpdate() {
|
|
2371
2436
|
dzToHandles.forEach(function (_ref, dz) {
|
|
@@ -2375,27 +2440,23 @@
|
|
|
2375
2440
|
}
|
|
2376
2441
|
function handleDrop() {
|
|
2377
2442
|
var dispatchConsider = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
2443
|
+
if (!isDragging || !focusedDz) return;
|
|
2378
2444
|
printDebug(function () {
|
|
2379
2445
|
return "drop";
|
|
2380
2446
|
});
|
|
2381
|
-
|
|
2447
|
+
var droppedDz = focusedDz;
|
|
2448
|
+
var droppedConfig = dzToConfig.get(droppedDz);
|
|
2449
|
+
var droppedItemId = focusedItemId;
|
|
2450
|
+
var droppedItemType = draggedItemType;
|
|
2451
|
+
if (!droppedConfig) return;
|
|
2452
|
+
if (!droppedConfig.autoAriaDisabled) {
|
|
2382
2453
|
alertToScreenReader("Stopped dragging item ".concat(focusedItemLabel));
|
|
2383
2454
|
}
|
|
2384
2455
|
if (allDragTargets.has(document.activeElement)) {
|
|
2385
2456
|
document.activeElement.blur();
|
|
2386
2457
|
}
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
trigger: TRIGGERS.DRAG_STOPPED,
|
|
2390
|
-
id: focusedItemId,
|
|
2391
|
-
source: SOURCES.KEYBOARD
|
|
2392
|
-
});
|
|
2393
|
-
}
|
|
2394
|
-
styleInactiveDropZones(typeToDropZones.get(draggedItemType), function (dz) {
|
|
2395
|
-
return dzToConfig.get(dz).dropTargetStyle;
|
|
2396
|
-
}, function (dz) {
|
|
2397
|
-
return dzToConfig.get(dz).dropTargetClasses;
|
|
2398
|
-
});
|
|
2458
|
+
// Clear global drag state before dispatching. A synchronous handler may destroy the
|
|
2459
|
+
// focused zone, and unregisterDropZone must not recursively enter handleDrop.
|
|
2399
2460
|
focusedItem = null;
|
|
2400
2461
|
focusedItemId = null;
|
|
2401
2462
|
focusedItemLabel = "";
|
|
@@ -2403,10 +2464,26 @@
|
|
|
2403
2464
|
focusedDz = null;
|
|
2404
2465
|
focusedDzLabel = "";
|
|
2405
2466
|
isDragging = false;
|
|
2467
|
+
if (dispatchConsider) {
|
|
2468
|
+
dispatchConsiderEvent(droppedDz, droppedConfig.items, {
|
|
2469
|
+
trigger: TRIGGERS.DRAG_STOPPED,
|
|
2470
|
+
id: droppedItemId,
|
|
2471
|
+
source: SOURCES.KEYBOARD
|
|
2472
|
+
});
|
|
2473
|
+
}
|
|
2474
|
+
var dropZones = typeToDropZones.get(droppedItemType);
|
|
2475
|
+
if (dropZones) {
|
|
2476
|
+
styleInactiveDropZones(dropZones, function (dz) {
|
|
2477
|
+
return dzToConfig.get(dz).dropTargetStyle;
|
|
2478
|
+
}, function (dz) {
|
|
2479
|
+
return dzToConfig.get(dz).dropTargetClasses;
|
|
2480
|
+
});
|
|
2481
|
+
}
|
|
2406
2482
|
triggerAllDzsUpdate();
|
|
2407
2483
|
}
|
|
2408
2484
|
//////
|
|
2409
2485
|
function dndzone$1(node, options) {
|
|
2486
|
+
var destroyed = false;
|
|
2410
2487
|
var config = {
|
|
2411
2488
|
items: undefined,
|
|
2412
2489
|
type: undefined,
|
|
@@ -2631,9 +2708,25 @@
|
|
|
2631
2708
|
configure(newOptions);
|
|
2632
2709
|
},
|
|
2633
2710
|
destroy: function destroy() {
|
|
2711
|
+
if (destroyed) return;
|
|
2712
|
+
destroyed = true;
|
|
2634
2713
|
printDebug(function () {
|
|
2635
2714
|
return "keyboard dndzone will destroy";
|
|
2636
2715
|
});
|
|
2716
|
+
node.removeEventListener("focus", handleZoneFocus);
|
|
2717
|
+
var _iterator = _createForOfIteratorHelper(node.children),
|
|
2718
|
+
_step;
|
|
2719
|
+
try {
|
|
2720
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
2721
|
+
var draggableEl = _step.value;
|
|
2722
|
+
draggableEl.removeEventListener("keydown", elToKeyDownListeners.get(draggableEl));
|
|
2723
|
+
draggableEl.removeEventListener("click", elToFocusListeners.get(draggableEl));
|
|
2724
|
+
}
|
|
2725
|
+
} catch (err) {
|
|
2726
|
+
_iterator.e(err);
|
|
2727
|
+
} finally {
|
|
2728
|
+
_iterator.f();
|
|
2729
|
+
}
|
|
2637
2730
|
unregisterDropZone(node, config.type);
|
|
2638
2731
|
dzToConfig["delete"](node);
|
|
2639
2732
|
dzToHandles["delete"](node);
|
|
@@ -2842,6 +2935,8 @@
|
|
|
2842
2935
|
updateZone();
|
|
2843
2936
|
},
|
|
2844
2937
|
destroy: function destroy() {
|
|
2938
|
+
isItemsDragDisabled.set(true);
|
|
2939
|
+
zone.destroy();
|
|
2845
2940
|
node.removeEventListener("consider", consider);
|
|
2846
2941
|
node.removeEventListener("finalize", finalize);
|
|
2847
2942
|
isItemsDragDisabled.unsubscribe(updateZone);
|
package/dist/index.mjs
CHANGED
|
@@ -1180,6 +1180,21 @@ var TRANSITION_DURATION_SECONDS = 0.2;
|
|
|
1180
1180
|
function trs(property) {
|
|
1181
1181
|
return "".concat(property, " ").concat(TRANSITION_DURATION_SECONDS, "s ease");
|
|
1182
1182
|
}
|
|
1183
|
+
|
|
1184
|
+
/**
|
|
1185
|
+
* Adds the size transitions after the dragged element's initial styles have been applied.
|
|
1186
|
+
* This normally happens in a timeout to avoid a browser rendering bug, but a synchronous
|
|
1187
|
+
* first morph can happen before that timeout and needs the transitions immediately.
|
|
1188
|
+
* @param {HTMLElement} draggedEl
|
|
1189
|
+
*/
|
|
1190
|
+
function ensureMorphSizeTransitions(draggedEl) {
|
|
1191
|
+
var transitionProperties = draggedEl.style.transitionProperty.split(",").map(function (property) {
|
|
1192
|
+
return property.trim();
|
|
1193
|
+
});
|
|
1194
|
+
if (transitionProperties.includes("all")) return;
|
|
1195
|
+
if (!transitionProperties.includes("width")) draggedEl.style.transition += ", ".concat(trs("width"));
|
|
1196
|
+
if (!transitionProperties.includes("height")) draggedEl.style.transition += ", ".concat(trs("height"));
|
|
1197
|
+
}
|
|
1183
1198
|
/**
|
|
1184
1199
|
* clones the given element and applies proper styles and transitions to the dragged element
|
|
1185
1200
|
* @param {HTMLElement} originalElement
|
|
@@ -1213,7 +1228,7 @@ function createDraggedElementFrom(originalElement, positionCenterOnXY) {
|
|
|
1213
1228
|
draggedEl.style.transition = "".concat(trs("top"), ", ").concat(trs("left"), ", ").concat(trs("background-color"), ", ").concat(trs("opacity"), ", ").concat(trs("color"), " ");
|
|
1214
1229
|
// this is a workaround for a strange browser bug that causes the right border to disappear when all the transitions are added at the same time
|
|
1215
1230
|
window.setTimeout(function () {
|
|
1216
|
-
return draggedEl
|
|
1231
|
+
return ensureMorphSizeTransitions(draggedEl);
|
|
1217
1232
|
}, 0);
|
|
1218
1233
|
draggedEl.style.zIndex = "9999";
|
|
1219
1234
|
draggedEl.style.cursor = "grabbing";
|
|
@@ -1236,22 +1251,26 @@ function moveDraggedElementToWasDroppedState(draggedEl) {
|
|
|
1236
1251
|
* @param {number} currentMouseY
|
|
1237
1252
|
*/
|
|
1238
1253
|
function morphDraggedElementToBeLike(draggedEl, copyFromEl, currentMouseX, currentMouseY) {
|
|
1254
|
+
ensureMorphSizeTransitions(draggedEl);
|
|
1239
1255
|
copyStylesFromTo(copyFromEl, draggedEl);
|
|
1240
1256
|
var newRect = copyFromEl.getBoundingClientRect();
|
|
1241
1257
|
var draggedElRect = draggedEl.getBoundingClientRect();
|
|
1258
|
+
var draggedElComputedStyle = window.getComputedStyle(draggedEl);
|
|
1259
|
+
var currentLeft = parseFloat(draggedElComputedStyle.left);
|
|
1260
|
+
var currentTop = parseFloat(draggedElComputedStyle.top);
|
|
1242
1261
|
var widthChange = newRect.width - draggedElRect.width;
|
|
1243
1262
|
var heightChange = newRect.height - draggedElRect.height;
|
|
1244
1263
|
if (widthChange || heightChange) {
|
|
1245
1264
|
var relativeDistanceOfMousePointerFromDraggedSides = {
|
|
1246
|
-
left: (currentMouseX - draggedElRect.left) / draggedElRect.width,
|
|
1247
|
-
top: (currentMouseY - draggedElRect.top) / draggedElRect.height
|
|
1265
|
+
left: draggedElRect.width ? (currentMouseX - draggedElRect.left) / draggedElRect.width : 0,
|
|
1266
|
+
top: draggedElRect.height ? (currentMouseY - draggedElRect.top) / draggedElRect.height : 0
|
|
1248
1267
|
};
|
|
1249
1268
|
if (!getFeatureFlag(FEATURE_FLAG_NAMES.USE_COMPUTED_STYLE_INSTEAD_OF_BOUNDING_RECT)) {
|
|
1250
1269
|
draggedEl.style.height = "".concat(newRect.height, "px");
|
|
1251
1270
|
draggedEl.style.width = "".concat(newRect.width, "px");
|
|
1252
1271
|
}
|
|
1253
|
-
draggedEl.style.left = "".concat(
|
|
1254
|
-
draggedEl.style.top = "".concat(
|
|
1272
|
+
draggedEl.style.left = "".concat(currentLeft - relativeDistanceOfMousePointerFromDraggedSides.left * widthChange, "px");
|
|
1273
|
+
draggedEl.style.top = "".concat(currentTop - relativeDistanceOfMousePointerFromDraggedSides.top * heightChange, "px");
|
|
1255
1274
|
}
|
|
1256
1275
|
}
|
|
1257
1276
|
|
|
@@ -1407,6 +1426,8 @@ var multiScroller;
|
|
|
1407
1426
|
var touchDragHoldTimer;
|
|
1408
1427
|
var touchHoldElapsed = false;
|
|
1409
1428
|
var useCursorForDetectionActive = false;
|
|
1429
|
+
var pendingDragOwner;
|
|
1430
|
+
var watchedDropZones = new Set();
|
|
1410
1431
|
|
|
1411
1432
|
// a map from type to a set of drop-zones
|
|
1412
1433
|
var typeToDropZones$1 = new Map();
|
|
@@ -1429,9 +1450,10 @@ function registerDropZone$1(dropZoneEl, type) {
|
|
|
1429
1450
|
}
|
|
1430
1451
|
}
|
|
1431
1452
|
function unregisterDropZone$1(dropZoneEl, type) {
|
|
1432
|
-
typeToDropZones$1.get(type)
|
|
1453
|
+
var dropZones = typeToDropZones$1.get(type);
|
|
1454
|
+
if (!dropZones || !dropZones["delete"](dropZoneEl)) return;
|
|
1433
1455
|
decrementActiveDropZoneCount();
|
|
1434
|
-
if (
|
|
1456
|
+
if (dropZones.size === 0) {
|
|
1435
1457
|
typeToDropZones$1["delete"](type);
|
|
1436
1458
|
}
|
|
1437
1459
|
}
|
|
@@ -1442,7 +1464,10 @@ function watchDraggedElement() {
|
|
|
1442
1464
|
return "watching dragged element";
|
|
1443
1465
|
});
|
|
1444
1466
|
var dropZones = typeToDropZones$1.get(draggedElType);
|
|
1445
|
-
|
|
1467
|
+
if (!dropZones || dropZones.size === 0) return;
|
|
1468
|
+
if (watchedDropZones.size > 0) unWatchDraggedElement();
|
|
1469
|
+
watchedDropZones = new Set(dropZones);
|
|
1470
|
+
var _iterator = _createForOfIteratorHelper(watchedDropZones),
|
|
1446
1471
|
_step;
|
|
1447
1472
|
try {
|
|
1448
1473
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
@@ -1459,11 +1484,11 @@ function watchDraggedElement() {
|
|
|
1459
1484
|
window.addEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop$1);
|
|
1460
1485
|
|
|
1461
1486
|
// it is important that we don't have an interval that is faster than the flip duration because it can cause elements to jump bach and forth
|
|
1462
|
-
var setIntervalMs = Math.max.apply(Math, _toConsumableArray(Array.from(
|
|
1487
|
+
var setIntervalMs = Math.max.apply(Math, _toConsumableArray(Array.from(watchedDropZones).map(function (dz) {
|
|
1463
1488
|
return dzToConfig$1.get(dz).dropAnimationDurationMs;
|
|
1464
1489
|
})));
|
|
1465
1490
|
var observationIntervalMs = setIntervalMs === 0 ? DISABLED_OBSERVATION_INTERVAL_MS : Math.max(setIntervalMs, MIN_OBSERVATION_INTERVAL_MS); // if setIntervalMs is 0 it goes to 20, otherwise it is max between it and min observation.
|
|
1466
|
-
multiScroller = createMultiScroller(
|
|
1491
|
+
multiScroller = createMultiScroller(watchedDropZones, function () {
|
|
1467
1492
|
return currentMousePosition;
|
|
1468
1493
|
});
|
|
1469
1494
|
// Returns reference point in document coordinates - either cursor position or element center
|
|
@@ -1475,14 +1500,13 @@ function watchDraggedElement() {
|
|
|
1475
1500
|
} : function () {
|
|
1476
1501
|
return findCenterOfElement(draggedEl);
|
|
1477
1502
|
};
|
|
1478
|
-
observe(draggedEl,
|
|
1503
|
+
observe(draggedEl, watchedDropZones, observationIntervalMs * 1.07, multiScroller, getReferencePoint);
|
|
1479
1504
|
}
|
|
1480
1505
|
function unWatchDraggedElement() {
|
|
1481
1506
|
printDebug(function () {
|
|
1482
1507
|
return "unwatching dragged element";
|
|
1483
1508
|
});
|
|
1484
|
-
var
|
|
1485
|
-
var _iterator2 = _createForOfIteratorHelper(dropZones),
|
|
1509
|
+
var _iterator2 = _createForOfIteratorHelper(watchedDropZones),
|
|
1486
1510
|
_step2;
|
|
1487
1511
|
try {
|
|
1488
1512
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
@@ -1496,6 +1520,7 @@ function unWatchDraggedElement() {
|
|
|
1496
1520
|
} finally {
|
|
1497
1521
|
_iterator2.f();
|
|
1498
1522
|
}
|
|
1523
|
+
watchedDropZones = new Set();
|
|
1499
1524
|
window.removeEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop$1);
|
|
1500
1525
|
// ensuring multiScroller is not already destroyed before destroying
|
|
1501
1526
|
if (multiScroller) {
|
|
@@ -1727,11 +1752,13 @@ function animateDraggedToFinalPosition(shadowElIdx, callback) {
|
|
|
1727
1752
|
window.setTimeout(callback, dropAnimationDurationMs);
|
|
1728
1753
|
}
|
|
1729
1754
|
function scheduleDZForRemovalAfterDrop(dz, destroy) {
|
|
1730
|
-
|
|
1755
|
+
var scheduledRemoval = {
|
|
1731
1756
|
dz: dz,
|
|
1732
1757
|
destroy: destroy
|
|
1733
|
-
}
|
|
1758
|
+
};
|
|
1759
|
+
scheduledForRemovalAfterDrop.push(scheduledRemoval);
|
|
1734
1760
|
window.requestAnimationFrame(function () {
|
|
1761
|
+
if (!scheduledForRemovalAfterDrop.includes(scheduledRemoval)) return;
|
|
1735
1762
|
hideElement(dz);
|
|
1736
1763
|
document.body.appendChild(dz);
|
|
1737
1764
|
});
|
|
@@ -1765,6 +1792,7 @@ function cleanupPostDrop() {
|
|
|
1765
1792
|
touchDragHoldTimer = undefined;
|
|
1766
1793
|
touchHoldElapsed = false;
|
|
1767
1794
|
useCursorForDetectionActive = false;
|
|
1795
|
+
pendingDragOwner = undefined;
|
|
1768
1796
|
if (scheduledForRemovalAfterDrop.length) {
|
|
1769
1797
|
printDebug(function () {
|
|
1770
1798
|
return ["will destroy zones that were removed during drag", scheduledForRemovalAfterDrop];
|
|
@@ -1780,6 +1808,7 @@ function cleanupPostDrop() {
|
|
|
1780
1808
|
}
|
|
1781
1809
|
function dndzone$2(node, options) {
|
|
1782
1810
|
var initialized = false;
|
|
1811
|
+
var destroyed = false;
|
|
1783
1812
|
var config = {
|
|
1784
1813
|
items: undefined,
|
|
1785
1814
|
type: undefined,
|
|
@@ -1827,11 +1856,17 @@ function dndzone$2(node, options) {
|
|
|
1827
1856
|
touchHoldElapsed = false;
|
|
1828
1857
|
}
|
|
1829
1858
|
}
|
|
1830
|
-
function
|
|
1859
|
+
function cancelPendingDrag() {
|
|
1860
|
+
if (pendingDragOwner !== node) return;
|
|
1831
1861
|
removeMaybeListeners();
|
|
1862
|
+
pendingDragOwner = undefined;
|
|
1832
1863
|
originalDragTarget = undefined;
|
|
1833
1864
|
dragStartMousePosition = undefined;
|
|
1834
1865
|
currentMousePosition = undefined;
|
|
1866
|
+
}
|
|
1867
|
+
function handleFalseAlarm(e) {
|
|
1868
|
+
if (pendingDragOwner !== node) return;
|
|
1869
|
+
cancelPendingDrag();
|
|
1835
1870
|
|
|
1836
1871
|
// dragging initiated by touch events prevents onclick from initially firing
|
|
1837
1872
|
if (e.type === "touchend") {
|
|
@@ -1844,6 +1879,7 @@ function dndzone$2(node, options) {
|
|
|
1844
1879
|
}
|
|
1845
1880
|
}
|
|
1846
1881
|
function handleMouseMoveMaybeDragStart(e) {
|
|
1882
|
+
if (destroyed || pendingDragOwner !== node) return;
|
|
1847
1883
|
var isTouch = !!e.touches;
|
|
1848
1884
|
var c = isTouch ? e.touches[0] : e;
|
|
1849
1885
|
// If touch drag delay is configured and not elapsed yet, allow scrolling until either
|
|
@@ -1872,7 +1908,6 @@ function dndzone$2(node, options) {
|
|
|
1872
1908
|
y: c.clientY
|
|
1873
1909
|
};
|
|
1874
1910
|
if (Math.abs(currentMousePosition.x - dragStartMousePosition.x) >= MIN_MOVEMENT_BEFORE_DRAG_START_PX || Math.abs(currentMousePosition.y - dragStartMousePosition.y) >= MIN_MOVEMENT_BEFORE_DRAG_START_PX) {
|
|
1875
|
-
removeMaybeListeners();
|
|
1876
1911
|
handleDragStart();
|
|
1877
1912
|
}
|
|
1878
1913
|
}
|
|
@@ -1891,9 +1926,9 @@ function dndzone$2(node, options) {
|
|
|
1891
1926
|
});
|
|
1892
1927
|
return;
|
|
1893
1928
|
}
|
|
1894
|
-
if (isWorkingOnPreviousDrag) {
|
|
1929
|
+
if (destroyed || isWorkingOnPreviousDrag || pendingDragOwner) {
|
|
1895
1930
|
printDebug(function () {
|
|
1896
|
-
return "cannot start a new drag before finalizing
|
|
1931
|
+
return "cannot start a new drag before finalizing the current drag or pending gesture";
|
|
1897
1932
|
});
|
|
1898
1933
|
return;
|
|
1899
1934
|
}
|
|
@@ -1903,6 +1938,7 @@ function dndzone$2(node, options) {
|
|
|
1903
1938
|
e.preventDefault();
|
|
1904
1939
|
}
|
|
1905
1940
|
e.stopPropagation();
|
|
1941
|
+
pendingDragOwner = node;
|
|
1906
1942
|
var c = isTouchStart ? e.touches[0] : e;
|
|
1907
1943
|
dragStartMousePosition = {
|
|
1908
1944
|
x: c.clientX,
|
|
@@ -1911,18 +1947,25 @@ function dndzone$2(node, options) {
|
|
|
1911
1947
|
currentMousePosition = _objectSpread2({}, dragStartMousePosition);
|
|
1912
1948
|
originalDragTarget = e.currentTarget;
|
|
1913
1949
|
if (useDelay) {
|
|
1950
|
+
var pendingTarget = originalDragTarget;
|
|
1914
1951
|
touchHoldElapsed = false;
|
|
1915
1952
|
touchDragHoldTimer = window.setTimeout(function () {
|
|
1916
|
-
// If the
|
|
1917
|
-
if (
|
|
1953
|
+
// If this action still owns the same pending gesture, transition it to a drag.
|
|
1954
|
+
if (destroyed || pendingDragOwner !== node || originalDragTarget !== pendingTarget) return;
|
|
1918
1955
|
touchHoldElapsed = true;
|
|
1919
|
-
removeMaybeListeners();
|
|
1920
1956
|
handleDragStart();
|
|
1921
1957
|
}, config.delayTouchStartMs);
|
|
1922
1958
|
}
|
|
1923
1959
|
addMaybeListeners();
|
|
1924
1960
|
}
|
|
1925
1961
|
function handleDragStart() {
|
|
1962
|
+
var _originalDragTarget;
|
|
1963
|
+
if (destroyed || pendingDragOwner !== node || isWorkingOnPreviousDrag || !((_originalDragTarget = originalDragTarget) !== null && _originalDragTarget !== void 0 && _originalDragTarget.parentElement)) {
|
|
1964
|
+
cancelPendingDrag();
|
|
1965
|
+
return;
|
|
1966
|
+
}
|
|
1967
|
+
removeMaybeListeners();
|
|
1968
|
+
pendingDragOwner = undefined;
|
|
1926
1969
|
printDebug(function () {
|
|
1927
1970
|
return ["drag start config: ".concat(toString(config)), originalDragTarget];
|
|
1928
1971
|
});
|
|
@@ -2121,11 +2164,29 @@ function dndzone$2(node, options) {
|
|
|
2121
2164
|
configure(newOptions);
|
|
2122
2165
|
},
|
|
2123
2166
|
destroy: function destroy() {
|
|
2167
|
+
if (destroyed) return;
|
|
2168
|
+
destroyed = true;
|
|
2169
|
+
cancelPendingDrag();
|
|
2170
|
+
var _iterator3 = _createForOfIteratorHelper(node.children),
|
|
2171
|
+
_step3;
|
|
2172
|
+
try {
|
|
2173
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
2174
|
+
var draggableEl = _step3.value;
|
|
2175
|
+
draggableEl.removeEventListener("mousedown", elToMouseDownListener.get(draggableEl));
|
|
2176
|
+
draggableEl.removeEventListener("touchstart", elToMouseDownListener.get(draggableEl));
|
|
2177
|
+
}
|
|
2178
|
+
} catch (err) {
|
|
2179
|
+
_iterator3.e(err);
|
|
2180
|
+
} finally {
|
|
2181
|
+
_iterator3.f();
|
|
2182
|
+
}
|
|
2124
2183
|
function destroyDz() {
|
|
2125
2184
|
printDebug(function () {
|
|
2126
2185
|
return "pointer dndzone will destroy";
|
|
2127
2186
|
});
|
|
2128
|
-
|
|
2187
|
+
var registeredConfig = dzToConfig$1.get(node);
|
|
2188
|
+
if (!registeredConfig) return;
|
|
2189
|
+
unregisterDropZone$1(node, registeredConfig.type);
|
|
2129
2190
|
dzToConfig$1["delete"](node);
|
|
2130
2191
|
}
|
|
2131
2192
|
if (isWorkingOnPreviousDrag && !node.closest("[".concat(ORIGINAL_DRAGGED_ITEM_MARKER_ATTRIBUTE, "]"))) {
|
|
@@ -2282,12 +2343,13 @@ function unregisterDropZone(dropZoneEl, type) {
|
|
|
2282
2343
|
printDebug(function () {
|
|
2283
2344
|
return "unregistering drop-zone";
|
|
2284
2345
|
});
|
|
2285
|
-
if (focusedDz === dropZoneEl) {
|
|
2346
|
+
if (isDragging && focusedDz === dropZoneEl) {
|
|
2286
2347
|
handleDrop();
|
|
2287
2348
|
}
|
|
2288
|
-
typeToDropZones.get(type)
|
|
2349
|
+
var dropZones = typeToDropZones.get(type);
|
|
2350
|
+
if (!dropZones || !dropZones["delete"](dropZoneEl)) return;
|
|
2289
2351
|
decrementActiveDropZoneCount();
|
|
2290
|
-
if (
|
|
2352
|
+
if (dropZones.size === 0) {
|
|
2291
2353
|
typeToDropZones["delete"](type);
|
|
2292
2354
|
}
|
|
2293
2355
|
if (typeToDropZones.size === 0) {
|
|
@@ -2349,17 +2411,20 @@ function handleZoneFocus(e) {
|
|
|
2349
2411
|
}
|
|
2350
2412
|
}
|
|
2351
2413
|
var dzFrom = focusedDz;
|
|
2414
|
+
var movedItemId = focusedItemId;
|
|
2415
|
+
focusedDz = newlyFocusedDz;
|
|
2352
2416
|
dispatchFinalizeEvent(dzFrom, originItems, {
|
|
2353
2417
|
trigger: TRIGGERS.DROPPED_INTO_ANOTHER,
|
|
2354
|
-
id:
|
|
2355
|
-
source: SOURCES.KEYBOARD
|
|
2356
|
-
});
|
|
2357
|
-
dispatchFinalizeEvent(newlyFocusedDz, targetItems, {
|
|
2358
|
-
trigger: TRIGGERS.DROPPED_INTO_ZONE,
|
|
2359
|
-
id: focusedItemId,
|
|
2418
|
+
id: movedItemId,
|
|
2360
2419
|
source: SOURCES.KEYBOARD
|
|
2361
2420
|
});
|
|
2362
|
-
|
|
2421
|
+
if (dzToConfig.has(newlyFocusedDz)) {
|
|
2422
|
+
dispatchFinalizeEvent(newlyFocusedDz, targetItems, {
|
|
2423
|
+
trigger: TRIGGERS.DROPPED_INTO_ZONE,
|
|
2424
|
+
id: movedItemId,
|
|
2425
|
+
source: SOURCES.KEYBOARD
|
|
2426
|
+
});
|
|
2427
|
+
}
|
|
2363
2428
|
}
|
|
2364
2429
|
function triggerAllDzsUpdate() {
|
|
2365
2430
|
dzToHandles.forEach(function (_ref, dz) {
|
|
@@ -2369,27 +2434,23 @@ function triggerAllDzsUpdate() {
|
|
|
2369
2434
|
}
|
|
2370
2435
|
function handleDrop() {
|
|
2371
2436
|
var dispatchConsider = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
2437
|
+
if (!isDragging || !focusedDz) return;
|
|
2372
2438
|
printDebug(function () {
|
|
2373
2439
|
return "drop";
|
|
2374
2440
|
});
|
|
2375
|
-
|
|
2441
|
+
var droppedDz = focusedDz;
|
|
2442
|
+
var droppedConfig = dzToConfig.get(droppedDz);
|
|
2443
|
+
var droppedItemId = focusedItemId;
|
|
2444
|
+
var droppedItemType = draggedItemType;
|
|
2445
|
+
if (!droppedConfig) return;
|
|
2446
|
+
if (!droppedConfig.autoAriaDisabled) {
|
|
2376
2447
|
alertToScreenReader("Stopped dragging item ".concat(focusedItemLabel));
|
|
2377
2448
|
}
|
|
2378
2449
|
if (allDragTargets.has(document.activeElement)) {
|
|
2379
2450
|
document.activeElement.blur();
|
|
2380
2451
|
}
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
trigger: TRIGGERS.DRAG_STOPPED,
|
|
2384
|
-
id: focusedItemId,
|
|
2385
|
-
source: SOURCES.KEYBOARD
|
|
2386
|
-
});
|
|
2387
|
-
}
|
|
2388
|
-
styleInactiveDropZones(typeToDropZones.get(draggedItemType), function (dz) {
|
|
2389
|
-
return dzToConfig.get(dz).dropTargetStyle;
|
|
2390
|
-
}, function (dz) {
|
|
2391
|
-
return dzToConfig.get(dz).dropTargetClasses;
|
|
2392
|
-
});
|
|
2452
|
+
// Clear global drag state before dispatching. A synchronous handler may destroy the
|
|
2453
|
+
// focused zone, and unregisterDropZone must not recursively enter handleDrop.
|
|
2393
2454
|
focusedItem = null;
|
|
2394
2455
|
focusedItemId = null;
|
|
2395
2456
|
focusedItemLabel = "";
|
|
@@ -2397,10 +2458,26 @@ function handleDrop() {
|
|
|
2397
2458
|
focusedDz = null;
|
|
2398
2459
|
focusedDzLabel = "";
|
|
2399
2460
|
isDragging = false;
|
|
2461
|
+
if (dispatchConsider) {
|
|
2462
|
+
dispatchConsiderEvent(droppedDz, droppedConfig.items, {
|
|
2463
|
+
trigger: TRIGGERS.DRAG_STOPPED,
|
|
2464
|
+
id: droppedItemId,
|
|
2465
|
+
source: SOURCES.KEYBOARD
|
|
2466
|
+
});
|
|
2467
|
+
}
|
|
2468
|
+
var dropZones = typeToDropZones.get(droppedItemType);
|
|
2469
|
+
if (dropZones) {
|
|
2470
|
+
styleInactiveDropZones(dropZones, function (dz) {
|
|
2471
|
+
return dzToConfig.get(dz).dropTargetStyle;
|
|
2472
|
+
}, function (dz) {
|
|
2473
|
+
return dzToConfig.get(dz).dropTargetClasses;
|
|
2474
|
+
});
|
|
2475
|
+
}
|
|
2400
2476
|
triggerAllDzsUpdate();
|
|
2401
2477
|
}
|
|
2402
2478
|
//////
|
|
2403
2479
|
function dndzone$1(node, options) {
|
|
2480
|
+
var destroyed = false;
|
|
2404
2481
|
var config = {
|
|
2405
2482
|
items: undefined,
|
|
2406
2483
|
type: undefined,
|
|
@@ -2625,9 +2702,25 @@ function dndzone$1(node, options) {
|
|
|
2625
2702
|
configure(newOptions);
|
|
2626
2703
|
},
|
|
2627
2704
|
destroy: function destroy() {
|
|
2705
|
+
if (destroyed) return;
|
|
2706
|
+
destroyed = true;
|
|
2628
2707
|
printDebug(function () {
|
|
2629
2708
|
return "keyboard dndzone will destroy";
|
|
2630
2709
|
});
|
|
2710
|
+
node.removeEventListener("focus", handleZoneFocus);
|
|
2711
|
+
var _iterator = _createForOfIteratorHelper(node.children),
|
|
2712
|
+
_step;
|
|
2713
|
+
try {
|
|
2714
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
2715
|
+
var draggableEl = _step.value;
|
|
2716
|
+
draggableEl.removeEventListener("keydown", elToKeyDownListeners.get(draggableEl));
|
|
2717
|
+
draggableEl.removeEventListener("click", elToFocusListeners.get(draggableEl));
|
|
2718
|
+
}
|
|
2719
|
+
} catch (err) {
|
|
2720
|
+
_iterator.e(err);
|
|
2721
|
+
} finally {
|
|
2722
|
+
_iterator.f();
|
|
2723
|
+
}
|
|
2631
2724
|
unregisterDropZone(node, config.type);
|
|
2632
2725
|
dzToConfig["delete"](node);
|
|
2633
2726
|
dzToHandles["delete"](node);
|
|
@@ -2836,6 +2929,8 @@ function dragHandleZone(node, options) {
|
|
|
2836
2929
|
updateZone();
|
|
2837
2930
|
},
|
|
2838
2931
|
destroy: function destroy() {
|
|
2932
|
+
isItemsDragDisabled.set(true);
|
|
2933
|
+
zone.destroy();
|
|
2839
2934
|
node.removeEventListener("consider", consider);
|
|
2840
2935
|
node.removeEventListener("finalize", finalize);
|
|
2841
2936
|
isItemsDragDisabled.unsubscribe(updateZone);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-dnd-action",
|
|
3
3
|
"description": "*An awesome drag and drop library for Svelte 3 and 4 (not using the browser's built-in dnd, thanks god): Rich animations, nested containers, touch support and more *",
|
|
4
|
-
"version": "0.9.
|
|
4
|
+
"version": "0.9.73",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/isaacHagoel/svelte-dnd-action.git"
|
package/src/helpers/styler.js
CHANGED
|
@@ -13,6 +13,19 @@ const TRANSITION_DURATION_SECONDS = 0.2;
|
|
|
13
13
|
function trs(property) {
|
|
14
14
|
return `${property} ${TRANSITION_DURATION_SECONDS}s ease`;
|
|
15
15
|
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Adds the size transitions after the dragged element's initial styles have been applied.
|
|
19
|
+
* This normally happens in a timeout to avoid a browser rendering bug, but a synchronous
|
|
20
|
+
* first morph can happen before that timeout and needs the transitions immediately.
|
|
21
|
+
* @param {HTMLElement} draggedEl
|
|
22
|
+
*/
|
|
23
|
+
function ensureMorphSizeTransitions(draggedEl) {
|
|
24
|
+
const transitionProperties = draggedEl.style.transitionProperty.split(",").map(property => property.trim());
|
|
25
|
+
if (transitionProperties.includes("all")) return;
|
|
26
|
+
if (!transitionProperties.includes("width")) draggedEl.style.transition += `, ${trs("width")}`;
|
|
27
|
+
if (!transitionProperties.includes("height")) draggedEl.style.transition += `, ${trs("height")}`;
|
|
28
|
+
}
|
|
16
29
|
/**
|
|
17
30
|
* clones the given element and applies proper styles and transitions to the dragged element
|
|
18
31
|
* @param {HTMLElement} originalElement
|
|
@@ -45,7 +58,7 @@ export function createDraggedElementFrom(originalElement, positionCenterOnXY) {
|
|
|
45
58
|
draggedEl.style.width = `${rect.width}px`;
|
|
46
59
|
draggedEl.style.transition = `${trs("top")}, ${trs("left")}, ${trs("background-color")}, ${trs("opacity")}, ${trs("color")} `;
|
|
47
60
|
// this is a workaround for a strange browser bug that causes the right border to disappear when all the transitions are added at the same time
|
|
48
|
-
window.setTimeout(() => (draggedEl
|
|
61
|
+
window.setTimeout(() => ensureMorphSizeTransitions(draggedEl), 0);
|
|
49
62
|
draggedEl.style.zIndex = "9999";
|
|
50
63
|
draggedEl.style.cursor = "grabbing";
|
|
51
64
|
|
|
@@ -68,22 +81,26 @@ export function moveDraggedElementToWasDroppedState(draggedEl) {
|
|
|
68
81
|
* @param {number} currentMouseY
|
|
69
82
|
*/
|
|
70
83
|
export function morphDraggedElementToBeLike(draggedEl, copyFromEl, currentMouseX, currentMouseY) {
|
|
84
|
+
ensureMorphSizeTransitions(draggedEl);
|
|
71
85
|
copyStylesFromTo(copyFromEl, draggedEl);
|
|
72
86
|
const newRect = copyFromEl.getBoundingClientRect();
|
|
73
87
|
const draggedElRect = draggedEl.getBoundingClientRect();
|
|
88
|
+
const draggedElComputedStyle = window.getComputedStyle(draggedEl);
|
|
89
|
+
const currentLeft = parseFloat(draggedElComputedStyle.left);
|
|
90
|
+
const currentTop = parseFloat(draggedElComputedStyle.top);
|
|
74
91
|
const widthChange = newRect.width - draggedElRect.width;
|
|
75
92
|
const heightChange = newRect.height - draggedElRect.height;
|
|
76
93
|
if (widthChange || heightChange) {
|
|
77
94
|
const relativeDistanceOfMousePointerFromDraggedSides = {
|
|
78
|
-
left: (currentMouseX - draggedElRect.left) / draggedElRect.width,
|
|
79
|
-
top: (currentMouseY - draggedElRect.top) / draggedElRect.height
|
|
95
|
+
left: draggedElRect.width ? (currentMouseX - draggedElRect.left) / draggedElRect.width : 0,
|
|
96
|
+
top: draggedElRect.height ? (currentMouseY - draggedElRect.top) / draggedElRect.height : 0
|
|
80
97
|
};
|
|
81
98
|
if (!getFeatureFlag(FEATURE_FLAG_NAMES.USE_COMPUTED_STYLE_INSTEAD_OF_BOUNDING_RECT)) {
|
|
82
99
|
draggedEl.style.height = `${newRect.height}px`;
|
|
83
100
|
draggedEl.style.width = `${newRect.width}px`;
|
|
84
101
|
}
|
|
85
|
-
draggedEl.style.left = `${
|
|
86
|
-
draggedEl.style.top = `${
|
|
102
|
+
draggedEl.style.left = `${currentLeft - relativeDistanceOfMousePointerFromDraggedSides.left * widthChange}px`;
|
|
103
|
+
draggedEl.style.top = `${currentTop - relativeDistanceOfMousePointerFromDraggedSides.top * heightChange}px`;
|
|
87
104
|
}
|
|
88
105
|
}
|
|
89
106
|
|
package/src/keyboardAction.js
CHANGED
|
@@ -50,12 +50,13 @@ function registerDropZone(dropZoneEl, type) {
|
|
|
50
50
|
}
|
|
51
51
|
function unregisterDropZone(dropZoneEl, type) {
|
|
52
52
|
printDebug(() => "unregistering drop-zone");
|
|
53
|
-
if (focusedDz === dropZoneEl) {
|
|
53
|
+
if (isDragging && focusedDz === dropZoneEl) {
|
|
54
54
|
handleDrop();
|
|
55
55
|
}
|
|
56
|
-
typeToDropZones.get(type)
|
|
56
|
+
const dropZones = typeToDropZones.get(type);
|
|
57
|
+
if (!dropZones || !dropZones.delete(dropZoneEl)) return;
|
|
57
58
|
decrementActiveDropZoneCount();
|
|
58
|
-
if (
|
|
59
|
+
if (dropZones.size === 0) {
|
|
59
60
|
typeToDropZones.delete(type);
|
|
60
61
|
}
|
|
61
62
|
if (typeToDropZones.size === 0) {
|
|
@@ -112,9 +113,12 @@ function handleZoneFocus(e) {
|
|
|
112
113
|
}
|
|
113
114
|
}
|
|
114
115
|
const dzFrom = focusedDz;
|
|
115
|
-
|
|
116
|
-
dispatchFinalizeEvent(newlyFocusedDz, targetItems, {trigger: TRIGGERS.DROPPED_INTO_ZONE, id: focusedItemId, source: SOURCES.KEYBOARD});
|
|
116
|
+
const movedItemId = focusedItemId;
|
|
117
117
|
focusedDz = newlyFocusedDz;
|
|
118
|
+
dispatchFinalizeEvent(dzFrom, originItems, {trigger: TRIGGERS.DROPPED_INTO_ANOTHER, id: movedItemId, source: SOURCES.KEYBOARD});
|
|
119
|
+
if (dzToConfig.has(newlyFocusedDz)) {
|
|
120
|
+
dispatchFinalizeEvent(newlyFocusedDz, targetItems, {trigger: TRIGGERS.DROPPED_INTO_ZONE, id: movedItemId, source: SOURCES.KEYBOARD});
|
|
121
|
+
}
|
|
118
122
|
}
|
|
119
123
|
|
|
120
124
|
function triggerAllDzsUpdate() {
|
|
@@ -122,25 +126,22 @@ function triggerAllDzsUpdate() {
|
|
|
122
126
|
}
|
|
123
127
|
|
|
124
128
|
function handleDrop(dispatchConsider = true) {
|
|
129
|
+
if (!isDragging || !focusedDz) return;
|
|
125
130
|
printDebug(() => "drop");
|
|
126
|
-
|
|
131
|
+
const droppedDz = focusedDz;
|
|
132
|
+
const droppedConfig = dzToConfig.get(droppedDz);
|
|
133
|
+
const droppedItemId = focusedItemId;
|
|
134
|
+
const droppedItemType = draggedItemType;
|
|
135
|
+
if (!droppedConfig) return;
|
|
136
|
+
|
|
137
|
+
if (!droppedConfig.autoAriaDisabled) {
|
|
127
138
|
alertToScreenReader(`Stopped dragging item ${focusedItemLabel}`);
|
|
128
139
|
}
|
|
129
140
|
if (allDragTargets.has(document.activeElement)) {
|
|
130
141
|
document.activeElement.blur();
|
|
131
142
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
trigger: TRIGGERS.DRAG_STOPPED,
|
|
135
|
-
id: focusedItemId,
|
|
136
|
-
source: SOURCES.KEYBOARD
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
styleInactiveDropZones(
|
|
140
|
-
typeToDropZones.get(draggedItemType),
|
|
141
|
-
dz => dzToConfig.get(dz).dropTargetStyle,
|
|
142
|
-
dz => dzToConfig.get(dz).dropTargetClasses
|
|
143
|
-
);
|
|
143
|
+
// Clear global drag state before dispatching. A synchronous handler may destroy the
|
|
144
|
+
// focused zone, and unregisterDropZone must not recursively enter handleDrop.
|
|
144
145
|
focusedItem = null;
|
|
145
146
|
focusedItemId = null;
|
|
146
147
|
focusedItemLabel = "";
|
|
@@ -148,10 +149,27 @@ function handleDrop(dispatchConsider = true) {
|
|
|
148
149
|
focusedDz = null;
|
|
149
150
|
focusedDzLabel = "";
|
|
150
151
|
isDragging = false;
|
|
152
|
+
|
|
153
|
+
if (dispatchConsider) {
|
|
154
|
+
dispatchConsiderEvent(droppedDz, droppedConfig.items, {
|
|
155
|
+
trigger: TRIGGERS.DRAG_STOPPED,
|
|
156
|
+
id: droppedItemId,
|
|
157
|
+
source: SOURCES.KEYBOARD
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
const dropZones = typeToDropZones.get(droppedItemType);
|
|
161
|
+
if (dropZones) {
|
|
162
|
+
styleInactiveDropZones(
|
|
163
|
+
dropZones,
|
|
164
|
+
dz => dzToConfig.get(dz).dropTargetStyle,
|
|
165
|
+
dz => dzToConfig.get(dz).dropTargetClasses
|
|
166
|
+
);
|
|
167
|
+
}
|
|
151
168
|
triggerAllDzsUpdate();
|
|
152
169
|
}
|
|
153
170
|
//////
|
|
154
171
|
export function dndzone(node, options) {
|
|
172
|
+
let destroyed = false;
|
|
155
173
|
const config = {
|
|
156
174
|
items: undefined,
|
|
157
175
|
type: undefined,
|
|
@@ -344,7 +362,14 @@ export function dndzone(node, options) {
|
|
|
344
362
|
configure(newOptions);
|
|
345
363
|
},
|
|
346
364
|
destroy: () => {
|
|
365
|
+
if (destroyed) return;
|
|
366
|
+
destroyed = true;
|
|
347
367
|
printDebug(() => "keyboard dndzone will destroy");
|
|
368
|
+
node.removeEventListener("focus", handleZoneFocus);
|
|
369
|
+
for (const draggableEl of node.children) {
|
|
370
|
+
draggableEl.removeEventListener("keydown", elToKeyDownListeners.get(draggableEl));
|
|
371
|
+
draggableEl.removeEventListener("click", elToFocusListeners.get(draggableEl));
|
|
372
|
+
}
|
|
348
373
|
unregisterDropZone(node, config.type);
|
|
349
374
|
dzToConfig.delete(node);
|
|
350
375
|
dzToHandles.delete(node);
|
package/src/pointerAction.js
CHANGED
|
@@ -64,6 +64,8 @@ let multiScroller;
|
|
|
64
64
|
let touchDragHoldTimer;
|
|
65
65
|
let touchHoldElapsed = false;
|
|
66
66
|
let useCursorForDetectionActive = false;
|
|
67
|
+
let pendingDragOwner;
|
|
68
|
+
let watchedDropZones = new Set();
|
|
67
69
|
|
|
68
70
|
// a map from type to a set of drop-zones
|
|
69
71
|
const typeToDropZones = new Map();
|
|
@@ -84,9 +86,10 @@ function registerDropZone(dropZoneEl, type) {
|
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
88
|
function unregisterDropZone(dropZoneEl, type) {
|
|
87
|
-
typeToDropZones.get(type)
|
|
89
|
+
const dropZones = typeToDropZones.get(type);
|
|
90
|
+
if (!dropZones || !dropZones.delete(dropZoneEl)) return;
|
|
88
91
|
decrementActiveDropZoneCount();
|
|
89
|
-
if (
|
|
92
|
+
if (dropZones.size === 0) {
|
|
90
93
|
typeToDropZones.delete(type);
|
|
91
94
|
}
|
|
92
95
|
}
|
|
@@ -95,8 +98,11 @@ function unregisterDropZone(dropZoneEl, type) {
|
|
|
95
98
|
function watchDraggedElement() {
|
|
96
99
|
printDebug(() => "watching dragged element");
|
|
97
100
|
const dropZones = typeToDropZones.get(draggedElType);
|
|
101
|
+
if (!dropZones || dropZones.size === 0) return;
|
|
102
|
+
if (watchedDropZones.size > 0) unWatchDraggedElement();
|
|
103
|
+
watchedDropZones = new Set(dropZones);
|
|
98
104
|
|
|
99
|
-
for (const dz of
|
|
105
|
+
for (const dz of watchedDropZones) {
|
|
100
106
|
dz.addEventListener(DRAGGED_ENTERED_EVENT_NAME, handleDraggedEntered);
|
|
101
107
|
dz.addEventListener(DRAGGED_LEFT_EVENT_NAME, handleDraggedLeft);
|
|
102
108
|
dz.addEventListener(DRAGGED_OVER_INDEX_EVENT_NAME, handleDraggedIsOverIndex);
|
|
@@ -104,9 +110,9 @@ function watchDraggedElement() {
|
|
|
104
110
|
window.addEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop);
|
|
105
111
|
|
|
106
112
|
// it is important that we don't have an interval that is faster than the flip duration because it can cause elements to jump bach and forth
|
|
107
|
-
const setIntervalMs = Math.max(...Array.from(
|
|
113
|
+
const setIntervalMs = Math.max(...Array.from(watchedDropZones).map(dz => dzToConfig.get(dz).dropAnimationDurationMs));
|
|
108
114
|
const observationIntervalMs = setIntervalMs === 0 ? DISABLED_OBSERVATION_INTERVAL_MS : Math.max(setIntervalMs, MIN_OBSERVATION_INTERVAL_MS); // if setIntervalMs is 0 it goes to 20, otherwise it is max between it and min observation.
|
|
109
|
-
multiScroller = createMultiScroller(
|
|
115
|
+
multiScroller = createMultiScroller(watchedDropZones, () => currentMousePosition);
|
|
110
116
|
// Returns reference point in document coordinates - either cursor position or element center
|
|
111
117
|
const getReferencePoint = useCursorForDetectionActive
|
|
112
118
|
? () => ({
|
|
@@ -114,16 +120,16 @@ function watchDraggedElement() {
|
|
|
114
120
|
y: currentMousePosition.y + window.scrollY
|
|
115
121
|
})
|
|
116
122
|
: () => findCenterOfElement(draggedEl);
|
|
117
|
-
observe(draggedEl,
|
|
123
|
+
observe(draggedEl, watchedDropZones, observationIntervalMs * 1.07, multiScroller, getReferencePoint);
|
|
118
124
|
}
|
|
119
125
|
function unWatchDraggedElement() {
|
|
120
126
|
printDebug(() => "unwatching dragged element");
|
|
121
|
-
const
|
|
122
|
-
for (const dz of dropZones) {
|
|
127
|
+
for (const dz of watchedDropZones) {
|
|
123
128
|
dz.removeEventListener(DRAGGED_ENTERED_EVENT_NAME, handleDraggedEntered);
|
|
124
129
|
dz.removeEventListener(DRAGGED_LEFT_EVENT_NAME, handleDraggedLeft);
|
|
125
130
|
dz.removeEventListener(DRAGGED_OVER_INDEX_EVENT_NAME, handleDraggedIsOverIndex);
|
|
126
131
|
}
|
|
132
|
+
watchedDropZones = new Set();
|
|
127
133
|
window.removeEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop);
|
|
128
134
|
// ensuring multiScroller is not already destroyed before destroying
|
|
129
135
|
if (multiScroller) {
|
|
@@ -315,8 +321,10 @@ function animateDraggedToFinalPosition(shadowElIdx, callback) {
|
|
|
315
321
|
}
|
|
316
322
|
|
|
317
323
|
function scheduleDZForRemovalAfterDrop(dz, destroy) {
|
|
318
|
-
|
|
324
|
+
const scheduledRemoval = {dz, destroy};
|
|
325
|
+
scheduledForRemovalAfterDrop.push(scheduledRemoval);
|
|
319
326
|
window.requestAnimationFrame(() => {
|
|
327
|
+
if (!scheduledForRemovalAfterDrop.includes(scheduledRemoval)) return;
|
|
320
328
|
hideElement(dz);
|
|
321
329
|
document.body.appendChild(dz);
|
|
322
330
|
});
|
|
@@ -351,6 +359,7 @@ function cleanupPostDrop() {
|
|
|
351
359
|
touchDragHoldTimer = undefined;
|
|
352
360
|
touchHoldElapsed = false;
|
|
353
361
|
useCursorForDetectionActive = false;
|
|
362
|
+
pendingDragOwner = undefined;
|
|
354
363
|
if (scheduledForRemovalAfterDrop.length) {
|
|
355
364
|
printDebug(() => ["will destroy zones that were removed during drag", scheduledForRemovalAfterDrop]);
|
|
356
365
|
scheduledForRemovalAfterDrop.forEach(({dz, destroy}) => {
|
|
@@ -363,6 +372,7 @@ function cleanupPostDrop() {
|
|
|
363
372
|
|
|
364
373
|
export function dndzone(node, options) {
|
|
365
374
|
let initialized = false;
|
|
375
|
+
let destroyed = false;
|
|
366
376
|
const config = {
|
|
367
377
|
items: undefined,
|
|
368
378
|
type: undefined,
|
|
@@ -398,11 +408,17 @@ export function dndzone(node, options) {
|
|
|
398
408
|
touchHoldElapsed = false;
|
|
399
409
|
}
|
|
400
410
|
}
|
|
401
|
-
function
|
|
411
|
+
function cancelPendingDrag() {
|
|
412
|
+
if (pendingDragOwner !== node) return;
|
|
402
413
|
removeMaybeListeners();
|
|
414
|
+
pendingDragOwner = undefined;
|
|
403
415
|
originalDragTarget = undefined;
|
|
404
416
|
dragStartMousePosition = undefined;
|
|
405
417
|
currentMousePosition = undefined;
|
|
418
|
+
}
|
|
419
|
+
function handleFalseAlarm(e) {
|
|
420
|
+
if (pendingDragOwner !== node) return;
|
|
421
|
+
cancelPendingDrag();
|
|
406
422
|
|
|
407
423
|
// dragging initiated by touch events prevents onclick from initially firing
|
|
408
424
|
if (e.type === "touchend") {
|
|
@@ -416,6 +432,7 @@ export function dndzone(node, options) {
|
|
|
416
432
|
}
|
|
417
433
|
|
|
418
434
|
function handleMouseMoveMaybeDragStart(e) {
|
|
435
|
+
if (destroyed || pendingDragOwner !== node) return;
|
|
419
436
|
const isTouch = !!e.touches;
|
|
420
437
|
const c = isTouch ? e.touches[0] : e;
|
|
421
438
|
// If touch drag delay is configured and not elapsed yet, allow scrolling until either
|
|
@@ -445,7 +462,6 @@ export function dndzone(node, options) {
|
|
|
445
462
|
Math.abs(currentMousePosition.x - dragStartMousePosition.x) >= MIN_MOVEMENT_BEFORE_DRAG_START_PX ||
|
|
446
463
|
Math.abs(currentMousePosition.y - dragStartMousePosition.y) >= MIN_MOVEMENT_BEFORE_DRAG_START_PX
|
|
447
464
|
) {
|
|
448
|
-
removeMaybeListeners();
|
|
449
465
|
handleDragStart();
|
|
450
466
|
}
|
|
451
467
|
}
|
|
@@ -460,8 +476,8 @@ export function dndzone(node, options) {
|
|
|
460
476
|
printDebug(() => `ignoring none left click button: ${e.button}`);
|
|
461
477
|
return;
|
|
462
478
|
}
|
|
463
|
-
if (isWorkingOnPreviousDrag) {
|
|
464
|
-
printDebug(() => "cannot start a new drag before finalizing
|
|
479
|
+
if (destroyed || isWorkingOnPreviousDrag || pendingDragOwner) {
|
|
480
|
+
printDebug(() => "cannot start a new drag before finalizing the current drag or pending gesture");
|
|
465
481
|
return;
|
|
466
482
|
}
|
|
467
483
|
const isTouchStart = !!e.touches;
|
|
@@ -471,6 +487,7 @@ export function dndzone(node, options) {
|
|
|
471
487
|
e.preventDefault();
|
|
472
488
|
}
|
|
473
489
|
e.stopPropagation();
|
|
490
|
+
pendingDragOwner = node;
|
|
474
491
|
|
|
475
492
|
const c = isTouchStart ? e.touches[0] : e;
|
|
476
493
|
dragStartMousePosition = {x: c.clientX, y: c.clientY};
|
|
@@ -478,12 +495,12 @@ export function dndzone(node, options) {
|
|
|
478
495
|
originalDragTarget = e.currentTarget;
|
|
479
496
|
|
|
480
497
|
if (useDelay) {
|
|
498
|
+
const pendingTarget = originalDragTarget;
|
|
481
499
|
touchHoldElapsed = false;
|
|
482
500
|
touchDragHoldTimer = window.setTimeout(() => {
|
|
483
|
-
// If the
|
|
484
|
-
if (
|
|
501
|
+
// If this action still owns the same pending gesture, transition it to a drag.
|
|
502
|
+
if (destroyed || pendingDragOwner !== node || originalDragTarget !== pendingTarget) return;
|
|
485
503
|
touchHoldElapsed = true;
|
|
486
|
-
removeMaybeListeners();
|
|
487
504
|
handleDragStart();
|
|
488
505
|
}, config.delayTouchStartMs);
|
|
489
506
|
}
|
|
@@ -492,6 +509,12 @@ export function dndzone(node, options) {
|
|
|
492
509
|
}
|
|
493
510
|
|
|
494
511
|
function handleDragStart() {
|
|
512
|
+
if (destroyed || pendingDragOwner !== node || isWorkingOnPreviousDrag || !originalDragTarget?.parentElement) {
|
|
513
|
+
cancelPendingDrag();
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
removeMaybeListeners();
|
|
517
|
+
pendingDragOwner = undefined;
|
|
495
518
|
printDebug(() => [`drag start config: ${toString(config)}`, originalDragTarget]);
|
|
496
519
|
isWorkingOnPreviousDrag = true;
|
|
497
520
|
|
|
@@ -670,9 +693,18 @@ export function dndzone(node, options) {
|
|
|
670
693
|
configure(newOptions);
|
|
671
694
|
},
|
|
672
695
|
destroy: () => {
|
|
696
|
+
if (destroyed) return;
|
|
697
|
+
destroyed = true;
|
|
698
|
+
cancelPendingDrag();
|
|
699
|
+
for (const draggableEl of node.children) {
|
|
700
|
+
draggableEl.removeEventListener("mousedown", elToMouseDownListener.get(draggableEl));
|
|
701
|
+
draggableEl.removeEventListener("touchstart", elToMouseDownListener.get(draggableEl));
|
|
702
|
+
}
|
|
673
703
|
function destroyDz() {
|
|
674
704
|
printDebug(() => "pointer dndzone will destroy");
|
|
675
|
-
|
|
705
|
+
const registeredConfig = dzToConfig.get(node);
|
|
706
|
+
if (!registeredConfig) return;
|
|
707
|
+
unregisterDropZone(node, registeredConfig.type);
|
|
676
708
|
dzToConfig.delete(node);
|
|
677
709
|
}
|
|
678
710
|
if (isWorkingOnPreviousDrag && !node.closest(`[${ORIGINAL_DRAGGED_ITEM_MARKER_ATTRIBUTE}]`)) {
|
|
@@ -77,6 +77,8 @@ export function dragHandleZone(node, options) {
|
|
|
77
77
|
updateZone();
|
|
78
78
|
},
|
|
79
79
|
destroy: () => {
|
|
80
|
+
isItemsDragDisabled.set(true);
|
|
81
|
+
zone.destroy();
|
|
80
82
|
node.removeEventListener("consider", consider);
|
|
81
83
|
node.removeEventListener("finalize", finalize);
|
|
82
84
|
isItemsDragDisabled.unsubscribe(updateZone);
|