992903ce40f7e37abec8ce817ddfaf9dee8d0ffdee697238c98c77f399f32b6b548f0d861ffb01aae0f2a7e9e12baa6be0f7c40eb36a8c99dd677d20e14307 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import { shallowRef, ref } from 'vue';
  2. import { getStyle, setStyle } from '../../../../utils/dom/style.mjs';
  3. import { useNamespace } from '../../../../hooks/use-namespace/index.mjs';
  4. import { isUndefined } from '../../../../utils/types.mjs';
  5. function useDragTag({
  6. wrapperRef,
  7. handleDragged,
  8. afterDragged
  9. }) {
  10. const ns = useNamespace("input-tag");
  11. const dropIndicatorRef = shallowRef();
  12. const showDropIndicator = ref(false);
  13. let draggingIndex;
  14. let draggingTag;
  15. let dropIndex;
  16. let dropType;
  17. function getTagClassName(index) {
  18. return `.${ns.e("inner")} .${ns.namespace.value}-tag:nth-child(${index + 1})`;
  19. }
  20. function handleDragStart(event, index) {
  21. draggingIndex = index;
  22. draggingTag = wrapperRef.value.querySelector(getTagClassName(index));
  23. if (draggingTag) {
  24. draggingTag.style.opacity = "0.5";
  25. }
  26. event.dataTransfer.effectAllowed = "move";
  27. }
  28. function handleDragOver(event, index) {
  29. dropIndex = index;
  30. event.preventDefault();
  31. event.dataTransfer.dropEffect = "move";
  32. if (isUndefined(draggingIndex) || draggingIndex === index) {
  33. showDropIndicator.value = false;
  34. return;
  35. }
  36. const dropPosition = wrapperRef.value.querySelector(getTagClassName(index)).getBoundingClientRect();
  37. const dropPrev = !(draggingIndex + 1 === index);
  38. const dropNext = !(draggingIndex - 1 === index);
  39. const distance = event.clientX - dropPosition.left;
  40. const prevPercent = dropPrev ? dropNext ? 0.5 : 1 : -1;
  41. const nextPercent = dropNext ? dropPrev ? 0.5 : 0 : 1;
  42. if (distance <= dropPosition.width * prevPercent) {
  43. dropType = "before";
  44. } else if (distance > dropPosition.width * nextPercent) {
  45. dropType = "after";
  46. } else {
  47. dropType = void 0;
  48. }
  49. const innerEl = wrapperRef.value.querySelector(`.${ns.e("inner")}`);
  50. const innerPosition = innerEl.getBoundingClientRect();
  51. const gap = Number.parseFloat(getStyle(innerEl, "gap")) / 2;
  52. const indicatorTop = dropPosition.top - innerPosition.top;
  53. let indicatorLeft = -9999;
  54. if (dropType === "before") {
  55. indicatorLeft = Math.max(dropPosition.left - innerPosition.left - gap, Math.floor(-gap / 2));
  56. } else if (dropType === "after") {
  57. const left = dropPosition.right - innerPosition.left;
  58. indicatorLeft = left + (innerPosition.width === left ? Math.floor(gap / 2) : gap);
  59. }
  60. setStyle(dropIndicatorRef.value, {
  61. top: `${indicatorTop}px`,
  62. left: `${indicatorLeft}px`
  63. });
  64. showDropIndicator.value = !!dropType;
  65. }
  66. function handleDragEnd(event) {
  67. event.preventDefault();
  68. if (draggingTag) {
  69. draggingTag.style.opacity = "";
  70. }
  71. if (dropType && !isUndefined(draggingIndex) && !isUndefined(dropIndex) && draggingIndex !== dropIndex) {
  72. handleDragged(draggingIndex, dropIndex, dropType);
  73. }
  74. showDropIndicator.value = false;
  75. draggingIndex = void 0;
  76. draggingTag = null;
  77. dropIndex = void 0;
  78. dropType = void 0;
  79. afterDragged == null ? void 0 : afterDragged();
  80. }
  81. return {
  82. dropIndicatorRef,
  83. showDropIndicator,
  84. handleDragStart,
  85. handleDragOver,
  86. handleDragEnd
  87. };
  88. }
  89. export { useDragTag };
  90. //# sourceMappingURL=use-drag-tag.mjs.map