svelte-dnd-action 0.9.40 → 0.9.42

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
@@ -22,7 +22,7 @@ It is being actively maintained.
22
22
  - Rich animations (can be opted out of)
23
23
  - Touch support
24
24
  - Define what can be dropped where (dnd-zones optionally have a "type")
25
- - Scroll dnd-zones and/or the window horizontally or vertically by placing the dragged element next to the edge
25
+ - Scroll dnd-zones (of the relevant "type"), parent containers that contains them and/or the window horizontally or vertically by placing the dragged element next to the edge
26
26
  - Supports advanced use-cases such as various flavours of copy-on-drag and custom drag handles (see examples below)
27
27
  - Performant and small footprint (no external dependencies, no fluff code)
28
28
  - Fully accessible (beta) - keyboard support, aria attributes and assistive instructions for screen readers
@@ -82,7 +82,7 @@ npm install --save-dev svelte-dnd-action
82
82
  width: 50%;
83
83
  padding: 0.3em;
84
84
  border: 1px solid black;
85
- /* this will allow the dragged element to scroll the list */
85
+ /* this will allow the dragged element to scroll the list although starting in version 0.9.41 the lib would detect any scrollable parent*/
86
86
  overflow: scroll;
87
87
  height: 200px;
88
88
  }
@@ -207,7 +207,6 @@ If you want to implement your own custom screen-reader alerts, roles and instruc
207
207
  - Any data that should "survive" when the items are dragged around and dropped should be included in the `items` array that is passed in.
208
208
  - The host component must refresh the items that are passed in to the custom-action when receiving consider and finalize events (do not omit any handler).
209
209
  - FYI, the library assumes it is okay to add a temporary item to the items list in any of the dnd-zones while an element is dragged around.
210
- - If you want dragged items to be able to scroll the container, make sure the scroll-container (the element with overflow:scroll) is the dnd-zone (the element decorated with this custom action)
211
210
  - Svelte's built-in transitions might not play nice with this library. Luckily, it is an easy issue to work around. There are examples above.
212
211
 
213
212
  ### Overriding the item id key name
@@ -373,6 +372,13 @@ This is an experimental feature added in version 0.9.29. If you have multiple le
373
372
  Specifically, it allows nested zones within the shadow element (the placeholder under the dragged element) to register and destroy.
374
373
  This is because Svelte calls nested actions before the parent action (opposite to the rendering order).
375
374
  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]} `
375
+ Starting with version 0.9.42. if you use the hint make sure to include it in the key you provide in your each block e.g:
376
+
377
+ ```sveltehtml
378
+ {#each columnItems as column (`${column._id}${column[SHADOW_ITEM_MARKER_PROPERTY_NAME] ? "_" + column[SHADOW_ITEM_MARKER_PROPERTY_NAME] : ""}`)}
379
+ ...
380
+ {/each}
381
+ ```
376
382
 
377
383
  #### Simplified Example (just shows where to place the attribute):
378
384
 
package/dist/index.js CHANGED
@@ -501,33 +501,13 @@
501
501
 
502
502
  /**
503
503
  * @param {HTMLElement} el - the element to check
504
- * @returns {boolean} - true if the element in its entirety is off screen including the scrollable area (the normal dom events look at the mouse rather than the element)
504
+ * @returns {boolean} - true if the element in its entirety is off-screen including the scrollable area (the normal dom events look at the mouse rather than the element)
505
505
  */
506
506
  function isElementOffDocument(el) {
507
507
  var rect = getAbsoluteRect(el);
508
508
  return rect.right < 0 || rect.left > document.documentElement.scrollWidth || rect.bottom < 0 || rect.top > document.documentElement.scrollHeight;
509
509
  }
510
510
 
511
- /**
512
- * If the point is inside the element returns its distances from the sides, otherwise returns null
513
- * @param {Point} point
514
- * @param {HTMLElement} el
515
- * @return {null|{top: number, left: number, bottom: number, right: number}}
516
- */
517
- function calcInnerDistancesBetweenPointAndSidesOfElement(point, el) {
518
- var rect = getAbsoluteRect(el);
519
- if (!isPointInsideRect(point, rect)) {
520
- return null;
521
- }
522
- return {
523
- top: point.y - rect.top,
524
- bottom: rect.bottom - point.y,
525
- left: point.x - rect.left,
526
- // TODO - figure out what is so special about right (why the rect is too big)
527
- right: Math.min(rect.right, document.documentElement.clientWidth) - point.x
528
- };
529
- }
530
-
531
511
  var dzToShadowIndexToRect;
532
512
 
533
513
  /**
@@ -541,17 +521,6 @@
541
521
  }
542
522
  resetIndexesCache();
543
523
 
544
- /**
545
- * Resets the cache that allows for smarter "would be index" resolution for a specific dropzone, should be called after the zone was scrolled
546
- * @param {HTMLElement} dz
547
- */
548
- function resetIndexesCacheForDz(dz) {
549
- printDebug(function () {
550
- return "resetting indexes cache for dz";
551
- });
552
- dzToShadowIndexToRect["delete"](dz);
553
- }
554
-
555
524
  /**
556
525
  * Caches the coordinates of the shadow element when it's in a certain index in a certain dropzone.
557
526
  * Helpful in order to determine "would be index" more effectively
@@ -634,102 +603,6 @@
634
603
  };
635
604
  }
636
605
 
637
- var SCROLL_ZONE_PX = 25;
638
- function makeScroller() {
639
- var scrollingInfo;
640
- function resetScrolling() {
641
- scrollingInfo = {
642
- directionObj: undefined,
643
- stepPx: 0
644
- };
645
- }
646
- resetScrolling();
647
- // directionObj {x: 0|1|-1, y:0|1|-1} - 1 means down in y and right in x
648
- function scrollContainer(containerEl) {
649
- var _scrollingInfo = scrollingInfo,
650
- directionObj = _scrollingInfo.directionObj,
651
- stepPx = _scrollingInfo.stepPx;
652
- if (directionObj) {
653
- containerEl.scrollBy(directionObj.x * stepPx, directionObj.y * stepPx);
654
- window.requestAnimationFrame(function () {
655
- return scrollContainer(containerEl);
656
- });
657
- }
658
- }
659
- function calcScrollStepPx(distancePx) {
660
- return SCROLL_ZONE_PX - distancePx;
661
- }
662
-
663
- /**
664
- * If the pointer is next to the sides of the element to scroll, will trigger scrolling
665
- * Can be called repeatedly with updated pointer and elementToScroll values without issues
666
- * @return {boolean} - true if scrolling was needed
667
- */
668
- function scrollIfNeeded(pointer, elementToScroll) {
669
- if (!elementToScroll) {
670
- return false;
671
- }
672
- var distances = calcInnerDistancesBetweenPointAndSidesOfElement(pointer, elementToScroll);
673
- if (distances === null) {
674
- resetScrolling();
675
- return false;
676
- }
677
- var isAlreadyScrolling = !!scrollingInfo.directionObj;
678
- var scrollingVertically = false,
679
- scrollingHorizontally = false;
680
- // vertical
681
- if (elementToScroll.scrollHeight > elementToScroll.clientHeight) {
682
- if (distances.bottom < SCROLL_ZONE_PX) {
683
- scrollingVertically = true;
684
- scrollingInfo.directionObj = {
685
- x: 0,
686
- y: 1
687
- };
688
- scrollingInfo.stepPx = calcScrollStepPx(distances.bottom);
689
- } else if (distances.top < SCROLL_ZONE_PX) {
690
- scrollingVertically = true;
691
- scrollingInfo.directionObj = {
692
- x: 0,
693
- y: -1
694
- };
695
- scrollingInfo.stepPx = calcScrollStepPx(distances.top);
696
- }
697
- if (!isAlreadyScrolling && scrollingVertically) {
698
- scrollContainer(elementToScroll);
699
- return true;
700
- }
701
- }
702
- // horizontal
703
- if (elementToScroll.scrollWidth > elementToScroll.clientWidth) {
704
- if (distances.right < SCROLL_ZONE_PX) {
705
- scrollingHorizontally = true;
706
- scrollingInfo.directionObj = {
707
- x: 1,
708
- y: 0
709
- };
710
- scrollingInfo.stepPx = calcScrollStepPx(distances.right);
711
- } else if (distances.left < SCROLL_ZONE_PX) {
712
- scrollingHorizontally = true;
713
- scrollingInfo.directionObj = {
714
- x: -1,
715
- y: 0
716
- };
717
- scrollingInfo.stepPx = calcScrollStepPx(distances.left);
718
- }
719
- if (!isAlreadyScrolling && scrollingHorizontally) {
720
- scrollContainer(elementToScroll);
721
- return true;
722
- }
723
- }
724
- resetScrolling();
725
- return false;
726
- }
727
- return {
728
- scrollIfNeeded: scrollIfNeeded,
729
- resetScrolling: resetScrolling
730
- };
731
- }
732
-
733
606
  /**
734
607
  * @param {Object} object
735
608
  * @return {string}
@@ -795,9 +668,6 @@
795
668
 
796
669
  var INTERVAL_MS = 200;
797
670
  var TOLERANCE_PX = 10;
798
- var _makeScroller = makeScroller(),
799
- scrollIfNeeded = _makeScroller.scrollIfNeeded,
800
- resetScrolling = _makeScroller.resetScrolling;
801
671
  var next;
802
672
 
803
673
  /**
@@ -805,9 +675,11 @@
805
675
  * @param {Set<HTMLElement>} dropZones
806
676
  * @param {HTMLElement} draggedEl
807
677
  * @param {number} [intervalMs = INTERVAL_MS]
678
+ * @param {MultiScroller} multiScroller
808
679
  */
809
680
  function observe(draggedEl, dropZones) {
810
681
  var intervalMs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : INTERVAL_MS;
682
+ var multiScroller = arguments.length > 3 ? arguments[3] : undefined;
811
683
  // initialization
812
684
  var lastDropZoneFound;
813
685
  var lastIndexFound;
@@ -823,7 +695,7 @@
823
695
  */
824
696
  function andNow() {
825
697
  var currentCenterOfDragged = findCenterOfElement(draggedEl);
826
- var scrolled = scrollIfNeeded(currentCenterOfDragged, lastDropZoneFound);
698
+ var scrolled = multiScroller.multiScrollIfNeeded();
827
699
  // we only want to make a new decision after the element was moved a bit to prevent flickering
828
700
  if (!scrolled && lastCentrePositionOfDragged && Math.abs(lastCentrePositionOfDragged.x - currentCenterOfDragged.x) < TOLERANCE_PX && Math.abs(lastCentrePositionOfDragged.y - currentCenterOfDragged.y) < TOLERANCE_PX) {
829
701
  next = window.setTimeout(andNow, intervalMs);
@@ -844,7 +716,7 @@
844
716
  try {
845
717
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
846
718
  var dz = _step.value;
847
- if (scrolled) resetIndexesCacheForDz(lastDropZoneFound);
719
+ if (scrolled) resetIndexesCache();
848
720
  var indexObj = findWouldBeIndex(draggedEl, dz);
849
721
  if (indexObj === null) {
850
722
  // it is not inside
@@ -889,61 +761,225 @@
889
761
  return "unobserving";
890
762
  });
891
763
  clearTimeout(next);
892
- resetScrolling();
893
764
  resetIndexesCache();
894
765
  }
895
766
 
896
- var INTERVAL_MS$1 = 300;
897
- var mousePosition;
767
+ var SCROLL_ZONE_PX = 30;
898
768
 
899
769
  /**
900
- * Do not use this! it is visible for testing only until we get over the issue Cypress not triggering the mousemove listeners
901
- * // TODO - make private (remove export)
902
- * @param {{clientX: number, clientY: number}} e
770
+ * Will make a scroller that can scroll any element given to it in any direction
771
+ * @returns {{scrollIfNeeded: function(Point, HTMLElement): boolean, resetScrolling: function(void):void}}
903
772
  */
904
- function updateMousePosition(e) {
905
- var c = e.touches ? e.touches[0] : e;
906
- mousePosition = {
907
- x: c.clientX,
908
- y: c.clientY
909
- };
910
- }
911
- var _makeScroller$1 = makeScroller(),
912
- scrollIfNeeded$1 = _makeScroller$1.scrollIfNeeded,
913
- resetScrolling$1 = _makeScroller$1.resetScrolling;
914
- var next$1;
915
- function loop() {
916
- if (mousePosition) {
917
- var scrolled = scrollIfNeeded$1(mousePosition, document.documentElement);
918
- if (scrolled) resetIndexesCache();
773
+ function makeScroller() {
774
+ var scrollingInfo;
775
+ function resetScrolling() {
776
+ scrollingInfo = {
777
+ directionObj: undefined,
778
+ stepPx: 0
779
+ };
780
+ }
781
+ resetScrolling();
782
+ // directionObj {x: 0|1|-1, y:0|1|-1} - 1 means down in y and right in x
783
+ function scrollContainer(containerEl) {
784
+ var _scrollingInfo = scrollingInfo,
785
+ directionObj = _scrollingInfo.directionObj,
786
+ stepPx = _scrollingInfo.stepPx;
787
+ if (directionObj) {
788
+ containerEl.scrollBy(directionObj.x * stepPx, directionObj.y * stepPx);
789
+ window.requestAnimationFrame(function () {
790
+ return scrollContainer(containerEl);
791
+ });
792
+ }
919
793
  }
920
- next$1 = window.setTimeout(loop, INTERVAL_MS$1);
794
+ function calcScrollStepPx(distancePx) {
795
+ return SCROLL_ZONE_PX - distancePx;
796
+ }
797
+
798
+ /**
799
+ * @param {Point} pointer - the pointer will be used to decide in which direction to scroll
800
+ * @param {HTMLElement} elementToScroll - the scroll container
801
+ * If the pointer is next to the sides of the element to scroll, will trigger scrolling
802
+ * Can be called repeatedly with updated pointer and elementToScroll values without issues
803
+ * @return {boolean} - true if scrolling was needed
804
+ */
805
+ function scrollIfNeeded(pointer, elementToScroll) {
806
+ if (!elementToScroll) {
807
+ return false;
808
+ }
809
+ var distances = calcInnerDistancesBetweenPointAndSidesOfElement(pointer, elementToScroll);
810
+ if (distances === null) {
811
+ resetScrolling();
812
+ return false;
813
+ }
814
+ var isAlreadyScrolling = !!scrollingInfo.directionObj;
815
+ var scrollingVertically = false,
816
+ scrollingHorizontally = false;
817
+ // vertical
818
+ if (elementToScroll.scrollHeight > elementToScroll.clientHeight) {
819
+ if (distances.bottom < SCROLL_ZONE_PX) {
820
+ scrollingVertically = true;
821
+ scrollingInfo.directionObj = {
822
+ x: 0,
823
+ y: 1
824
+ };
825
+ scrollingInfo.stepPx = calcScrollStepPx(distances.bottom);
826
+ } else if (distances.top < SCROLL_ZONE_PX) {
827
+ scrollingVertically = true;
828
+ scrollingInfo.directionObj = {
829
+ x: 0,
830
+ y: -1
831
+ };
832
+ scrollingInfo.stepPx = calcScrollStepPx(distances.top);
833
+ }
834
+ if (!isAlreadyScrolling && scrollingVertically) {
835
+ scrollContainer(elementToScroll);
836
+ return true;
837
+ }
838
+ }
839
+ // horizontal
840
+ if (elementToScroll.scrollWidth > elementToScroll.clientWidth) {
841
+ if (distances.right < SCROLL_ZONE_PX) {
842
+ scrollingHorizontally = true;
843
+ scrollingInfo.directionObj = {
844
+ x: 1,
845
+ y: 0
846
+ };
847
+ scrollingInfo.stepPx = calcScrollStepPx(distances.right);
848
+ } else if (distances.left < SCROLL_ZONE_PX) {
849
+ scrollingHorizontally = true;
850
+ scrollingInfo.directionObj = {
851
+ x: -1,
852
+ y: 0
853
+ };
854
+ scrollingInfo.stepPx = calcScrollStepPx(distances.left);
855
+ }
856
+ if (!isAlreadyScrolling && scrollingHorizontally) {
857
+ scrollContainer(elementToScroll);
858
+ return true;
859
+ }
860
+ }
861
+ resetScrolling();
862
+ return false;
863
+ }
864
+ return {
865
+ scrollIfNeeded: scrollIfNeeded,
866
+ resetScrolling: resetScrolling
867
+ };
921
868
  }
922
869
 
923
870
  /**
924
- * will start watching the mouse pointer and scroll the window if it goes next to the edges
871
+ * If the point is inside the element returns its distances from the sides, otherwise returns null
872
+ * @param {Point} point
873
+ * @param {HTMLElement} el
874
+ * @return {null|{top: number, left: number, bottom: number, right: number}}
925
875
  */
926
- function armWindowScroller() {
927
- printDebug(function () {
928
- return "arming window scroller";
929
- });
930
- window.addEventListener("mousemove", updateMousePosition);
931
- window.addEventListener("touchmove", updateMousePosition);
932
- loop();
876
+ function calcInnerDistancesBetweenPointAndSidesOfElement(point, el) {
877
+ // Even if the scrolling element is small it acts as a scroller for the viewport
878
+ var rect = el === document.scrollingElement ? {
879
+ top: 0,
880
+ bottom: window.innerHeight,
881
+ left: 0,
882
+ right: window.innerWidth
883
+ } : el.getBoundingClientRect();
884
+ if (!isPointInsideRect(point, rect)) {
885
+ return null;
886
+ }
887
+ return {
888
+ top: point.y - rect.top,
889
+ bottom: rect.bottom - point.y,
890
+ left: point.x - rect.left,
891
+ right: rect.right - point.x
892
+ };
933
893
  }
934
894
 
935
895
  /**
936
- * will stop watching the mouse pointer and won't scroll the window anymore
896
+ @typedef {Object} MultiScroller
897
+ @property {function():boolean} multiScrollIfNeeded - call this on every "tick" to scroll containers if needed, returns true if anything was scrolled
898
+ /**
899
+ * Creates a scroller than can scroll any of the provided containers or any of their scrollable parents (including the document's scrolling element)
900
+ * @param {HTMLElement[]} baseElementsForScrolling
901
+ * @param {function():Point} getPointerPosition
902
+ * @return {MultiScroller}
937
903
  */
938
- function disarmWindowScroller() {
904
+ function createMultiScroller() {
905
+ var baseElementsForScrolling = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
906
+ var getPointerPosition = arguments.length > 1 ? arguments[1] : undefined;
939
907
  printDebug(function () {
940
- return "disarming window scroller";
908
+ return "creating multi-scroller";
909
+ });
910
+ var scrollingContainersSet = findRelevantScrollContainers(baseElementsForScrolling);
911
+ var scrollingContainersDeepToShallow = Array.from(scrollingContainersSet).sort(function (dz1, dz2) {
912
+ return getDepth(dz2) - getDepth(dz1);
941
913
  });
942
- window.removeEventListener("mousemove", updateMousePosition);
943
- window.removeEventListener("touchmove", updateMousePosition);
944
- mousePosition = undefined;
945
- window.clearTimeout(next$1);
946
- resetScrolling$1();
914
+ var _makeScroller = makeScroller(),
915
+ scrollIfNeeded = _makeScroller.scrollIfNeeded;
916
+
917
+ /**
918
+ * @return {boolean} - was any container scrolled
919
+ */
920
+ function tick() {
921
+ var mousePosition = getPointerPosition();
922
+ if (!mousePosition || !scrollingContainersDeepToShallow) {
923
+ return false;
924
+ }
925
+ var scrollContainersUnderCursor = scrollingContainersDeepToShallow.filter(function (el) {
926
+ return isPointInsideRect(mousePosition, el.getBoundingClientRect()) || el === document.scrollingElement;
927
+ });
928
+ for (var i = 0; i < scrollContainersUnderCursor.length; i++) {
929
+ var scrolled = scrollIfNeeded(mousePosition, scrollContainersUnderCursor[i]);
930
+ if (scrolled) {
931
+ return true;
932
+ }
933
+ }
934
+ return false;
935
+ }
936
+ return {
937
+ multiScrollIfNeeded: scrollingContainersSet.size > 0 ? tick : function () {
938
+ return false;
939
+ }
940
+ };
941
+ }
942
+
943
+ // internal utils
944
+ function findScrollableParents(element) {
945
+ if (!element) {
946
+ return [];
947
+ }
948
+ var scrollableContainers = [];
949
+ var parent = element;
950
+ while (parent) {
951
+ var _window$getComputedSt = window.getComputedStyle(parent),
952
+ overflow = _window$getComputedSt.overflow;
953
+ if (overflow.split(" ").some(function (o) {
954
+ return o.includes("auto") || o.includes("scroll");
955
+ })) {
956
+ scrollableContainers.push(parent);
957
+ }
958
+ parent = parent.parentElement;
959
+ }
960
+ return scrollableContainers;
961
+ }
962
+ function findRelevantScrollContainers(dropZones) {
963
+ var scrollingContainers = new Set();
964
+ var _iterator = _createForOfIteratorHelper(dropZones),
965
+ _step;
966
+ try {
967
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
968
+ var dz = _step.value;
969
+ findScrollableParents(dz).forEach(function (container) {
970
+ return scrollingContainers.add(container);
971
+ });
972
+ }
973
+ // The scrolling element might have overflow visible and still be scrollable
974
+ } catch (err) {
975
+ _iterator.e(err);
976
+ } finally {
977
+ _iterator.f();
978
+ }
979
+ if (document.scrollingElement.scrollHeight > document.scrollingElement.clientHeight || document.scrollingElement.scrollWidth > document.scrollingElement.clientHeight) {
980
+ scrollingContainers.add(document.scrollingElement);
981
+ }
982
+ return scrollingContainers;
947
983
  }
948
984
 
949
985
  /**
@@ -1292,7 +1328,6 @@
1292
1328
  printDebug(function () {
1293
1329
  return "watching dragged element";
1294
1330
  });
1295
- armWindowScroller();
1296
1331
  var dropZones = typeToDropZones.get(draggedElType);
1297
1332
  var _iterator = _createForOfIteratorHelper(dropZones),
1298
1333
  _step;
@@ -1309,18 +1344,21 @@
1309
1344
  _iterator.f();
1310
1345
  }
1311
1346
  window.addEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop);
1347
+
1312
1348
  // 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
1313
1349
  var setIntervalMs = Math.max.apply(Math, _toConsumableArray(Array.from(dropZones.keys()).map(function (dz) {
1314
1350
  return dzToConfig.get(dz).dropAnimationDurationMs;
1315
1351
  })));
1316
- 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.
1317
- observe(draggedEl, dropZones, observationIntervalMs * 1.07);
1352
+ 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.
1353
+ var multiScroller = createMultiScroller(dropZones, function () {
1354
+ return currentMousePosition;
1355
+ });
1356
+ observe(draggedEl, dropZones, observationIntervalMs * 1.07, multiScroller);
1318
1357
  }
1319
1358
  function unWatchDraggedElement() {
1320
1359
  printDebug(function () {
1321
1360
  return "unwatching dragged element";
1322
1361
  });
1323
- disarmWindowScroller();
1324
1362
  var dropZones = typeToDropZones.get(draggedElType);
1325
1363
  var _iterator2 = _createForOfIteratorHelper(dropZones),
1326
1364
  _step2;
@@ -1401,7 +1439,7 @@
1401
1439
  return ["dragged left", e.currentTarget, e.detail];
1402
1440
  });
1403
1441
  var _dzToConfig$get2 = dzToConfig.get(e.currentTarget),
1404
- items = _dzToConfig$get2.items,
1442
+ originalItems = _dzToConfig$get2.items,
1405
1443
  dropFromOthersDisabled = _dzToConfig$get2.dropFromOthersDisabled;
1406
1444
  if (dropFromOthersDisabled && e.currentTarget !== originDropZone && e.currentTarget !== shadowElDropZone) {
1407
1445
  printDebug(function () {
@@ -1409,10 +1447,12 @@
1409
1447
  });
1410
1448
  return;
1411
1449
  }
1450
+ var items = _toConsumableArray(originalItems);
1412
1451
  var shadowElIdx = findShadowElementIdx(items);
1413
1452
  if (shadowElIdx !== -1) {
1414
1453
  items.splice(shadowElIdx, 1);
1415
1454
  }
1455
+ var origShadowDz = shadowElDropZone;
1416
1456
  shadowElDropZone = undefined;
1417
1457
  var _e$detail = e.detail,
1418
1458
  type = _e$detail.type,
@@ -1423,7 +1463,8 @@
1423
1463
  });
1424
1464
  isDraggedOutsideOfAnyDz = true;
1425
1465
  shadowElDropZone = originDropZone;
1426
- var originZoneItems = dzToConfig.get(originDropZone).items;
1466
+ // if the last zone it left is the origin dz, we will put it back into items (which we just removed it from)
1467
+ var originZoneItems = origShadowDz === originDropZone ? items : _toConsumableArray(dzToConfig.get(originDropZone).items);
1427
1468
  originZoneItems.splice(originIndex, 0, shadowElData);
1428
1469
  dispatchConsiderEvent(originDropZone, originZoneItems, {
1429
1470
  trigger: TRIGGERS.DRAGGED_LEFT_ALL,
@@ -1443,7 +1484,7 @@
1443
1484
  return ["dragged is over index", e.currentTarget, e.detail];
1444
1485
  });
1445
1486
  var _dzToConfig$get3 = dzToConfig.get(e.currentTarget),
1446
- items = _dzToConfig$get3.items,
1487
+ originalItems = _dzToConfig$get3.items,
1447
1488
  dropFromOthersDisabled = _dzToConfig$get3.dropFromOthersDisabled;
1448
1489
  if (dropFromOthersDisabled && e.currentTarget !== originDropZone) {
1449
1490
  printDebug(function () {
@@ -1451,6 +1492,7 @@
1451
1492
  });
1452
1493
  return;
1453
1494
  }
1495
+ var items = _toConsumableArray(originalItems);
1454
1496
  isDraggedOutsideOfAnyDz = false;
1455
1497
  var index = e.detail.indexObj.index;
1456
1498
  var shadowElIdx = findShadowElementIdx(items);
@@ -1509,8 +1551,6 @@
1509
1551
  if (shadowElIdx === -1) {
1510
1552
  if (shadowElDropZone === originDropZone) {
1511
1553
  shadowElIdx = originIndex;
1512
- } else if (shadowElDropZone.children.length > 0) {
1513
- shadowElIdx = shadowElDropZone.children.length - 1;
1514
1554
  }
1515
1555
  }
1516
1556
  items = items.map(function (item) {
@@ -1534,12 +1574,12 @@
1534
1574
  if (shadowElIdx !== -1) unDecorateShadowElement(shadowElDropZone.children[shadowElIdx]);
1535
1575
  cleanupPostDrop();
1536
1576
  }
1537
- if (shadowElIdx !== -1) animateDraggedToFinalPosition(shadowElIdx, finalizeWithinZone);
1577
+ animateDraggedToFinalPosition(shadowElIdx, finalizeWithinZone);
1538
1578
  }
1539
1579
 
1540
1580
  // helper function for handleDrop
1541
1581
  function animateDraggedToFinalPosition(shadowElIdx, callback) {
1542
- var shadowElRect = getBoundingRectNoTransforms(shadowElDropZone.children[shadowElIdx]);
1582
+ var shadowElRect = shadowElIdx > -1 ? getBoundingRectNoTransforms(shadowElDropZone.children[shadowElIdx]) : getBoundingRectNoTransforms(shadowElDropZone);
1543
1583
  var newTransform = {
1544
1584
  x: shadowElRect.left - parseFloat(draggedEl.style.left),
1545
1585
  y: shadowElRect.top - parseFloat(draggedEl.style.top)
@@ -1695,9 +1735,10 @@
1695
1735
  /** @type {ShadowRoot | HTMLDocument | Element } */
1696
1736
  var rootNode = originDropZone.closest("dialog") || originDropZone.getRootNode();
1697
1737
  var originDropZoneRoot = rootNode.body || rootNode;
1698
- var items = config.items,
1738
+ var originalItems = config.items,
1699
1739
  type = config.type,
1700
1740
  centreDraggedOnCursor = config.centreDraggedOnCursor;
1741
+ var items = _toConsumableArray(originalItems);
1701
1742
  draggedElData = items[currentIdx];
1702
1743
  draggedElType = type;
1703
1744
  shadowElData = createShadowElData(draggedElData);
@@ -1715,6 +1756,8 @@
1715
1756
  watchDraggedElement();
1716
1757
  hideElement(originalDragTarget);
1717
1758
  originDropZoneRoot.appendChild(originalDragTarget);
1759
+ // after the removal of the original element we can give the shadow element the original item id so that the host zone can find it and render it correctly if it does lookups by id
1760
+ shadowElData[ITEM_ID_KEY] = draggedElData[ITEM_ID_KEY];
1718
1761
  } else {
1719
1762
  window.requestAnimationFrame(keepOriginalElementInDom);
1720
1763
  }