helper.mjs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. import { ref, onMounted, watch, onBeforeUnmount, computed, unref, watchEffect } from 'vue';
  2. import { offset, flip, shift, detectOverflow, arrow, computePosition, autoUpdate } from '@floating-ui/dom';
  3. import { isArray, isString, isFunction } from '@vue/shared';
  4. import { isClient } from '@vueuse/core';
  5. import { keysOf } from '../../../utils/objects.mjs';
  6. const useTarget = (target, open, gap, mergedMask, scrollIntoViewOptions) => {
  7. const posInfo = ref(null);
  8. const getTargetEl = () => {
  9. let targetEl;
  10. if (isString(target.value)) {
  11. targetEl = document.querySelector(target.value);
  12. } else if (isFunction(target.value)) {
  13. targetEl = target.value();
  14. } else {
  15. targetEl = target.value;
  16. }
  17. return targetEl;
  18. };
  19. const updatePosInfo = () => {
  20. const targetEl = getTargetEl();
  21. if (!targetEl || !open.value) {
  22. posInfo.value = null;
  23. return;
  24. }
  25. if (!isInViewPort(targetEl)) {
  26. targetEl.scrollIntoView(scrollIntoViewOptions.value);
  27. }
  28. const { left, top, width, height } = targetEl.getBoundingClientRect();
  29. posInfo.value = {
  30. left,
  31. top,
  32. width,
  33. height,
  34. radius: 0
  35. };
  36. };
  37. onMounted(() => {
  38. watch([open, target], () => {
  39. updatePosInfo();
  40. }, {
  41. immediate: true
  42. });
  43. window.addEventListener("resize", updatePosInfo);
  44. });
  45. onBeforeUnmount(() => {
  46. window.removeEventListener("resize", updatePosInfo);
  47. });
  48. const getGapOffset = (index) => {
  49. var _a;
  50. return (_a = isArray(gap.value.offset) ? gap.value.offset[index] : gap.value.offset) != null ? _a : 6;
  51. };
  52. const mergedPosInfo = computed(() => {
  53. var _a;
  54. if (!posInfo.value)
  55. return posInfo.value;
  56. const gapOffsetX = getGapOffset(0);
  57. const gapOffsetY = getGapOffset(1);
  58. const gapRadius = ((_a = gap.value) == null ? void 0 : _a.radius) || 2;
  59. return {
  60. left: posInfo.value.left - gapOffsetX,
  61. top: posInfo.value.top - gapOffsetY,
  62. width: posInfo.value.width + gapOffsetX * 2,
  63. height: posInfo.value.height + gapOffsetY * 2,
  64. radius: gapRadius
  65. };
  66. });
  67. const triggerTarget = computed(() => {
  68. const targetEl = getTargetEl();
  69. if (!mergedMask.value || !targetEl || !window.DOMRect) {
  70. return targetEl || void 0;
  71. }
  72. return {
  73. getBoundingClientRect() {
  74. var _a, _b, _c, _d;
  75. return window.DOMRect.fromRect({
  76. width: ((_a = mergedPosInfo.value) == null ? void 0 : _a.width) || 0,
  77. height: ((_b = mergedPosInfo.value) == null ? void 0 : _b.height) || 0,
  78. x: ((_c = mergedPosInfo.value) == null ? void 0 : _c.left) || 0,
  79. y: ((_d = mergedPosInfo.value) == null ? void 0 : _d.top) || 0
  80. });
  81. }
  82. };
  83. });
  84. return {
  85. mergedPosInfo,
  86. triggerTarget
  87. };
  88. };
  89. const tourKey = Symbol("ElTour");
  90. function isInViewPort(element) {
  91. const viewWidth = window.innerWidth || document.documentElement.clientWidth;
  92. const viewHeight = window.innerHeight || document.documentElement.clientHeight;
  93. const { top, right, bottom, left } = element.getBoundingClientRect();
  94. return top >= 0 && left >= 0 && right <= viewWidth && bottom <= viewHeight;
  95. }
  96. const useFloating = (referenceRef, contentRef, arrowRef, placement, strategy, offset$1, zIndex, showArrow) => {
  97. const x = ref();
  98. const y = ref();
  99. const middlewareData = ref({});
  100. const states = {
  101. x,
  102. y,
  103. placement,
  104. strategy,
  105. middlewareData
  106. };
  107. const middleware = computed(() => {
  108. const _middleware = [
  109. offset(unref(offset$1)),
  110. flip(),
  111. shift(),
  112. overflowMiddleware()
  113. ];
  114. if (unref(showArrow) && unref(arrowRef)) {
  115. _middleware.push(arrow({
  116. element: unref(arrowRef)
  117. }));
  118. }
  119. return _middleware;
  120. });
  121. const update = async () => {
  122. if (!isClient)
  123. return;
  124. const referenceEl = unref(referenceRef);
  125. const contentEl = unref(contentRef);
  126. if (!referenceEl || !contentEl)
  127. return;
  128. const data = await computePosition(referenceEl, contentEl, {
  129. placement: unref(placement),
  130. strategy: unref(strategy),
  131. middleware: unref(middleware)
  132. });
  133. keysOf(states).forEach((key) => {
  134. states[key].value = data[key];
  135. });
  136. };
  137. const contentStyle = computed(() => {
  138. if (!unref(referenceRef)) {
  139. return {
  140. position: "fixed",
  141. top: "50%",
  142. left: "50%",
  143. transform: "translate3d(-50%, -50%, 0)",
  144. maxWidth: "100vw",
  145. zIndex: unref(zIndex)
  146. };
  147. }
  148. const { overflow } = unref(middlewareData);
  149. return {
  150. position: unref(strategy),
  151. zIndex: unref(zIndex),
  152. top: unref(y) != null ? `${unref(y)}px` : "",
  153. left: unref(x) != null ? `${unref(x)}px` : "",
  154. maxWidth: (overflow == null ? void 0 : overflow.maxWidth) ? `${overflow == null ? void 0 : overflow.maxWidth}px` : ""
  155. };
  156. });
  157. const arrowStyle = computed(() => {
  158. if (!unref(showArrow))
  159. return {};
  160. const { arrow: arrow2 } = unref(middlewareData);
  161. return {
  162. left: (arrow2 == null ? void 0 : arrow2.x) != null ? `${arrow2 == null ? void 0 : arrow2.x}px` : "",
  163. top: (arrow2 == null ? void 0 : arrow2.y) != null ? `${arrow2 == null ? void 0 : arrow2.y}px` : ""
  164. };
  165. });
  166. let cleanup;
  167. onMounted(() => {
  168. const referenceEl = unref(referenceRef);
  169. const contentEl = unref(contentRef);
  170. if (referenceEl && contentEl) {
  171. cleanup = autoUpdate(referenceEl, contentEl, update);
  172. }
  173. watchEffect(() => {
  174. update();
  175. });
  176. });
  177. onBeforeUnmount(() => {
  178. cleanup && cleanup();
  179. });
  180. return {
  181. update,
  182. contentStyle,
  183. arrowStyle
  184. };
  185. };
  186. const overflowMiddleware = () => {
  187. return {
  188. name: "overflow",
  189. async fn(state) {
  190. const overflow = await detectOverflow(state);
  191. let overWidth = 0;
  192. if (overflow.left > 0)
  193. overWidth = overflow.left;
  194. if (overflow.right > 0)
  195. overWidth = overflow.right;
  196. const floatingWidth = state.rects.floating.width;
  197. return {
  198. data: {
  199. maxWidth: floatingWidth - overWidth
  200. }
  201. };
  202. }
  203. };
  204. };
  205. export { tourKey, useFloating, useTarget };
  206. //# sourceMappingURL=helper.mjs.map