websites/apps/panoramablick/components/AppThumbnailCarousel.vue
Dominik Milacher 85d080ab05
All checks were successful
Build and deploy updated apps / Build & deploy (push) Successful in 2m12s
Add panoramablick implementation
2025-06-13 23:11:04 +02:00

64 lines
1.6 KiB
Vue

<script setup lang="ts">
import {ref} from 'vue'
import {useTemplateRef} from '#imports'
interface Props {
images?: string[] // ❶ Fragezeichen = optional
}
const props = withDefaults(defineProps<Props>(), {
images: () => [
'/ap-1/1.webp',
'/ap-1/2.webp'
]
})
/* ───────── 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)
}
</script>
<template>
<div class="flex flex-col items-center justify-center p-4">
<!-- main slider -->
<UCarousel
ref="carousel"
v-slot="{ item }"
:items="props.images"
:autoplay="{ delay: 5_000 }"
:ui="{item: 'ps-0'}"
loop
class="relative w-full max-w-3xl"
@select="onSelect"
>
<img :src="item" class="w-full h-auto object-cover" alt="Bild"/>
</UCarousel>
<!-- thumbnails -->
<div class="flex 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>