TallStackUI 4.0 is here! Seven new components and thousand of improvements. See what's new .

Powerful suite of Blade components for TALL Stack apps

Carousel

Carousel component.

<!-- Basic array -->
<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
]" />
 
<!-- Also accept Laravel collection -->
<x-carousel :images="collect([
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
])" />
<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
]" round />
 
<!--
default => rounded-xl,
xs => rounded-xs,
sm => rounded-sm,
md => rounded-md,
lg => rounded-lg,
xl => rounded-xl,
2xl => rounded-2xl,
3xl => rounded-3xl,
full => rounded-full,
-->
<x-carousel ... round="xl" />
<!-- Using a dedicated attribute -->
<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
]" :cover="2" />
 
<!-- Setting per file -->
<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2', 'cover' => true],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
]" />

An option to shuffle the images in the carousel.

<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
]" shuffle />
<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
]" autoplay />
 
<!-- You can use "interval" to control the time in seconds. -->
<x-carousel ... autoplay interval="2" />
<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
]" autoplay stop-on-hover />
<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
]" autoplay without-loop />
<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
]" without-indicators />

An option to render a row of small square tiles below the slides.

<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
]" thumbnails />

Clicking a tile moves the carousel to that slide and restarts the autoplay timer, exactly like the dot indicators. The tile of the current slide carries a primary ring and aria-current="true" , the other tiles carry a subtle gray ring. The strip already shows the position, so thumbnails implies without-indicators . The tiles follow the shuffle order and round applies to them the same way it applies to the slides.

<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
['src' => url('assets/images/wallpapers/4.jpg'), 'alt' => 'Wallpaper 4'],
['src' => url('assets/images/wallpapers/5.jpg'), 'alt' => 'Wallpaper 5'],
['src' => url('assets/images/wallpapers/6.jpg'), 'alt' => 'Wallpaper 6'],
['src' => url('assets/images/wallpapers/7.jpg'), 'alt' => 'Wallpaper 7'],
['src' => url('assets/images/wallpapers/8.jpg'), 'alt' => 'Wallpaper 8'],
['src' => url('assets/images/wallpapers/9.jpg'), 'alt' => 'Wallpaper 9'],
]" thumbnails :limit="5" round="xl" />

limit caps the number of tiles, six by default. When the carousel holds more images than the limit, the last tile keeps its image under a +N overlay counting the images left out of the strip. Clicking it moves to that image and the arrows keep going from there. While the current slide sits beyond the visible tiles, the last tile keeps the highlight.

<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
]" thumbnails without-highlight />

without-highlight drops the primary ring, so every tile shares the inactive look while aria-current keeps marking the current slide for assistive technology.

Click a thumbnail to jump to that photo.

<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
]" thumbnails autoplay :interval="5" stop-on-hover>
<x-slot:footer>
<p class="mt-2 text-sm text-gray-500">Click a thumbnail to jump to that photo.</p>
</x-slot:footer>
</x-carousel>

The strip sits between the slides and the footer slot.

limit and without-highlight require thumbnails , and limit must be at least 2
You can turn the strip on for every carousel, and set the default limit and without-highlight , in the configuration file. The inline attributes always win, so :thumbnails="false" hides the strip on a single carousel. without-highlight is only read when the strip renders, so a carousel without thumbnails ignores it instead of throwing.
// ...
 
'carousel' => [
Components\Carousel\Component::class,
[
// ...
'thumbnails' => true,
'limit' => 6,
'without-highlight' => false,
],
],
 
// ...
<x-carousel :images="[
[
'src' => url('assets/images/wallpapers/1.jpg'),
'alt' => 'Wallpaper 1',
'title' => 'Image 1',
'description' => 'Lorem Ipsum is simply dummy text of the printing and typesetting industry.'
],
[
'src' => url('assets/images/wallpapers/2.jpg'),
'alt' => 'Wallpaper 2',
'title' => 'Image 2',
'description' => 'Lorem Ipsum is simply dummy text of the printing and typesetting industry.'
],
[
'src' => url('assets/images/wallpapers/3.jpg'),
'alt' => 'Wallpaper 3',
'title' => 'Image 3',
'description' => 'Lorem Ipsum is simply dummy text of the printing and typesetting industry.'
],
]" />

An option to allow the images to be expanded when clicked.

<!-- When clickable is set, clicking any image opens it in a fullscreen
lightbox with a close button at the top-right. Esc and clicking
outside the image also close it. -->
<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
]" clickable />
 
<!-- The lightbox dispatches expand/collapse events on the carousel root.
$event.detail will receive: {image: object|null} -->
<x-carousel :images="[...]" clickable
x-on:expand="alert('Lightbox opened: ' + $event.detail.image.alt)"
x-on:collapse="alert('Lightbox closed')" />

An option to display a title and description in the lightbox.

<x-carousel clickable caption="overlay" :images="$images" />

You can also set caption="footer" to display the title and description out of the image.

<x-carousel clickable caption="footer" :images="$images" />

An option to browse the gallery from inside the lightbox.

<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
]" clickable navigable />
The navigable prop requires clickable .
<x-carousel clickable navigable caption="overlay" :images="[
[
'src' => url('assets/images/wallpapers/1.jpg'),
'alt' => 'Wallpaper 1',
'title' => 'Image 1',
'description' => 'Lorem Ipsum is simply dummy text of the printing and typesetting industry.'
],
[
'src' => url('assets/images/wallpapers/2.jpg'),
'alt' => 'Wallpaper 2',
'title' => 'Image 2',
'description' => 'Lorem Ipsum is simply dummy text of the printing and typesetting industry.'
],
[
'src' => url('assets/images/wallpapers/3.jpg'),
'alt' => 'Wallpaper 3',
'title' => 'Image 3',
'description' => 'Lorem Ipsum is simply dummy text of the printing and typesetting industry.'
],
]" />
<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
]" clickable navigable without-loop />
<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
]" wrapper="aspect-[3/1]" />
Remember to rebuild your assets to tell TailwindCSS to build these aspect ratio classes.

An option to show the whole image over a blurred copy of itself.

<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1', 'backdrop' => true],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3', 'backdrop' => true],
]" wrapper="aspect-[3/1]" />

An image that sets 'backdrop' => true shows whole and centered over a blurred, enlarged copy of itself that fills the empty bands, instead of being cropped to the frame. The carousel keeps the same height on every slide, and the images without the key keep the default crop, like the second slide above.

<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1', 'backdrop' => true],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2', 'backdrop' => true],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3', 'backdrop' => true],
]" wrapper="aspect-[3/1]" round clickable />

The copy lives inside the slide, so url , target , clickable and stop-on-hover work the same way, and round clips it to the slide corners. The copy is decorative, rendered with an empty alt and aria-hidden="true" , and the thumbnail tiles and the lightbox show the plain image.

The image of a backdrop slide uses the images.contain block instead of images.base , and the blurred copy uses images.backdrop.wrapper and images.backdrop.image , so you can tune the effect through soft customization.
// AppServiceProvider, "boot" method.
 
TallStackUi::customize()
->carousel()
->block('images.backdrop.image')
->replace('blur-lg', 'blur-2xl');
Header
Footer
<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
]">
<x-slot:header>
Header
</x-slot:header>
<x-slot:footer>
Footer
</x-slot:footer>
</x-carousel>
<!--
The "next" and "previous" events fire both for the main carousel view
and for in-lightbox navigation when "navigable" is enabled. The same
listeners cover both cases without changes.
$event.detail will receive: {current: integer, image: object{current image}}
-->
 
<x-carousel :images="[
['src' => url('assets/images/wallpapers/1.jpg'), 'alt' => 'Wallpaper 1'],
['src' => url('assets/images/wallpapers/2.jpg'), 'alt' => 'Wallpaper 2'],
['src' => url('assets/images/wallpapers/3.jpg'), 'alt' => 'Wallpaper 3'],
]" x-on:next="alert('Navigated to the next image')"
x-on:previous="alert('Navigated to the previous image')" />
 
<!--
"expand" and "collapse" fire only on the actual open/close transitions
of the lightbox — not on each step of the in-lightbox navigation. Use
"next" / "previous" to track navigation inside the lightbox.
-->
Event Detail Fired when
expand { image } The lightbox opens
collapse { image: null } The lightbox closes
next { current, image } The carousel or lightbox steps forward
previous { current, image } The carousel or lightbox steps backward

Code highlighting provided by Torchlight