element-plus
Version:
A Component Library for Vue 3
210 lines (207 loc) • 6.24 kB
JavaScript
import { ref, onMounted, watch, onBeforeUnmount, computed, unref, watchEffect } from 'vue';
import { offset, flip, shift, arrow, computePosition, autoUpdate, detectOverflow } from '@floating-ui/dom';
import '../../../utils/index.mjs';
import { isString, isFunction, isArray } from '@vue/shared';
import { isClient } from '@vueuse/core';
import { keysOf } from '../../../utils/objects.mjs';
const useTarget = (target, open, gap, mergedMask, scrollIntoViewOptions) => {
const posInfo = ref(null);
const getTargetEl = () => {
let targetEl;
if (isString(target.value)) {
targetEl = document.querySelector(target.value);
} else if (isFunction(target.value)) {
targetEl = target.value();
} else {
targetEl = target.value;
}
return targetEl;
};
const updatePosInfo = () => {
const targetEl = getTargetEl();
if (!targetEl || !open.value) {
posInfo.value = null;
return;
}
if (!isInViewPort(targetEl) && open.value) {
targetEl.scrollIntoView(scrollIntoViewOptions.value);
}
const { left, top, width, height } = targetEl.getBoundingClientRect();
posInfo.value = {
left,
top,
width,
height,
radius: 0
};
};
onMounted(() => {
watch([open, target], () => {
updatePosInfo();
}, {
immediate: true
});
window.addEventListener("resize", updatePosInfo);
});
onBeforeUnmount(() => {
window.removeEventListener("resize", updatePosInfo);
});
const getGapOffset = (index) => {
var _a;
return (_a = isArray(gap.value.offset) ? gap.value.offset[index] : gap.value.offset) != null ? _a : 6;
};
const mergedPosInfo = computed(() => {
var _a;
if (!posInfo.value)
return posInfo.value;
const gapOffsetX = getGapOffset(0);
const gapOffsetY = getGapOffset(1);
const gapRadius = ((_a = gap.value) == null ? void 0 : _a.radius) || 2;
return {
left: posInfo.value.left - gapOffsetX,
top: posInfo.value.top - gapOffsetY,
width: posInfo.value.width + gapOffsetX * 2,
height: posInfo.value.height + gapOffsetY * 2,
radius: gapRadius
};
});
const triggerTarget = computed(() => {
const targetEl = getTargetEl();
if (!mergedMask.value || !targetEl || !window.DOMRect) {
return targetEl || void 0;
}
return {
getBoundingClientRect() {
var _a, _b, _c, _d;
return window.DOMRect.fromRect({
width: ((_a = mergedPosInfo.value) == null ? void 0 : _a.width) || 0,
height: ((_b = mergedPosInfo.value) == null ? void 0 : _b.height) || 0,
x: ((_c = mergedPosInfo.value) == null ? void 0 : _c.left) || 0,
y: ((_d = mergedPosInfo.value) == null ? void 0 : _d.top) || 0
});
}
};
});
return {
mergedPosInfo,
triggerTarget
};
};
const tourKey = Symbol("ElTour");
function isInViewPort(element) {
const viewWidth = window.innerWidth || document.documentElement.clientWidth;
const viewHeight = window.innerHeight || document.documentElement.clientHeight;
const { top, right, bottom, left } = element.getBoundingClientRect();
return top >= 0 && left >= 0 && right <= viewWidth && bottom <= viewHeight;
}
const useFloating = (referenceRef, contentRef, arrowRef, placement, strategy, offset$1, zIndex, showArrow) => {
const x = ref();
const y = ref();
const middlewareData = ref({});
const states = {
x,
y,
placement,
strategy,
middlewareData
};
const middleware = computed(() => {
const _middleware = [
offset(unref(offset$1)),
flip(),
shift(),
overflowMiddleware()
];
if (unref(showArrow) && unref(arrowRef)) {
_middleware.push(arrow({
element: unref(arrowRef)
}));
}
return _middleware;
});
const update = async () => {
if (!isClient)
return;
const referenceEl = unref(referenceRef);
const contentEl = unref(contentRef);
if (!referenceEl || !contentEl)
return;
const data = await computePosition(referenceEl, contentEl, {
placement: unref(placement),
strategy: unref(strategy),
middleware: unref(middleware)
});
keysOf(states).forEach((key) => {
states[key].value = data[key];
});
};
const contentStyle = computed(() => {
if (!unref(referenceRef)) {
return {
position: "fixed",
top: "50%",
left: "50%",
transform: "translate3d(-50%, -50%, 0)",
maxWidth: "100vw",
zIndex: unref(zIndex)
};
}
const { overflow } = unref(middlewareData);
return {
position: unref(strategy),
zIndex: unref(zIndex),
top: unref(y) != null ? `${unref(y)}px` : "",
left: unref(x) != null ? `${unref(x)}px` : "",
maxWidth: (overflow == null ? void 0 : overflow.maxWidth) ? `${overflow == null ? void 0 : overflow.maxWidth}px` : ""
};
});
const arrowStyle = computed(() => {
if (!unref(showArrow))
return {};
const { arrow: arrow2 } = unref(middlewareData);
return {
left: (arrow2 == null ? void 0 : arrow2.x) != null ? `${arrow2 == null ? void 0 : arrow2.x}px` : "",
top: (arrow2 == null ? void 0 : arrow2.y) != null ? `${arrow2 == null ? void 0 : arrow2.y}px` : ""
};
});
let cleanup;
onMounted(() => {
const referenceEl = unref(referenceRef);
const contentEl = unref(contentRef);
if (referenceEl && contentEl) {
cleanup = autoUpdate(referenceEl, contentEl, update);
}
watchEffect(() => {
update();
});
});
onBeforeUnmount(() => {
cleanup && cleanup();
});
return {
update,
contentStyle,
arrowStyle
};
};
const overflowMiddleware = () => {
return {
name: "overflow",
async fn(state) {
const overflow = await detectOverflow(state);
let overWidth = 0;
if (overflow.left > 0)
overWidth = overflow.left;
if (overflow.right > 0)
overWidth = overflow.right;
const floatingWidth = state.rects.floating.width;
return {
data: {
maxWidth: floatingWidth - overWidth
}
};
}
};
};
export { tourKey, useFloating, useTarget };
//# sourceMappingURL=helper.mjs.map