Skip to content
Snippets Groups Projects
Image.vue 1.14 KiB
Newer Older
<template>
  <div
    ref="containerEl"
    class="tw-overflow-hidden"
    :class="{
      'tw-aspect-square': square,
    }"
  >
    <img
      v-if="image"
      :alt="image.altText"
      class="tw-object-cover tw-w-full tw-max-w-full tw-max-h-full"
      :src="image.image"
      :sizes="`${containerWidth}px`"
      :srcset="srcset"
      :class="{
        'tw-h-full': square,
      }"
    />
  </div>
</template>

<script lang="ts" setup>
import { Image } from '@/stores/images'
import { computed, ref } from 'vue'
import { useElementSize } from '@vueuse/core'

defineOptions({ compatConfig: { MODE: 3 } })
const props = defineProps<{ image: Image | null | undefined; square?: boolean }>()
const containerEl = ref<HTMLDivElement>()
const { width: containerWidth } = useElementSize(containerEl)

const srcset = computed(() => {
  const image = props.image
  if (!image) return ''
  let sources = [
    { width: image.width, height: image.height, url: image.image },
    ...image.thumbnails,
  ]
  if (props.square) sources = sources.filter((img) => img.width === img.height)
  return sources.map(({ width, url }) => `${url} ${width}w`).join(',')
})
</script>