hongluan-ui
Version:
Hongluan Component Library for Vue 3
1 lines • 11.5 kB
Source Map (JSON)
{"version":3,"file":"thumb2.mjs","sources":["../../../../../../packages/components/thumb/src/thumb.vue"],"sourcesContent":["<template>\n <div\n ref=\"container\"\n v-bind=\"containerAttrs\"\n :class=\"[\n namespace,\n round && 'round',\n radius && 'radius',\n bordered && 'bordered',\n effect ? effect : '',\n size,\n $attrs.class,\n type,\n full && 'full',\n ]\"\n >\n <slot v-if=\"hasLoadError\" name=\"error\">\n <div class=\"thumb-error\">{{ t('hl.image.error') }}</div>\n </slot>\n <template v-else>\n <img\n v-if=\"imageSrc !== undefined\"\n class=\"thumb-inner\"\n v-bind=\"imgAttrs\"\n :src=\"imageSrc\"\n :loading=\"loading\"\n :style=\"imageStyle\"\n :class=\"{ 'thumb-preview': preview, 'is-loading': isLoading }\"\n :crossorigin=\"crossorigin\"\n @click=\"clickHandler\"\n @load=\"handleLoad\"\n @error=\"handleError\"\n >\n <slot v-else></slot>\n <slot v-if=\"src && isLoading\" name=\"placeholder\">\n <hl-spinner class=\"thumb-placeholder\" />\n </slot>\n </template>\n <template v-if=\"preview\">\n <image-viewer\n v-if=\"showViewer\"\n :z-index=\"zIndex\"\n :crossorigin=\"crossorigin\"\n :initial-index=\"imageIndex\"\n :url-list=\"previewSrcList\"\n :infinite=\"infinite\"\n :zoom-rate=\"zoomRate\"\n :min-scale=\"minScale\"\n :max-scale=\"maxScale\"\n :hide-on-click-modal=\"hideOnClickModal\"\n :teleported=\"teleported\"\n :close-on-press-escape=\"closeOnPressEscape\"\n @close=\"closeViewer\"\n @switch=\"switchViewer\"\n >\n <div v-if=\"$slots.viewer\">\n <slot name=\"viewer\"></slot>\n </div>\n <template v-if=\"$slots['tools-after']\" #tools-after=\"imgData\">\n <slot name=\"tools-after\" v-bind=\"imgData\"></slot>\n </template>\n <template v-if=\"$slots['tools-before']\" #tools-before=\"imgData\">\n <slot name=\"tools-before\" v-bind=\"imgData\"></slot>\n </template>\n </image-viewer>\n </template>\n </div>\n</template>\n\n<script lang='ts'>\nimport {\n defineComponent,\n computed,\n ref,\n onMounted,\n watch,\n nextTick,\n useAttrs as useRawAttrs,\n} from 'vue'\nimport { fromPairs } from 'lodash-unified'\nimport { isString } from '@vue/shared'\nimport { useEventListener, useThrottleFn } from '@vueuse/core'\nimport { getScrollContainer, isClient, isInContainer, isElement } from '@hongluan-ui/utils'\nimport { useAttrs, useLocale, useNamespace } from '@hongluan-ui/hooks'\nimport ImageViewer from '@hongluan-ui/components/image-viewer'\nimport HlSpinner from '@hongluan-ui/components/spinner'\nimport { thumbProps } from './thumb'\n\nlet prevOverflow = ''\n\nexport default defineComponent({\n name: 'Thumb',\n components: {\n ImageViewer,\n HlSpinner,\n },\n inheritAttrs: false,\n props: thumbProps,\n emits: ['error', 'switch', 'close', 'load', 'show'],\n setup(props, { emit }) {\n const { namespace } = useNamespace('thumb')\n const { t } = useLocale()\n const rawAttrs = useRawAttrs()\n\n const containerAttrs = computed(() => {\n return fromPairs(\n Object.entries(rawAttrs).filter(\n ([key]) => /^(data-|on[A-Z])/i.test(key) || ['id', 'style'].includes(key),\n ),\n )\n })\n const imgAttrs = useAttrs({\n excludeListeners: true,\n excludeKeys: computed<string[]>(() => {\n return Object.keys(containerAttrs.value)\n }),\n })\n\n // init here\n const imageSrc = ref<string | undefined>()\n const hasLoadError = ref(false)\n const isLoading = ref(true)\n\n const showViewer = ref(false)\n const container = ref<HTMLElement | null>(null)\n const _scrollContainer = ref<HTMLElement | Window>()\n\n const supportLoading = isClient && 'loading' in HTMLImageElement.prototype\n let stopScrollListener: (() => void) | undefined\n let stopWheelListener: (() => void) | undefined\n\n const imageStyle = computed<any>(() => {\n const { fit } = props\n if (isClient && fit) {\n return { objectFit: fit }\n }\n return {}\n })\n\n const preview = computed(() => {\n const { previewSrcList } = props\n return Array.isArray(previewSrcList) && previewSrcList.length > 0\n })\n const teleported = computed(() => {\n return props.appendToBody || props.previewTeleported\n })\n const imageIndex = computed(() => {\n const { previewSrcList, initialIndex } = props\n let previewIndex = initialIndex\n if (initialIndex > previewSrcList.length - 1) {\n previewIndex = 0\n }\n return previewIndex\n })\n const isManual = computed(() => {\n if (props.loading === 'eager') return false\n return (!supportLoading && props.loading === 'lazy') || props.lazy\n })\n\n const loadImage = () => {\n if (!isClient) return\n if (props.src) {\n // reset status\n isLoading.value = true\n hasLoadError.value = false\n imageSrc.value = props.src\n }\n }\n\n function handleLoad(event: Event) {\n isLoading.value = false\n hasLoadError.value = false\n emit('load', event)\n }\n\n function handleError(event: Event) {\n isLoading.value = false\n hasLoadError.value = true\n emit('error', event)\n }\n\n function handleLazyLoad() {\n if (isInContainer(container.value, _scrollContainer.value)) {\n loadImage()\n removeLazyLoadListener()\n }\n }\n\n const lazyLoadHandler = useThrottleFn(handleLazyLoad, 200, true)\n\n async function addLazyLoadListener() {\n if (!isClient) return\n\n await nextTick()\n\n const { scrollContainer } = props\n if (isElement(scrollContainer)) {\n _scrollContainer.value = scrollContainer\n } else if (isString(scrollContainer) && scrollContainer !== '') {\n _scrollContainer.value = document.querySelector<HTMLElement>(scrollContainer) ?? undefined\n } else if (container.value) {\n _scrollContainer.value = getScrollContainer(container.value)\n }\n\n if (_scrollContainer.value) {\n stopScrollListener = useEventListener(\n _scrollContainer,\n 'scroll',\n lazyLoadHandler,\n )\n setTimeout(() => handleLazyLoad(), 100)\n }\n }\n\n function removeLazyLoadListener() {\n if (!isClient || !_scrollContainer.value || !lazyLoadHandler) return\n\n stopScrollListener?.()\n _scrollContainer.value = undefined\n }\n\n function wheelHandler(e: WheelEvent) {\n if (!e.ctrlKey) return\n\n if (e.deltaY < 0) {\n e.preventDefault()\n return false\n } else if (e.deltaY > 0) {\n e.preventDefault()\n return false\n }\n }\n\n function clickHandler() {\n // don't show viewer when preview is false\n if (!preview.value) return\n\n stopWheelListener = useEventListener('wheel', wheelHandler, {\n passive: false,\n })\n\n // prevent body scroll\n prevOverflow = document.body.style.overflow\n document.body.style.overflow = 'hidden'\n showViewer.value = true\n emit('show')\n }\n\n function closeViewer() {\n stopWheelListener?.()\n document.body.style.overflow = prevOverflow\n showViewer.value = false\n emit('close')\n }\n\n function switchViewer(val: number) {\n emit('switch', val)\n }\n\n watch(() => props.src, () => {\n if (isManual.value) {\n // reset status\n isLoading.value = true\n hasLoadError.value = false\n removeLazyLoadListener()\n addLazyLoadListener()\n } else {\n loadImage()\n }\n })\n\n onMounted(() => {\n if (isManual.value) {\n nextTick(addLazyLoadListener)\n } else {\n loadImage()\n }\n })\n\n return {\n namespace,\n imageSrc,\n containerAttrs,\n imgAttrs,\n teleported,\n isLoading,\n hasLoadError,\n showViewer,\n imageStyle,\n preview,\n imageIndex,\n clickHandler,\n closeViewer,\n switchViewer,\n container,\n handleError,\n handleLoad,\n t,\n }\n },\n})\n</script>\n"],"names":["ImageViewer","useRawAttrs","useAttrs","_createElementBlock"],"mappings":"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"}