useDragNode.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
  2. require("../../../../_virtual/_rolldown/runtime.js");
  3. const require_style = require("../../../../utils/dom/style.js");
  4. const require_index = require("../../../../hooks/use-namespace/index.js");
  5. let vue = require("vue");
  6. let _vue_shared = require("@vue/shared");
  7. //#region ../../packages/components/tree/src/model/useDragNode.ts
  8. const dragEventsKey = Symbol("dragEvents");
  9. function useDragNodeHandler({ props, ctx, el$, dropIndicator$, store }) {
  10. const ns = require_index.useNamespace("tree");
  11. const dragState = (0, vue.ref)({
  12. showDropIndicator: false,
  13. draggingNode: null,
  14. dropNode: null,
  15. allowDrop: true,
  16. dropType: null
  17. });
  18. const treeNodeDragStart = ({ event, treeNode }) => {
  19. if (!event.dataTransfer) return;
  20. if ((0, _vue_shared.isFunction)(props.allowDrag) && !props.allowDrag(treeNode.node)) {
  21. event.preventDefault();
  22. return false;
  23. }
  24. event.dataTransfer.effectAllowed = "move";
  25. try {
  26. event.dataTransfer.setData("text/plain", "");
  27. } catch {}
  28. dragState.value.draggingNode = treeNode;
  29. ctx.emit("node-drag-start", treeNode.node, event);
  30. };
  31. const treeNodeDragOver = ({ event, treeNode }) => {
  32. if (!event.dataTransfer) return;
  33. const dropNode = treeNode;
  34. const oldDropNode = dragState.value.dropNode;
  35. if (oldDropNode && oldDropNode.node.id !== dropNode.node.id) require_style.removeClass(oldDropNode.$el, ns.is("drop-inner"));
  36. const draggingNode = dragState.value.draggingNode;
  37. if (!draggingNode || !dropNode) return;
  38. let dropPrev = true;
  39. let dropInner = true;
  40. let dropNext = true;
  41. let userAllowDropInner = true;
  42. if ((0, _vue_shared.isFunction)(props.allowDrop)) {
  43. dropPrev = props.allowDrop(draggingNode.node, dropNode.node, "prev");
  44. userAllowDropInner = dropInner = props.allowDrop(draggingNode.node, dropNode.node, "inner");
  45. dropNext = props.allowDrop(draggingNode.node, dropNode.node, "next");
  46. }
  47. event.dataTransfer.dropEffect = dropInner || dropPrev || dropNext ? "move" : "none";
  48. if ((dropPrev || dropInner || dropNext) && oldDropNode?.node.id !== dropNode.node.id) {
  49. if (oldDropNode) ctx.emit("node-drag-leave", draggingNode.node, oldDropNode.node, event);
  50. ctx.emit("node-drag-enter", draggingNode.node, dropNode.node, event);
  51. }
  52. if (dropPrev || dropInner || dropNext) dragState.value.dropNode = dropNode;
  53. else dragState.value.dropNode = null;
  54. if (dropNode.node.nextSibling === draggingNode.node) dropNext = false;
  55. if (dropNode.node.previousSibling === draggingNode.node) dropPrev = false;
  56. if (dropNode.node.contains(draggingNode.node, false)) dropInner = false;
  57. if (draggingNode.node === dropNode.node || draggingNode.node.contains(dropNode.node)) {
  58. dropPrev = false;
  59. dropInner = false;
  60. dropNext = false;
  61. }
  62. const dropEl = dropNode.$el;
  63. const targetPosition = dropEl.querySelector(`.${ns.be("node", "content")}`).getBoundingClientRect();
  64. const treePosition = el$.value.getBoundingClientRect();
  65. const treeScrollTop = el$.value.scrollTop;
  66. let dropType;
  67. const prevPercent = dropPrev ? dropInner ? .25 : dropNext ? .45 : 1 : Number.NEGATIVE_INFINITY;
  68. const nextPercent = dropNext ? dropInner ? .75 : dropPrev ? .55 : 0 : Number.POSITIVE_INFINITY;
  69. let indicatorTop = -9999;
  70. const distance = event.clientY - targetPosition.top;
  71. if (distance < targetPosition.height * prevPercent) dropType = "before";
  72. else if (distance > targetPosition.height * nextPercent) dropType = "after";
  73. else if (dropInner) dropType = "inner";
  74. else dropType = "none";
  75. const iconPosition = dropEl.querySelector(`.${ns.be("node", "expand-icon")}`).getBoundingClientRect();
  76. const dropIndicator = dropIndicator$.value;
  77. if (dropType === "before") indicatorTop = iconPosition.top - treePosition.top + treeScrollTop;
  78. else if (dropType === "after") indicatorTop = iconPosition.bottom - treePosition.top + treeScrollTop;
  79. dropIndicator.style.top = `${indicatorTop}px`;
  80. dropIndicator.style.left = `${iconPosition.right - treePosition.left}px`;
  81. if (dropType === "inner") require_style.addClass(dropEl, ns.is("drop-inner"));
  82. else require_style.removeClass(dropEl, ns.is("drop-inner"));
  83. dragState.value.showDropIndicator = dropType === "before" || dropType === "after";
  84. dragState.value.allowDrop = dragState.value.showDropIndicator || userAllowDropInner;
  85. dragState.value.dropType = dropType;
  86. ctx.emit("node-drag-over", draggingNode.node, dropNode.node, event);
  87. };
  88. const treeNodeDragEnd = (event) => {
  89. const { draggingNode, dropType, dropNode } = dragState.value;
  90. event.preventDefault();
  91. if (event.dataTransfer) event.dataTransfer.dropEffect = "move";
  92. if (draggingNode?.node.data && dropNode) {
  93. const draggingNodeCopy = { data: draggingNode.node.data };
  94. if (dropType !== "none") draggingNode.node.remove();
  95. if (dropType === "before") dropNode.node.parent?.insertBefore(draggingNodeCopy, dropNode.node);
  96. else if (dropType === "after") dropNode.node.parent?.insertAfter(draggingNodeCopy, dropNode.node);
  97. else if (dropType === "inner") dropNode.node.insertChild(draggingNodeCopy);
  98. if (dropType !== "none") {
  99. store.value.registerNode(draggingNodeCopy);
  100. if (store.value.key) draggingNode.node.eachNode((node) => {
  101. store.value.nodesMap[node.data[store.value.key]]?.setChecked(node.checked, !store.value.checkStrictly);
  102. });
  103. }
  104. require_style.removeClass(dropNode.$el, ns.is("drop-inner"));
  105. ctx.emit("node-drag-end", draggingNode.node, dropNode.node, dropType, event);
  106. if (dropType !== "none") ctx.emit("node-drop", draggingNode.node, dropNode.node, dropType, event);
  107. }
  108. if (draggingNode && !dropNode) ctx.emit("node-drag-end", draggingNode.node, null, dropType, event);
  109. dragState.value.showDropIndicator = false;
  110. dragState.value.draggingNode = null;
  111. dragState.value.dropNode = null;
  112. dragState.value.allowDrop = true;
  113. };
  114. (0, vue.provide)(dragEventsKey, {
  115. treeNodeDragStart,
  116. treeNodeDragOver,
  117. treeNodeDragEnd
  118. });
  119. return { dragState };
  120. }
  121. //#endregion
  122. exports.dragEventsKey = dragEventsKey;
  123. exports.useDragNodeHandler = useDragNodeHandler;
  124. //# sourceMappingURL=useDragNode.js.map