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 +9 -3
- package/dist/index.js +226 -183
- package/dist/index.mjs +226 -183
- package/package.json +1 -1
- package/src/helpers/intersection.js +1 -21
- package/src/helpers/listUtil.js +0 -9
- package/src/helpers/multiScroller.js +74 -0
- package/src/helpers/observer.js +5 -7
- package/src/helpers/scroller.js +36 -2
- package/src/pointerAction.js +20 -13
- package/src/helpers/windowScroller.js +0 -48
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
|
|
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 =
|
|
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)
|
|
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
|
|
897
|
-
var mousePosition;
|
|
767
|
+
var SCROLL_ZONE_PX = 30;
|
|
898
768
|
|
|
899
769
|
/**
|
|
900
|
-
*
|
|
901
|
-
*
|
|
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
|
|
905
|
-
var
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
if (
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
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
|
-
|
|
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
|
|
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 "
|
|
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
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
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
|
|
1317
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
}
|