{"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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"}