479 lines
14 KiB
JavaScript
479 lines
14 KiB
JavaScript
import {
|
|
getAbsolutePos,
|
|
getDomNode,
|
|
toCssUnit
|
|
} from "./chunk-PBZHTG65.js";
|
|
import {
|
|
getLastZIndex,
|
|
nextZIndex
|
|
} from "./chunk-REHJGRQO.js";
|
|
import {
|
|
getSlotVNs
|
|
} from "./chunk-LXH6LNL6.js";
|
|
import {
|
|
defineVxeComponent
|
|
} from "./chunk-ML6NAHIO.js";
|
|
import {
|
|
createEvent,
|
|
getConfig,
|
|
require_xe_utils,
|
|
useSize
|
|
} from "./chunk-YJNUXQVJ.js";
|
|
import {
|
|
computed,
|
|
h,
|
|
nextTick,
|
|
onBeforeUnmount,
|
|
onMounted,
|
|
reactive,
|
|
ref,
|
|
watch
|
|
} from "./chunk-AAHVYXXY.js";
|
|
import {
|
|
__toESM
|
|
} from "./chunk-V4OQ3NZ2.js";
|
|
|
|
// ../node_modules/.pnpm/vxe-pc-ui@4.10.22_vue@3.5.24_typescript@5.9.3_/node_modules/vxe-pc-ui/es/tooltip/src/tooltip.js
|
|
var import_xe_utils = __toESM(require_xe_utils());
|
|
var tooltip_default = defineVxeComponent({
|
|
name: "VxeTooltip",
|
|
props: {
|
|
modelValue: Boolean,
|
|
size: {
|
|
type: String,
|
|
default: () => getConfig().tooltip.size || getConfig().size
|
|
},
|
|
selector: String,
|
|
trigger: {
|
|
type: String,
|
|
default: () => getConfig().tooltip.trigger || "hover"
|
|
},
|
|
theme: {
|
|
type: String,
|
|
default: () => getConfig().tooltip.theme || "dark"
|
|
},
|
|
content: {
|
|
type: [String, Number],
|
|
default: null
|
|
},
|
|
useHTML: Boolean,
|
|
zIndex: [String, Number],
|
|
popupClassName: [String, Function],
|
|
width: {
|
|
type: [String, Number],
|
|
default: () => getConfig().tooltip.Width
|
|
},
|
|
height: {
|
|
type: [String, Number],
|
|
default: () => getConfig().tooltip.height
|
|
},
|
|
minWidth: {
|
|
type: [String, Number],
|
|
default: () => getConfig().tooltip.minWidth
|
|
},
|
|
minHeight: {
|
|
type: [String, Number],
|
|
default: () => getConfig().tooltip.minHeight
|
|
},
|
|
maxWidth: {
|
|
type: [String, Number],
|
|
default: () => getConfig().tooltip.maxWidth
|
|
},
|
|
maxHeight: {
|
|
type: [String, Number],
|
|
default: () => getConfig().tooltip.maxHeight
|
|
},
|
|
isArrow: {
|
|
type: Boolean,
|
|
default: () => getConfig().tooltip.isArrow
|
|
},
|
|
enterable: {
|
|
type: Boolean,
|
|
default: () => getConfig().tooltip.enterable
|
|
},
|
|
enterDelay: {
|
|
type: Number,
|
|
default: () => getConfig().tooltip.enterDelay
|
|
},
|
|
leaveDelay: {
|
|
type: Number,
|
|
default: () => getConfig().tooltip.leaveDelay
|
|
}
|
|
},
|
|
emits: [
|
|
"update:modelValue"
|
|
],
|
|
setup(props, context) {
|
|
const { slots, emit } = context;
|
|
const xID = import_xe_utils.default.uniqueId();
|
|
const { computeSize } = useSize(props);
|
|
const reactData = reactive({
|
|
target: null,
|
|
isUpdate: false,
|
|
visible: false,
|
|
tipContent: "",
|
|
tipActive: false,
|
|
tipTarget: null,
|
|
tipZindex: 0,
|
|
tipStore: {
|
|
style: {},
|
|
placement: "",
|
|
arrowStyle: {}
|
|
}
|
|
});
|
|
const internalData = {};
|
|
const refElem = ref();
|
|
const contentWrapperfElem = ref();
|
|
const computeWrapperStyle = computed(() => {
|
|
const { width, height, minHeight, minWidth, maxHeight, maxWidth } = props;
|
|
const stys = {};
|
|
if (width) {
|
|
stys.width = toCssUnit(width);
|
|
}
|
|
if (height) {
|
|
stys.height = toCssUnit(height);
|
|
}
|
|
if (minWidth) {
|
|
stys.minWidth = toCssUnit(minWidth);
|
|
}
|
|
if (minHeight) {
|
|
stys.minHeight = toCssUnit(minHeight);
|
|
}
|
|
if (maxWidth) {
|
|
stys.maxWidth = toCssUnit(maxWidth);
|
|
}
|
|
if (maxHeight) {
|
|
stys.maxHeight = toCssUnit(maxHeight);
|
|
}
|
|
return stys;
|
|
});
|
|
const refMaps = {
|
|
refElem
|
|
};
|
|
const $xeTooltip = {
|
|
xID,
|
|
props,
|
|
context,
|
|
reactData,
|
|
internalData,
|
|
getRefMaps: () => refMaps
|
|
};
|
|
let tooltipMethods = {};
|
|
const updateTipStyle = () => {
|
|
const { tipTarget, tipStore } = reactData;
|
|
if (tipTarget) {
|
|
const { scrollTop, scrollLeft, visibleWidth } = getDomNode();
|
|
const { top, left } = getAbsolutePos(tipTarget);
|
|
const el = refElem.value;
|
|
if (!el) {
|
|
return;
|
|
}
|
|
const marginSize = 6;
|
|
const offsetHeight = el.offsetHeight;
|
|
const offsetWidth = el.offsetWidth;
|
|
let tipLeft = left;
|
|
let tipTop = top - offsetHeight - marginSize;
|
|
tipLeft = Math.max(marginSize, left + Math.floor((tipTarget.offsetWidth - offsetWidth) / 2));
|
|
if (tipLeft + offsetWidth + marginSize > scrollLeft + visibleWidth) {
|
|
tipLeft = scrollLeft + visibleWidth - offsetWidth - marginSize;
|
|
}
|
|
if (top - offsetHeight < scrollTop + marginSize) {
|
|
tipStore.placement = "bottom";
|
|
tipTop = top + tipTarget.offsetHeight + marginSize;
|
|
}
|
|
tipStore.style.top = `${tipTop}px`;
|
|
tipStore.style.left = `${tipLeft}px`;
|
|
tipStore.arrowStyle.left = `${left - tipLeft + tipTarget.offsetWidth / 2}px`;
|
|
}
|
|
};
|
|
const updateValue = (value) => {
|
|
if (value !== reactData.visible) {
|
|
reactData.visible = value;
|
|
reactData.isUpdate = true;
|
|
emit("update:modelValue", value);
|
|
}
|
|
};
|
|
const updateZindex = () => {
|
|
if (reactData.tipZindex < getLastZIndex()) {
|
|
reactData.tipZindex = nextZIndex();
|
|
}
|
|
};
|
|
const clickEvent = () => {
|
|
if (reactData.visible) {
|
|
tooltipMethods.close();
|
|
} else {
|
|
handleVisible(reactData.target || getSelectorEl(), props.content);
|
|
}
|
|
};
|
|
const targetMouseenterEvent = () => {
|
|
handleVisible(reactData.target || getSelectorEl(), props.content);
|
|
};
|
|
const targetMouseleaveEvent = () => {
|
|
const { trigger, enterable, leaveDelay } = props;
|
|
reactData.tipActive = false;
|
|
if (enterable && trigger === "hover") {
|
|
setTimeout(() => {
|
|
if (!reactData.tipActive) {
|
|
tooltipMethods.close();
|
|
}
|
|
}, leaveDelay);
|
|
} else {
|
|
tooltipMethods.close();
|
|
}
|
|
};
|
|
const wrapperMouseenterEvent = () => {
|
|
reactData.tipActive = true;
|
|
};
|
|
const wrapperMouseleaveEvent = () => {
|
|
const { trigger, enterable, leaveDelay } = props;
|
|
reactData.tipActive = false;
|
|
if (enterable && trigger === "hover") {
|
|
setTimeout(() => {
|
|
if (!reactData.tipActive) {
|
|
tooltipMethods.close();
|
|
}
|
|
}, leaveDelay);
|
|
}
|
|
};
|
|
const showTip = () => {
|
|
const { tipStore } = reactData;
|
|
const el = refElem.value;
|
|
if (el) {
|
|
const parentNode = el.parentNode;
|
|
if (!parentNode) {
|
|
document.body.appendChild(el);
|
|
}
|
|
}
|
|
updateValue(true);
|
|
updateZindex();
|
|
tipStore.placement = "top";
|
|
tipStore.style = { width: "auto", left: 0, top: 0, zIndex: props.zIndex || reactData.tipZindex };
|
|
tipStore.arrowStyle = { left: "50%" };
|
|
return tooltipMethods.updatePlacement();
|
|
};
|
|
const handleDelayFn = () => {
|
|
internalData.showDelayTip = import_xe_utils.default.debounce(() => {
|
|
if (reactData.tipActive) {
|
|
showTip();
|
|
}
|
|
}, props.enterDelay, { leading: false, trailing: true });
|
|
};
|
|
const handleVisible = (target, content) => {
|
|
const contentSlot = slots.content;
|
|
if (!contentSlot && (content === "" || import_xe_utils.default.eqNull(content))) {
|
|
return nextTick();
|
|
}
|
|
if (target) {
|
|
const { showDelayTip } = internalData;
|
|
const { trigger, enterDelay } = props;
|
|
reactData.tipActive = true;
|
|
reactData.tipTarget = target;
|
|
reactData.tipContent = content;
|
|
if (enterDelay && trigger === "hover") {
|
|
if (showDelayTip) {
|
|
showDelayTip();
|
|
}
|
|
} else {
|
|
return showTip();
|
|
}
|
|
}
|
|
return nextTick();
|
|
};
|
|
const getSelectorEl = () => {
|
|
const { selector } = props;
|
|
if (selector) {
|
|
if (import_xe_utils.default.isElement(selector)) {
|
|
return selector;
|
|
}
|
|
if (import_xe_utils.default.isString(selector)) {
|
|
return document.querySelector(selector);
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
tooltipMethods = {
|
|
dispatchEvent(type, params, evnt) {
|
|
emit(type, createEvent(evnt, { $tooltip: $xeTooltip }, params));
|
|
},
|
|
open(target, content) {
|
|
return handleVisible(target || reactData.target || getSelectorEl(), content);
|
|
},
|
|
close() {
|
|
reactData.tipTarget = null;
|
|
reactData.tipActive = false;
|
|
Object.assign(reactData.tipStore, {
|
|
style: {},
|
|
placement: "",
|
|
arrowStyle: null
|
|
});
|
|
updateValue(false);
|
|
return nextTick();
|
|
},
|
|
toVisible(target, content) {
|
|
return handleVisible(target, content);
|
|
},
|
|
updatePlacement() {
|
|
return nextTick().then(() => {
|
|
const { tipTarget } = reactData;
|
|
const el = refElem.value;
|
|
if (tipTarget && el) {
|
|
updateTipStyle();
|
|
return nextTick().then(() => {
|
|
updateTipStyle();
|
|
});
|
|
}
|
|
});
|
|
},
|
|
isActived() {
|
|
return reactData.tipActive;
|
|
},
|
|
setActived(active) {
|
|
reactData.tipActive = !!active;
|
|
}
|
|
};
|
|
const wheelEvent = (evnt) => {
|
|
evnt.stopPropagation();
|
|
};
|
|
Object.assign($xeTooltip, tooltipMethods);
|
|
const renderContent = () => {
|
|
const { useHTML } = props;
|
|
const { tipContent } = reactData;
|
|
const wrapperStyle = computeWrapperStyle.value;
|
|
const contentSlot = slots.content;
|
|
const contVNs = [];
|
|
if (contentSlot) {
|
|
contVNs.push(h("div", {
|
|
key: 1
|
|
}, getSlotVNs(contentSlot({}))));
|
|
} else if (useHTML) {
|
|
contVNs.push(h("div", {
|
|
key: 2,
|
|
innerHTML: tipContent
|
|
}));
|
|
} else {
|
|
contVNs.push(h("span", {
|
|
key: 3
|
|
}, `${tipContent}`));
|
|
}
|
|
return h("div", {
|
|
key: 3,
|
|
ref: contentWrapperfElem,
|
|
class: "vxe-tooltip--content",
|
|
style: wrapperStyle
|
|
}, contVNs);
|
|
};
|
|
const renderVN = () => {
|
|
const { popupClassName, theme, isArrow, enterable } = props;
|
|
const { tipActive, visible, tipStore } = reactData;
|
|
const defaultSlot = slots.default;
|
|
const vSize = computeSize.value;
|
|
let ons;
|
|
if (enterable) {
|
|
ons = {
|
|
onMouseenter: wrapperMouseenterEvent,
|
|
onMouseleave: wrapperMouseleaveEvent
|
|
};
|
|
}
|
|
return h("div", Object.assign({ ref: refElem, class: ["vxe-tooltip--wrapper", `theme--${theme}`, popupClassName ? import_xe_utils.default.isFunction(popupClassName) ? popupClassName({ $tooltip: $xeTooltip }) : popupClassName : "", {
|
|
[`size--${vSize}`]: vSize,
|
|
[`placement--${tipStore.placement}`]: tipStore.placement,
|
|
"is--enterable": enterable,
|
|
"is--visible": visible,
|
|
"is--arrow": isArrow,
|
|
"is--active": tipActive
|
|
}], style: tipStore.style }, ons), [
|
|
renderContent(),
|
|
h("div", {
|
|
class: "vxe-tooltip--arrow",
|
|
style: tipStore.arrowStyle
|
|
}),
|
|
...defaultSlot ? getSlotVNs(defaultSlot({})) : []
|
|
]);
|
|
};
|
|
watch(() => props.enterDelay, () => {
|
|
handleDelayFn();
|
|
});
|
|
watch(() => props.content, (val) => {
|
|
reactData.tipContent = val;
|
|
});
|
|
watch(() => props.modelValue, (val) => {
|
|
if (!reactData.isUpdate) {
|
|
if (val) {
|
|
handleVisible(reactData.target || getSelectorEl(), props.content);
|
|
} else {
|
|
tooltipMethods.close();
|
|
}
|
|
}
|
|
reactData.isUpdate = false;
|
|
});
|
|
onMounted(() => {
|
|
const contentWrapperfEl = contentWrapperfElem.value;
|
|
if (contentWrapperfEl) {
|
|
contentWrapperfEl.addEventListener("wheel", wheelEvent, { passive: false });
|
|
}
|
|
nextTick(() => {
|
|
const { trigger, content } = props;
|
|
const wrapperElem = refElem.value;
|
|
if (wrapperElem) {
|
|
const parentNode = wrapperElem.parentNode;
|
|
if (parentNode) {
|
|
reactData.tipContent = content;
|
|
reactData.tipZindex = nextZIndex();
|
|
import_xe_utils.default.arrayEach(wrapperElem.children, (elem, index) => {
|
|
if (index > 1) {
|
|
parentNode.insertBefore(elem, wrapperElem);
|
|
if (!reactData.target) {
|
|
reactData.target = elem;
|
|
}
|
|
}
|
|
});
|
|
parentNode.removeChild(wrapperElem);
|
|
const { target } = reactData;
|
|
if (target) {
|
|
if (trigger === "hover") {
|
|
target.onmouseenter = targetMouseenterEvent;
|
|
target.onmouseleave = targetMouseleaveEvent;
|
|
} else if (trigger === "click") {
|
|
target.onclick = clickEvent;
|
|
}
|
|
}
|
|
if (props.modelValue) {
|
|
handleVisible(target || getSelectorEl(), content);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
onBeforeUnmount(() => {
|
|
const { target } = reactData;
|
|
const wrapperElem = refElem.value;
|
|
if (target) {
|
|
target.onmouseenter = null;
|
|
target.onmouseleave = null;
|
|
target.onclick = null;
|
|
}
|
|
const contentWrapperfEl = contentWrapperfElem.value;
|
|
if (contentWrapperfEl) {
|
|
contentWrapperfEl.removeEventListener("wheel", wheelEvent);
|
|
}
|
|
if (wrapperElem) {
|
|
const parentNode = wrapperElem.parentNode;
|
|
if (parentNode) {
|
|
parentNode.removeChild(wrapperElem);
|
|
}
|
|
}
|
|
});
|
|
handleDelayFn();
|
|
$xeTooltip.renderVN = renderVN;
|
|
return $xeTooltip;
|
|
},
|
|
render() {
|
|
return this.renderVN();
|
|
}
|
|
});
|
|
|
|
export {
|
|
tooltip_default
|
|
};
|
|
//# sourceMappingURL=chunk-ULIXT2HE.js.map
|