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 CHANGED
@@ -1,5 +1,7 @@
1
1
  # SVELTE DND ACTION [![Known Vulnerabilities](https://snyk.io/test/github/isaacHagoel/svelte-dnd-action/badge.svg?targetFile=package.json)](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
- - [Maitaining internal scroll poisition on scrollable dragabble](https://svelte.dev/playground/eb2f5988bd2f46488810606c1fb13392?version=3)
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 _e$detail$indexObj = e.detail.indexObj,
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 _e$detail$indexObj = e.detail.indexObj,
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.63",
4
+ "version": "0.9.65",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/isaacHagoel/svelte-dnd-action.git"
@@ -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
  }
@@ -154,8 +154,7 @@ function handleDraggedEntered(e) {
154
154
  source: SOURCES.POINTER
155
155
  });
156
156
  }
157
- const {index, isProximityBased} = e.detail.indexObj;
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});