svelte-dnd-action 0.9.28 → 0.9.30
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 +27 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +30 -26
- package/dist/index.mjs +30 -26
- package/package.json +2 -2
- package/src/action.js +17 -1
- package/src/constants.js +2 -1
- package/src/pointerAction.js +11 -23
package/README.md
CHANGED
|
@@ -106,7 +106,7 @@ An options-object with the following attributes:
|
|
|
106
106
|
| Name | Type | Required? | Default Value | Description |
|
|
107
107
|
| ------------------------- | -------------- | ------------------------------------------------------------ | ------------------------------------------------- | ------------------------------------------------------------ |
|
|
108
108
|
| `items` | Array<Object> | Yes. Each object in the array **has to have** an `id` property (key name can be overridden globally) with a unique value (within all dnd-zones of the same type) | N/A | The data array that is used to produce the list with the draggable items (the same thing you run your #each block on). The dndzone should not have children that don't originate in `items` |
|
|
109
|
-
| `flipDurationMs` | Number | No | `0` | The same value you give the flip animation on the items (to make them animated as they "make space" for the dragged item). Set to zero
|
|
109
|
+
| `flipDurationMs` | Number | No | `0` | The same value you give the flip animation on the items (to make them animated as they "make space" for the dragged item). Set to zero if you dont want animations, if unset it defaults to 100ms |
|
|
110
110
|
| `type` | String | No | Internal | dnd-zones that share the same type can have elements from one dragged into another. By default, all dnd-zones have the same type |
|
|
111
111
|
| `dragDisabled` | Boolean | No | `false` | Setting it to true will make it impossible to drag elements out of the dnd-zone. You can change it at any time, and the zone will adjust on the fly |
|
|
112
112
|
| `morphDisabled` | Boolean | No | `false` | By default, when dragging over a zone, the dragged element is morphed to look like it would if dropped. You can prevent it by setting this option. |
|
|
@@ -347,6 +347,32 @@ You can use generics to set the type of `items` you are expecting in `DndEvent`.
|
|
|
347
347
|
</script>
|
|
348
348
|
```
|
|
349
349
|
|
|
350
|
+
### Nested Zones Optional Optimization (experimental)
|
|
351
|
+
|
|
352
|
+
This is an experimental feature added in version 0.9.29. If you have multiple levels of nesting, the lib might do unnecessary work when dragging an element that has nested zones inside.
|
|
353
|
+
Specifically, it allows nested zones within the shadow element (the placeholder under the dragged element) to register and destroy.
|
|
354
|
+
This is because Svelte calls nested actions before the parent action (opposite to the rendering order).
|
|
355
|
+
You can use a data attribute **on the items** to help the lib prevent this: `data-is-dnd-shadow-item-hint={item[SHADOW_ITEM_MARKER_PROPERTY_NAME]} `
|
|
356
|
+
|
|
357
|
+
#### Simplified Example (just shows where to place the attribute):
|
|
358
|
+
|
|
359
|
+
```html
|
|
360
|
+
<script>
|
|
361
|
+
import {dndzone, SHADOW_ITEM_MARKER_PROPERTY_NAME} from 'svelte-dnd-action';
|
|
362
|
+
let items = [];
|
|
363
|
+
</script>
|
|
364
|
+
<section>
|
|
365
|
+
<div use:dndzone={{items}} on:consider={e => items = e.detail.items} on:finalize={e => items = e.detail.items}>
|
|
366
|
+
{#each items as item (item.id)}
|
|
367
|
+
<div data-is-dnd-shadow-item-hint={item[SHADOW_ITEM_MARKER_PROPERTY_NAME]}>
|
|
368
|
+
<h1>{item.title}</h1>
|
|
369
|
+
<!--more nested zones go here, can include the attribute on their items as demonstrated above-->
|
|
370
|
+
</div>
|
|
371
|
+
{/each}
|
|
372
|
+
</div>
|
|
373
|
+
</section>
|
|
374
|
+
```
|
|
375
|
+
|
|
350
376
|
### Contributing [](https://github.com/isaacHagoel/svelte-dnd-action/issues)
|
|
351
377
|
|
|
352
378
|
There is still quite a lot to do. If you'd like to contribute please get in touch (raise an issue or comment on an existing one).
|
package/dist/index.d.ts
CHANGED
|
@@ -78,6 +78,7 @@ export type DndEvent<T = Item> = {
|
|
|
78
78
|
export declare const SHADOW_ITEM_MARKER_PROPERTY_NAME: "isDndShadowItem";
|
|
79
79
|
export declare const SHADOW_PLACEHOLDER_ITEM_ID: "id:dnd-shadow-placeholder-0000";
|
|
80
80
|
export declare const DRAGGED_ELEMENT_ID: "dnd-action-dragged-el";
|
|
81
|
+
export declare const SHADOW_ELEMENT_HINT_ATTRIBUTE_NAME = "data-is-dnd-shadow-item-hint";
|
|
81
82
|
|
|
82
83
|
/**
|
|
83
84
|
* Allows the user to show/hide console debug output
|
package/dist/index.js
CHANGED
|
@@ -294,7 +294,8 @@
|
|
|
294
294
|
KEYBOARD: "keyboard"
|
|
295
295
|
};
|
|
296
296
|
var SHADOW_ITEM_MARKER_PROPERTY_NAME = "isDndShadowItem";
|
|
297
|
-
var SHADOW_ELEMENT_ATTRIBUTE_NAME = "data-is-dnd-shadow-item";
|
|
297
|
+
var SHADOW_ELEMENT_ATTRIBUTE_NAME = "data-is-dnd-shadow-item-internal";
|
|
298
|
+
var SHADOW_ELEMENT_HINT_ATTRIBUTE_NAME = "data-is-dnd-shadow-item-hint";
|
|
298
299
|
var SHADOW_PLACEHOLDER_ITEM_ID = "id:dnd-shadow-placeholder-0000";
|
|
299
300
|
var DRAGGED_ELEMENT_ID = "dnd-action-dragged-el";
|
|
300
301
|
var ITEM_ID_KEY = "id";
|
|
@@ -1225,10 +1226,12 @@
|
|
|
1225
1226
|
|
|
1226
1227
|
var DEFAULT_DROP_ZONE_TYPE = "--any--";
|
|
1227
1228
|
var MIN_OBSERVATION_INTERVAL_MS = 100;
|
|
1229
|
+
var DISABLED_OBSERVATION_INTERVAL_MS = 20;
|
|
1228
1230
|
var MIN_MOVEMENT_BEFORE_DRAG_START_PX = 3;
|
|
1229
1231
|
var DEFAULT_DROP_TARGET_STYLE = {
|
|
1230
1232
|
outline: "rgba(255, 255, 102, 0.7) solid 2px"
|
|
1231
1233
|
};
|
|
1234
|
+
var ORIGINAL_DRAGGED_ITEM_MARKER_ATTRIBUTE = "data-is-dnd-original-dragged-item";
|
|
1232
1235
|
var originalDragTarget;
|
|
1233
1236
|
var draggedEl;
|
|
1234
1237
|
var draggedElData;
|
|
@@ -1296,9 +1299,10 @@
|
|
|
1296
1299
|
}
|
|
1297
1300
|
window.addEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop);
|
|
1298
1301
|
// 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
|
|
1299
|
-
var
|
|
1302
|
+
var setIntervalMs = Math.max.apply(Math, _toConsumableArray(Array.from(dropZones.keys()).map(function (dz) {
|
|
1300
1303
|
return dzToConfig.get(dz).dropAnimationDurationMs;
|
|
1301
|
-
})))
|
|
1304
|
+
})));
|
|
1305
|
+
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.
|
|
1302
1306
|
observe(draggedEl, dropZones, observationIntervalMs * 1.07);
|
|
1303
1307
|
}
|
|
1304
1308
|
function unWatchDraggedElement() {
|
|
@@ -1324,17 +1328,9 @@
|
|
|
1324
1328
|
window.removeEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop);
|
|
1325
1329
|
unobserve();
|
|
1326
1330
|
}
|
|
1327
|
-
|
|
1328
|
-
// finds the initial placeholder that is placed there on drag start
|
|
1329
|
-
function findShadowPlaceHolderIdx(items) {
|
|
1330
|
-
return items.findIndex(function (item) {
|
|
1331
|
-
return item[ITEM_ID_KEY] === SHADOW_PLACEHOLDER_ITEM_ID;
|
|
1332
|
-
});
|
|
1333
|
-
}
|
|
1334
1331
|
function findShadowElementIdx(items) {
|
|
1335
|
-
// checking that the id is not the placeholder's for Dragula like usecases
|
|
1336
1332
|
return items.findIndex(function (item) {
|
|
1337
|
-
return !!item[SHADOW_ITEM_MARKER_PROPERTY_NAME]
|
|
1333
|
+
return !!item[SHADOW_ITEM_MARKER_PROPERTY_NAME];
|
|
1338
1334
|
});
|
|
1339
1335
|
}
|
|
1340
1336
|
|
|
@@ -1370,15 +1366,6 @@
|
|
|
1370
1366
|
id: draggedElData[ITEM_ID_KEY],
|
|
1371
1367
|
source: SOURCES.POINTER
|
|
1372
1368
|
});
|
|
1373
|
-
} else {
|
|
1374
|
-
var shadowPlaceHolderIdx = findShadowPlaceHolderIdx(items);
|
|
1375
|
-
if (shadowPlaceHolderIdx !== -1) {
|
|
1376
|
-
// only happens right after drag start, on the first drag entered event
|
|
1377
|
-
printDebug(function () {
|
|
1378
|
-
return "removing placeholder item from origin dz";
|
|
1379
|
-
});
|
|
1380
|
-
items.splice(shadowPlaceHolderIdx, 1);
|
|
1381
|
-
}
|
|
1382
1369
|
}
|
|
1383
1370
|
var _e$detail$indexObj = e.detail.indexObj,
|
|
1384
1371
|
index = _e$detail$indexObj.index,
|
|
@@ -1671,6 +1658,7 @@
|
|
|
1671
1658
|
addMaybeListeners();
|
|
1672
1659
|
}
|
|
1673
1660
|
function handleDragStart() {
|
|
1661
|
+
var _objectSpread2$1;
|
|
1674
1662
|
printDebug(function () {
|
|
1675
1663
|
return ["drag start config: ".concat(toString(config)), originalDragTarget];
|
|
1676
1664
|
});
|
|
@@ -1688,12 +1676,12 @@
|
|
|
1688
1676
|
centreDraggedOnCursor = config.centreDraggedOnCursor;
|
|
1689
1677
|
draggedElData = _objectSpread2({}, items[currentIdx]);
|
|
1690
1678
|
draggedElType = type;
|
|
1691
|
-
shadowElData = _objectSpread2(_objectSpread2({}, draggedElData), {},
|
|
1692
|
-
// The initial shadow element. We need a different id at first in order to avoid conflicts and timing issues
|
|
1693
|
-
var placeHolderElData = _objectSpread2(_objectSpread2({}, shadowElData), {}, _defineProperty({}, ITEM_ID_KEY, SHADOW_PLACEHOLDER_ITEM_ID));
|
|
1679
|
+
shadowElData = _objectSpread2(_objectSpread2({}, draggedElData), {}, (_objectSpread2$1 = {}, _defineProperty(_objectSpread2$1, SHADOW_ITEM_MARKER_PROPERTY_NAME, true), _defineProperty(_objectSpread2$1, ITEM_ID_KEY, SHADOW_PLACEHOLDER_ITEM_ID), _objectSpread2$1));
|
|
1694
1680
|
|
|
1695
1681
|
// creating the draggable element
|
|
1696
1682
|
draggedEl = createDraggedElementFrom(originalDragTarget, centreDraggedOnCursor && currentMousePosition);
|
|
1683
|
+
originalDragTarget.setAttribute(ORIGINAL_DRAGGED_ITEM_MARKER_ATTRIBUTE, true);
|
|
1684
|
+
|
|
1697
1685
|
// We will keep the original dom node in the dom because touch events keep firing on it, we want to re-add it after the framework removes it
|
|
1698
1686
|
function keepOriginalElementInDom() {
|
|
1699
1687
|
if (!draggedEl.parentElement) {
|
|
@@ -1717,7 +1705,7 @@
|
|
|
1717
1705
|
});
|
|
1718
1706
|
|
|
1719
1707
|
// removing the original element by removing its data entry
|
|
1720
|
-
items.splice(currentIdx, 1,
|
|
1708
|
+
items.splice(currentIdx, 1, shadowElData);
|
|
1721
1709
|
unlockOriginDzMinDimensions = preventShrinking(originDropZone);
|
|
1722
1710
|
dispatchConsiderEvent(originDropZone, items, {
|
|
1723
1711
|
trigger: TRIGGERS.DRAG_STARTED,
|
|
@@ -1852,7 +1840,7 @@
|
|
|
1852
1840
|
unregisterDropZone(node, dzToConfig.get(node).type);
|
|
1853
1841
|
dzToConfig["delete"](node);
|
|
1854
1842
|
}
|
|
1855
|
-
if (isWorkingOnPreviousDrag) {
|
|
1843
|
+
if (isWorkingOnPreviousDrag && !node.closest("[".concat(ORIGINAL_DRAGGED_ITEM_MARKER_ATTRIBUTE, "]"))) {
|
|
1856
1844
|
printDebug(function () {
|
|
1857
1845
|
return "pointer dndzone will be scheduled for destruction";
|
|
1858
1846
|
});
|
|
@@ -2382,6 +2370,12 @@
|
|
|
2382
2370
|
* @return {{update: function, destroy: function}}
|
|
2383
2371
|
*/
|
|
2384
2372
|
function dndzone$2(node, options) {
|
|
2373
|
+
if (shouldIgnoreZone(node)) {
|
|
2374
|
+
return {
|
|
2375
|
+
update: function update() {},
|
|
2376
|
+
destroy: function destroy() {}
|
|
2377
|
+
};
|
|
2378
|
+
}
|
|
2385
2379
|
validateOptions(options);
|
|
2386
2380
|
var pointerZone = dndzone(node, options);
|
|
2387
2381
|
var keyboardZone = dndzone$1(node, options);
|
|
@@ -2397,6 +2391,16 @@
|
|
|
2397
2391
|
}
|
|
2398
2392
|
};
|
|
2399
2393
|
}
|
|
2394
|
+
|
|
2395
|
+
/**
|
|
2396
|
+
* If the user marked something in the ancestry of our node as shadow element, we can ignore it
|
|
2397
|
+
* We need the user to mark it for us because svelte updates the action from deep to shallow (but renders top down)
|
|
2398
|
+
* @param {HTMLElement} node
|
|
2399
|
+
* @return {boolean}
|
|
2400
|
+
*/
|
|
2401
|
+
function shouldIgnoreZone(node) {
|
|
2402
|
+
return !!node.closest("[".concat(SHADOW_ELEMENT_HINT_ATTRIBUTE_NAME, "=\"true\"]"));
|
|
2403
|
+
}
|
|
2400
2404
|
function validateOptions(options) {
|
|
2401
2405
|
/*eslint-disable*/
|
|
2402
2406
|
var items = options.items,
|
package/dist/index.mjs
CHANGED
|
@@ -288,7 +288,8 @@ var SOURCES = {
|
|
|
288
288
|
KEYBOARD: "keyboard"
|
|
289
289
|
};
|
|
290
290
|
var SHADOW_ITEM_MARKER_PROPERTY_NAME = "isDndShadowItem";
|
|
291
|
-
var SHADOW_ELEMENT_ATTRIBUTE_NAME = "data-is-dnd-shadow-item";
|
|
291
|
+
var SHADOW_ELEMENT_ATTRIBUTE_NAME = "data-is-dnd-shadow-item-internal";
|
|
292
|
+
var SHADOW_ELEMENT_HINT_ATTRIBUTE_NAME = "data-is-dnd-shadow-item-hint";
|
|
292
293
|
var SHADOW_PLACEHOLDER_ITEM_ID = "id:dnd-shadow-placeholder-0000";
|
|
293
294
|
var DRAGGED_ELEMENT_ID = "dnd-action-dragged-el";
|
|
294
295
|
var ITEM_ID_KEY = "id";
|
|
@@ -1219,10 +1220,12 @@ function preventShrinking(el) {
|
|
|
1219
1220
|
|
|
1220
1221
|
var DEFAULT_DROP_ZONE_TYPE = "--any--";
|
|
1221
1222
|
var MIN_OBSERVATION_INTERVAL_MS = 100;
|
|
1223
|
+
var DISABLED_OBSERVATION_INTERVAL_MS = 20;
|
|
1222
1224
|
var MIN_MOVEMENT_BEFORE_DRAG_START_PX = 3;
|
|
1223
1225
|
var DEFAULT_DROP_TARGET_STYLE = {
|
|
1224
1226
|
outline: "rgba(255, 255, 102, 0.7) solid 2px"
|
|
1225
1227
|
};
|
|
1228
|
+
var ORIGINAL_DRAGGED_ITEM_MARKER_ATTRIBUTE = "data-is-dnd-original-dragged-item";
|
|
1226
1229
|
var originalDragTarget;
|
|
1227
1230
|
var draggedEl;
|
|
1228
1231
|
var draggedElData;
|
|
@@ -1290,9 +1293,10 @@ function watchDraggedElement() {
|
|
|
1290
1293
|
}
|
|
1291
1294
|
window.addEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop);
|
|
1292
1295
|
// 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
|
|
1293
|
-
var
|
|
1296
|
+
var setIntervalMs = Math.max.apply(Math, _toConsumableArray(Array.from(dropZones.keys()).map(function (dz) {
|
|
1294
1297
|
return dzToConfig.get(dz).dropAnimationDurationMs;
|
|
1295
|
-
})))
|
|
1298
|
+
})));
|
|
1299
|
+
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.
|
|
1296
1300
|
observe(draggedEl, dropZones, observationIntervalMs * 1.07);
|
|
1297
1301
|
}
|
|
1298
1302
|
function unWatchDraggedElement() {
|
|
@@ -1318,17 +1322,9 @@ function unWatchDraggedElement() {
|
|
|
1318
1322
|
window.removeEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop);
|
|
1319
1323
|
unobserve();
|
|
1320
1324
|
}
|
|
1321
|
-
|
|
1322
|
-
// finds the initial placeholder that is placed there on drag start
|
|
1323
|
-
function findShadowPlaceHolderIdx(items) {
|
|
1324
|
-
return items.findIndex(function (item) {
|
|
1325
|
-
return item[ITEM_ID_KEY] === SHADOW_PLACEHOLDER_ITEM_ID;
|
|
1326
|
-
});
|
|
1327
|
-
}
|
|
1328
1325
|
function findShadowElementIdx(items) {
|
|
1329
|
-
// checking that the id is not the placeholder's for Dragula like usecases
|
|
1330
1326
|
return items.findIndex(function (item) {
|
|
1331
|
-
return !!item[SHADOW_ITEM_MARKER_PROPERTY_NAME]
|
|
1327
|
+
return !!item[SHADOW_ITEM_MARKER_PROPERTY_NAME];
|
|
1332
1328
|
});
|
|
1333
1329
|
}
|
|
1334
1330
|
|
|
@@ -1364,15 +1360,6 @@ function handleDraggedEntered(e) {
|
|
|
1364
1360
|
id: draggedElData[ITEM_ID_KEY],
|
|
1365
1361
|
source: SOURCES.POINTER
|
|
1366
1362
|
});
|
|
1367
|
-
} else {
|
|
1368
|
-
var shadowPlaceHolderIdx = findShadowPlaceHolderIdx(items);
|
|
1369
|
-
if (shadowPlaceHolderIdx !== -1) {
|
|
1370
|
-
// only happens right after drag start, on the first drag entered event
|
|
1371
|
-
printDebug(function () {
|
|
1372
|
-
return "removing placeholder item from origin dz";
|
|
1373
|
-
});
|
|
1374
|
-
items.splice(shadowPlaceHolderIdx, 1);
|
|
1375
|
-
}
|
|
1376
1363
|
}
|
|
1377
1364
|
var _e$detail$indexObj = e.detail.indexObj,
|
|
1378
1365
|
index = _e$detail$indexObj.index,
|
|
@@ -1665,6 +1652,7 @@ function dndzone(node, options) {
|
|
|
1665
1652
|
addMaybeListeners();
|
|
1666
1653
|
}
|
|
1667
1654
|
function handleDragStart() {
|
|
1655
|
+
var _objectSpread2$1;
|
|
1668
1656
|
printDebug(function () {
|
|
1669
1657
|
return ["drag start config: ".concat(toString(config)), originalDragTarget];
|
|
1670
1658
|
});
|
|
@@ -1682,12 +1670,12 @@ function dndzone(node, options) {
|
|
|
1682
1670
|
centreDraggedOnCursor = config.centreDraggedOnCursor;
|
|
1683
1671
|
draggedElData = _objectSpread2({}, items[currentIdx]);
|
|
1684
1672
|
draggedElType = type;
|
|
1685
|
-
shadowElData = _objectSpread2(_objectSpread2({}, draggedElData), {},
|
|
1686
|
-
// The initial shadow element. We need a different id at first in order to avoid conflicts and timing issues
|
|
1687
|
-
var placeHolderElData = _objectSpread2(_objectSpread2({}, shadowElData), {}, _defineProperty({}, ITEM_ID_KEY, SHADOW_PLACEHOLDER_ITEM_ID));
|
|
1673
|
+
shadowElData = _objectSpread2(_objectSpread2({}, draggedElData), {}, (_objectSpread2$1 = {}, _defineProperty(_objectSpread2$1, SHADOW_ITEM_MARKER_PROPERTY_NAME, true), _defineProperty(_objectSpread2$1, ITEM_ID_KEY, SHADOW_PLACEHOLDER_ITEM_ID), _objectSpread2$1));
|
|
1688
1674
|
|
|
1689
1675
|
// creating the draggable element
|
|
1690
1676
|
draggedEl = createDraggedElementFrom(originalDragTarget, centreDraggedOnCursor && currentMousePosition);
|
|
1677
|
+
originalDragTarget.setAttribute(ORIGINAL_DRAGGED_ITEM_MARKER_ATTRIBUTE, true);
|
|
1678
|
+
|
|
1691
1679
|
// We will keep the original dom node in the dom because touch events keep firing on it, we want to re-add it after the framework removes it
|
|
1692
1680
|
function keepOriginalElementInDom() {
|
|
1693
1681
|
if (!draggedEl.parentElement) {
|
|
@@ -1711,7 +1699,7 @@ function dndzone(node, options) {
|
|
|
1711
1699
|
});
|
|
1712
1700
|
|
|
1713
1701
|
// removing the original element by removing its data entry
|
|
1714
|
-
items.splice(currentIdx, 1,
|
|
1702
|
+
items.splice(currentIdx, 1, shadowElData);
|
|
1715
1703
|
unlockOriginDzMinDimensions = preventShrinking(originDropZone);
|
|
1716
1704
|
dispatchConsiderEvent(originDropZone, items, {
|
|
1717
1705
|
trigger: TRIGGERS.DRAG_STARTED,
|
|
@@ -1846,7 +1834,7 @@ function dndzone(node, options) {
|
|
|
1846
1834
|
unregisterDropZone(node, dzToConfig.get(node).type);
|
|
1847
1835
|
dzToConfig["delete"](node);
|
|
1848
1836
|
}
|
|
1849
|
-
if (isWorkingOnPreviousDrag) {
|
|
1837
|
+
if (isWorkingOnPreviousDrag && !node.closest("[".concat(ORIGINAL_DRAGGED_ITEM_MARKER_ATTRIBUTE, "]"))) {
|
|
1850
1838
|
printDebug(function () {
|
|
1851
1839
|
return "pointer dndzone will be scheduled for destruction";
|
|
1852
1840
|
});
|
|
@@ -2376,6 +2364,12 @@ var _excluded = ["items", "flipDurationMs", "type", "dragDisabled", "morphDisabl
|
|
|
2376
2364
|
* @return {{update: function, destroy: function}}
|
|
2377
2365
|
*/
|
|
2378
2366
|
function dndzone$2(node, options) {
|
|
2367
|
+
if (shouldIgnoreZone(node)) {
|
|
2368
|
+
return {
|
|
2369
|
+
update: function update() {},
|
|
2370
|
+
destroy: function destroy() {}
|
|
2371
|
+
};
|
|
2372
|
+
}
|
|
2379
2373
|
validateOptions(options);
|
|
2380
2374
|
var pointerZone = dndzone(node, options);
|
|
2381
2375
|
var keyboardZone = dndzone$1(node, options);
|
|
@@ -2391,6 +2385,16 @@ function dndzone$2(node, options) {
|
|
|
2391
2385
|
}
|
|
2392
2386
|
};
|
|
2393
2387
|
}
|
|
2388
|
+
|
|
2389
|
+
/**
|
|
2390
|
+
* If the user marked something in the ancestry of our node as shadow element, we can ignore it
|
|
2391
|
+
* We need the user to mark it for us because svelte updates the action from deep to shallow (but renders top down)
|
|
2392
|
+
* @param {HTMLElement} node
|
|
2393
|
+
* @return {boolean}
|
|
2394
|
+
*/
|
|
2395
|
+
function shouldIgnoreZone(node) {
|
|
2396
|
+
return !!node.closest("[".concat(SHADOW_ELEMENT_HINT_ATTRIBUTE_NAME, "=\"true\"]"));
|
|
2397
|
+
}
|
|
2394
2398
|
function validateOptions(options) {
|
|
2395
2399
|
/*eslint-disable*/
|
|
2396
2400
|
var items = options.items,
|
package/package.json
CHANGED
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"src",
|
|
43
43
|
"dist"
|
|
44
44
|
],
|
|
45
|
-
"description": "*An awesome drag and drop library for Svelte 3 (not using the browser's built-in dnd, thanks god): Rich animations, nested containers, touch support and more *",
|
|
46
|
-
"version": "0.9.
|
|
45
|
+
"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 *",
|
|
46
|
+
"version": "0.9.30",
|
|
47
47
|
"repository": {
|
|
48
48
|
"type": "git",
|
|
49
49
|
"url": "git+https://github.com/isaacHagoel/svelte-dnd-action.git"
|
package/src/action.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {dndzone as pointerDndZone} from "./pointerAction";
|
|
2
2
|
import {dndzone as keyboardDndZone} from "./keyboardAction";
|
|
3
|
-
import {ITEM_ID_KEY} from "./constants";
|
|
3
|
+
import {ITEM_ID_KEY, SHADOW_ELEMENT_HINT_ATTRIBUTE_NAME} from "./constants";
|
|
4
4
|
import {toString} from "./helpers/util";
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -25,6 +25,12 @@ import {toString} from "./helpers/util";
|
|
|
25
25
|
* @return {{update: function, destroy: function}}
|
|
26
26
|
*/
|
|
27
27
|
export function dndzone(node, options) {
|
|
28
|
+
if (shouldIgnoreZone(node)) {
|
|
29
|
+
return {
|
|
30
|
+
update: () => {},
|
|
31
|
+
destroy: () => {}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
28
34
|
validateOptions(options);
|
|
29
35
|
const pointerZone = pointerDndZone(node, options);
|
|
30
36
|
const keyboardZone = keyboardDndZone(node, options);
|
|
@@ -41,6 +47,16 @@ export function dndzone(node, options) {
|
|
|
41
47
|
};
|
|
42
48
|
}
|
|
43
49
|
|
|
50
|
+
/**
|
|
51
|
+
* If the user marked something in the ancestry of our node as shadow element, we can ignore it
|
|
52
|
+
* We need the user to mark it for us because svelte updates the action from deep to shallow (but renders top down)
|
|
53
|
+
* @param {HTMLElement} node
|
|
54
|
+
* @return {boolean}
|
|
55
|
+
*/
|
|
56
|
+
function shouldIgnoreZone(node) {
|
|
57
|
+
return !!node.closest(`[${SHADOW_ELEMENT_HINT_ATTRIBUTE_NAME}="true"]`);
|
|
58
|
+
}
|
|
59
|
+
|
|
44
60
|
function validateOptions(options) {
|
|
45
61
|
/*eslint-disable*/
|
|
46
62
|
const {
|
package/src/constants.js
CHANGED
|
@@ -19,7 +19,8 @@ export const SOURCES = {
|
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
export const SHADOW_ITEM_MARKER_PROPERTY_NAME = "isDndShadowItem";
|
|
22
|
-
export const SHADOW_ELEMENT_ATTRIBUTE_NAME = "data-is-dnd-shadow-item";
|
|
22
|
+
export const SHADOW_ELEMENT_ATTRIBUTE_NAME = "data-is-dnd-shadow-item-internal";
|
|
23
|
+
export const SHADOW_ELEMENT_HINT_ATTRIBUTE_NAME = "data-is-dnd-shadow-item-hint";
|
|
23
24
|
export const SHADOW_PLACEHOLDER_ITEM_ID = "id:dnd-shadow-placeholder-0000";
|
|
24
25
|
export const DRAGGED_ELEMENT_ID = "dnd-action-dragged-el";
|
|
25
26
|
|
package/src/pointerAction.js
CHANGED
|
@@ -36,10 +36,12 @@ import {getBoundingRectNoTransforms} from "./helpers/intersection";
|
|
|
36
36
|
|
|
37
37
|
const DEFAULT_DROP_ZONE_TYPE = "--any--";
|
|
38
38
|
const MIN_OBSERVATION_INTERVAL_MS = 100;
|
|
39
|
+
const DISABLED_OBSERVATION_INTERVAL_MS = 20;
|
|
39
40
|
const MIN_MOVEMENT_BEFORE_DRAG_START_PX = 3;
|
|
40
41
|
const DEFAULT_DROP_TARGET_STYLE = {
|
|
41
42
|
outline: "rgba(255, 255, 102, 0.7) solid 2px"
|
|
42
43
|
};
|
|
44
|
+
const ORIGINAL_DRAGGED_ITEM_MARKER_ATTRIBUTE = "data-is-dnd-original-dragged-item";
|
|
43
45
|
|
|
44
46
|
let originalDragTarget;
|
|
45
47
|
let draggedEl;
|
|
@@ -95,10 +97,8 @@ function watchDraggedElement() {
|
|
|
95
97
|
}
|
|
96
98
|
window.addEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop);
|
|
97
99
|
// 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
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
...Array.from(dropZones.keys()).map(dz => dzToConfig.get(dz).dropAnimationDurationMs)
|
|
101
|
-
);
|
|
100
|
+
const setIntervalMs = Math.max(...Array.from(dropZones.keys()).map(dz => dzToConfig.get(dz).dropAnimationDurationMs));
|
|
101
|
+
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.
|
|
102
102
|
observe(draggedEl, dropZones, observationIntervalMs * 1.07);
|
|
103
103
|
}
|
|
104
104
|
function unWatchDraggedElement() {
|
|
@@ -114,13 +114,8 @@ function unWatchDraggedElement() {
|
|
|
114
114
|
unobserve();
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
// finds the initial placeholder that is placed there on drag start
|
|
118
|
-
function findShadowPlaceHolderIdx(items) {
|
|
119
|
-
return items.findIndex(item => item[ITEM_ID_KEY] === SHADOW_PLACEHOLDER_ITEM_ID);
|
|
120
|
-
}
|
|
121
117
|
function findShadowElementIdx(items) {
|
|
122
|
-
|
|
123
|
-
return items.findIndex(item => !!item[SHADOW_ITEM_MARKER_PROPERTY_NAME] && item[ITEM_ID_KEY] !== SHADOW_PLACEHOLDER_ITEM_ID);
|
|
118
|
+
return items.findIndex(item => !!item[SHADOW_ITEM_MARKER_PROPERTY_NAME]);
|
|
124
119
|
}
|
|
125
120
|
|
|
126
121
|
/* custom drag-events handlers */
|
|
@@ -144,15 +139,7 @@ function handleDraggedEntered(e) {
|
|
|
144
139
|
id: draggedElData[ITEM_ID_KEY],
|
|
145
140
|
source: SOURCES.POINTER
|
|
146
141
|
});
|
|
147
|
-
} else {
|
|
148
|
-
const shadowPlaceHolderIdx = findShadowPlaceHolderIdx(items);
|
|
149
|
-
if (shadowPlaceHolderIdx !== -1) {
|
|
150
|
-
// only happens right after drag start, on the first drag entered event
|
|
151
|
-
printDebug(() => "removing placeholder item from origin dz");
|
|
152
|
-
items.splice(shadowPlaceHolderIdx, 1);
|
|
153
|
-
}
|
|
154
142
|
}
|
|
155
|
-
|
|
156
143
|
const {index, isProximityBased} = e.detail.indexObj;
|
|
157
144
|
const shadowElIdx = isProximityBased && index === e.currentTarget.children.length - 1 ? index + 1 : index;
|
|
158
145
|
shadowElDropZone = e.currentTarget;
|
|
@@ -245,6 +232,7 @@ function handleDrop() {
|
|
|
245
232
|
let shadowElIdx = findShadowElementIdx(items);
|
|
246
233
|
// the handler might remove the shadow element, ex: dragula like copy on drag
|
|
247
234
|
if (shadowElIdx === -1) shadowElIdx = originIndex;
|
|
235
|
+
|
|
248
236
|
items = items.map(item => (item[SHADOW_ITEM_MARKER_PROPERTY_NAME] ? draggedElData : item));
|
|
249
237
|
function finalizeWithinZone() {
|
|
250
238
|
unlockOriginDzMinDimensions();
|
|
@@ -401,12 +389,12 @@ export function dndzone(node, options) {
|
|
|
401
389
|
const {items, type, centreDraggedOnCursor} = config;
|
|
402
390
|
draggedElData = {...items[currentIdx]};
|
|
403
391
|
draggedElType = type;
|
|
404
|
-
shadowElData = {...draggedElData, [SHADOW_ITEM_MARKER_PROPERTY_NAME]: true};
|
|
405
|
-
// The initial shadow element. We need a different id at first in order to avoid conflicts and timing issues
|
|
406
|
-
const placeHolderElData = {...shadowElData, [ITEM_ID_KEY]: SHADOW_PLACEHOLDER_ITEM_ID};
|
|
392
|
+
shadowElData = {...draggedElData, [SHADOW_ITEM_MARKER_PROPERTY_NAME]: true, [ITEM_ID_KEY]: SHADOW_PLACEHOLDER_ITEM_ID};
|
|
407
393
|
|
|
408
394
|
// creating the draggable element
|
|
409
395
|
draggedEl = createDraggedElementFrom(originalDragTarget, centreDraggedOnCursor && currentMousePosition);
|
|
396
|
+
originalDragTarget.setAttribute(ORIGINAL_DRAGGED_ITEM_MARKER_ATTRIBUTE, true);
|
|
397
|
+
|
|
410
398
|
// We will keep the original dom node in the dom because touch events keep firing on it, we want to re-add it after the framework removes it
|
|
411
399
|
function keepOriginalElementInDom() {
|
|
412
400
|
if (!draggedEl.parentElement) {
|
|
@@ -429,7 +417,7 @@ export function dndzone(node, options) {
|
|
|
429
417
|
);
|
|
430
418
|
|
|
431
419
|
// removing the original element by removing its data entry
|
|
432
|
-
items.splice(currentIdx, 1,
|
|
420
|
+
items.splice(currentIdx, 1, shadowElData);
|
|
433
421
|
unlockOriginDzMinDimensions = preventShrinking(originDropZone);
|
|
434
422
|
|
|
435
423
|
dispatchConsiderEvent(originDropZone, items, {trigger: TRIGGERS.DRAG_STARTED, id: draggedElData[ITEM_ID_KEY], source: SOURCES.POINTER});
|
|
@@ -549,7 +537,7 @@ export function dndzone(node, options) {
|
|
|
549
537
|
unregisterDropZone(node, dzToConfig.get(node).type);
|
|
550
538
|
dzToConfig.delete(node);
|
|
551
539
|
}
|
|
552
|
-
if (isWorkingOnPreviousDrag) {
|
|
540
|
+
if (isWorkingOnPreviousDrag && !node.closest(`[${ORIGINAL_DRAGGED_ITEM_MARKER_ATTRIBUTE}]`)) {
|
|
553
541
|
printDebug(() => "pointer dndzone will be scheduled for destruction");
|
|
554
542
|
scheduleDZForRemovalAfterDrop(node, destroyDz);
|
|
555
543
|
} else {
|