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>

252 lines (251 loc) 9.51 kB
"use strict"; const vue = require("vue"); const global = require("../_utils/global.js"); const htmlTag = require("../_components/html-tag.js"); const index = require("../layer/index.js"); const icons = require("../_utils/icons.js"); const is = require("../_utils/is.js"); const useIntersectionObserver = require("../hooks/use-intersection-observer.js"); const useScreen = require("../hooks/use-screen.js"); const types = require("./types.js"); const helper = require("../_utils/helper.js"); const _hoisted_1 = { key: 0, class: "o-figure-error-wrap" }; const _hoisted_2 = ["src", "alt", "loading"]; const _hoisted_3 = ["src", "alt", "loading"]; const _hoisted_4 = { key: 1, class: "o-figure-main" }; const _hoisted_5 = { key: 0, class: "o-figure-mask" }; const _hoisted_6 = { class: "o-figure-play-icon" }; const _hoisted_7 = { key: 1, class: "o-figure-content" }; const _hoisted_8 = { class: "o-figure-title" }; const _hoisted_9 = { class: "o-figure-preview-img" }; const _hoisted_10 = ["src"]; const _sfc_main = /* @__PURE__ */ vue.defineComponent({ __name: "OFigure", props: types.figureProps, emits: ["error", "load", "preview"], setup(__props, { expose: __expose, emit: __emit }) { const props = __props; const emits = __emit; const imgRef = vue.ref(null); const { isPhonePad } = useScreen.useScreen(); const isLoading = vue.ref(true); const isError = vue.ref(false); const prestColor = props.colorful ? global.defaultPrestColorPool.value.pick() : ""; const imgSrc = vue.ref(void 0); const bgUrl = vue.computed(() => props.background && imgSrc.value ? `url(${imgSrc.value})` : void 0); const useObserver = props.lazy && props.background || is.isObject(props.lazy); const onImgLoaded = () => { isLoading.value = false; isError.value = false; emits("load"); }; const onImgError = () => { isLoading.value = false; isError.value = true; emits("error"); }; vue.watchEffect(() => { if (!props.src) { return; } if (props.lazy === false) { imgSrc.value = props.src; } else { if (!useObserver) { imgSrc.value = props.src; } } if (props.background && imgSrc.value) { helper.requestImage(imgSrc.value).then(onImgLoaded).catch(onImgError); } }); let io = null; const rootEl = vue.ref(null); vue.onMounted(() => { if (imgRef.value && imgRef.value.complete && imgSrc.value) { onImgLoaded(); } if (useObserver) { io = useIntersectionObserver.useIntersectionObserver(is.isObject(props.lazy) ? props.lazy : {}); if (rootEl.value) { io == null ? void 0 : io.observe(rootEl.value.$el, (entry) => { if (entry.isIntersecting) { imgSrc.value = props.src; } }); } } }); const paddingTop = vue.computed(() => { if (props.ratio) { return `${(1 / props.ratio * 100).toFixed(2)}%`; } return ""; }); const previewVisible = vue.ref(false); const canPreview = vue.computed(() => props.preview || props.lazyPreiew); const previewCloseTypes = vue.computed(() => { if (!props.previewClose) { return isPhonePad.value ? ["image", "mask", "button"] : ["mask", "button"]; } else if (Array.isArray(props.previewClose)) { return props.previewClose; } return [props.previewClose]; }); const isMaskClose = vue.computed(() => previewCloseTypes.value.includes("mask")); const isButtonClose = vue.computed(() => previewCloseTypes.value.includes("button")); const isBodyClose = vue.computed(() => previewCloseTypes.value.includes("body")); const preview = (visible = true) => { if (canPreview.value) { previewVisible.value = visible; } }; const onPreviewChange = (visible) => { emits("preview", visible); }; const onPreviewImgClick = () => { if (isBodyClose.value) { previewVisible.value = false; } }; const onFigureClick = () => { if (props.preview) { preview(); } }; __expose({ preview }); return (_ctx, _cache) => { return vue.openBlock(), vue.createBlock(vue.unref(htmlTag), { tag: !!props.href ? "a" : "div", class: vue.normalizeClass(["o-figure", { "is-loading": isLoading.value, "is-error": isError.value, "is-colorful": props.colorful, "o-figure-hoverable": props.hoverable || !!props.href || props.preview || props.videoPoster, "o-figure-previewable": props.preview, "o-figure-video-poster": props.videoPoster }]), href: props.href, style: vue.normalizeStyle({ "--figure-prest-color": vue.unref(prestColor), "--figure-padding-top": paddingTop.value, "--figure-fit": props.fit }), onClick: onFigureClick, ref_key: "rootEl", ref: rootEl }, { default: vue.withCtx(() => [ imgSrc.value ? (vue.openBlock(), vue.createElementBlock( vue.Fragment, { key: 0 }, [ paddingTop.value || isError.value ? (vue.openBlock(), vue.createElementBlock( "div", { key: 0, class: vue.normalizeClass(["o-figure-wrap", { "o-figure-bg": props.background }]), style: vue.normalizeStyle({ backgroundImage: bgUrl.value }) }, [ isError.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [ vue.renderSlot(_ctx.$slots, "error", {}, () => [ vue.createVNode(vue.unref(icons.IconImageError)) ]) ])) : !props.background ? (vue.openBlock(), vue.createElementBlock("img", { key: 1, ref_key: "imgRef", ref: imgRef, src: imgSrc.value, alt: props.alt, class: "o-figure-img-ratio", loading: props.lazy === true ? "lazy" : "eager", onLoad: onImgLoaded, onError: onImgError }, null, 40, _hoisted_2)) : vue.createCommentVNode("v-if", true) ], 6 /* CLASS, STYLE */ )) : !isError.value ? (vue.openBlock(), vue.createElementBlock("img", { key: 1, ref_key: "imgRef", ref: imgRef, src: imgSrc.value, alt: props.alt, class: "o-figure-img", loading: props.lazy === true ? "lazy" : "eager", onLoad: onImgLoaded, onError: onImgError }, null, 40, _hoisted_3)) : vue.createCommentVNode("v-if", true) ], 64 /* STABLE_FRAGMENT */ )) : vue.createCommentVNode("v-if", true), props.videoPoster || _ctx.$slots.content || _ctx.$slots.title || _ctx.$slots.default ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_4, [ vue.renderSlot(_ctx.$slots, "default"), props.videoPoster ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_5, [ vue.renderSlot(_ctx.$slots, "play-icon", {}, () => [ vue.createElementVNode("div", _hoisted_6, [ vue.createVNode(vue.unref(icons.IconVideoPlay)) ]) ]) ])) : vue.createCommentVNode("v-if", true), _ctx.$slots.content || _ctx.$slots.title ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_7, [ vue.renderSlot(_ctx.$slots, "content", {}, () => [ vue.createElementVNode("div", _hoisted_8, [ vue.renderSlot(_ctx.$slots, "title") ]) ]) ])) : vue.createCommentVNode("v-if", true) ])) : vue.createCommentVNode("v-if", true), canPreview.value ? (vue.openBlock(), vue.createBlock(vue.unref(index.OLayer), { key: 2, visible: previewVisible.value, "onUpdate:visible": _cache[0] || (_cache[0] = ($event) => previewVisible.value = $event), class: "o-figure-preview-layer", onChange: onPreviewChange, "mask-close": isMaskClose.value, "button-close": isButtonClose.value }, { default: vue.withCtx(() => [ vue.createElementVNode("div", { class: "o-figure-preview-wrapper", onClick: onPreviewImgClick }, [ vue.renderSlot(_ctx.$slots, "preview", { image: imgSrc.value }, () => [ vue.createElementVNode("div", _hoisted_9, [ vue.createElementVNode("img", { src: imgSrc.value }, null, 8, _hoisted_10) ]), vue.renderSlot(_ctx.$slots, "preview-extra") ]) ]) ]), _: 3 /* FORWARDED */ }, 8, ["visible", "mask-close", "button-close"])) : vue.createCommentVNode("v-if", true) ]), _: 3 /* FORWARDED */ }, 8, ["tag", "href", "class", "style"]); }; } }); module.exports = _sfc_main;