@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
JavaScript
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
};