UNPKG

@extclp/vexip-ui

Version:

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

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