UNPKG

@opensig/opendesign

Version:

<p align="center"><img src="../docs/public/opendesign-logo-light.png"/></p> <h1 align="center">opendesign</h1> <p align="center">一个 Vue 3 组件库</p> <p align="center"><b>皮肤可定制,使用 TypeScript</b></p>

269 lines (268 loc) 8.28 kB
import { defineComponent, ref, watch, computed, onMounted, onUnmounted, createBlock, openBlock, Teleport, withDirectives, createCommentVNode, createElementBlock, mergeProps, createVNode, Transition, withCtx, createElementVNode, vShow, normalizeStyle, normalizeClass, renderSlot, unref, nextTick } from "vue"; import { layerProps } from "./types.mjs"; import { useMouse } from "../hooks/use-mouse.mjs"; import { isFunction } from "../_utils/is.mjs"; import { createTopZIndex, removeZIndex } from "../_utils/z-index.mjs"; import { IconClose } from "../_utils/icons.mjs"; import { OIcon } from "../icon/index.mjs"; const __default__ = { inheritAttrs: false }; const _sfc_main = /* @__PURE__ */ defineComponent({ ...__default__, __name: "OLayer", props: layerProps, emits: ["change", "update:visible", "click:mask", "click:button"], setup(__props, { expose: __expose, emit: __emit }) { const props = __props; const emits = __emit; const visible = ref(props.visible); const toMount = ref(props.visible); const zIndex = ref(visible.value ? createTopZIndex() : 0); const isToBody = ref(false); const LayerClass = { OPEN: "o-layer-open" }; const mainRef = ref(null); let mouse = useMouse({ type: "client" }); const layerRef = ref(null); let wrapperEl = null; const initWrapperEl = () => { if (!wrapperEl && layerRef.value) { wrapperEl = layerRef.value.offsetParent; if (!wrapperEl) { wrapperEl = document.body; isToBody.value = true; } else { isToBody.value = wrapperEl === document.body; } } return wrapperEl; }; const handleWrapperScroll = () => { nextTick(() => { initWrapperEl(); if (wrapperEl) { if (visible.value) { wrapperEl.classList.add(LayerClass.OPEN); } else { wrapperEl.classList.remove(LayerClass.OPEN); } } }); }; const mainStyle = ref({}); const getOriginStyle = () => { let ox = "center"; let oy = "center"; if (mainRef.value && mouse) { const { offsetLeft, offsetTop } = mainRef.value; if (isToBody.value) { ox = `${mouse.x.value - offsetLeft}px`; oy = `${mouse.y.value - offsetTop}px`; } else if (wrapperEl) { const size = wrapperEl.getBoundingClientRect(); ox = `${mouse.x.value - offsetLeft - size.x}px`; oy = `${mouse.y.value - offsetTop - size.y}px`; } } return `${ox} ${oy}`; }; const updateOrigin = (_el) => { if (props.transitionOrign === "mouse") { initWrapperEl(); mainStyle.value.transformOrigin = getOriginStyle(); } }; const beforeToggle = async (show) => { let goon = true; if (show) { if (isFunction(props.beforeShow)) { goon = await props.beforeShow(); } } else { if (isFunction(props.beforeHide)) { goon = await props.beforeHide(); } } return goon !== false; }; const updateZIndex = (show) => { if (show) { zIndex.value = createTopZIndex(); } else { removeZIndex(zIndex.value); } }; watch( () => props.visible, async (v) => { if (visible.value !== v) { const goon = await beforeToggle(v); if (!goon) { emits("update:visible", visible.value); return; } updateZIndex(v); visible.value = v; emits("change", v); handleWrapperScroll(); } } ); const toggle = async (show) => { if (visible.value === show) { return; } let toShow = show === void 0 ? !visible.value : show; const goon = await beforeToggle(toShow); if (!goon) { return; } updateZIndex(toShow); visible.value = toShow; emits("update:visible", visible.value); emits("change", visible.value); handleWrapperScroll(); }; const isMounted = computed(() => { return !props.unmountOnHide || visible.value || toMount.value; }); const handleTransitionStart = () => { toMount.value = true; }; const handleTransitionEnter = () => { if (visible.value) { updateOrigin(mainRef.value); } }; const handleTransitionEnd = () => { if (!props.unmountOnHide) { toMount.value = false; } else if (!visible.value) { toMount.value = false; } }; const onMaskClick = (e) => { if (props.maskClose) { toggle(false); } emits("click:mask", e); }; const onCloseButtonClick = (e) => { toggle(false); emits("click:button", e); }; onMounted(() => { if (visible.value) { handleWrapperScroll(); } }); onUnmounted(() => { mouse == null ? void 0 : mouse.destroy(); wrapperEl == null ? void 0 : wrapperEl.classList.remove(LayerClass.OPEN); }); __expose({ /** Toggle the OLayer */ toggle }); return (_ctx, _cache) => { return openBlock(), createBlock(Teleport, { to: props.wrapper, disabled: !props.wrapper }, [ isMounted.value ? withDirectives((openBlock(), createElementBlock( "div", mergeProps({ key: 0, ref_key: "layerRef", ref: layerRef, class: ["o-layer", { "o-layer-to-body": isToBody.value }] }, _ctx.$attrs, { style: { "--layer-z-index": zIndex.value } }), [ props.mask ? (openBlock(), createBlock(Transition, { key: 0, name: props.maskTransition, appear: true, persisted: "" }, { default: withCtx(() => [ withDirectives(createElementVNode( "div", { class: "o-layer-mask", onClick: onMaskClick }, null, 512 /* NEED_PATCH */ ), [ [vShow, visible.value] ]) ]), _: 1 /* STABLE */ }, 8, ["name"])) : createCommentVNode("v-if", true), createVNode(Transition, { appear: true, name: props.mainTransition, onBeforeEnter: handleTransitionStart, onEnter: handleTransitionEnter, onAfterEnter: handleTransitionEnd, onBeforeLeave: handleTransitionStart, onAfterLeave: handleTransitionEnd, persisted: "" }, { default: withCtx(() => [ withDirectives(createElementVNode( "div", { ref_key: "mainRef", ref: mainRef, class: normalizeClass([props.mainClass, "o-layer-main"]), style: normalizeStyle(mainStyle.value) }, [ renderSlot(_ctx.$slots, "default") ], 6 /* CLASS, STYLE */ ), [ [vShow, visible.value] ]) ]), _: 3 /* FORWARDED */ }, 8, ["name"]), props.buttonClose ? (openBlock(), createElementBlock("div", { key: 1, class: "o-layer-close", onClick: onCloseButtonClick }, [ renderSlot(_ctx.$slots, "close", {}, () => [ createVNode(unref(OIcon), { button: "", icon: unref(IconClose), class: "o-layer-close-icon" }, null, 8, ["icon"]) ]) ])) : createCommentVNode("v-if", true) ], 16 /* FULL_PROPS */ )), [ [vShow, visible.value || toMount.value] ]) : createCommentVNode("v-if", true) ], 8, ["to", "disabled"]); }; } }); export { _sfc_main as default };