Dominik Milacher b8ec6af312
All checks were successful
Build and deploy updated apps / Build & deploy (push) Successful in 1m55s
Hacky fix for carousel
2025-10-16 13:51:32 +02:00

87 lines
2.5 KiB
Vue

<script setup lang="ts">
// import {ref} from 'vue'
// const {t, tm, rt} = useVariantData()
// import {useTemplateRef} from '#imports'
//
interface Props {
images?: string[] // ❶ Fragezeichen = optional
}
//
const props = withDefaults(defineProps<Props>(), {
images: () => [
'https://picsum.photos/200/300'
]
})
/* ───────── shared slider state ───────── */
const carousel = useTemplateRef('carousel')
const activeIndex = ref(0)
function onSelect(index: number) {
activeIndex.value = index
}
function select(index: number) {
activeIndex.value = index
carousel.value?.emblaApi?.scrollTo(index)
}
// Weird stuff is going on here.
// - If the page loads slowly, some images are not shown in the carousel viewport
// - However they are visible when dragging left or right
// - When removing overflow-hidden from the direct parent of the images row all are visible
// - Potentially only happens when auto-height plugin is used
// - When resizing the window suddenly all images become visible
// - Updating the key to force to re-render is just a hack
const loaded = Object.fromEntries(props.images.map(img => [img, ref(img)]))
function setLoaded(item) {
loaded[item].value = item + 'loaded'
}
</script>
<template>
<div class="flex flex-col items-center justify-start p-4">
<!-- main slider -->
<UCarousel
ref="carousel"
auto-height
arrows
prev-icon="i-lucide-chevron-left"
next-icon="i-lucide-chevron-right"
v-slot="{ item }"
:items="props.images"
:autoplay="{ delay: 5_000 }"
:ui="{item: 'ps-0',
controls: 'absolute top-6 inset-x-15',
dots: '-top-7',
dot: 'w-1 h-1'}"
loop
class="relative w-full"
@select="onSelect"
>
<NuxtImg :key="loaded[item]" :src="item" class="object-cover" alt="Bild" preload @load="setLoaded(item)"/>
</UCarousel>
<!-- thumbnails -->
<!-- <div class="flex flex-wrap gap-2 pt-4">-->
<!-- <button-->
<!-- v-for="(thumb, idx) in props.images"-->
<!-- :key="idx"-->
<!-- @click="select(idx)"-->
<!-- :class="[-->
<!-- 'size-16 rounded-lg overflow-hidden opacity-40 hover:opacity-100',-->
<!-- 'transition-opacity focus:outline-none focus-visible:ring',-->
<!-- activeIndex === idx && 'opacity-100 ring-2 ring-primary-500'-->
<!-- ]"-->
<!-- >-->
<!-- <img :src="thumb" alt="" class="w-full h-full object-cover"/>-->
<!-- </button>-->
<!-- </div>-->
</div>
</template>