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.
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