Slideshow
A slideshow works similarly to a carousel, in that it shows a collection of slides within it. There are some fundamental differences though:
Slideshows rely on Alpine/Livewire to work, and especially for users to have manual control upon them.
Slides cover their slideshow container entirely.
Data is typically passed to <x-slideshow> using its slides attribute, then the elements are rendered in a loop.
<x-slideshow class="max-h-120" :slides="$slides" buttons>
@foreach($component->slides as $slide)
<x-slide align="items-center justify-center" :image="$slide['img']" class="max-h-120 overflow-hidden p-4 text-white bg-linear-to-t from-neutral-950/85 to-transparent" x-transition.opacity.duration.1000ms>
<div class="flex flex-col items-center gap-2 justify-self-center self-end">
<h3 class="text-balance text-3xl">{{ $slide['title'] }}</h3>
<span class="text-balance text-center">{!! $slide['description'] !!}</span>
<x-button type="button" no-spinner href="#" class="text-white bg-transparent shadow-none border border-white transition hover:not-active:opacity-75">{{ $slide['ctaText'] }}</x-button>
</div>
</x-slide>
@endforeach
</x-slideshow>
slides = [
[
'img' => '/assets/default-slide-1.webp',
'title' => 'Front end developers',
'description' => 'The architects of the digital world, constantly battling against their mortal enemy – browser compatibility.',
'ctaText' => 'Become a Developer',
], [
'img' => '/assets/default-slide-2.webp',
'title' => 'Back end developers',
'description' => 'Because not all superheroes wear capes, some wear headphones and stare at terminal screens',
'ctaText' => 'Become a Developer',
], [
'img' => '/assets/default-slide-3.webp',
'title' => 'Full stack developers',
'description' => 'Where “burnout” is just a fancy term for “Tuesday”.',
'ctaText' => 'Become a Developer',
]
];
#Controls
The buttons and indicators attributes provide users with a way to change which slide is displayed.
<x-slideshow class="max-h-120" :slides="$slides" buttons indicators>
@foreach($component->slides as $slide)
<x-slide align="items-center justify-center" :image="$slide['img']" class="max-h-120 overflow-hidden p-12 text-white bg-linear-to-t from-neutral-950/85 to-transparent" x-transition.opacity.duration.1000ms>
<div class="flex flex-col items-center gap-2 justify-self-center self-end">
<h3 class="text-balance text-3xl">{{ $slide['title'] }}</h3>
<span class="text-balance text-center">{!! $slide['description'] !!}</span>
<x-button type="button" no-spinner href="#" class="text-white bg-transparent shadow-none border border-white transition hover:not-active:opacity-75">{{ $slide['ctaText'] }}</x-button>
</div>
</x-slide>
@endforeach
</x-slideshow>
slides = [
[
'img' => '/assets/default-slide-1.webp',
'title' => 'Front end developers',
'description' => 'The architects of the digital world, constantly battling against their mortal enemy – browser compatibility.',
'ctaText' => 'Become a Developer',
], [
'img' => '/assets/default-slide-2.webp',
'title' => 'Back end developers',
'description' => 'Because not all superheroes wear capes, some wear headphones and stare at terminal screens',
'ctaText' => 'Become a Developer',
], [
'img' => '/assets/default-slide-3.webp',
'title' => 'Full stack developers',
'description' => 'Where “burnout” is just a fancy term for “Tuesday”.',
'ctaText' => 'Become a Developer',
]
];
#Autoplay
Thanks to the autoplay={milliseconds} attribute, slideshow do not need buttons for users to control them manually. By default, the timing is 5s (i.e. 5000ms), such as the example below, but you can set it to any value you like.
<x-slideshow class="max-h-120" :slides="$slides" autoplay>
@foreach($component->slides as $slide)
<x-slide align="items-center justify-center" :image="$slide['img']" class="max-h-120 overflow-hidden p-4 text-white bg-linear-to-t from-neutral-950/85 to-transparent" x-transition.opacity.duration.1000ms>
<div class="flex flex-col items-center gap-2 justify-self-center self-end">
<h3 class="text-balance text-3xl">{{ $slide['title'] }}</h3>
<span class="text-balance text-center">{!! $slide['description'] !!}</span>
<x-button type="button" no-spinner href="#" class="text-white bg-transparent shadow-none border border-white transition hover:not-active:opacity-75">{{ $slide['ctaText'] }}</x-button>
</div>
</x-slide>
@endforeach
</x-slideshow>
slides = [
[
'img' => '/assets/default-slide-1.webp',
'title' => 'Front end developers',
'description' => 'The architects of the digital world, constantly battling against their mortal enemy – browser compatibility.',
'ctaText' => 'Become a Developer',
], [
'img' => '/assets/default-slide-2.webp',
'title' => 'Back end developers',
'description' => 'Because not all superheroes wear capes, some wear headphones and stare at terminal screens',
'ctaText' => 'Become a Developer',
], [
'img' => '/assets/default-slide-3.webp',
'title' => 'Full stack developers',
'description' => 'Where “burnout” is just a fancy term for “Tuesday”.',
'ctaText' => 'Become a Developer',
]
];
In addition, you can use the with-pause attribute to add a Play/Pause button to the bottom-right of the slideshow and, of course, you can add buttons to autoplay slideshows if you want your user to still be able to have manual control.
<x-slideshow class="max-h-120" autoplay="3000" with-pause buttons indicators :slides="$slides">
@foreach($component->slides as $slide)
<x-slide align="items-center justify-center" :image="$slide['img']" class="max-h-120 overflow-hidden p-12 text-white bg-linear-to-t from-neutral-950/85 to-transparent" x-transition.opacity.duration.1000ms>
<div class="flex flex-col items-center gap-2 justify-self-center self-end">
<h3 class="text-balance text-3xl">{{ $slide['title'] }}</h3>
<span class="text-balance text-center">{!! $slide['description'] !!}</span>
<x-button type="button" no-spinner href="#" class="text-white bg-transparent shadow-none border border-white transition hover:not-active:opacity-75">{{ $slide['ctaText'] }}</x-button>
</div>
</x-slide>
@endforeach
</x-slideshow>
slides = [
[
'img' => '/assets/default-slide-1.webp',
'title' => 'Front end developers',
'description' => 'The architects of the digital world, constantly battling against their mortal enemy – browser compatibility.',
'ctaText' => 'Become a Developer',
], [
'img' => '/assets/default-slide-2.webp',
'title' => 'Back end developers',
'description' => 'Because not all superheroes wear capes, some wear headphones and stare at terminal screens',
'ctaText' => 'Become a Developer',
], [
'img' => '/assets/default-slide-3.webp',
'title' => 'Full stack developers',
'description' => 'Where “burnout” is just a fancy term for “Tuesday”.',
'ctaText' => 'Become a Developer',
]
];
#Hardcoded slides
Although this should be an exception in your website, it is in fact possible to render slides without using a for-each loop.
A slideshow where slides rendering is hardcoded must satisfy either of the following 2 conditions:
Its children are
<x-slide>components.Or it is provided the
count={integer}attribute as a clue for what it contains.
<x-slideshow class="max-h-120" count="3" buttons>
<x-slide image="/assets/default-slide-1.webp" class="p-4 text-white flex flex-col gap-2 items-center justify-end bg-linear-to-t from-neutral-950/85 to-transparent" x-transition.opacity.duration.1000ms>
<div class="flex flex-col items-center gap-2 justify-self-center self-end">
<h3 class="text-balance text-3xl">Front end developers</h3>
The architects of the digital world, constantly battling against their mortal enemy – browser compatibility.
<x-button type="button" no-spinner href="#" class="text-white bg-transparent shadow-none border border-white transition hover:not-active:opacity-75">Become a Developer</x-button>
</div>
</x-slide>
<x-slide image="/assets/default-slide-2.webp" class="p-4 text-white flex flex-col gap-2 items-center justify-end bg-linear-to-t from-neutral-950/85 to-transparent" x-transition.opacity.duration.1000ms>
<div class="flex flex-col items-center gap-2 justify-self-center self-end">
<h3 class="text-balance text-3xl">Back end developers</h3>
Because not all superheroes wear capes, some wear headphones and stare at terminal screens.
<x-button type="button" no-spinner href="#" class="text-white bg-transparent shadow-none border border-white transition hover:not-active:opacity-75">Become a Developer</x-button>
</div>
</x-slide>
<x-slide image="/assets/default-slide-3.webp" class="p-4 text-white flex flex-col gap-2 items-center justify-end bg-linear-to-t from-neutral-950/85 to-transparent" x-transition.opacity.duration.1000ms>
<div class="flex flex-col items-center gap-2 justify-self-center self-end">
<h3 class="text-balance text-3xl">Full stack developers</h3>
Where “burnout” is just a fancy term for “Tuesday”.
<x-button type="button" no-spinner href="#" class="text-white bg-transparent shadow-none border border-white transition hover:not-active:opacity-75">Become a Developer</x-button>
</div>
</x-slide>
</x-slideshow>
#Using <template>
If that is your preferred way of working, generating slides with <template> is also possible. To achieve this, you need to provide:
The
template-slotattribute as a clue to the slideshow.The
slidesattribute containing your slide object; it will be accessible as a Javascript variable calledslides.Alpine's
x-cloak x-show="currentSlideIndex == index + 1"attributes or equivalent Javascript code inside the slide's root<div>to control which slide is displayed at any time.
<x-slideshow template-slot class="max-h-120" buttons indicators :slides="$slides">
<template x-for="(slide, index) in slides">
<div x-cloak x-show="currentSlideIndex == index + 1" class="flex items-center justify-center" x-transition.opacity.duration.1000ms>
<img class="w-full" x-bind:src="slide.imgSrc" x-bind:alt="slide.imgAlt" />
<div class="grid grid-cols-1 grid-rows-1 *:row-start-1 *:col-start-1 absolute top-0 w-full h-full max-h-120 overflow-hidden p-12 text-white bg-linear-to-t from-neutral-950/85 to-transparent">
<div class="flex flex-col items-center gap-2 justify-self-center self-end">
<h3 class="text-balance text-3xl" x-text="slide.title" x-bind:aria-describedby="'slide' + (index + 1) + 'Description'"></h3>
<span class="text-balance text-center" x-text="slide.description" x-bind:id="'slide' + (index + 1) + 'Description'"></span>
<a href="#" class="btn text-white bg-transparent shadow-none border border-white transition hover:not-active:opacity-75" type="button" x-text="slide.ctaText"></a>
</div>
</div>
</div>
</template>
</x-slideshow>
slides = [
[
'imgSrc' => '/assets/default-slide-1.webp',
'title' => 'Front end developers',
'description' => 'The architects of the digital world, constantly battling against their mortal enemy – browser compatibility.',
'ctaUrl' => '#',
'ctaText' => 'Become a Developer',
], [
'imgSrc' => '/assets/default-slide-2.webp',
'title' => 'Back end developers',
'description' => 'Because not all superheroes wear capes, some wear headphones and stare at terminal screens',
'ctaUrl' => '#',
'ctaText' => 'Become a Developer',
], [
'imgSrc' => '/assets/default-slide-3.webp',
'title' => 'Full stack developers',
'description' => 'Where "burnout" is just a fancy term for "Tuesday".',
'ctaUrl' => '#',
'ctaText' => 'Become a Developer',
]
];