svelte-dnd-action 0.9.63 → 0.9.65
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 +3 -1
- package/dist/index.js +27 -4
- package/dist/index.mjs +27 -4
- package/package.json +1 -1
- package/src/helpers/listUtil.js +28 -0
- package/src/pointerAction.js +1 -2
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# SVELTE DND ACTION [](https://snyk.io/test/github/isaacHagoel/svelte-dnd-action?targetFile=package.json)
|
|
2
2
|
|
|
3
|
+
> Shameless plug: If you are making AI Apps check out my brand-new, open source [dev tool](https://github.com/pragmaticfish/sushify)
|
|
4
|
+
|
|
3
5
|
This is a feature-complete implementation of drag and drop for Svelte using a custom action. It supports almost every imaginable drag and drop use-case, any input device and is fully accessible. <br />
|
|
4
6
|
It requires very minimal configuration, while offering a rich set of primitives that allow overriding basically any of its default behaviours (using the handler functions). <br /><br />
|
|
5
7
|
See full features list below. <br />
|
|
@@ -262,7 +264,7 @@ Notes:
|
|
|
262
264
|
- [Unsortable lists with custom aria instructions](https://svelte.dev/playground/e020ea1051dc4ae3ac2b697064f234bc?version=3)
|
|
263
265
|
- [Crazy nesting](https://svelte.dev/playground/fe8c9eca04f9417a94a8b6041df77139?version=3), courtesy of @zahachtah
|
|
264
266
|
- [Generic List Component (Alternative to Slots)](https://svelte.dev/playground/028674733f67409c94bd52995d5906f1?version=3)
|
|
265
|
-
- [
|
|
267
|
+
- [Maintaining internal scroll poisition on scrollable dragabble](https://svelte.dev/playground/eb2f5988bd2f46488810606c1fb13392?version=3)
|
|
266
268
|
- [Scrabble like board using over a 100 single slot dnd-zones](https://svelte.dev/playground/ed2e138417094281be6db1aef23d7859?version=3)
|
|
267
269
|
- [Select multiple elements to drag (multi-drag) with mouse or keyboard](https://svelte.dev/playground/c4eb917bb8df42c4b17402a7dda54856?version=3)
|
|
268
270
|
|
package/dist/index.js
CHANGED
|
@@ -647,6 +647,32 @@
|
|
|
647
647
|
indexOfMin = _i;
|
|
648
648
|
}
|
|
649
649
|
}
|
|
650
|
+
|
|
651
|
+
// -------- Phantom slot check --------
|
|
652
|
+
// Regardless of layout (simple vertical list, flex-wrap, grid, floats …) the
|
|
653
|
+
// visually closest drop target can be *after* the current last **real** child.
|
|
654
|
+
// In simple layouts the would be index from the existing children would always be the last index
|
|
655
|
+
// but in more complex layouts (flex-wrap, grid, floats …) it can be any index.
|
|
656
|
+
// The problem is we can't predict where an additional element would be rendered in the general case,
|
|
657
|
+
// We therefore create a temporary, invisible clone of that last element, let
|
|
658
|
+
// the browser position it, measure the distance, and remove it immediately
|
|
659
|
+
// (same task → no paint). This leaves `children` back in its original state
|
|
660
|
+
// before we exit the function, so existing index-caching logic and shadow-
|
|
661
|
+
// element bookkeeping continue to work unchanged.
|
|
662
|
+
if (children.length > 0) {
|
|
663
|
+
var originalLen = children.length; // before we append the phantom
|
|
664
|
+
var template = children[originalLen - 1];
|
|
665
|
+
var phantom = template.cloneNode(false); // shallow clone is enough for size
|
|
666
|
+
phantom.style.visibility = "hidden";
|
|
667
|
+
phantom.style.pointerEvents = "none";
|
|
668
|
+
collectionBelowEl.appendChild(phantom);
|
|
669
|
+
var phantomDistance = calcDistanceBetweenCenters(floatingAboveEl, phantom);
|
|
670
|
+
if (phantomDistance < minDistanceSoFar) {
|
|
671
|
+
indexOfMin = originalLen; // index of phantom slot in original list
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
collectionBelowEl.removeChild(phantom);
|
|
675
|
+
}
|
|
650
676
|
return {
|
|
651
677
|
index: indexOfMin,
|
|
652
678
|
isProximityBased: true
|
|
@@ -1485,10 +1511,7 @@
|
|
|
1485
1511
|
source: SOURCES.POINTER
|
|
1486
1512
|
});
|
|
1487
1513
|
}
|
|
1488
|
-
var
|
|
1489
|
-
index = _e$detail$indexObj.index,
|
|
1490
|
-
isProximityBased = _e$detail$indexObj.isProximityBased;
|
|
1491
|
-
var shadowElIdx = isProximityBased && index === e.currentTarget.children.length - 1 ? index + 1 : index;
|
|
1514
|
+
var shadowElIdx = e.detail.indexObj.index;
|
|
1492
1515
|
shadowElDropZone = e.currentTarget;
|
|
1493
1516
|
items.splice(shadowElIdx, 0, shadowElData);
|
|
1494
1517
|
dispatchConsiderEvent(e.currentTarget, items, {
|
package/dist/index.mjs
CHANGED
|
@@ -641,6 +641,32 @@ function findWouldBeIndex(floatingAboveEl, collectionBelowEl) {
|
|
|
641
641
|
indexOfMin = _i;
|
|
642
642
|
}
|
|
643
643
|
}
|
|
644
|
+
|
|
645
|
+
// -------- Phantom slot check --------
|
|
646
|
+
// Regardless of layout (simple vertical list, flex-wrap, grid, floats …) the
|
|
647
|
+
// visually closest drop target can be *after* the current last **real** child.
|
|
648
|
+
// In simple layouts the would be index from the existing children would always be the last index
|
|
649
|
+
// but in more complex layouts (flex-wrap, grid, floats …) it can be any index.
|
|
650
|
+
// The problem is we can't predict where an additional element would be rendered in the general case,
|
|
651
|
+
// We therefore create a temporary, invisible clone of that last element, let
|
|
652
|
+
// the browser position it, measure the distance, and remove it immediately
|
|
653
|
+
// (same task → no paint). This leaves `children` back in its original state
|
|
654
|
+
// before we exit the function, so existing index-caching logic and shadow-
|
|
655
|
+
// element bookkeeping continue to work unchanged.
|
|
656
|
+
if (children.length > 0) {
|
|
657
|
+
var originalLen = children.length; // before we append the phantom
|
|
658
|
+
var template = children[originalLen - 1];
|
|
659
|
+
var phantom = template.cloneNode(false); // shallow clone is enough for size
|
|
660
|
+
phantom.style.visibility = "hidden";
|
|
661
|
+
phantom.style.pointerEvents = "none";
|
|
662
|
+
collectionBelowEl.appendChild(phantom);
|
|
663
|
+
var phantomDistance = calcDistanceBetweenCenters(floatingAboveEl, phantom);
|
|
664
|
+
if (phantomDistance < minDistanceSoFar) {
|
|
665
|
+
indexOfMin = originalLen; // index of phantom slot in original list
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
collectionBelowEl.removeChild(phantom);
|
|
669
|
+
}
|
|
644
670
|
return {
|
|
645
671
|
index: indexOfMin,
|
|
646
672
|
isProximityBased: true
|
|
@@ -1479,10 +1505,7 @@ function handleDraggedEntered(e) {
|
|
|
1479
1505
|
source: SOURCES.POINTER
|
|
1480
1506
|
});
|
|
1481
1507
|
}
|
|
1482
|
-
var
|
|
1483
|
-
index = _e$detail$indexObj.index,
|
|
1484
|
-
isProximityBased = _e$detail$indexObj.isProximityBased;
|
|
1485
|
-
var shadowElIdx = isProximityBased && index === e.currentTarget.children.length - 1 ? index + 1 : index;
|
|
1508
|
+
var shadowElIdx = e.detail.indexObj.index;
|
|
1486
1509
|
shadowElDropZone = e.currentTarget;
|
|
1487
1510
|
items.splice(shadowElIdx, 0, shadowElData);
|
|
1488
1511
|
dispatchConsiderEvent(e.currentTarget, items, {
|
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.65",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/isaacHagoel/svelte-dnd-action.git"
|
package/src/helpers/listUtil.js
CHANGED
|
@@ -77,5 +77,33 @@ export function findWouldBeIndex(floatingAboveEl, collectionBelowEl) {
|
|
|
77
77
|
indexOfMin = i;
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
+
|
|
81
|
+
// -------- Phantom slot check --------
|
|
82
|
+
// Regardless of layout (simple vertical list, flex-wrap, grid, floats …) the
|
|
83
|
+
// visually closest drop target can be *after* the current last **real** child.
|
|
84
|
+
// In simple layouts the would be index from the existing children would always be the last index
|
|
85
|
+
// but in more complex layouts (flex-wrap, grid, floats …) it can be any index.
|
|
86
|
+
// The problem is we can't predict where an additional element would be rendered in the general case,
|
|
87
|
+
// We therefore create a temporary, invisible clone of that last element, let
|
|
88
|
+
// the browser position it, measure the distance, and remove it immediately
|
|
89
|
+
// (same task → no paint). This leaves `children` back in its original state
|
|
90
|
+
// before we exit the function, so existing index-caching logic and shadow-
|
|
91
|
+
// element bookkeeping continue to work unchanged.
|
|
92
|
+
if (children.length > 0) {
|
|
93
|
+
const originalLen = children.length; // before we append the phantom
|
|
94
|
+
const template = children[originalLen - 1];
|
|
95
|
+
const phantom = template.cloneNode(false); // shallow clone is enough for size
|
|
96
|
+
phantom.style.visibility = "hidden";
|
|
97
|
+
phantom.style.pointerEvents = "none";
|
|
98
|
+
collectionBelowEl.appendChild(phantom);
|
|
99
|
+
|
|
100
|
+
const phantomDistance = calcDistanceBetweenCenters(floatingAboveEl, phantom);
|
|
101
|
+
if (phantomDistance < minDistanceSoFar) {
|
|
102
|
+
indexOfMin = originalLen; // index of phantom slot in original list
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
collectionBelowEl.removeChild(phantom);
|
|
106
|
+
}
|
|
107
|
+
|
|
80
108
|
return {index: indexOfMin, isProximityBased: true};
|
|
81
109
|
}
|
package/src/pointerAction.js
CHANGED
|
@@ -154,8 +154,7 @@ function handleDraggedEntered(e) {
|
|
|
154
154
|
source: SOURCES.POINTER
|
|
155
155
|
});
|
|
156
156
|
}
|
|
157
|
-
const {index
|
|
158
|
-
const shadowElIdx = isProximityBased && index === e.currentTarget.children.length - 1 ? index + 1 : index;
|
|
157
|
+
const {index: shadowElIdx} = e.detail.indexObj;
|
|
159
158
|
shadowElDropZone = e.currentTarget;
|
|
160
159
|
items.splice(shadowElIdx, 0, shadowElData);
|
|
161
160
|
dispatchConsiderEvent(e.currentTarget, items, {trigger: TRIGGERS.DRAGGED_ENTERED, id: draggedElData[ITEM_ID_KEY], source: SOURCES.POINTER});
|