UNPKG

@extclp/vexip-ui

Version:

A Vue 3 UI library, Highly customizability, full TypeScript, performance pretty good

1 lines 14.4 kB
{"version":3,"file":"image.vue2.mjs","sources":["../../../components/image/image.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { ImageViewer } from '@/components/image-viewer'\r\nimport { Renderer } from '@/components/renderer'\r\nimport { Skeleton } from '@/components/skeleton'\r\n\r\nimport { computed, inject, onBeforeUnmount, reactive, ref, watch, watchEffect } from 'vue'\r\n\r\nimport { emitEvent, useLocale, useNameHelper, useProps } from '@vexip-ui/config'\r\nimport { useIntersection } from '@vexip-ui/hooks'\r\nimport { isClient, supportImgLoading, toCssSize } from '@vexip-ui/utils'\r\nimport { imageProps } from './props'\r\nimport { GROUP_STATE, objectFitValues } from './symbol'\r\n\r\nimport type { ImageSlots, ImageState } from './symbol'\r\n\r\nconst useImgLoading = supportImgLoading()\r\n\r\ndefineOptions({ name: 'Image' })\r\n\r\nconst _props = defineProps(imageProps)\r\nconst props = useProps('image', _props, {\r\n src: {\r\n default: '',\r\n static: true,\r\n },\r\n fallbackSrc: '',\r\n alt: '',\r\n fit: {\r\n default: 'cover',\r\n validator: value => objectFitValues.includes(value),\r\n },\r\n width: '',\r\n height: '',\r\n imgAttrs: () => ({}),\r\n lazy: false,\r\n root: {\r\n default: null,\r\n static: true,\r\n },\r\n rootMargin: '',\r\n preview: false,\r\n skeleton: false,\r\n placeholder: '',\r\n errorTip: '',\r\n radius: 0,\r\n border: false,\r\n previewSrc: '',\r\n viewerTransfer: null,\r\n viewerProps: () => ({}),\r\n slots: () => ({}),\r\n})\r\n\r\nconst slots = defineSlots<ImageSlots>()\r\n\r\nconst groupState = inject(GROUP_STATE, null)\r\n\r\nconst nh = useNameHelper('image')\r\nconst locale = useLocale('image')\r\n\r\nconst showImg = ref(useImgLoading)\r\nconst loading = ref(showImg.value)\r\nconst currentSrc = ref('')\r\nconst loadFail = ref(false)\r\nconst fallbackFail = ref(false)\r\nconst viewerActive = ref(false)\r\nconst hidden = ref(false)\r\n\r\nconst wrapper = ref<HTMLElement>()\r\n\r\nconst showError = computed(() => {\r\n return loadFail.value && (!props.fallbackSrc || fallbackFail.value)\r\n})\r\nconst hasPreview = computed(() => !groupState && props.preview)\r\nconst className = computed(() => {\r\n return [\r\n nh.b(),\r\n nh.bs('vars'),\r\n {\r\n [nh.bm('inherit')]: props.inherit,\r\n [nh.bm('border')]: props.border,\r\n [nh.bm('loading')]: loading.value,\r\n [nh.bm('error')]: showError.value,\r\n [nh.bm('preview')]: groupState?.preview || hasPreview.value,\r\n },\r\n ]\r\n})\r\nconst style = computed(() => {\r\n const style: Record<string, string> = {\r\n width: toCssSize(props.width),\r\n height: toCssSize(props.height),\r\n [nh.cv('fit')]: props.fit,\r\n [nh.cv('radius')]: props.radius ? `${props.radius}px` : '',\r\n }\r\n\r\n if (props.border && typeof props.border === 'string') {\r\n style[nh.cv('b-color')] = props.border\r\n }\r\n\r\n return style\r\n})\r\nconst imageSrc = computed(() => props.src || (props.imgAttrs?.src as string))\r\nconst imgLoading = computed(() => {\r\n return hidden.value || (useImgLoading && props.lazy) ? 'lazy' : undefined\r\n})\r\nconst skeletonProps = computed(() => {\r\n return typeof props.skeleton === 'object'\r\n ? Object.assign({ activated: true }, props.skeleton)\r\n : { activated: true }\r\n})\r\n\r\nwatch(imageSrc, value => {\r\n loading.value = showImg.value\r\n currentSrc.value = value\r\n loadFail.value = false\r\n fallbackFail.value = false\r\n})\r\nwatch(\r\n () => props.fallbackSrc,\r\n value => {\r\n fallbackFail.value = false\r\n\r\n if (loadFail.value) {\r\n loading.value = showImg.value\r\n currentSrc.value = value\r\n }\r\n },\r\n)\r\n\r\ncurrentSrc.value = imageSrc.value\r\n\r\nconst state: ImageState = reactive({\r\n src: computed(() => props.previewSrc || currentSrc.value),\r\n index: 0,\r\n total: 0,\r\n})\r\n\r\nif (groupState) {\r\n groupState.increaseItem(state)\r\n\r\n const stopWatch = watchEffect(() => {\r\n hidden.value = !groupState.showAll && state.index > 0\r\n })\r\n\r\n onBeforeUnmount(() => {\r\n stopWatch()\r\n groupState.decreaseItem(state)\r\n })\r\n}\r\n\r\nif (!useImgLoading) {\r\n let disconnect: (() => void) | undefined\r\n\r\n const stopWatch = watchEffect(() => {\r\n disconnect?.()\r\n disconnect = undefined\r\n\r\n if (!isClient) return\r\n\r\n const root =\r\n typeof props.root === 'string' ? document.querySelector(props.root) : (props.root as Element)\r\n\r\n if (props.lazy) {\r\n disconnect = useIntersection({\r\n root: typeof root === 'object' ? root : document.documentElement,\r\n rootMargin: props.rootMargin,\r\n target: wrapper,\r\n handler: () => {\r\n disconnect?.()\r\n disconnect = undefined\r\n showImg.value = true\r\n loading.value = true\r\n },\r\n }).disconnect\r\n }\r\n })\r\n\r\n onBeforeUnmount(() => {\r\n stopWatch()\r\n disconnect?.()\r\n })\r\n}\r\n\r\ndefineExpose({\r\n loading,\r\n fallbackFail,\r\n viewerActive,\r\n hidden,\r\n wrapper,\r\n})\r\n\r\nfunction handleLoad(event: Event) {\r\n loading.value = false\r\n\r\n if (!props.fallbackSrc || currentSrc.value !== props.fallbackSrc) {\r\n emitEvent(props.onLoad, event)\r\n }\r\n}\r\n\r\nfunction handleError(event: Event) {\r\n if (props.fallbackSrc) {\r\n if (currentSrc.value === props.fallbackSrc) {\r\n loading.value = false\r\n fallbackFail.value = true\r\n\r\n return\r\n }\r\n\r\n currentSrc.value = props.fallbackSrc\r\n } else {\r\n loading.value = false\r\n }\r\n\r\n loadFail.value = true\r\n emitEvent(props.onError, event)\r\n}\r\n\r\nfunction handlePreview() {\r\n if (!groupState) {\r\n if (props.preview) {\r\n viewerActive.value = true\r\n }\r\n\r\n emitEvent(props.onPreview, props.previewSrc || currentSrc.value)\r\n return\r\n }\r\n\r\n groupState.handlePreview(state)\r\n}\r\n</script>\r\n\r\n<template>\r\n <div\r\n v-show=\"!hidden\"\r\n ref=\"wrapper\"\r\n :class=\"className\"\r\n role=\"none\"\r\n :style=\"style\"\r\n >\r\n <slot v-if=\"loading\" name=\"placeholder\">\r\n <Renderer :renderer=\"props.slots.placeholder\">\r\n <Skeleton\r\n v-if=\"props.skeleton\"\r\n v-bind=\"skeletonProps\"\r\n :class=\"nh.be('skeleton')\"\r\n image\r\n ></Skeleton>\r\n <template v-else>\r\n <span :class=\"nh.be('placeholder')\">\r\n {{ props.placeholder || locale.placeholder }}\r\n </span>\r\n </template>\r\n </Renderer>\r\n </slot>\r\n <slot v-else-if=\"showError\" name=\"error\">\r\n <Renderer :renderer=\"props.slots.error\">\r\n <span :class=\"nh.be('error')\">\r\n {{ props.errorTip || props.alt || locale.error }}\r\n </span>\r\n </Renderer>\r\n </slot>\r\n <img\r\n v-if=\"showImg && !showError\"\r\n v-bind=\"props.imgAttrs\"\r\n :class=\"nh.be('img')\"\r\n :src=\"currentSrc\"\r\n :alt=\"props.alt\"\r\n :width=\"props.width || undefined\"\r\n :height=\"props.height || undefined\"\r\n :loading=\"imgLoading\"\r\n :aria-label=\"props.alt\"\r\n @load=\"handleLoad\"\r\n @error=\"handleError\"\r\n @click=\"handlePreview\"\r\n />\r\n <ImageViewer\r\n v-if=\"hasPreview\"\r\n v-bind=\"viewerProps\"\r\n v-model:active=\"viewerActive\"\r\n :src-list=\"props.previewSrc || currentSrc\"\r\n :transfer=\"props.viewerTransfer\"\r\n >\r\n <template v-if=\"slots.preview || props.slots.preview\" #default=\"{ src }\">\r\n <slot name=\"preview\" :src=\"src\">\r\n <Renderer :renderer=\"props.slots.preview\" :data=\"{ src }\"></Renderer>\r\n </slot>\r\n </template>\r\n </ImageViewer>\r\n </div>\r\n</template>\r\n"],"names":["useImgLoading","supportImgLoading","props","useProps","__props","value","objectFitValues","slots","_useSlots","groupState","inject","GROUP_STATE","nh","useNameHelper","locale","useLocale","showImg","ref","loading","currentSrc","loadFail","fallbackFail","viewerActive","hidden","wrapper","showError","computed","hasPreview","className","style","toCssSize","imageSrc","_a","imgLoading","skeletonProps","watch","state","reactive","stopWatch","watchEffect","onBeforeUnmount","disconnect","isClient","root","useIntersection","__expose","handleLoad","event","emitEvent","handleError","handlePreview","_createElementBlock","_renderSlot","_ctx","_createVNode","_unref","Renderer","_createBlock","Skeleton","_mergeProps","_normalizeClass","_toDisplayString","_createElementVNode","_openBlock","ImageViewer","viewerProps","$event","_withCtx","src"],"mappings":"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"}