UNPKG

@opensig/opendesign

Version:

140 lines (139 loc) 4.2 kB
import { render, h, nextTick } from "vue"; import { isString } from "../_utils/is.mjs"; import _sfc_main from "./OMessageList.vue.mjs"; import { resolveHtmlElement } from "../_utils/vue-utils.mjs"; const DEFAULT_OPTIONS = { status: "info", position: "top", duration: 3e3 }; const instanceMap = /* @__PURE__ */ new Map(); const targetOffset = 8; const normalizeOptions = (params) => { const options = !params || isString(params) ? { content: params } : params; const normalized = { ...DEFAULT_OPTIONS, ...options }; return normalized; }; const getMessageStyle = (targetEl, position = "top", align = "center") => { if (!targetEl) { return; } const rect = targetEl.getBoundingClientRect(); let pos = "bottom"; let top = window.innerHeight - rect.top + targetOffset; let left = rect.left; let transform = "translateX(-50%)"; if (position === "bottom") { pos = "top"; top = rect.top + rect.height + targetOffset; } if (align === "right") { left = rect.left + rect.width; transform = "translateX(-100%)"; } else if (align === "left") { left = rect.left; transform = "translateX(0%)"; } else { left = rect.left + rect.width / 2; transform = "translateX(-50%)"; } return { position: pos, "--message-list-offset": `${top}px`, [`--message-list-${pos}-offset`]: `${top}px`, left: `${left}px`, transform }; }; const createMessageListVnode = ({ position, wrap, style, targetEl }) => { return h(_sfc_main, { position: (style == null ? void 0 : style.position) ?? position, onDestroy: async () => { if (wrap) { render(null, wrap); await nextTick(); document.body.removeChild(wrap); } instanceMap.delete(targetEl ?? position); }, style }); }; const showMessage = (target, closeHandlers, params) => { const options = normalizeOptions(params); const { position, targetAlign } = options; let id = -1; let instance; let isClosed = false; resolveHtmlElement(target).then((targetEl) => { var _a, _b; if (isClosed) { return; } const msgStyle = getMessageStyle(targetEl, position, targetAlign); instance = instanceMap.get(targetEl ?? position); if (!instance) { const wrap = document.createElement("div"); const vnode = createMessageListVnode({ position, wrap, style: msgStyle, targetEl }); render(vnode, wrap); const vm = vnode.component; id = (_a = vm.exposed) == null ? void 0 : _a.add(options); instance = vm; instanceMap.set(targetEl ?? position, instance); document.body.appendChild(wrap); } else { id = (_b = instance.exposed) == null ? void 0 : _b.add(options); } }); const closeHandler = () => { var _a; isClosed = true; (_a = instance == null ? void 0 : instance.exposed) == null ? void 0 : _a.close(id); closeHandlers.delete(closeHandler); }; closeHandlers.add(closeHandler); return closeHandler; }; const showMessageWithStatus = (status, target, closeHandlers, params) => { return showMessage(target, closeHandlers, { ...normalizeOptions(params), status }); }; const closeAll = () => { var _a; for (const ins of instanceMap.values()) { (_a = ins == null ? void 0 : ins.exposed) == null ? void 0 : _a.removeAll(); } }; const close = (closeHandlers) => { closeHandlers.forEach((handler) => handler()); }; function useMessage(target) { const closeHandlers = /* @__PURE__ */ new Set(); return { show: showMessage.bind(null, target, closeHandlers), info: showMessageWithStatus.bind(null, "info", target, closeHandlers), success: showMessageWithStatus.bind(null, "success", target, closeHandlers), warning: showMessageWithStatus.bind(null, "warning", target, closeHandlers), danger: showMessageWithStatus.bind(null, "danger", target, closeHandlers), loading: showMessageWithStatus.bind(null, "loading", target, closeHandlers), /** 关闭本 useMessage 实例渲染的所有消息 */ close: close.bind(null, closeHandlers), /** 关闭所有实例渲染的所有消息 */ closeAll }; } export { useMessage };