@bsol-oss/react-datatable5 7.6.2 → 7.6.3

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.
Files changed (3) hide show
  1. package/dist/index.js +2206 -12
  2. package/dist/index.mjs +2198 -4
  3. package/package.json +4 -5
package/dist/index.js CHANGED
@@ -11,7 +11,11 @@ var fa6 = require('react-icons/fa6');
11
11
  var bi = require('react-icons/bi');
12
12
  var cg = require('react-icons/cg');
13
13
  var io = require('react-icons/io');
14
- var adapter = require('@atlaskit/pragmatic-drag-and-drop/element/adapter');
14
+ var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
15
+ var bindEventListener = require('bind-event-listener');
16
+ var _defineProperty = require('@babel/runtime/helpers/defineProperty');
17
+ var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
18
+ var rafSchd = require('raf-schd');
15
19
  var invariant = require('tiny-invariant');
16
20
  var hi2 = require('react-icons/hi2');
17
21
  var reactTable = require('@tanstack/react-table');
@@ -25,9 +29,6 @@ var axios = require('axios');
25
29
  var usehooks = require('@uidotdev/usehooks');
26
30
  var reactHookForm = require('react-hook-form');
27
31
  var dayjs = require('dayjs');
28
- var adapter$1 = require('@atlaskit/pragmatic-drag-and-drop/external/adapter');
29
- var file = require('@atlaskit/pragmatic-drag-and-drop/external/file');
30
- var text = require('@atlaskit/pragmatic-drag-and-drop/external/text');
31
32
 
32
33
  function _interopNamespaceDefault(e) {
33
34
  var n = Object.create(null);
@@ -458,6 +459,1896 @@ const EditSortingButton = ({ text, icon = jsxRuntime.jsx(md.MdOutlineSort, {}),
458
459
  return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(DialogRoot, { size: ["full", "full", "md", "md"], children: [jsxRuntime.jsx(react.DialogBackdrop, {}), jsxRuntime.jsx(DialogTrigger, { children: jsxRuntime.jsxs(react.Button, { as: "div", variant: "ghost", onClick: sortingModal.onOpen, children: [icon, " ", text] }) }), jsxRuntime.jsxs(DialogContent, { children: [jsxRuntime.jsx(DialogCloseTrigger, {}), jsxRuntime.jsxs(DialogHeader, { children: [jsxRuntime.jsx(DialogTitle, {}), title] }), jsxRuntime.jsx(DialogBody, { children: jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: "0.25rem", children: [jsxRuntime.jsx(TableSorter, {}), jsxRuntime.jsx(ResetSortingButton, {})] }) }), jsxRuntime.jsx(DialogFooter, {})] })] }) }));
459
460
  };
460
461
 
462
+ // pulling this into a separate file so adapter(s) that don't
463
+ // need the honey pot can pay as little as possible for it.
464
+ var honeyPotDataAttribute = 'data-pdnd-honey-pot';
465
+
466
+ function isHoneyPotElement(target) {
467
+ return target instanceof Element && target.hasAttribute(honeyPotDataAttribute);
468
+ }
469
+
470
+ function getElementFromPointWithoutHoneypot(client) {
471
+ // eslint-disable-next-line no-restricted-syntax
472
+ var _document$elementsFro = document.elementsFromPoint(client.x, client.y),
473
+ _document$elementsFro2 = _slicedToArray(_document$elementsFro, 2),
474
+ top = _document$elementsFro2[0],
475
+ second = _document$elementsFro2[1];
476
+ if (!top) {
477
+ return null;
478
+ }
479
+ if (isHoneyPotElement(top)) {
480
+ return second !== null && second !== void 0 ? second : null;
481
+ }
482
+ return top;
483
+ }
484
+
485
+ // Maximum possible z-index
486
+ // https://stackoverflow.com/questions/491052/minimum-and-maximum-value-of-z-index
487
+ var maxZIndex = 2147483647;
488
+
489
+ function ownKeys$2(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
490
+ function _objectSpread$2(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$2(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$2(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
491
+ var honeyPotSize = 2;
492
+ var halfHoneyPotSize = honeyPotSize / 2;
493
+
494
+ /**
495
+ * `clientX` and `clientY` can be in sub pixels (eg `2.332`)
496
+ * However, browser hitbox testing is commonly do to the closest pixel.
497
+ *
498
+ * → https://issues.chromium.org/issues/40940531
499
+ *
500
+ * To be sure that the honey pot will be over the `client` position,
501
+ * we `.floor()` `clientX` and`clientY` and then make it `2px` in size.
502
+ **/
503
+ function floorToClosestPixel(point) {
504
+ return {
505
+ x: Math.floor(point.x),
506
+ y: Math.floor(point.y)
507
+ };
508
+ }
509
+
510
+ /**
511
+ * We want to make sure the honey pot sits around the users position.
512
+ * This seemed to be the most resilient while testing.
513
+ */
514
+ function pullBackByHalfHoneyPotSize(point) {
515
+ return {
516
+ x: point.x - halfHoneyPotSize,
517
+ y: point.y - halfHoneyPotSize
518
+ };
519
+ }
520
+
521
+ /**
522
+ * Prevent the honey pot from changing the window size.
523
+ * This is super unlikely to occur, but just being safe.
524
+ */
525
+ function preventGoingBackwardsOffScreen(point) {
526
+ return {
527
+ x: Math.max(point.x, 0),
528
+ y: Math.max(point.y, 0)
529
+ };
530
+ }
531
+
532
+ /**
533
+ * Prevent the honey pot from changing the window size.
534
+ * This is super unlikely to occur, but just being safe.
535
+ */
536
+ function preventGoingForwardsOffScreen(point) {
537
+ return {
538
+ x: Math.min(point.x, window.innerWidth - honeyPotSize),
539
+ y: Math.min(point.y, window.innerHeight - honeyPotSize)
540
+ };
541
+ }
542
+
543
+ /**
544
+ * Create a `2x2` `DOMRect` around the `client` position
545
+ */
546
+ function getHoneyPotRectFor(_ref) {
547
+ var client = _ref.client;
548
+ var point = preventGoingForwardsOffScreen(preventGoingBackwardsOffScreen(pullBackByHalfHoneyPotSize(floorToClosestPixel(client))));
549
+
550
+ // When debugging, it is helpful to
551
+ // make this element a bit bigger
552
+ return DOMRect.fromRect({
553
+ x: point.x,
554
+ y: point.y,
555
+ width: honeyPotSize,
556
+ height: honeyPotSize
557
+ });
558
+ }
559
+ function getRectStyles(_ref2) {
560
+ var clientRect = _ref2.clientRect;
561
+ return {
562
+ left: "".concat(clientRect.left, "px"),
563
+ top: "".concat(clientRect.top, "px"),
564
+ width: "".concat(clientRect.width, "px"),
565
+ height: "".concat(clientRect.height, "px")
566
+ };
567
+ }
568
+ function isWithin(_ref3) {
569
+ var client = _ref3.client,
570
+ clientRect = _ref3.clientRect;
571
+ return (
572
+ // is within horizontal bounds
573
+ client.x >= clientRect.x && client.x <= clientRect.x + clientRect.width &&
574
+ // is within vertical bounds
575
+ client.y >= clientRect.y && client.y <= clientRect.y + clientRect.height
576
+ );
577
+ }
578
+ /**
579
+ * The honey pot fix is designed to get around a painful bug in all browsers.
580
+ *
581
+ * [Overview](https://www.youtube.com/watch?v=udE9qbFTeQg)
582
+ *
583
+ * **Background**
584
+ *
585
+ * When a drag starts, browsers incorrectly think that the users pointer is
586
+ * still depressed where the drag started. Any element that goes under this position
587
+ * will be entered into, causing `"mouseenter"` events and `":hover"` styles to be applied.
588
+ *
589
+ * _This is a violation of the spec_
590
+ *
591
+ * > "From the moment that the user agent is to initiate the drag-and-drop operation,
592
+ * > until the end of the drag-and-drop operation, device input events
593
+ * > (e.g. mouse and keyboard events) must be suppressed."
594
+ * >
595
+ * > - https://html.spec.whatwg.org/multipage/dnd.html#drag-and-drop-processing-model
596
+ *
597
+ * _Some impacts_
598
+ *
599
+ * - `":hover"` styles being applied where they shouldn't (looks messy)
600
+ * - components such as tooltips responding to `"mouseenter"` can show during a drag,
601
+ * and on an element the user isn't even over
602
+ *
603
+ * Bug: https://issues.chromium.org/issues/41129937
604
+ *
605
+ * **Honey pot fix**
606
+ *
607
+ * 1. Create an element where the browser thinks the depressed pointer is
608
+ * to absorb the incorrect pointer events
609
+ * 2. Remove that element when it is no longer needed
610
+ */
611
+ function mountHoneyPot(_ref4) {
612
+ var initial = _ref4.initial;
613
+ var element = document.createElement('div');
614
+ element.setAttribute(honeyPotDataAttribute, 'true');
615
+
616
+ // can shift during the drag thanks to Firefox
617
+ var clientRect = getHoneyPotRectFor({
618
+ client: initial
619
+ });
620
+ Object.assign(element.style, _objectSpread$2(_objectSpread$2({
621
+ // Setting a background color explicitly to avoid any inherited styles.
622
+ // Looks like this could be `opacity: 0`, but worried that _might_
623
+ // cause the element to be ignored on some platforms.
624
+ // When debugging, set backgroundColor to something like "red".
625
+ backgroundColor: 'transparent',
626
+ position: 'fixed',
627
+ // Being explicit to avoid inheriting styles
628
+ padding: 0,
629
+ margin: 0,
630
+ boxSizing: 'border-box'
631
+ }, getRectStyles({
632
+ clientRect: clientRect
633
+ })), {}, {
634
+ // We want this element to absorb pointer events,
635
+ // it's kind of the whole point 😉
636
+ pointerEvents: 'auto',
637
+ // Want to make sure the honey pot is top of everything else.
638
+ // Don't need to worry about native drag previews, as they will
639
+ // have been rendered (and removed) before the honey pot is rendered
640
+ zIndex: maxZIndex
641
+ }));
642
+ document.body.appendChild(element);
643
+
644
+ /**
645
+ * 🦊 In firefox we can get `"pointermove"` events after the drag
646
+ * has started, which is a spec violation.
647
+ * The final `"pointermove"` will reveal where the "depressed" position
648
+ * is for our honey pot fix.
649
+ */
650
+ var unbindPointerMove = bindEventListener.bind(window, {
651
+ type: 'pointermove',
652
+ listener: function listener(event) {
653
+ var client = {
654
+ x: event.clientX,
655
+ y: event.clientY
656
+ };
657
+ clientRect = getHoneyPotRectFor({
658
+ client: client
659
+ });
660
+ Object.assign(element.style, getRectStyles({
661
+ clientRect: clientRect
662
+ }));
663
+ },
664
+ // using capture so we are less likely to be impacted by event stopping
665
+ options: {
666
+ capture: true
667
+ }
668
+ });
669
+ return function finish(_ref5) {
670
+ var current = _ref5.current;
671
+ // Don't need this any more
672
+ unbindPointerMove();
673
+
674
+ // If the user is hover the honey pot, we remove it
675
+ // so that the user can continue to interact with the page normally.
676
+ if (isWithin({
677
+ client: current,
678
+ clientRect: clientRect
679
+ })) {
680
+ element.remove();
681
+ return;
682
+ }
683
+ function cleanup() {
684
+ unbindPostDragEvents();
685
+ element.remove();
686
+ }
687
+ var unbindPostDragEvents = bindEventListener.bindAll(window, [{
688
+ type: 'pointerdown',
689
+ listener: cleanup
690
+ }, {
691
+ type: 'pointermove',
692
+ listener: cleanup
693
+ }, {
694
+ type: 'focusin',
695
+ listener: cleanup
696
+ }, {
697
+ type: 'focusout',
698
+ listener: cleanup
699
+ },
700
+ // a 'pointerdown' should happen before 'dragstart', but just being super safe
701
+ {
702
+ type: 'dragstart',
703
+ listener: cleanup
704
+ },
705
+ // if the user has dragged something out of the window
706
+ // and then is dragging something back into the window
707
+ // the first events we will see are "dragenter" (and then "dragover").
708
+ // So if we see any of these we need to clear the post drag fix.
709
+ {
710
+ type: 'dragenter',
711
+ listener: cleanup
712
+ }, {
713
+ type: 'dragover',
714
+ listener: cleanup
715
+ }
716
+
717
+ // Not adding a "wheel" event listener, as "wheel" by itself does not
718
+ // resolve the bug.
719
+ ], {
720
+ // Using `capture` so less likely to be impacted by other code stopping events
721
+ capture: true
722
+ });
723
+ };
724
+ }
725
+ function makeHoneyPotFix() {
726
+ var latestPointerMove = null;
727
+ function bindEvents() {
728
+ // For sanity, only collecting this value from when events are first bound.
729
+ // This prevents the case where a super old "pointermove" could be used
730
+ // from a prior interaction.
731
+ latestPointerMove = null;
732
+ return bindEventListener.bind(window, {
733
+ type: 'pointermove',
734
+ listener: function listener(event) {
735
+ latestPointerMove = {
736
+ x: event.clientX,
737
+ y: event.clientY
738
+ };
739
+ },
740
+ // listening for pointer move in capture phase
741
+ // so we are less likely to be impacted by events being stopped.
742
+ options: {
743
+ capture: true
744
+ }
745
+ });
746
+ }
747
+ function getOnPostDispatch() {
748
+ var finish = null;
749
+ return function onPostEvent(_ref6) {
750
+ var eventName = _ref6.eventName,
751
+ payload = _ref6.payload;
752
+ // We are adding the honey pot `onDragStart` so we don't
753
+ // impact the creation of the native drag preview.
754
+ if (eventName === 'onDragStart') {
755
+ var _latestPointerMove;
756
+ var input = payload.location.initial.input;
757
+
758
+ // Sometimes there will be no latest "pointermove" (eg iOS).
759
+ // In which case, we use the start position of the drag.
760
+ var initial = (_latestPointerMove = latestPointerMove) !== null && _latestPointerMove !== void 0 ? _latestPointerMove : {
761
+ x: input.clientX,
762
+ y: input.clientY
763
+ };
764
+
765
+ // Don't need to defensively call `finish()` as `onDrop` from
766
+ // one interaction is guaranteed to be called before `onDragStart`
767
+ // of the next.
768
+ finish = mountHoneyPot({
769
+ initial: initial
770
+ });
771
+ }
772
+ if (eventName === 'onDrop') {
773
+ var _finish;
774
+ var _input = payload.location.current.input;
775
+ (_finish = finish) === null || _finish === void 0 || _finish({
776
+ current: {
777
+ x: _input.clientX,
778
+ y: _input.clientY
779
+ }
780
+ });
781
+ finish = null;
782
+ // this interaction is finished, we want to use
783
+ // the latest "pointermove" for each interaction
784
+ latestPointerMove = null;
785
+ }
786
+ };
787
+ }
788
+ return {
789
+ bindEvents: bindEvents,
790
+ getOnPostDispatch: getOnPostDispatch
791
+ };
792
+ }
793
+
794
+ /** Provide a function that you only ever want to be called a single time */
795
+ function once(fn) {
796
+ var cache = null;
797
+ return function wrapped() {
798
+ if (!cache) {
799
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
800
+ args[_key] = arguments[_key];
801
+ }
802
+ var result = fn.apply(this, args);
803
+ cache = {
804
+ result: result
805
+ };
806
+ }
807
+ return cache.result;
808
+ };
809
+ }
810
+
811
+ // using `cache` as our `isFirefox()` result will not change in a browser
812
+
813
+ /**
814
+ * Returns `true` if a `Firefox` browser
815
+ * */
816
+ var isFirefox = once(function isFirefox() {
817
+ if (process.env.NODE_ENV === 'test') {
818
+ return false;
819
+ }
820
+ return navigator.userAgent.includes('Firefox');
821
+ });
822
+
823
+ // using `cache` as our `isSafari()` result will not change in a browser
824
+
825
+ /**
826
+ * Returns `true` if a `Safari` browser.
827
+ * Returns `true` if the browser is running on iOS (they are all Safari).
828
+ * */
829
+ var isSafari = once(function isSafari() {
830
+ if (process.env.NODE_ENV === 'test') {
831
+ return false;
832
+ }
833
+ var _navigator = navigator,
834
+ userAgent = _navigator.userAgent;
835
+ return userAgent.includes('AppleWebKit') && !userAgent.includes('Chrome');
836
+ });
837
+
838
+ /* For "dragenter" events, the browser should set `relatedTarget` to the previous element.
839
+ * For external drag operations, our first "dragenter" event should have a `event.relatedTarget` of `null`.
840
+ *
841
+ * Unfortunately in Safari `event.relatedTarget` is *always* set to `null`
842
+ * Safari bug: https://bugs.webkit.org/show_bug.cgi?id=242627
843
+ * To work around this we count "dragenter" and "dragleave" events */
844
+
845
+ // Using symbols for event properties so we don't clash with
846
+ // anything on the `event` object
847
+ var symbols = {
848
+ isLeavingWindow: Symbol('leaving'),
849
+ isEnteringWindow: Symbol('entering')
850
+ };
851
+ function isEnteringWindowInSafari(_ref) {
852
+ var dragEnter = _ref.dragEnter;
853
+ if (!isSafari()) {
854
+ return false;
855
+ }
856
+ return dragEnter.hasOwnProperty(symbols.isEnteringWindow);
857
+ }
858
+ function isLeavingWindowInSafari(_ref2) {
859
+ var dragLeave = _ref2.dragLeave;
860
+ if (!isSafari()) {
861
+ return false;
862
+ }
863
+ return dragLeave.hasOwnProperty(symbols.isLeavingWindow);
864
+ }
865
+ (function fixSafari() {
866
+ // Don't do anything when server side rendering
867
+ if (typeof window === 'undefined') {
868
+ return;
869
+ }
870
+
871
+ // rather than checking the userAgent for "jsdom" we can do this check
872
+ // so that the check will be removed completely in production code
873
+ if (process.env.NODE_ENV === 'test') {
874
+ return;
875
+ }
876
+ if (!isSafari()) {
877
+ return;
878
+ }
879
+ function getInitialState() {
880
+ return {
881
+ enterCount: 0,
882
+ isOverWindow: false
883
+ };
884
+ }
885
+ var state = getInitialState();
886
+ function resetState() {
887
+ state = getInitialState();
888
+ }
889
+
890
+ // These event listeners are bound _forever_ and _never_ removed
891
+ // We don't bother cleaning up these event listeners (for now)
892
+ // as this workaround is only for Safari
893
+
894
+ // This is how the event count works:
895
+ //
896
+ // lift (+1 enterCount)
897
+ // - dragstart(draggable) [enterCount: 0]
898
+ // - dragenter(draggable) [enterCount: 1]
899
+ // leaving draggable (+0 enterCount)
900
+ // - dragenter(document.body) [enterCount: 2]
901
+ // - dragleave(draggable) [enterCount: 1]
902
+ // leaving window (-1 enterCount)
903
+ // - dragleave(document.body) [enterCount: 0] {leaving the window}
904
+
905
+ // Things to note:
906
+ // - dragenter and dragleave bubble
907
+ // - the first dragenter when entering a window might not be on `window`
908
+ // - it could be on an element that is pressed up against the window
909
+ // - (so we cannot rely on `event.target` values)
910
+
911
+ bindEventListener.bindAll(window, [{
912
+ type: 'dragstart',
913
+ listener: function listener() {
914
+ state.enterCount = 0;
915
+ // drag start occurs in the source window
916
+ state.isOverWindow = true;
917
+ // When a drag first starts it will also trigger a "dragenter" on the draggable element
918
+ }
919
+ }, {
920
+ type: 'drop',
921
+ listener: resetState
922
+ }, {
923
+ type: 'dragend',
924
+ listener: resetState
925
+ }, {
926
+ type: 'dragenter',
927
+ listener: function listener(event) {
928
+ if (!state.isOverWindow && state.enterCount === 0) {
929
+ // Patching the `event` object
930
+ // The `event` object is shared with all event listeners for the event
931
+ // @ts-expect-error: adding property to the event object
932
+ event[symbols.isEnteringWindow] = true;
933
+ }
934
+ state.isOverWindow = true;
935
+ state.enterCount++;
936
+ }
937
+ }, {
938
+ type: 'dragleave',
939
+ listener: function listener(event) {
940
+ state.enterCount--;
941
+ if (state.isOverWindow && state.enterCount === 0) {
942
+ // Patching the `event` object as it is shared with all event listeners
943
+ // The `event` object is shared with all event listeners for the event
944
+ // @ts-expect-error: adding property to the event object
945
+ event[symbols.isLeavingWindow] = true;
946
+ state.isOverWindow = false;
947
+ }
948
+ }
949
+ }],
950
+ // using `capture: true` so that adding event listeners
951
+ // in bubble phase will have the correct symbols
952
+ {
953
+ capture: true
954
+ });
955
+ })();
956
+
957
+ /**
958
+ * Does the `EventTarget` look like a `Node` based on "duck typing".
959
+ *
960
+ * Helpful when the `Node` might be outside of the current document
961
+ * so we cannot to an `target instanceof Node` check.
962
+ */
963
+ function isNodeLike(target) {
964
+ return 'nodeName' in target;
965
+ }
966
+
967
+ /**
968
+ * Is an `EventTarget` a `Node` from another `window`?
969
+ */
970
+ function isFromAnotherWindow(eventTarget) {
971
+ return isNodeLike(eventTarget) && eventTarget.ownerDocument !== document;
972
+ }
973
+
974
+ function isLeavingWindow(_ref) {
975
+ var dragLeave = _ref.dragLeave;
976
+ var type = dragLeave.type,
977
+ relatedTarget = dragLeave.relatedTarget;
978
+ if (type !== 'dragleave') {
979
+ return false;
980
+ }
981
+ if (isSafari()) {
982
+ return isLeavingWindowInSafari({
983
+ dragLeave: dragLeave
984
+ });
985
+ }
986
+
987
+ // Standard check: if going to `null` we are leaving the `window`
988
+ if (relatedTarget == null) {
989
+ return true;
990
+ }
991
+
992
+ /**
993
+ * 🦊 Exception: `iframe` in Firefox (`125.0`)
994
+ *
995
+ * Case 1: parent `window` → child `iframe`
996
+ * `dragLeave.relatedTarget` is element _inside_ the child `iframe`
997
+ * (foreign element)
998
+ *
999
+ * Case 2: child `iframe` → parent `window`
1000
+ * `dragLeave.relatedTarget` is the `iframe` in the parent `window`
1001
+ * (foreign element)
1002
+ */
1003
+
1004
+ if (isFirefox()) {
1005
+ return isFromAnotherWindow(relatedTarget);
1006
+ }
1007
+
1008
+ /**
1009
+ * 🌏 Exception: `iframe` in Chrome (`124.0`)
1010
+ *
1011
+ * Case 1: parent `window` → child `iframe`
1012
+ * `dragLeave.relatedTarget` is the `iframe` in the parent `window`
1013
+ *
1014
+ * Case 2: child `iframe` → parent `window`
1015
+ * `dragLeave.relatedTarget` is `null` *(standard check)*
1016
+ */
1017
+
1018
+ // Case 2
1019
+ // Using `instanceof` check as the element will be in the same `window`
1020
+ return relatedTarget instanceof HTMLIFrameElement;
1021
+ }
1022
+
1023
+ function getBindingsForBrokenDrags(_ref) {
1024
+ var onDragEnd = _ref.onDragEnd;
1025
+ return [
1026
+ // ## Detecting drag ending for removed draggables
1027
+ //
1028
+ // If a draggable element is removed during a drag and the user drops:
1029
+ // 1. if over a valid drop target: we get a "drop" event to know the drag is finished
1030
+ // 2. if not over a valid drop target (or cancelled): we get nothing
1031
+ // The "dragend" event will not fire on the source draggable if it has been
1032
+ // removed from the DOM.
1033
+ // So we need to figure out if a drag operation has finished by looking at other events
1034
+ // We can do this by looking at other events
1035
+
1036
+ // ### First detection: "pointermove" events
1037
+
1038
+ // 1. "pointermove" events cannot fire during a drag and drop operation
1039
+ // according to the spec. So if we get a "pointermove" it means that
1040
+ // the drag and drop operations has finished. So if we get a "pointermove"
1041
+ // we know that the drag is over
1042
+ // 2. 🦊😤 Drag and drop operations are _supposed_ to suppress
1043
+ // other pointer events. However, firefox will allow a few
1044
+ // pointer event to get through after a drag starts.
1045
+ // The most I've seen is 3
1046
+ {
1047
+ type: 'pointermove',
1048
+ listener: function () {
1049
+ var callCount = 0;
1050
+ return function listener() {
1051
+ // Using 20 as it is far bigger than the most observed (3)
1052
+ if (callCount < 20) {
1053
+ callCount++;
1054
+ return;
1055
+ }
1056
+ onDragEnd();
1057
+ };
1058
+ }()
1059
+ },
1060
+ // ### Second detection: "pointerdown" events
1061
+
1062
+ // If we receive this event then we know that a drag operation has finished
1063
+ // and potentially another one is about to start.
1064
+ // Note: `pointerdown` fires on all browsers / platforms before "dragstart"
1065
+ {
1066
+ type: 'pointerdown',
1067
+ listener: onDragEnd
1068
+ }];
1069
+ }
1070
+
1071
+ function getInput(event) {
1072
+ return {
1073
+ altKey: event.altKey,
1074
+ button: event.button,
1075
+ buttons: event.buttons,
1076
+ ctrlKey: event.ctrlKey,
1077
+ metaKey: event.metaKey,
1078
+ shiftKey: event.shiftKey,
1079
+ clientX: event.clientX,
1080
+ clientY: event.clientY,
1081
+ pageX: event.pageX,
1082
+ pageY: event.pageY
1083
+ };
1084
+ }
1085
+
1086
+ var scheduleOnDrag = rafSchd(function (fn) {
1087
+ return fn();
1088
+ });
1089
+ var dragStart = function () {
1090
+ var scheduled = null;
1091
+ function schedule(fn) {
1092
+ var frameId = requestAnimationFrame(function () {
1093
+ scheduled = null;
1094
+ fn();
1095
+ });
1096
+ scheduled = {
1097
+ frameId: frameId,
1098
+ fn: fn
1099
+ };
1100
+ }
1101
+ function flush() {
1102
+ if (scheduled) {
1103
+ cancelAnimationFrame(scheduled.frameId);
1104
+ scheduled.fn();
1105
+ scheduled = null;
1106
+ }
1107
+ }
1108
+ return {
1109
+ schedule: schedule,
1110
+ flush: flush
1111
+ };
1112
+ }();
1113
+ function makeDispatch(_ref) {
1114
+ var source = _ref.source,
1115
+ initial = _ref.initial,
1116
+ dispatchEvent = _ref.dispatchEvent;
1117
+ var previous = {
1118
+ dropTargets: []
1119
+ };
1120
+ function safeDispatch(args) {
1121
+ dispatchEvent(args);
1122
+ previous = {
1123
+ dropTargets: args.payload.location.current.dropTargets
1124
+ };
1125
+ }
1126
+ var dispatch = {
1127
+ start: function start(_ref2) {
1128
+ var nativeSetDragImage = _ref2.nativeSetDragImage;
1129
+ // Ensuring that both `onGenerateDragPreview` and `onDragStart` get the same location.
1130
+ // We do this so that `previous` is`[]` in `onDragStart` (which is logical)
1131
+ var location = {
1132
+ current: initial,
1133
+ previous: previous,
1134
+ initial: initial
1135
+ };
1136
+ // a `onGenerateDragPreview` does _not_ add another entry for `previous`
1137
+ // onDragPreview
1138
+ safeDispatch({
1139
+ eventName: 'onGenerateDragPreview',
1140
+ payload: {
1141
+ source: source,
1142
+ location: location,
1143
+ nativeSetDragImage: nativeSetDragImage
1144
+ }
1145
+ });
1146
+ dragStart.schedule(function () {
1147
+ safeDispatch({
1148
+ eventName: 'onDragStart',
1149
+ payload: {
1150
+ source: source,
1151
+ location: location
1152
+ }
1153
+ });
1154
+ });
1155
+ },
1156
+ dragUpdate: function dragUpdate(_ref3) {
1157
+ var current = _ref3.current;
1158
+ dragStart.flush();
1159
+ scheduleOnDrag.cancel();
1160
+ safeDispatch({
1161
+ eventName: 'onDropTargetChange',
1162
+ payload: {
1163
+ source: source,
1164
+ location: {
1165
+ initial: initial,
1166
+ previous: previous,
1167
+ current: current
1168
+ }
1169
+ }
1170
+ });
1171
+ },
1172
+ drag: function drag(_ref4) {
1173
+ var current = _ref4.current;
1174
+ scheduleOnDrag(function () {
1175
+ dragStart.flush();
1176
+ var location = {
1177
+ initial: initial,
1178
+ previous: previous,
1179
+ current: current
1180
+ };
1181
+ safeDispatch({
1182
+ eventName: 'onDrag',
1183
+ payload: {
1184
+ source: source,
1185
+ location: location
1186
+ }
1187
+ });
1188
+ });
1189
+ },
1190
+ drop: function drop(_ref5) {
1191
+ var current = _ref5.current,
1192
+ updatedSourcePayload = _ref5.updatedSourcePayload;
1193
+ dragStart.flush();
1194
+ scheduleOnDrag.cancel();
1195
+ safeDispatch({
1196
+ eventName: 'onDrop',
1197
+ payload: {
1198
+ source: updatedSourcePayload !== null && updatedSourcePayload !== void 0 ? updatedSourcePayload : source,
1199
+ location: {
1200
+ current: current,
1201
+ previous: previous,
1202
+ initial: initial
1203
+ }
1204
+ }
1205
+ });
1206
+ }
1207
+ };
1208
+ return dispatch;
1209
+ }
1210
+
1211
+ var globalState = {
1212
+ isActive: false
1213
+ };
1214
+ function canStart() {
1215
+ return !globalState.isActive;
1216
+ }
1217
+ function getNativeSetDragImage(event) {
1218
+ if (event.dataTransfer) {
1219
+ // need to use `.bind` as `setDragImage` is required
1220
+ // to be run with `event.dataTransfer` as the "this" context
1221
+ return event.dataTransfer.setDragImage.bind(event.dataTransfer);
1222
+ }
1223
+ return null;
1224
+ }
1225
+ function hasHierarchyChanged(_ref) {
1226
+ var current = _ref.current,
1227
+ next = _ref.next;
1228
+ if (current.length !== next.length) {
1229
+ return true;
1230
+ }
1231
+ // not checking stickiness, data or dropEffect,
1232
+ // just whether the hierarchy has changed
1233
+ for (var i = 0; i < current.length; i++) {
1234
+ if (current[i].element !== next[i].element) {
1235
+ return true;
1236
+ }
1237
+ }
1238
+ return false;
1239
+ }
1240
+ function start(_ref2) {
1241
+ var event = _ref2.event,
1242
+ dragType = _ref2.dragType,
1243
+ getDropTargetsOver = _ref2.getDropTargetsOver,
1244
+ dispatchEvent = _ref2.dispatchEvent;
1245
+ if (!canStart()) {
1246
+ return;
1247
+ }
1248
+ var initial = getStartLocation({
1249
+ event: event,
1250
+ dragType: dragType,
1251
+ getDropTargetsOver: getDropTargetsOver
1252
+ });
1253
+ globalState.isActive = true;
1254
+ var state = {
1255
+ current: initial
1256
+ };
1257
+
1258
+ // Setting initial drop effect for the drag
1259
+ setDropEffectOnEvent({
1260
+ event: event,
1261
+ current: initial.dropTargets
1262
+ });
1263
+ var dispatch = makeDispatch({
1264
+ source: dragType.payload,
1265
+ dispatchEvent: dispatchEvent,
1266
+ initial: initial
1267
+ });
1268
+ function updateState(next) {
1269
+ // only looking at whether hierarchy has changed to determine whether something as 'changed'
1270
+ var hasChanged = hasHierarchyChanged({
1271
+ current: state.current.dropTargets,
1272
+ next: next.dropTargets
1273
+ });
1274
+
1275
+ // Always updating the state to include latest data, dropEffect and stickiness
1276
+ // Only updating consumers if the hierarchy has changed in some way
1277
+ // Consumers can get the latest data by using `onDrag`
1278
+ state.current = next;
1279
+ if (hasChanged) {
1280
+ dispatch.dragUpdate({
1281
+ current: state.current
1282
+ });
1283
+ }
1284
+ }
1285
+ function onUpdateEvent(event) {
1286
+ var input = getInput(event);
1287
+
1288
+ // If we are over the honey pot, we need to get the element
1289
+ // that the user would have been over if not for the honey pot
1290
+ var target = isHoneyPotElement(event.target) ? getElementFromPointWithoutHoneypot({
1291
+ x: input.clientX,
1292
+ y: input.clientY
1293
+ }) : event.target;
1294
+ var nextDropTargets = getDropTargetsOver({
1295
+ target: target,
1296
+ input: input,
1297
+ source: dragType.payload,
1298
+ current: state.current.dropTargets
1299
+ });
1300
+ if (nextDropTargets.length) {
1301
+ // 🩸 must call `event.preventDefault()` to allow a browser drop to occur
1302
+ event.preventDefault();
1303
+ setDropEffectOnEvent({
1304
+ event: event,
1305
+ current: nextDropTargets
1306
+ });
1307
+ }
1308
+ updateState({
1309
+ dropTargets: nextDropTargets,
1310
+ input: input
1311
+ });
1312
+ }
1313
+ function cancel() {
1314
+ // The spec behaviour is that when a drag is cancelled, or when dropping on no drop targets,
1315
+ // a "dragleave" event is fired on the active drop target before a "dragend" event.
1316
+ // We are replicating that behaviour in `cancel` if there are any active drop targets to
1317
+ // ensure consistent behaviour.
1318
+ //
1319
+ // Note: When cancelling, or dropping on no drop targets, a "dragleave" event
1320
+ // will have already cleared the dropTargets to `[]` (as that particular "dragleave" has a `relatedTarget` of `null`)
1321
+
1322
+ if (state.current.dropTargets.length) {
1323
+ updateState({
1324
+ dropTargets: [],
1325
+ input: state.current.input
1326
+ });
1327
+ }
1328
+ dispatch.drop({
1329
+ current: state.current,
1330
+ updatedSourcePayload: null
1331
+ });
1332
+ finish();
1333
+ }
1334
+ function finish() {
1335
+ globalState.isActive = false;
1336
+ unbindEvents();
1337
+ }
1338
+ var unbindEvents = bindEventListener.bindAll(window, [{
1339
+ // 👋 Note: we are repurposing the `dragover` event as our `drag` event
1340
+ // this is because firefox does not publish pointer coordinates during
1341
+ // a `drag` event, but does for every other type of drag event
1342
+ // `dragover` fires on all elements that are being dragged over
1343
+ // Because we are binding to `window` - our `dragover` is effectively the same as a `drag`
1344
+ // 🦊😤
1345
+ type: 'dragover',
1346
+ listener: function listener(event) {
1347
+ // We need to regularly calculate the drop targets in order to allow:
1348
+ // - dynamic `canDrop()` checks
1349
+ // - rapid updating `getData()` calls to attach data in response to user input (eg for edge detection)
1350
+ // Sadly we cannot schedule inspecting changes resulting from this event
1351
+ // we need to be able to conditionally cancel the event with `event.preventDefault()`
1352
+ // to enable the correct native drop experience.
1353
+
1354
+ // 1. check to see if anything has changed
1355
+ onUpdateEvent(event);
1356
+
1357
+ // 2. let consumers know a move has occurred
1358
+ // This will include the latest 'input' values
1359
+ dispatch.drag({
1360
+ current: state.current
1361
+ });
1362
+ }
1363
+ }, {
1364
+ type: 'dragenter',
1365
+ listener: onUpdateEvent
1366
+ }, {
1367
+ type: 'dragleave',
1368
+ listener: function listener(event) {
1369
+ if (!isLeavingWindow({
1370
+ dragLeave: event
1371
+ })) {
1372
+ return;
1373
+ }
1374
+
1375
+ /**
1376
+ * At this point we don't know if a drag is being cancelled,
1377
+ * or if a drag is leaving the `window`.
1378
+ *
1379
+ * Both have:
1380
+ * 1. "dragleave" (with `relatedTarget: null`)
1381
+ * 2. "dragend" (a "dragend" can occur when outside the `window`)
1382
+ *
1383
+ * **Clearing drop targets**
1384
+ *
1385
+ * For either case we are clearing the the drop targets
1386
+ *
1387
+ * - cancelling: we clear drop targets in `"dragend"` anyway
1388
+ * - leaving the `window`: we clear the drop targets (to clear stickiness)
1389
+ *
1390
+ * **Leaving the window and finishing the drag**
1391
+ *
1392
+ * _internal drags_
1393
+ *
1394
+ * - The drag continues when the user is outside the `window`
1395
+ * and can resume if the user drags back over the `window`,
1396
+ * or end when the user drops in an external `window`.
1397
+ * - We will get a `"dragend"`, or we can listen for other
1398
+ * events to determine the drag is finished when the user re-enters the `window`).
1399
+ *
1400
+ * _external drags_
1401
+ *
1402
+ * - We conclude the drag operation.
1403
+ * - We have no idea if the user will drag back over the `window`,
1404
+ * or if the drag ends elsewhere.
1405
+ * - We will create a new drag if the user re-enters the `window`.
1406
+ *
1407
+ * **Not updating `input`**
1408
+ *
1409
+ * 🐛 Bug[Chrome] the final `"dragleave"` has default input values (eg `clientX == 0`)
1410
+ * Workaround: intentionally not updating `input` in "dragleave"
1411
+ * rather than the users current input values
1412
+ * - [Conversation](https://twitter.com/alexandereardon/status/1642697633864241152)
1413
+ * - [Bug](https://bugs.chromium.org/p/chromium/issues/detail?id=1429937)
1414
+ **/
1415
+
1416
+ updateState({
1417
+ input: state.current.input,
1418
+ dropTargets: []
1419
+ });
1420
+ if (dragType.startedFrom === 'external') {
1421
+ cancel();
1422
+ }
1423
+ }
1424
+ }, {
1425
+ // A "drop" can only happen if the browser allowed the drop
1426
+ type: 'drop',
1427
+ listener: function listener(event) {
1428
+ // Capture the final input.
1429
+ // We are capturing the final `input` for the
1430
+ // most accurate honey pot experience
1431
+ state.current = {
1432
+ dropTargets: state.current.dropTargets,
1433
+ input: getInput(event)
1434
+ };
1435
+
1436
+ /** If there are no drop targets, then we will get
1437
+ * a "drop" event if:
1438
+ * - `preventUnhandled()` is being used
1439
+ * - there is an unmanaged drop target (eg another library)
1440
+ * In these cases, it's up to the consumer
1441
+ * to handle the drop if it's not over one of our drop targets
1442
+ * - `preventUnhandled()` will cancel the "drop"
1443
+ * - unmanaged drop targets can handle the "drop" how they want to
1444
+ * We won't call `event.preventDefault()` in this call path */
1445
+
1446
+ if (!state.current.dropTargets.length) {
1447
+ cancel();
1448
+ return;
1449
+ }
1450
+ event.preventDefault();
1451
+
1452
+ // applying the latest drop effect to the event
1453
+ setDropEffectOnEvent({
1454
+ event: event,
1455
+ current: state.current.dropTargets
1456
+ });
1457
+ dispatch.drop({
1458
+ current: state.current,
1459
+ // When dropping something native, we need to extract the latest
1460
+ // `.items` from the "drop" event as it is now accessible
1461
+ updatedSourcePayload: dragType.type === 'external' ? dragType.getDropPayload(event) : null
1462
+ });
1463
+ finish();
1464
+ }
1465
+ }, {
1466
+ // "dragend" fires when on the drag source (eg a draggable element)
1467
+ // when the drag is finished.
1468
+ // "dragend" will fire after "drop" (if there was a successful drop)
1469
+ // "dragend" does not fire if the draggable source has been removed during the drag
1470
+ // or for external drag sources (eg files)
1471
+
1472
+ // This "dragend" listener will not fire if there was a successful drop
1473
+ // as we will have already removed the event listener
1474
+
1475
+ type: 'dragend',
1476
+ listener: function listener(event) {
1477
+ // In firefox, the position of the "dragend" event can
1478
+ // be a bit different to the last "dragover" event.
1479
+ // Updating the input so we can get the best possible
1480
+ // information for the honey pot.
1481
+ state.current = {
1482
+ dropTargets: state.current.dropTargets,
1483
+ input: getInput(event)
1484
+ };
1485
+ cancel();
1486
+ }
1487
+ }].concat(_toConsumableArray(getBindingsForBrokenDrags({
1488
+ onDragEnd: cancel
1489
+ }))),
1490
+ // Once we have started a managed drag operation it is important that we see / own all drag events
1491
+ // We got one adoption bug pop up where some code was stopping (`event.stopPropagation()`)
1492
+ // all "drop" events in the bubble phase on the `document.body`.
1493
+ // This meant that we never saw the "drop" event.
1494
+ {
1495
+ capture: true
1496
+ });
1497
+ dispatch.start({
1498
+ nativeSetDragImage: getNativeSetDragImage(event)
1499
+ });
1500
+ }
1501
+ function setDropEffectOnEvent(_ref3) {
1502
+ var _current$;
1503
+ var event = _ref3.event,
1504
+ current = _ref3.current;
1505
+ // setting the `dropEffect` to be the innerMost drop targets dropEffect
1506
+ var innerMost = (_current$ = current[0]) === null || _current$ === void 0 ? void 0 : _current$.dropEffect;
1507
+ if (innerMost != null && event.dataTransfer) {
1508
+ event.dataTransfer.dropEffect = innerMost;
1509
+ }
1510
+ }
1511
+ function getStartLocation(_ref4) {
1512
+ var event = _ref4.event,
1513
+ dragType = _ref4.dragType,
1514
+ getDropTargetsOver = _ref4.getDropTargetsOver;
1515
+ var input = getInput(event);
1516
+
1517
+ // When dragging from outside of the browser,
1518
+ // the drag is not being sourced from any local drop targets
1519
+ if (dragType.startedFrom === 'external') {
1520
+ return {
1521
+ input: input,
1522
+ dropTargets: []
1523
+ };
1524
+ }
1525
+ var dropTargets = getDropTargetsOver({
1526
+ input: input,
1527
+ source: dragType.payload,
1528
+ target: event.target,
1529
+ current: []
1530
+ });
1531
+ return {
1532
+ input: input,
1533
+ dropTargets: dropTargets
1534
+ };
1535
+ }
1536
+ var lifecycle = {
1537
+ canStart: canStart,
1538
+ start: start
1539
+ };
1540
+
1541
+ // Extending `Map` to allow us to link Key and Values together
1542
+
1543
+ var ledger = new Map();
1544
+ function registerUsage(_ref) {
1545
+ var typeKey = _ref.typeKey,
1546
+ mount = _ref.mount;
1547
+ var entry = ledger.get(typeKey);
1548
+ if (entry) {
1549
+ entry.usageCount++;
1550
+ return entry;
1551
+ }
1552
+ var initial = {
1553
+ typeKey: typeKey,
1554
+ unmount: mount(),
1555
+ usageCount: 1
1556
+ };
1557
+ ledger.set(typeKey, initial);
1558
+ return initial;
1559
+ }
1560
+ function register(args) {
1561
+ var entry = registerUsage(args);
1562
+ return function unregister() {
1563
+ entry.usageCount--;
1564
+ if (entry.usageCount > 0) {
1565
+ return;
1566
+ }
1567
+ // Only a single usage left, remove it
1568
+ entry.unmount();
1569
+ ledger.delete(args.typeKey);
1570
+ };
1571
+ }
1572
+
1573
+ /** Create a new combined function that will call all the provided functions */
1574
+ function combine() {
1575
+ for (var _len = arguments.length, fns = new Array(_len), _key = 0; _key < _len; _key++) {
1576
+ fns[_key] = arguments[_key];
1577
+ }
1578
+ return function cleanup() {
1579
+ fns.forEach(function (fn) {
1580
+ return fn();
1581
+ });
1582
+ };
1583
+ }
1584
+
1585
+ function addAttribute(element, _ref) {
1586
+ var attribute = _ref.attribute,
1587
+ value = _ref.value;
1588
+ element.setAttribute(attribute, value);
1589
+ return function () {
1590
+ return element.removeAttribute(attribute);
1591
+ };
1592
+ }
1593
+
1594
+ function ownKeys$1(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
1595
+ function _objectSpread$1(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$1(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$1(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
1596
+ function _createForOfIteratorHelper$1(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$1(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
1597
+ function _unsupportedIterableToArray$1(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$1(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray$1(r, a) : void 0; } }
1598
+ function _arrayLikeToArray$1(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
1599
+ function copyReverse(array) {
1600
+ return array.slice(0).reverse();
1601
+ }
1602
+ function makeDropTarget(_ref) {
1603
+ var typeKey = _ref.typeKey,
1604
+ defaultDropEffect = _ref.defaultDropEffect;
1605
+ var registry = new WeakMap();
1606
+ var dropTargetDataAtt = "data-drop-target-for-".concat(typeKey);
1607
+ var dropTargetSelector = "[".concat(dropTargetDataAtt, "]");
1608
+ function addToRegistry(args) {
1609
+ registry.set(args.element, args);
1610
+ return function () {
1611
+ return registry.delete(args.element);
1612
+ };
1613
+ }
1614
+ function dropTargetForConsumers(args) {
1615
+ // Guardrail: warn if the draggable element is already registered
1616
+ if (process.env.NODE_ENV !== 'production') {
1617
+ var existing = registry.get(args.element);
1618
+ if (existing) {
1619
+ // eslint-disable-next-line no-console
1620
+ console.warn("You have already registered a [".concat(typeKey, "] dropTarget on the same element"), {
1621
+ existing: existing,
1622
+ proposed: args
1623
+ });
1624
+ }
1625
+ if (args.element instanceof HTMLIFrameElement) {
1626
+ // eslint-disable-next-line no-console
1627
+ console.warn("\n We recommend not registering <iframe> elements as drop targets\n as it can result in some strange browser event ordering.\n " // Removing newlines and excessive whitespace
1628
+ .replace(/\s{2,}/g, ' ').trim());
1629
+ }
1630
+ }
1631
+ return combine(addAttribute(args.element, {
1632
+ attribute: dropTargetDataAtt,
1633
+ value: 'true'
1634
+ }), addToRegistry(args));
1635
+ }
1636
+ function getActualDropTargets(_ref2) {
1637
+ var _args$getData, _args$getData2, _args$getDropEffect, _args$getDropEffect2;
1638
+ var source = _ref2.source,
1639
+ target = _ref2.target,
1640
+ input = _ref2.input,
1641
+ _ref2$result = _ref2.result,
1642
+ result = _ref2$result === void 0 ? [] : _ref2$result;
1643
+ if (target == null) {
1644
+ return result;
1645
+ }
1646
+ if (!(target instanceof Element)) {
1647
+ // For "text-selection" drags, the original `target`
1648
+ // is not an `Element`, so we need to start looking from
1649
+ // the parent element
1650
+ if (target instanceof Node) {
1651
+ return getActualDropTargets({
1652
+ source: source,
1653
+ target: target.parentElement,
1654
+ input: input,
1655
+ result: result
1656
+ });
1657
+ }
1658
+
1659
+ // not sure what we are working with,
1660
+ // so we can exit.
1661
+ return result;
1662
+ }
1663
+ var closest = target.closest(dropTargetSelector);
1664
+
1665
+ // Cannot find anything else
1666
+ if (closest == null) {
1667
+ return result;
1668
+ }
1669
+ var args = registry.get(closest);
1670
+
1671
+ // error: something had a dropTargetSelector but we could not
1672
+ // find a match. For now, failing silently
1673
+ if (args == null) {
1674
+ return result;
1675
+ }
1676
+ var feedback = {
1677
+ input: input,
1678
+ source: source,
1679
+ element: args.element
1680
+ };
1681
+
1682
+ // if dropping is not allowed, skip this drop target
1683
+ // and continue looking up the DOM tree
1684
+ if (args.canDrop && !args.canDrop(feedback)) {
1685
+ return getActualDropTargets({
1686
+ source: source,
1687
+ target: args.element.parentElement,
1688
+ input: input,
1689
+ result: result
1690
+ });
1691
+ }
1692
+
1693
+ // calculate our new record
1694
+ var data = (_args$getData = (_args$getData2 = args.getData) === null || _args$getData2 === void 0 ? void 0 : _args$getData2.call(args, feedback)) !== null && _args$getData !== void 0 ? _args$getData : {};
1695
+ var dropEffect = (_args$getDropEffect = (_args$getDropEffect2 = args.getDropEffect) === null || _args$getDropEffect2 === void 0 ? void 0 : _args$getDropEffect2.call(args, feedback)) !== null && _args$getDropEffect !== void 0 ? _args$getDropEffect : defaultDropEffect;
1696
+ var record = {
1697
+ data: data,
1698
+ element: args.element,
1699
+ dropEffect: dropEffect,
1700
+ // we are collecting _actual_ drop targets, so these are
1701
+ // being applied _not_ due to stickiness
1702
+ isActiveDueToStickiness: false
1703
+ };
1704
+ return getActualDropTargets({
1705
+ source: source,
1706
+ target: args.element.parentElement,
1707
+ input: input,
1708
+ // Using bubble ordering. Same ordering as `event.getPath()`
1709
+ result: [].concat(_toConsumableArray(result), [record])
1710
+ });
1711
+ }
1712
+ function notifyCurrent(_ref3) {
1713
+ var eventName = _ref3.eventName,
1714
+ payload = _ref3.payload;
1715
+ var _iterator = _createForOfIteratorHelper$1(payload.location.current.dropTargets),
1716
+ _step;
1717
+ try {
1718
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
1719
+ var _entry$eventName;
1720
+ var record = _step.value;
1721
+ var entry = registry.get(record.element);
1722
+ var args = _objectSpread$1(_objectSpread$1({}, payload), {}, {
1723
+ self: record
1724
+ });
1725
+ entry === null || entry === void 0 || (_entry$eventName = entry[eventName]) === null || _entry$eventName === void 0 || _entry$eventName.call(entry,
1726
+ // I cannot seem to get the types right here.
1727
+ // TS doesn't seem to like that one event can need `nativeSetDragImage`
1728
+ // @ts-expect-error
1729
+ args);
1730
+ }
1731
+ } catch (err) {
1732
+ _iterator.e(err);
1733
+ } finally {
1734
+ _iterator.f();
1735
+ }
1736
+ }
1737
+ var actions = {
1738
+ onGenerateDragPreview: notifyCurrent,
1739
+ onDrag: notifyCurrent,
1740
+ onDragStart: notifyCurrent,
1741
+ onDrop: notifyCurrent,
1742
+ onDropTargetChange: function onDropTargetChange(_ref4) {
1743
+ var payload = _ref4.payload;
1744
+ var isCurrent = new Set(payload.location.current.dropTargets.map(function (record) {
1745
+ return record.element;
1746
+ }));
1747
+ var visited = new Set();
1748
+ var _iterator2 = _createForOfIteratorHelper$1(payload.location.previous.dropTargets),
1749
+ _step2;
1750
+ try {
1751
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
1752
+ var _entry$onDropTargetCh;
1753
+ var record = _step2.value;
1754
+ visited.add(record.element);
1755
+ var entry = registry.get(record.element);
1756
+ var isOver = isCurrent.has(record.element);
1757
+ var args = _objectSpread$1(_objectSpread$1({}, payload), {}, {
1758
+ self: record
1759
+ });
1760
+ entry === null || entry === void 0 || (_entry$onDropTargetCh = entry.onDropTargetChange) === null || _entry$onDropTargetCh === void 0 || _entry$onDropTargetCh.call(entry, args);
1761
+
1762
+ // if we cannot find the drop target in the current array, then it has been left
1763
+ if (!isOver) {
1764
+ var _entry$onDragLeave;
1765
+ entry === null || entry === void 0 || (_entry$onDragLeave = entry.onDragLeave) === null || _entry$onDragLeave === void 0 || _entry$onDragLeave.call(entry, args);
1766
+ }
1767
+ }
1768
+ } catch (err) {
1769
+ _iterator2.e(err);
1770
+ } finally {
1771
+ _iterator2.f();
1772
+ }
1773
+ var _iterator3 = _createForOfIteratorHelper$1(payload.location.current.dropTargets),
1774
+ _step3;
1775
+ try {
1776
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
1777
+ var _entry$onDropTargetCh2, _entry$onDragEnter;
1778
+ var _record = _step3.value;
1779
+ // already published an update to this drop target
1780
+ if (visited.has(_record.element)) {
1781
+ continue;
1782
+ }
1783
+ // at this point we have a new drop target that is being entered into
1784
+ var _args = _objectSpread$1(_objectSpread$1({}, payload), {}, {
1785
+ self: _record
1786
+ });
1787
+ var _entry = registry.get(_record.element);
1788
+ _entry === null || _entry === void 0 || (_entry$onDropTargetCh2 = _entry.onDropTargetChange) === null || _entry$onDropTargetCh2 === void 0 || _entry$onDropTargetCh2.call(_entry, _args);
1789
+ _entry === null || _entry === void 0 || (_entry$onDragEnter = _entry.onDragEnter) === null || _entry$onDragEnter === void 0 || _entry$onDragEnter.call(_entry, _args);
1790
+ }
1791
+ } catch (err) {
1792
+ _iterator3.e(err);
1793
+ } finally {
1794
+ _iterator3.f();
1795
+ }
1796
+ }
1797
+ };
1798
+ function dispatchEvent(args) {
1799
+ actions[args.eventName](args);
1800
+ }
1801
+ function getIsOver(_ref5) {
1802
+ var source = _ref5.source,
1803
+ target = _ref5.target,
1804
+ input = _ref5.input,
1805
+ current = _ref5.current;
1806
+ var actual = getActualDropTargets({
1807
+ source: source,
1808
+ target: target,
1809
+ input: input
1810
+ });
1811
+
1812
+ // stickiness is only relevant when we have less
1813
+ // drop targets than we did before
1814
+ if (actual.length >= current.length) {
1815
+ return actual;
1816
+ }
1817
+
1818
+ // less 'actual' drop targets than before,
1819
+ // we need to see if 'stickiness' applies
1820
+
1821
+ // An old drop target will continue to be dropped on if:
1822
+ // 1. it has the same parent
1823
+ // 2. nothing exists in it's previous index
1824
+
1825
+ var lastCaptureOrdered = copyReverse(current);
1826
+ var actualCaptureOrdered = copyReverse(actual);
1827
+ var resultCaptureOrdered = [];
1828
+ for (var index = 0; index < lastCaptureOrdered.length; index++) {
1829
+ var _argsForLast$getIsSti;
1830
+ var last = lastCaptureOrdered[index];
1831
+ var fresh = actualCaptureOrdered[index];
1832
+
1833
+ // if a record is in the new index -> use that
1834
+ // it will have the latest data + dropEffect
1835
+ if (fresh != null) {
1836
+ resultCaptureOrdered.push(fresh);
1837
+ continue;
1838
+ }
1839
+
1840
+ // At this point we have no drop target in the old spot
1841
+ // Check to see if we can use a previous sticky drop target
1842
+
1843
+ // The "parent" is the one inside of `resultCaptureOrdered`
1844
+ // (the parent might be a drop target that was sticky)
1845
+ var parent = resultCaptureOrdered[index - 1];
1846
+ var lastParent = lastCaptureOrdered[index - 1];
1847
+
1848
+ // Stickiness is based on parent relationships, so if the parent relationship has change
1849
+ // then we can stop our search
1850
+ if ((parent === null || parent === void 0 ? void 0 : parent.element) !== (lastParent === null || lastParent === void 0 ? void 0 : lastParent.element)) {
1851
+ break;
1852
+ }
1853
+
1854
+ // We need to check whether the old drop target can still be dropped on
1855
+
1856
+ var argsForLast = registry.get(last.element);
1857
+
1858
+ // We cannot drop on a drop target that is no longer mounted
1859
+ if (!argsForLast) {
1860
+ break;
1861
+ }
1862
+ var feedback = {
1863
+ input: input,
1864
+ source: source,
1865
+ element: argsForLast.element
1866
+ };
1867
+
1868
+ // We cannot drop on a drop target that no longer allows being dropped on
1869
+ if (argsForLast.canDrop && !argsForLast.canDrop(feedback)) {
1870
+ break;
1871
+ }
1872
+
1873
+ // We cannot drop on a drop target that is no longer sticky
1874
+ if (!((_argsForLast$getIsSti = argsForLast.getIsSticky) !== null && _argsForLast$getIsSti !== void 0 && _argsForLast$getIsSti.call(argsForLast, feedback))) {
1875
+ break;
1876
+ }
1877
+
1878
+ // Note: intentionally not recollecting `getData()` or `getDropEffect()`
1879
+ // Previous values for `data` and `dropEffect` will be borrowed
1880
+ // This is to prevent things like the 'closest edge' changing when
1881
+ // no longer over a drop target.
1882
+ // We could change our mind on this behaviour in the future
1883
+
1884
+ resultCaptureOrdered.push(_objectSpread$1(_objectSpread$1({}, last), {}, {
1885
+ // making it clear to consumers this drop target is active due to stickiness
1886
+ isActiveDueToStickiness: true
1887
+ }));
1888
+ }
1889
+
1890
+ // return bubble ordered result
1891
+ return copyReverse(resultCaptureOrdered);
1892
+ }
1893
+ return {
1894
+ dropTargetForConsumers: dropTargetForConsumers,
1895
+ getIsOver: getIsOver,
1896
+ dispatchEvent: dispatchEvent
1897
+ };
1898
+ }
1899
+
1900
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
1901
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
1902
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
1903
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
1904
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
1905
+ function makeMonitor() {
1906
+ var registry = new Set();
1907
+ var dragging = null;
1908
+ function tryAddToActive(monitor) {
1909
+ if (!dragging) {
1910
+ return;
1911
+ }
1912
+ // Monitor is allowed to monitor events if:
1913
+ // 1. It has no `canMonitor` function (default is that a monitor can listen to everything)
1914
+ // 2. `canMonitor` returns true
1915
+ if (!monitor.canMonitor || monitor.canMonitor(dragging.canMonitorArgs)) {
1916
+ dragging.active.add(monitor);
1917
+ }
1918
+ }
1919
+ function monitorForConsumers(args) {
1920
+ // We are giving each `args` a new reference so that you
1921
+ // can create multiple monitors with the same `args`.
1922
+ var entry = _objectSpread({}, args);
1923
+ registry.add(entry);
1924
+
1925
+ // if there is an active drag we need to see if this new monitor is relevant
1926
+ tryAddToActive(entry);
1927
+ return function cleanup() {
1928
+ registry.delete(entry);
1929
+
1930
+ // We need to stop publishing events during a drag to this monitor!
1931
+ if (dragging) {
1932
+ dragging.active.delete(entry);
1933
+ }
1934
+ };
1935
+ }
1936
+ function dispatchEvent(_ref) {
1937
+ var eventName = _ref.eventName,
1938
+ payload = _ref.payload;
1939
+ if (eventName === 'onGenerateDragPreview') {
1940
+ dragging = {
1941
+ canMonitorArgs: {
1942
+ initial: payload.location.initial,
1943
+ source: payload.source
1944
+ },
1945
+ active: new Set()
1946
+ };
1947
+ var _iterator = _createForOfIteratorHelper(registry),
1948
+ _step;
1949
+ try {
1950
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
1951
+ var monitor = _step.value;
1952
+ tryAddToActive(monitor);
1953
+ }
1954
+ } catch (err) {
1955
+ _iterator.e(err);
1956
+ } finally {
1957
+ _iterator.f();
1958
+ }
1959
+ }
1960
+
1961
+ // This should never happen.
1962
+ if (!dragging) {
1963
+ return;
1964
+ }
1965
+
1966
+ // Creating an array from the set _before_ iterating
1967
+ // This is so that monitors added during the current event will not be called.
1968
+ // This behaviour matches native EventTargets where an event listener
1969
+ // cannot add another event listener during an active event to the same
1970
+ // event target in the same event (for us we have a single global event target)
1971
+ var active = Array.from(dragging.active);
1972
+ for (var _i = 0, _active = active; _i < _active.length; _i++) {
1973
+ var _monitor = _active[_i];
1974
+ // A monitor can be removed by another monitor during an event.
1975
+ // We need to check that the monitor is still registered before calling it
1976
+ if (dragging.active.has(_monitor)) {
1977
+ var _monitor$eventName;
1978
+ // @ts-expect-error: I cannot get this type working!
1979
+ (_monitor$eventName = _monitor[eventName]) === null || _monitor$eventName === void 0 || _monitor$eventName.call(_monitor, payload);
1980
+ }
1981
+ }
1982
+ if (eventName === 'onDrop') {
1983
+ dragging.active.clear();
1984
+ dragging = null;
1985
+ }
1986
+ }
1987
+ return {
1988
+ dispatchEvent: dispatchEvent,
1989
+ monitorForConsumers: monitorForConsumers
1990
+ };
1991
+ }
1992
+
1993
+ function makeAdapter(_ref) {
1994
+ var typeKey = _ref.typeKey,
1995
+ mount = _ref.mount,
1996
+ dispatchEventToSource = _ref.dispatchEventToSource,
1997
+ onPostDispatch = _ref.onPostDispatch,
1998
+ defaultDropEffect = _ref.defaultDropEffect;
1999
+ var monitorAPI = makeMonitor();
2000
+ var dropTargetAPI = makeDropTarget({
2001
+ typeKey: typeKey,
2002
+ defaultDropEffect: defaultDropEffect
2003
+ });
2004
+ function dispatchEvent(args) {
2005
+ // 1. forward the event to source
2006
+ dispatchEventToSource === null || dispatchEventToSource === void 0 || dispatchEventToSource(args);
2007
+
2008
+ // 2. forward the event to relevant dropTargets
2009
+ dropTargetAPI.dispatchEvent(args);
2010
+
2011
+ // 3. forward event to monitors
2012
+ monitorAPI.dispatchEvent(args);
2013
+
2014
+ // 4. post consumer dispatch (used for honey pot fix)
2015
+ onPostDispatch === null || onPostDispatch === void 0 || onPostDispatch(args);
2016
+ }
2017
+ function start(_ref2) {
2018
+ var event = _ref2.event,
2019
+ dragType = _ref2.dragType;
2020
+ lifecycle.start({
2021
+ event: event,
2022
+ dragType: dragType,
2023
+ getDropTargetsOver: dropTargetAPI.getIsOver,
2024
+ dispatchEvent: dispatchEvent
2025
+ });
2026
+ }
2027
+ function registerUsage() {
2028
+ function mountAdapter() {
2029
+ var api = {
2030
+ canStart: lifecycle.canStart,
2031
+ start: start
2032
+ };
2033
+ return mount(api);
2034
+ }
2035
+ return register({
2036
+ typeKey: typeKey,
2037
+ mount: mountAdapter
2038
+ });
2039
+ }
2040
+ return {
2041
+ registerUsage: registerUsage,
2042
+ dropTarget: dropTargetAPI.dropTargetForConsumers,
2043
+ monitor: monitorAPI.monitorForConsumers
2044
+ };
2045
+ }
2046
+
2047
+ // using `cache` as our `isAndroid()` result will not change in a browser
2048
+ var isAndroid = once(function isAndroid() {
2049
+ return navigator.userAgent.toLocaleLowerCase().includes('android');
2050
+ });
2051
+ var androidFallbackText = 'pdnd:android-fallback';
2052
+
2053
+ // Why we put the media types in their own files:
2054
+ //
2055
+ // - we are not putting them all in one file as not all adapters need all types
2056
+ // - we are not putting them in the external helpers as some things just need the
2057
+ // types and not the external functions code
2058
+ var textMediaType = 'text/plain';
2059
+
2060
+ // Why we put the media types in their own files:
2061
+ //
2062
+ // - we are not putting them all in one file as not all adapters need all types
2063
+ // - we are not putting them in the external helpers as some things just need the
2064
+ // types and not the external functions code
2065
+ var URLMediaType = 'text/uri-list';
2066
+
2067
+ /**
2068
+ * This key has been pulled into a separate module
2069
+ * so that the external adapter does not need to import
2070
+ * the element adapter
2071
+ */
2072
+ var elementAdapterNativeDataKey = 'application/vnd.pdnd';
2073
+
2074
+ var draggableRegistry = new WeakMap();
2075
+ function addToRegistry(args) {
2076
+ draggableRegistry.set(args.element, args);
2077
+ return function cleanup() {
2078
+ draggableRegistry.delete(args.element);
2079
+ };
2080
+ }
2081
+ var honeyPotFix = makeHoneyPotFix();
2082
+ var adapter$1 = makeAdapter({
2083
+ typeKey: 'element',
2084
+ defaultDropEffect: 'move',
2085
+ mount: function mount(api) {
2086
+ /** Binding event listeners the `document` rather than `window` so that
2087
+ * this adapter always gets preference over the text adapter.
2088
+ * `document` is the first `EventTarget` under `window`
2089
+ * https://twitter.com/alexandereardon/status/1604658588311465985
2090
+ */
2091
+ return combine(honeyPotFix.bindEvents(), bindEventListener.bind(document, {
2092
+ type: 'dragstart',
2093
+ listener: function listener(event) {
2094
+ var _entry$dragHandle, _entry$getInitialData, _entry$getInitialData2, _entry$dragHandle2, _entry$getInitialData3, _entry$getInitialData4;
2095
+ if (!api.canStart(event)) {
2096
+ return;
2097
+ }
2098
+
2099
+ // If the "dragstart" event is cancelled, then a drag won't start
2100
+ // There will be no further drag operation events (eg no "dragend" event)
2101
+ if (event.defaultPrevented) {
2102
+ return;
2103
+ }
2104
+
2105
+ // Technically `dataTransfer` can be `null` according to the types
2106
+ // But that behaviour does not seem to appear in the spec.
2107
+ // If there is not `dataTransfer`, we can assume something is wrong and not
2108
+ // start a drag
2109
+ if (!event.dataTransfer) {
2110
+ // Including this code on "test" and "development" environments:
2111
+ // - Browser tests commonly run against "development" builds
2112
+ // - Unit tests commonly run in "test"
2113
+ if (process.env.NODE_ENV !== 'production') {
2114
+ // eslint-disable-next-line no-console
2115
+ console.warn("\n It appears as though you have are not testing DragEvents correctly.\n\n - If you are unit testing, ensure you have polyfilled DragEvent.\n - If you are browser testing, ensure you are dispatching drag events correctly.\n\n Please see our testing guides for more information:\n https://atlassian.design/components/pragmatic-drag-and-drop/core-package/testing\n ".replace(/ {2}/g, ''));
2116
+ }
2117
+ return;
2118
+ }
2119
+
2120
+ // the closest parent that is a draggable element will be marked as
2121
+ // the `event.target` for the event
2122
+ var target = event.target;
2123
+
2124
+ // this source is only for elements
2125
+ // Note: only HTMLElements can have the "draggable" attribute
2126
+ if (!(target instanceof HTMLElement)) {
2127
+ return null;
2128
+ }
2129
+
2130
+ // see if the thing being dragged is owned by us
2131
+ var entry = draggableRegistry.get(target);
2132
+
2133
+ // no matching element found
2134
+ // → dragging an element with `draggable="true"` that is not controlled by us
2135
+ if (!entry) {
2136
+ return null;
2137
+ }
2138
+
2139
+ /**
2140
+ * A text selection drag _can_ have the `draggable` element be
2141
+ * the `event.target` if the user is dragging the text selection
2142
+ * from the `draggable`.
2143
+ *
2144
+ * To know if the `draggable` is being dragged, we look at whether any
2145
+ * `"text/plain"` data is being dragged. If it is, then a text selection
2146
+ * drag is occurring.
2147
+ *
2148
+ * This behaviour has been validated on:
2149
+ *
2150
+ * - Chrome@128 on Android@14
2151
+ * - Chrome@128 on iOS@17.6.1
2152
+ * - Chrome@128 on Windows@11
2153
+ * - Chrome@128 on MacOS@14.6.1
2154
+ * - Firefox@129 on Windows@11 (not possible for user to select text in a draggable)
2155
+ * - Firefox@129 on MacOS@14.6.1 (not possible for user to select text in a draggable)
2156
+ *
2157
+ * Note: Could usually just use: `event.dataTransfer.types.includes(textMediaType)`
2158
+ * but unfortunately ProseMirror is always setting `""` as the dragged text
2159
+ *
2160
+ * Note: Unfortunately editor is (heavily) leaning on the current functionality today
2161
+ * and unwinding it will be a decent amount of effort. So for now, a text selection
2162
+ * where the `event.target` is a `draggable` element will still trigger the
2163
+ * element adapter.
2164
+ *
2165
+ * // Future state:
2166
+ * if(event.dataTransfer.getData(textMediaType)) {
2167
+ * return;
2168
+ * }
2169
+ *
2170
+ */
2171
+
2172
+ var input = getInput(event);
2173
+ var feedback = {
2174
+ element: entry.element,
2175
+ dragHandle: (_entry$dragHandle = entry.dragHandle) !== null && _entry$dragHandle !== void 0 ? _entry$dragHandle : null,
2176
+ input: input
2177
+ };
2178
+
2179
+ // Check: does the draggable want to allow dragging?
2180
+ if (entry.canDrag && !entry.canDrag(feedback)) {
2181
+ // cancel drag operation if we cannot drag
2182
+ event.preventDefault();
2183
+ return null;
2184
+ }
2185
+
2186
+ // Check: is there a drag handle and is the user using it?
2187
+ if (entry.dragHandle) {
2188
+ // technically don't need this util, but just being
2189
+ // consistent with how we look up what is under the users
2190
+ // cursor.
2191
+ var over = getElementFromPointWithoutHoneypot({
2192
+ x: input.clientX,
2193
+ y: input.clientY
2194
+ });
2195
+
2196
+ // if we are not dragging from the drag handle (or something inside the drag handle)
2197
+ // then we will cancel the active drag
2198
+ if (!entry.dragHandle.contains(over)) {
2199
+ event.preventDefault();
2200
+ return null;
2201
+ }
2202
+ }
2203
+
2204
+ /**
2205
+ * **Goal**
2206
+ * Pass information to other applications
2207
+ *
2208
+ * **Approach**
2209
+ * Put data into the native data store
2210
+ *
2211
+ * **What about the native adapter?**
2212
+ * When the element adapter puts native data into the native data store
2213
+ * the native adapter is not triggered in the current window,
2214
+ * but a native adapter in an external window _can_ be triggered
2215
+ *
2216
+ * **Why bake this into core?**
2217
+ * This functionality could be pulled out and exposed inside of
2218
+ * `onGenerateDragPreview`. But decided to make it a part of the
2219
+ * base API as it felt like a common enough use case and ended
2220
+ * up being a similar amount of code to include this function as
2221
+ * it was to expose the hook for it
2222
+ */
2223
+ var nativeData = (_entry$getInitialData = (_entry$getInitialData2 = entry.getInitialDataForExternal) === null || _entry$getInitialData2 === void 0 ? void 0 : _entry$getInitialData2.call(entry, feedback)) !== null && _entry$getInitialData !== void 0 ? _entry$getInitialData : null;
2224
+ if (nativeData) {
2225
+ for (var _i = 0, _Object$entries = Object.entries(nativeData); _i < _Object$entries.length; _i++) {
2226
+ var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
2227
+ key = _Object$entries$_i[0],
2228
+ data = _Object$entries$_i[1];
2229
+ event.dataTransfer.setData(key, data !== null && data !== void 0 ? data : '');
2230
+ }
2231
+ }
2232
+
2233
+ /**
2234
+ * 📱 For Android devices, a drag operation will not start unless
2235
+ * "text/plain" or "text/uri-list" data exists in the native data store
2236
+ * https://twitter.com/alexandereardon/status/1732189803754713424
2237
+ *
2238
+ * Tested on:
2239
+ * Device: Google Pixel 5
2240
+ * Android version: 14 (November 5, 2023)
2241
+ * Chrome version: 120.0
2242
+ */
2243
+ if (isAndroid() && !event.dataTransfer.types.includes(textMediaType) && !event.dataTransfer.types.includes(URLMediaType)) {
2244
+ event.dataTransfer.setData(textMediaType, androidFallbackText);
2245
+ }
2246
+
2247
+ /**
2248
+ * 1. Must set any media type for `iOS15` to work
2249
+ * 2. We are also doing adding data so that the native adapter
2250
+ * can know that the element adapter has handled this drag
2251
+ *
2252
+ * We used to wrap this `setData()` in a `try/catch` for Firefox,
2253
+ * but it looks like that was not needed.
2254
+ *
2255
+ * Tested using: https://codesandbox.io/s/checking-firefox-throw-behaviour-on-dragstart-qt8h4f
2256
+ *
2257
+ * - ✅ Firefox@70.0 (Oct 2019) on macOS Sonoma
2258
+ * - ✅ Firefox@70.0 (Oct 2019) on macOS Big Sur
2259
+ * - ✅ Firefox@70.0 (Oct 2019) on Windows 10
2260
+ *
2261
+ * // just checking a few more combinations to be super safe
2262
+ *
2263
+ * - ✅ Chrome@78 (Oct 2019) on macOS Big Sur
2264
+ * - ✅ Chrome@78 (Oct 2019) on Windows 10
2265
+ * - ✅ Safari@14.1 on macOS Big Sur
2266
+ */
2267
+ event.dataTransfer.setData(elementAdapterNativeDataKey, '');
2268
+ var payload = {
2269
+ element: entry.element,
2270
+ dragHandle: (_entry$dragHandle2 = entry.dragHandle) !== null && _entry$dragHandle2 !== void 0 ? _entry$dragHandle2 : null,
2271
+ data: (_entry$getInitialData3 = (_entry$getInitialData4 = entry.getInitialData) === null || _entry$getInitialData4 === void 0 ? void 0 : _entry$getInitialData4.call(entry, feedback)) !== null && _entry$getInitialData3 !== void 0 ? _entry$getInitialData3 : {}
2272
+ };
2273
+ var dragType = {
2274
+ type: 'element',
2275
+ payload: payload,
2276
+ startedFrom: 'internal'
2277
+ };
2278
+ api.start({
2279
+ event: event,
2280
+ dragType: dragType
2281
+ });
2282
+ }
2283
+ }));
2284
+ },
2285
+ dispatchEventToSource: function dispatchEventToSource(_ref) {
2286
+ var _draggableRegistry$ge, _draggableRegistry$ge2;
2287
+ var eventName = _ref.eventName,
2288
+ payload = _ref.payload;
2289
+ // During a drag operation, a draggable can be:
2290
+ // - remounted with different functions
2291
+ // - removed completely
2292
+ // So we need to get the latest entry from the registry in order
2293
+ // to call the latest event functions
2294
+
2295
+ (_draggableRegistry$ge = draggableRegistry.get(payload.source.element)) === null || _draggableRegistry$ge === void 0 || (_draggableRegistry$ge2 = _draggableRegistry$ge[eventName]) === null || _draggableRegistry$ge2 === void 0 || _draggableRegistry$ge2.call(_draggableRegistry$ge,
2296
+ // I cannot seem to get the types right here.
2297
+ // TS doesn't seem to like that one event can need `nativeSetDragImage`
2298
+ // @ts-expect-error
2299
+ payload);
2300
+ },
2301
+ onPostDispatch: honeyPotFix.getOnPostDispatch()
2302
+ });
2303
+ var dropTargetForElements = adapter$1.dropTarget;
2304
+ var monitorForElements = adapter$1.monitor;
2305
+ function draggable(args) {
2306
+ // Guardrail: warn if the drag handle is not contained in draggable element
2307
+ if (process.env.NODE_ENV !== 'production') {
2308
+ if (args.dragHandle && !args.element.contains(args.dragHandle)) {
2309
+ // eslint-disable-next-line no-console
2310
+ console.warn('Drag handle element must be contained in draggable element', {
2311
+ element: args.element,
2312
+ dragHandle: args.dragHandle
2313
+ });
2314
+ }
2315
+ }
2316
+ // Guardrail: warn if the draggable element is already registered
2317
+ if (process.env.NODE_ENV !== 'production') {
2318
+ var existing = draggableRegistry.get(args.element);
2319
+ if (existing) {
2320
+ // eslint-disable-next-line no-console
2321
+ console.warn('You have already registered a `draggable` on the same element', {
2322
+ existing: existing,
2323
+ proposed: args
2324
+ });
2325
+ }
2326
+ }
2327
+ return combine(
2328
+ // making the draggable register the adapter rather than drop targets
2329
+ // this is because you *must* have a draggable element to start a drag
2330
+ // but you _might_ not have any drop targets immediately
2331
+ // (You might create drop targets async)
2332
+ adapter$1.registerUsage(), addToRegistry(args), addAttribute(args.element, {
2333
+ attribute: 'draggable',
2334
+ value: 'true'
2335
+ }));
2336
+ }
2337
+
2338
+ /** Common event payload for all events */
2339
+
2340
+ /** A map containing payloads for all events */
2341
+
2342
+ /** Common event payload for all drop target events */
2343
+
2344
+ /** A map containing payloads for all events on drop targets */
2345
+
2346
+ /** Arguments given to all feedback functions (eg `canDrag()`) on for a `draggable()` */
2347
+
2348
+ /** Arguments given to all feedback functions (eg `canDrop()`) on a `dropTargetForElements()` */
2349
+
2350
+ /** Arguments given to all monitor feedback functions (eg `canMonitor()`) for a `monitorForElements` */
2351
+
461
2352
  const CheckboxCard = React__namespace.forwardRef(function CheckboxCard(props, ref) {
462
2353
  const { inputProps, label, description, icon, addon, indicator = jsxRuntime.jsx(react.CheckboxCard.Indicator, {}), indicatorPlacement = "end", ...rest } = props;
463
2354
  const hasContent = label || description || icon;
@@ -476,7 +2367,7 @@ function ColumnCard({ columnId }) {
476
2367
  React.useEffect(() => {
477
2368
  const el = ref.current;
478
2369
  invariant(el);
479
- return adapter.draggable({
2370
+ return draggable({
480
2371
  element: el,
481
2372
  getInitialData: () => {
482
2373
  return { column: table.getColumn(columnId) };
@@ -493,7 +2384,7 @@ function CardContainer({ location, children }) {
493
2384
  React.useEffect(() => {
494
2385
  const el = ref.current;
495
2386
  invariant(el);
496
- return adapter.dropTargetForElements({
2387
+ return dropTargetForElements({
497
2388
  element: el,
498
2389
  getData: () => ({ location }),
499
2390
  onDragEnter: () => setIsDraggedOver(true),
@@ -527,7 +2418,7 @@ const TableViewer = () => {
527
2418
  return column.id;
528
2419
  }));
529
2420
  React.useEffect(() => {
530
- return adapter.monitorForElements({
2421
+ return monitorForElements({
531
2422
  onDrop({ source, location }) {
532
2423
  const destination = location.current.dropTargets[0];
533
2424
  if (!destination) {
@@ -2181,22 +4072,325 @@ const TagPicker = ({ column }) => {
2181
4072
  }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: (errors[`${column}`]?.message ?? "No error message") }))] }));
2182
4073
  };
2183
4074
 
4075
+ function isEnteringWindow(_ref) {
4076
+ var dragEnter = _ref.dragEnter;
4077
+ var type = dragEnter.type,
4078
+ relatedTarget = dragEnter.relatedTarget;
4079
+ if (type !== 'dragenter') {
4080
+ return false;
4081
+ }
4082
+ if (isSafari()) {
4083
+ return isEnteringWindowInSafari({
4084
+ dragEnter: dragEnter
4085
+ });
4086
+ }
4087
+
4088
+ // standard check
4089
+ if (relatedTarget == null) {
4090
+ return true;
4091
+ }
4092
+
4093
+ /**
4094
+ * 🦊 Exception: `iframe` in Firefox (`125.0`)
4095
+ *
4096
+ * Case 1: parent `window` → child `iframe`
4097
+ * `relatedTarget` is the `iframe` element in the parent `window`
4098
+ * (foreign element)
4099
+ *
4100
+ * Case 2: child `iframe` → parent `window`
4101
+ * `relatedTarget` is an element inside the child `iframe`
4102
+ * (foreign element)
4103
+ */
4104
+
4105
+ if (isFirefox()) {
4106
+ return isFromAnotherWindow(relatedTarget);
4107
+ }
4108
+
4109
+ /**
4110
+ * 🌏 Exception: `iframe` in Chrome (`124.0`)
4111
+ *
4112
+ * Case 1: parent `window` → child `iframe`
4113
+ * `relatedTarget` is `null` *(standard check)*
4114
+ *
4115
+ * Case 2: child `iframe` → parent `window`
4116
+ * `relatedTarget` is the `iframe` element in the parent `window`
4117
+ */
4118
+
4119
+ // Case 2
4120
+ // Using `instanceof` check as the element will be in the same `window`
4121
+ return relatedTarget instanceof HTMLIFrameElement;
4122
+ }
4123
+
4124
+ function isAnAvailableType(_ref) {
4125
+ var type = _ref.type,
4126
+ value = _ref.value;
4127
+ // We don't want to expose our private elementAdapter key / value
4128
+ if (type === elementAdapterNativeDataKey) {
4129
+ return false;
4130
+ }
4131
+ // Not exposing "text/plain" if it contains the android fallback text
4132
+ // We _could_ add an `isAndroid()` check, but it's probably safest
4133
+ // to trim this data out, regardless of what OS we see it on.
4134
+ if (type === textMediaType && value === androidFallbackText) {
4135
+ return false;
4136
+ }
4137
+ return true;
4138
+ }
4139
+ function getAvailableTypes(transfer) {
4140
+ return Array.from(transfer.types).filter(function (type) {
4141
+ return isAnAvailableType({
4142
+ type: type,
4143
+ value: transfer.getData(type)
4144
+ });
4145
+ });
4146
+ }
4147
+ function getAvailableItems(dataTransfer) {
4148
+ // item.kind is 'string' | 'file'
4149
+ // For 'string' item.type is the mimeType (eg 'text/plain')
4150
+ // For 'file' item.type is the file type (eg 'image/jpg')
4151
+
4152
+ return Array.from(dataTransfer.items).filter(function (item) {
4153
+ return item.kind === 'file' || isAnAvailableType({
4154
+ type: item.type,
4155
+ value: dataTransfer.getData(item.type)
4156
+ });
4157
+ });
4158
+ }
4159
+ var didDragStartLocally = false;
4160
+ var adapter = makeAdapter({
4161
+ typeKey: 'external',
4162
+ // for external drags, we are generally making a copy of something that is being dragged
4163
+ defaultDropEffect: 'copy',
4164
+ mount: function mount(api) {
4165
+ // Binding to the `window` so that the element adapter
4166
+ // has a chance to get in first on the`document`.
4167
+ // We are giving preference to the element adapter.
4168
+ return bindEventListener.bind(window, {
4169
+ type: 'dragenter',
4170
+ listener: function listener(event) {
4171
+ // drag operation was started within the document, it won't be an "external" drag
4172
+ if (didDragStartLocally) {
4173
+ return;
4174
+ }
4175
+
4176
+ // Note: not checking if event was cancelled (`event.defaultPrevented`) as
4177
+ // cancelling a "dragenter" accepts the drag operation (not prevent it)
4178
+
4179
+ // Something has gone wrong with our drag event
4180
+ if (!event.dataTransfer) {
4181
+ // Including this code on "test" and "development" environments:
4182
+ // - Browser tests commonly run against "development" builds
4183
+ // - Unit tests commonly run in "test"
4184
+ if (process.env.NODE_ENV !== 'production') {
4185
+ // eslint-disable-next-line no-console
4186
+ console.warn("\n It appears as though you have are not testing DragEvents correctly.\n\n - If you are unit testing, ensure you have polyfilled DragEvent.\n - If you are browser testing, ensure you are dispatching drag events correctly.\n\n Please see our testing guides for more information:\n https://atlassian.design/components/pragmatic-drag-and-drop/core-package/testing\n ".replace(/ {2}/g, ''));
4187
+ }
4188
+ return;
4189
+ }
4190
+ if (!api.canStart(event)) {
4191
+ return;
4192
+ }
4193
+ if (!isEnteringWindow({
4194
+ dragEnter: event
4195
+ })) {
4196
+ return;
4197
+ }
4198
+
4199
+ // Note: not checking types for `elementAdapterNativeDataKey` as we expect to see that
4200
+ // key when pdnd started the drag in another document
4201
+ var types = getAvailableTypes(event.dataTransfer);
4202
+ if (!types.length) {
4203
+ return;
4204
+ }
4205
+ var locked = {
4206
+ types: types,
4207
+ items: [],
4208
+ getStringData: function getStringData() {
4209
+ return null;
4210
+ }
4211
+ };
4212
+ api.start({
4213
+ event: event,
4214
+ dragType: {
4215
+ type: 'external',
4216
+ startedFrom: 'external',
4217
+ payload: locked,
4218
+ getDropPayload: function getDropPayload(event) {
4219
+ // this would be a platform error
4220
+ // trying to handle it gracefully rather than throwing (for now)
4221
+ if (!event.dataTransfer) {
4222
+ return locked;
4223
+ }
4224
+ var items = getAvailableItems(event.dataTransfer);
4225
+ // need to use `.bind` as `getData` is required
4226
+ // to be run with `event.dataTransfer` as the "this" context
4227
+ var nativeGetData = event.dataTransfer.getData.bind(event.dataTransfer);
4228
+ return {
4229
+ types: types,
4230
+ items: items,
4231
+ // return `null` if there is no result, otherwise string
4232
+ getStringData: function getStringData(mediaType) {
4233
+ // not dragging the requested type
4234
+ // return `null` (no result)
4235
+ if (!types.includes(mediaType)) {
4236
+ return null;
4237
+ }
4238
+
4239
+ // nativeGetData will return `""` when there is no value,
4240
+ // but at this point we know we will only get explicitly set
4241
+ // values back as we have checked the `types`.
4242
+ // `""` can be an explicitly set value.
4243
+ var value = nativeGetData(mediaType);
4244
+
4245
+ // not exposing data for unavailable types
4246
+ if (!isAnAvailableType({
4247
+ type: mediaType,
4248
+ value: value
4249
+ })) {
4250
+ return null;
4251
+ }
4252
+ return value;
4253
+ }
4254
+ };
4255
+ }
4256
+ }
4257
+ });
4258
+ }
4259
+ });
4260
+ }
4261
+ });
4262
+
4263
+ /**
4264
+ * Some events don't make sense for the external adapter
4265
+ *
4266
+ * `onGenerateDragPreview`
4267
+ * The browser creates the drag preview for external drags, so we don't
4268
+ * need an event to generate the preview for _monitors_ or the _dropTarget_
4269
+ *
4270
+ * `onDragStart`
4271
+ * An external drag can never start from in the `window`, so _dropTarget_'s
4272
+ * don't need `onDragStart`
4273
+ */
4274
+
4275
+ function dropTargetForExternal(args) {
4276
+ // not removing unused events, just leaning on the type system
4277
+ return adapter.dropTarget(args);
4278
+ }
4279
+ (function startup() {
4280
+ // server side rendering check
4281
+ if (typeof window === 'undefined') {
4282
+ return;
4283
+ }
4284
+
4285
+ // A shared single usage registration as we want to capture
4286
+ // all external drag operations, even if there are no drop targets
4287
+ // on the page yet
4288
+ adapter.registerUsage();
4289
+ // independent of pdnd, we need to keep track of
4290
+ // all drag operations so that we can know if a drag operation
4291
+ // has started locally
4292
+
4293
+ var idle = {
4294
+ type: 'idle'
4295
+ };
4296
+ var state = idle;
4297
+ function clear() {
4298
+ if (state.type !== 'dragging') {
4299
+ return;
4300
+ }
4301
+ didDragStartLocally = false;
4302
+ state.cleanup();
4303
+ state = idle;
4304
+ }
4305
+ function bindEndEvents() {
4306
+ return bindEventListener.bindAll(window, [{
4307
+ type: 'dragend',
4308
+ listener: clear
4309
+ }].concat(_toConsumableArray(getBindingsForBrokenDrags({
4310
+ onDragEnd: clear
4311
+ }))),
4312
+ // we want to make sure we get all the events,
4313
+ // and this helps avoid not seeing events when folks stop
4314
+ // them later on the event path
4315
+ {
4316
+ capture: true
4317
+ });
4318
+ }
4319
+
4320
+ // we always keep this event listener active
4321
+ bindEventListener.bind(window, {
4322
+ type: 'dragstart',
4323
+ listener: function listener() {
4324
+ // something bad has happened if this is true!
4325
+ if (state.type !== 'idle') {
4326
+ return;
4327
+ }
4328
+ // set our global flag
4329
+ didDragStartLocally = true;
4330
+ state = {
4331
+ type: 'dragging',
4332
+ cleanup: bindEndEvents()
4333
+ };
4334
+ },
4335
+ // binding in the capture phase so these listeners are called
4336
+ // before our listeners in the adapters `mount` function
4337
+ options: {
4338
+ capture: true
4339
+ }
4340
+ });
4341
+ })();
4342
+
4343
+ /** Common event payload for all events */
4344
+
4345
+ /** A map containing payloads for all events */
4346
+
4347
+ /** Common event payload for all drop target events */
4348
+
4349
+ /** A map containing payloads for all events on drop targets */
4350
+
4351
+ /** Arguments given to all feedback functions (eg `canDrop()`) on a `dropTargetForExternal` */
4352
+
4353
+ /** Arguments given to all monitor feedback functions (eg `canMonitor()`) for a `monitorForExternal` */
4354
+
4355
+ /** Obtain an array of the dragged `File`s */
4356
+ function getFiles(_ref2) {
4357
+ var source = _ref2.source;
4358
+ return source.items
4359
+ // unlike other media types, for files:
4360
+ // item.kind is 'file'
4361
+ // item.type is the type of file eg 'image/jpg'
4362
+ // for other media types, item.type is the mime format
4363
+ .filter(function (item) {
4364
+ return item.kind === 'file';
4365
+ }).map(function (item) {
4366
+ return item.getAsFile();
4367
+ }).filter(function (file) {
4368
+ return file != null;
4369
+ });
4370
+ }
4371
+
4372
+ /* Get the plain text that a user is dragging */
4373
+ function getText(_ref2) {
4374
+ var source = _ref2.source;
4375
+ return source.getStringData(textMediaType);
4376
+ }
4377
+
2184
4378
  const FileDropzone = ({ children = undefined, gridProps = {}, onDrop = () => { }, placeholder = "Drop files here or click to upload", }) => {
2185
4379
  const ref = React.useRef(null);
2186
4380
  const [isDraggedOver, setIsDraggedOver] = React.useState(false);
2187
4381
  React.useEffect(() => {
2188
4382
  const el = ref.current;
2189
4383
  invariant(el);
2190
- return adapter$1.dropTargetForExternal({
4384
+ return dropTargetForExternal({
2191
4385
  element: el,
2192
4386
  onDragEnter: () => setIsDraggedOver(true),
2193
4387
  onDragLeave: () => setIsDraggedOver(false),
2194
4388
  // canDrop: some(containsFiles, containsText),
2195
4389
  onDrop: ({ source }) => {
2196
- const files = file.getFiles({ source });
2197
- const text$1 = text.getText({ source });
2198
- console.log(files, text$1, "dfposa");
2199
- onDrop({ files, text: text$1 });
4390
+ const files = getFiles({ source });
4391
+ const text = getText({ source });
4392
+ console.log(files, text, "dfposa");
4393
+ onDrop({ files, text });
2200
4394
  },
2201
4395
  });
2202
4396
  }, [onDrop]);