Carousel
A carousel with motion and swipe built using Stimulus.
<%= render Shadcn::Carousel.new(class_name: "w-[280px]") do |carousel| %>
<% carousel.with_slides do |slides| %>
<% slides.with_item do %>
<div class="flex aspect-square items-center justify-center rounded-md border bg-muted text-4xl font-semibold">
1
</div>
<% end %>
<% slides.with_item do %>
<div class="flex aspect-square items-center justify-center rounded-md border bg-muted text-4xl font-semibold">
2
</div>
<% end %>
<% slides.with_item do %>
<div class="flex aspect-square items-center justify-center rounded-md border bg-muted text-4xl font-semibold">
3
</div>
<% end %>
<% end %>
<% carousel.with_previous %>
<% carousel.with_next %>
<% end %>
Installation
Add the component to your project:
rails generate shadcn:add carousel
Usage
<%= render Shadcn::Carousel.new(class_name: "w-[280px]") do |carousel| %>
<% carousel.with_slides do |slides| %>
<% slides.with_item do %>
<div class="flex aspect-square items-center justify-center rounded-md border bg-muted text-4xl font-semibold">
1
</div>
<% end %>
<% slides.with_item do %>
<div class="flex aspect-square items-center justify-center rounded-md border bg-muted text-4xl font-semibold">
2
</div>
<% end %>
<% slides.with_item do %>
<div class="flex aspect-square items-center justify-center rounded-md border bg-muted text-4xl font-semibold">
3
</div>
<% end %>
<% end %>
<% carousel.with_previous %>
<% carousel.with_next %>
<% end %>
Examples
With Images
Display images in a carousel.
<div class="w-full max-w-lg mx-auto px-12">
<%= render Shadcn::CarouselComponent.new do |carousel| %>
<% carousel.with_slides do |slides| %>
<% slides.with_item do %>
<div class="aspect-video bg-gradient-to-br from-blue-500 to-purple-600 rounded-lg flex items-center justify-center text-white text-xl font-bold">
Image 1
</div>
<% end %>
<% slides.with_item do %>
<div class="aspect-video bg-gradient-to-br from-green-500 to-teal-600 rounded-lg flex items-center justify-center text-white text-xl font-bold">
Image 2
</div>
<% end %>
<% slides.with_item do %>
<div class="aspect-video bg-gradient-to-br from-orange-500 to-red-600 rounded-lg flex items-center justify-center text-white text-xl font-bold">
Image 3
</div>
<% end %>
<% end %>
<% carousel.with_previous %>
<% carousel.with_next %>
<% end %>
</div>
Custom Item Sizes
Use the basis prop on items to show multiple slides at once.
<div class="w-full max-w-xl mx-auto px-12">
<%= render Shadcn::CarouselComponent.new do |carousel| %>
<% carousel.with_slides do |slides| %>
<% 8.times do |i| %>
<% slides.with_item(basis: "basis-1/3") do %>
<div class="flex aspect-square items-center justify-center p-4 bg-muted rounded-lg">
<span class="text-2xl font-semibold"><%= i + 1 %></span>
</div>
<% end %>
<% end %>
<% end %>
<% carousel.with_previous %>
<% carousel.with_next %>
<% end %>
</div>
Vertical Orientation
Use orientation: :vertical for vertical carousels.
<div class="w-full max-w-xs mx-auto pt-12 pb-12">
<%= render Shadcn::CarouselComponent.new(orientation: :vertical) do |carousel| %>
<% carousel.with_slides(class_name: "max-h-[200px]") do |slides| %>
<% 5.times do |i| %>
<% slides.with_item do %>
<div class="flex h-[80px] items-center justify-center bg-muted rounded-lg">
<span class="text-2xl font-semibold"><%= i + 1 %></span>
</div>
<% end %>
<% end %>
<% end %>
<% carousel.with_previous %>
<% carousel.with_next %>
<% end %>
</div>
Infinite Loop
Enable infinite looping with the loop option.
<div class="w-full max-w-md mx-auto px-12">
<%= render Shadcn::CarouselComponent.new(loop: true) do |carousel| %>
<% carousel.with_slides do |slides| %>
<% 5.times do |i| %>
<% slides.with_item do %>
<div class="flex aspect-square items-center justify-center p-6 bg-muted rounded-lg">
<span class="text-4xl font-semibold"><%= i + 1 %></span>
</div>
<% end %>
<% end %>
<% end %>
<% carousel.with_previous %>
<% carousel.with_next %>
<% end %>
</div>
Autoplay
Automatically advance slides with the autoplay option.
<div class="w-full max-w-md mx-auto px-12">
<%= render Shadcn::CarouselComponent.new(autoplay: true, autoplay_interval: 3000, loop: true) do |carousel| %>
<% carousel.with_slides do |slides| %>
<% 5.times do |i| %>
<% slides.with_item do %>
<div class="flex aspect-square items-center justify-center p-6 bg-primary text-primary-foreground rounded-lg">
<span class="text-4xl font-semibold"><%= i + 1 %></span>
</div>
<% end %>
<% end %>
<% end %>
<% carousel.with_previous %>
<% carousel.with_next %>
<% end %>
</div>
With Card Content
Carousel items can contain any content, including cards.
Getting Started
Learn the basics of the framework
Components
Explore our component library
Theming
Customize colors and styles
<% cards = [
{ title: "Getting Started", description: "Learn the basics of the framework" },
{ title: "Components", description: "Explore our component library" },
{ title: "Theming", description: "Customize colors and styles" }
] %>
<div class="w-full max-w-lg mx-auto px-12">
<%= render Shadcn::Carousel.new do |carousel| %>
<% carousel.with_slides do |slides| %>
<% cards.each do |card| %>
<% slides.with_item do %>
<%= render Shadcn::Card.new do |c| %>
<% c.with_header do |header| %>
<% header.with_title { card[:title] } %>
<% header.with_description { card[:description] } %>
<% end %>
<% c.with_content do %>
<div class="h-24 bg-muted rounded flex items-center justify-center">
Content goes here
</div>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>
<% carousel.with_previous %>
<% carousel.with_next %>
<% end %>
</div>
API Reference
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| orientation |
Symbol
|
:horizontal
|
Direction of carousel (:horizontal, :vertical) |
| loop |
Boolean
|
false
|
Whether to loop infinitely |
| autoplay |
Boolean
|
false
|
Whether to auto-advance slides |
| autoplay_interval |
Integer
|
4000
|
Milliseconds between auto-advance |
| align |
Symbol
|
:start
|
Item alignment (:start, :center, :end) |
| class_name |
String
|
nil
|
Additional CSS classes |
Slots
| Slot | Description |
|---|---|
| with_slides | Container for carousel items |
| slides.with_item(basis:) | Individual carousel item. Use basis for custom widths |
| with_previous | Previous slide button |
| with_next | Next slide button |
Stimulus Controller
This component requires JavaScript. The Stimulus controller shadcn--carousel provides interactivity.
Manages carousel navigation, autoplay, keyboard navigation, and touch/swipe gestures.
Installation
Add to your config/importmap.rb:
pin "shadcn", to: "index.esm.js"
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn"
const application = Application.start()
registerShadcnControllers(application)
Install the package:
npm install shadcn-rails-stimulus
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails-stimulus"
const application = Application.start()
registerShadcnControllers(application)
Install the package:
yarn add shadcn-rails-stimulus
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails-stimulus"
const application = Application.start()
registerShadcnControllers(application)
Install the package:
npm install shadcn-rails-stimulus
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails-stimulus"
const application = Application.start()
registerShadcnControllers(application)
Or import just this controller:
import CarouselController from "shadcn-rails-stimulus/controllers/carousel_controller"
application.register("shadcn--carousel", CarouselController)
Values
| Name | Type | Default | Description |
|---|---|---|---|
| orientation | String |
"horizontal"
|
Direction (horizontal or vertical) |
| loop | Boolean |
false
|
Whether to loop infinitely |
| autoplay | Boolean |
false
|
Whether to auto-advance |
| autoplayInterval | Number |
4000
|
Milliseconds between auto-advance |
| align | String |
"start"
|
Item alignment (start, center, end) |
| selectedIndex | Number |
0
|
Currently selected slide index |
Actions
| Action | Description |
|---|---|
| previous | Go to the previous slide |
| next | Go to the next slide |
| goToSlide | Go to a specific slide by index (use data-index) |
TypeScript
Type definitions are included. Import types as needed:
import type { CarouselController } from "shadcn-rails-stimulus"
Accessibility
- Uses
role="region"witharia-roledescription="carousel" - Each slide has
role="group"witharia-roledescription="slide" - Non-visible slides are marked with
aria-hidden="true"andinert - Keyboard navigation: Arrow Left/Right (horizontal) or Up/Down (vertical)
- Touch/swipe support on mobile devices
- Autoplay pauses on hover and touch interaction
On This Page