Carousel
Examples
Default
A carousel built with Embla Carousel.
1
2
3
4
5
<div class="mx-auto w-full max-w-xs">
<%= render "ui/carousel" do %>
<%= render "ui/carousel/content" do %>
<% 5.times do |i| %>
<%= render "ui/carousel/item" do %>
<div class="p-1">
<div class="flex aspect-square items-center justify-center p-6 border rounded-lg">
<span class="text-4xl font-semibold"><%= i + 1 %></span>
</div>
</div>
<% end %>
<% end %>
<% end %>
<%= render "ui/carousel/previous" %>
<%= render "ui/carousel/next" %>
<% end %>
</div>
1
2
3
4
5
<div class="mx-auto w-full max-w-xs">
<%= render UI::Carousel.new do %>
<%= render UI::CarouselContent.new do %>
<% 5.times do |i| %>
<%= render UI::CarouselItem.new do %>
<div class="p-1">
<div class="flex aspect-square items-center justify-center p-6 border rounded-lg">
<span class="text-4xl font-semibold"><%= i + 1 %></span>
</div>
</div>
<% end %>
<% end %>
<% end %>
<%= render UI::CarouselPrevious.new %>
<%= render UI::CarouselNext.new %>
<% end %>
</div>
1
2
3
4
5
<div class="mx-auto w-full max-w-xs">
<%= render UI::CarouselComponent.new do %>
<%= render UI::CarouselContentComponent.new do %>
<% 5.times do |i| %>
<%= render UI::CarouselItemComponent.new do %>
<div class="p-1">
<div class="flex aspect-square items-center justify-center p-6 border rounded-lg">
<span class="text-4xl font-semibold"><%= i + 1 %></span>
</div>
</div>
<% end %>
<% end %>
<% end %>
<%= render UI::CarouselPreviousComponent.new %>
<%= render UI::CarouselNextComponent.new %>
<% end %>
</div>Sizes
Set the size of an item using the classes prop.
1
2
3
4
5
<div class="mx-auto w-full max-w-sm">
<%= render "ui/carousel" do %>
<%= render "ui/carousel/content" do %>
<% 5.times do |i| %>
<%= render "ui/carousel/item", classes: "md:basis-1/2 lg:basis-1/3" do %>
<div class="p-1">
<div class="flex aspect-square items-center justify-center p-6 border rounded-lg">
<span class="text-3xl font-semibold"><%= i + 1 %></span>
</div>
</div>
<% end %>
<% end %>
<% end %>
<%= render "ui/carousel/previous" %>
<%= render "ui/carousel/next" %>
<% end %>
</div>
1
2
3
4
5
<div class="mx-auto w-full max-w-sm">
<%= render UI::Carousel.new do %>
<%= render UI::CarouselContent.new do %>
<% 5.times do |i| %>
<%= render UI::CarouselItem.new(classes: "md:basis-1/2 lg:basis-1/3") do %>
<div class="p-1">
<div class="flex aspect-square items-center justify-center p-6 border rounded-lg">
<span class="text-3xl font-semibold"><%= i + 1 %></span>
</div>
</div>
<% end %>
<% end %>
<% end %>
<%= render UI::CarouselPrevious.new %>
<%= render UI::CarouselNext.new %>
<% end %>
</div>
1
2
3
4
5
<div class="mx-auto w-full max-w-sm">
<%= render UI::CarouselComponent.new do %>
<%= render UI::CarouselContentComponent.new do %>
<% 5.times do |i| %>
<%= render UI::CarouselItemComponent.new(classes: "md:basis-1/2 lg:basis-1/3") do %>
<div class="p-1">
<div class="flex aspect-square items-center justify-center p-6 border rounded-lg">
<span class="text-3xl font-semibold"><%= i + 1 %></span>
</div>
</div>
<% end %>
<% end %>
<% end %>
<%= render UI::CarouselPreviousComponent.new %>
<%= render UI::CarouselNextComponent.new %>
<% end %>
</div>Spacing
Set the spacing between items using the content classes.
1
2
3
4
5
<div class="mx-auto w-full max-w-sm">
<%= render "ui/carousel" do %>
<%= render "ui/carousel/content", classes: "-ml-4" do %>
<% 5.times do |i| %>
<%= render "ui/carousel/item", classes: "pl-4 md:basis-1/2 lg:basis-1/3" do %>
<div class="flex aspect-square items-center justify-center p-6 border rounded-lg">
<span class="text-3xl font-semibold"><%= i + 1 %></span>
</div>
<% end %>
<% end %>
<% end %>
<%= render "ui/carousel/previous" %>
<%= render "ui/carousel/next" %>
<% end %>
</div>
1
2
3
4
5
<div class="mx-auto w-full max-w-sm">
<%= render UI::Carousel.new do %>
<%= render UI::CarouselContent.new(classes: "-ml-4") do %>
<% 5.times do |i| %>
<%= render UI::CarouselItem.new(classes: "pl-4 md:basis-1/2 lg:basis-1/3") do %>
<div class="flex aspect-square items-center justify-center p-6 border rounded-lg">
<span class="text-3xl font-semibold"><%= i + 1 %></span>
</div>
<% end %>
<% end %>
<% end %>
<%= render UI::CarouselPrevious.new %>
<%= render UI::CarouselNext.new %>
<% end %>
</div>
1
2
3
4
5
<div class="mx-auto w-full max-w-sm">
<%= render UI::CarouselComponent.new do %>
<%= render UI::CarouselContentComponent.new(classes: "-ml-4") do %>
<% 5.times do |i| %>
<%= render UI::CarouselItemComponent.new(classes: "pl-4 md:basis-1/2 lg:basis-1/3") do %>
<div class="flex aspect-square items-center justify-center p-6 border rounded-lg">
<span class="text-3xl font-semibold"><%= i + 1 %></span>
</div>
<% end %>
<% end %>
<% end %>
<%= render UI::CarouselPreviousComponent.new %>
<%= render UI::CarouselNextComponent.new %>
<% end %>
</div>Orientation Vertical
Use the orientation prop to set a vertical carousel.
1
2
3
4
5
<div class="mx-auto w-full max-w-xs py-16">
<%= render "ui/carousel", orientation: "vertical", classes: "w-full max-w-xs", opts: { align: "start" } do %>
<%= render "ui/carousel/content", classes: "-mt-1 h-[200px]" do %>
<% 5.times do |i| %>
<%= render "ui/carousel/item", classes: "pt-1 md:basis-1/2" do %>
<div class="p-1">
<div class="flex items-center justify-center p-6 border rounded-lg min-h-[120px]">
<span class="text-3xl font-semibold"><%= i + 1 %></span>
</div>
</div>
<% end %>
<% end %>
<% end %>
<%= render "ui/carousel/previous" %>
<%= render "ui/carousel/next" %>
<% end %>
</div>
1
2
3
4
5
<div class="mx-auto w-full max-w-xs py-16">
<%= render UI::Carousel.new(orientation: "vertical", classes: "w-full max-w-xs", opts: { align: "start" }) do %>
<%= render UI::CarouselContent.new(classes: "-mt-1 h-[200px]") do %>
<% 5.times do |i| %>
<%= render UI::CarouselItem.new(classes: "pt-1 md:basis-1/2") do %>
<div class="p-1">
<div class="flex items-center justify-center p-6 border rounded-lg min-h-[120px]">
<span class="text-3xl font-semibold"><%= i + 1 %></span>
</div>
</div>
<% end %>
<% end %>
<% end %>
<%= render UI::CarouselPrevious.new %>
<%= render UI::CarouselNext.new %>
<% end %>
</div>
1
2
3
4
5
<div class="mx-auto w-full max-w-xs py-16">
<%= render UI::CarouselComponent.new(orientation: "vertical", classes: "w-full max-w-xs", opts: { align: "start" }) do %>
<%= render UI::CarouselContentComponent.new(classes: "-mt-1 h-[200px]") do %>
<% 5.times do |i| %>
<%= render UI::CarouselItemComponent.new(classes: "pt-1 md:basis-1/2") do %>
<div class="p-1">
<div class="flex items-center justify-center p-6 border rounded-lg min-h-[120px]">
<span class="text-3xl font-semibold"><%= i + 1 %></span>
</div>
</div>
<% end %>
<% end %>
<% end %>
<%= render UI::CarouselPreviousComponent.new %>
<%= render UI::CarouselNextComponent.new %>
<% end %>
</div>Autoplay with Loop
Use plugins to enable autoplay and loop functionality.
1
2
3
4
5
<div class="mx-auto w-full max-w-xs">
<%= render "ui/carousel",
opts: { loop: true },
plugins: [
{ name: "autoplay", options: { delay: 2000, stopOnInteraction: false } }
] do %>
<%= render "ui/carousel/content" do %>
<% 5.times do |i| %>
<%= render "ui/carousel/item" do %>
<div class="p-1">
<div class="flex aspect-square items-center justify-center p-6 border rounded-lg bg-gradient-to-br from-purple-500 to-pink-500">
<span class="text-4xl font-semibold text-white"><%= i + 1 %></span>
</div>
</div>
<% end %>
<% end %>
<% end %>
<%= render "ui/carousel/previous" %>
<%= render "ui/carousel/next" %>
1
2
3
4
5
<div class="mx-auto w-full max-w-xs">
<%= render UI::Carousel.new(
opts: { loop: true },
plugins: [
{ name: "autoplay", options: { delay: 2000, stopOnInteraction: false } }
]
) do %>
<%= render UI::CarouselContent.new do %>
<% 5.times do |i| %>
<%= render UI::CarouselItem.new do %>
<div class="p-1">
<div class="flex aspect-square items-center justify-center p-6 border rounded-lg bg-gradient-to-br from-purple-500 to-pink-500">
<span class="text-4xl font-semibold text-white"><%= i + 1 %></span>
</div>
</div>
<% end %>
<% end %>
<% end %>
<%= render UI::CarouselPrevious.new %>
<%= render UI::CarouselNext.new %>
1
2
3
4
5
<div class="mx-auto w-full max-w-xs">
<%= render UI::CarouselComponent.new(
opts: { loop: true },
plugins: [
{ name: "autoplay", options: { delay: 2000, stopOnInteraction: false } }
]
) do %>
<%= render UI::CarouselContentComponent.new do %>
<% 5.times do |i| %>
<%= render UI::CarouselItemComponent.new do %>
<div class="p-1">
<div class="flex aspect-square items-center justify-center p-6 border rounded-lg bg-gradient-to-br from-purple-500 to-pink-500">
<span class="text-4xl font-semibold text-white"><%= i + 1 %></span>
</div>
</div>
<% end %>
<% end %>
<% end %>
<%= render UI::CarouselPreviousComponent.new %>
<%= render UI::CarouselNextComponent.new %>Features
- Custom styling with Tailwind classes
- ARIA attributes for accessibility
- Keyboard navigation with arrow keys
API Reference
Carousel
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| orientation | String | horizontal | Orientation (horizontal or vertical) |
| opts | Hash | {} | The opts |
| plugins | String | nil | The plugins |
Content
Item
Next
Previous
Accessibility
Adheres to theCarousel WAI-ARIA design pattern
Implements the WAI-ARIA Carousel pattern with proper roles, states, and keyboard navigation.
ARIA Attributes
- aria-roledescription
- role="region"
Keyboard Shortcuts
| Key | Description |
|---|---|
| ArrowDown | Moves focus to next item |
| ArrowUp | Moves focus to previous item |
| ArrowLeft | Moves focus left or decreases value |
| ArrowRight | Moves focus right or increases value |
JavaScript
Stimulus Controller
ui--carouselValues
| Name | Type | Description |
|---|---|---|
| orientation | String | Layout orientation |
Actions
initializeCarouselbuildPluginsapplyOrientationClasseskeydownEvents
| Event | Description | Detail |
|---|---|---|
| carousel:init | Fired when carousel init | - |