troylusty.com/src/components/Carousel.astro

99 lines
3 KiB
Text
Raw Normal View History

---
interface Props {
data: string;
}
const { data } = Astro.props;
---
<div
class="pt-6"
data-slides={data}
x-data="{
// Sets the time between each slides in milliseconds
autoplayIntervalTime: 5000,
init() {
this.slides = JSON.parse(this.$el.dataset.slides);
},
currentSlideIndex: 1,
isPaused: false,
autoplayInterval: null,
previous() {
if (this.currentSlideIndex > 1) {
this.currentSlideIndex = this.currentSlideIndex - 1
} else {
// If it's the first slide, go to the last slide
this.currentSlideIndex = this.slides.length
}
},
next() {
if (this.currentSlideIndex < this.slides.length) {
this.currentSlideIndex = this.currentSlideIndex + 1
} else {
// If it's the last slide, go to the first slide
this.currentSlideIndex = 1
}
},
autoplay() {
this.autoplayInterval = setInterval(() => {
if (! this.isPaused) {
this.next()
}
}, this.autoplayIntervalTime)
},
// Updates interval time
setAutoplayInterval(newIntervalTime) {
clearInterval(this.autoplayInterval)
this.autoplayIntervalTime = newIntervalTime
this.autoplay()
},
}"
x-init="autoplay"
class="relative w-full overflow-hidden"
>
<div class="relative min-h-[50svh] w-full">
<template x-for="(slide, index) in slides">
<div
x-cloak
x-show="currentSlideIndex == index + 1"
class="absolute inset-0"
x-transition.opacity.duration.1000ms
>
<img
class="absolute inset-0 h-full w-full rounded-sm object-cover"
x-bind:src="slide.data.image.url.src"
x-bind:alt="slide.data.image.alt"
/>
<a
class="absolute inset-0 z-20"
x-bind:aria-label="slide.data.title"
x-bind:href="'/' + slide.collection + '/' + slide.slug"></a>
</div>
</template>
</div>
2025-02-13 00:25:26 +00:00
<div class="relative min-h-16">
<template x-for="(slide, index) in slides">
<div
x-show="currentSlideIndex == index + 1"
2025-02-13 00:25:26 +00:00
class="text-secondary absolute top-0 left-0 flex w-full justify-end pt-1 text-right font-serif text-lg"
x-transition.opacity.duration.1000ms.delay.100ms
>
<div class="flex w-full flex-col items-end">
<h3
x-text="slide.data.title"
x-bind:aria-describedby="'slide' + (index + 1) + 'Description'"
2025-02-13 00:25:26 +00:00
class="italic"
>
</h3>
<p
class="text-tertiary w-fit text-sm text-pretty lg:w-1/2"
x-text="slide.data.description"
x-bind:id="'slide' + (index + 1) + 'Description'"
>
</p>
</div>
</div>
</template>
</div>
</div>