Carousel
A slideshow for cycling through content, built on native scroll-snap.
Installation
Included in poetry-ui — available as
poetry_carousel
the moment you've installed Poetry,
with no per-component step. To own the source and edit it, copy it into your app:
bin/rails g poetry:add carousel
Default
<%= poetry_carousel(label: "Featured artwork", class: "mx-14 w-64") do |carousel| %>
<% 3.times do |n| %>
<% carousel.with_item do %>
<div class="flex aspect-square items-center justify-center rounded-md border bg-muted text-2xl">
Slide <%= n + 1 %>
</div>
<% end %>
<% end %>
<% end %>
Sizes
<%= poetry_carousel(label: "Gallery sizes", class: "mx-14 w-full max-w-48 sm:max-w-xs md:max-w-sm") do |carousel| %>
<% 5.times do |n| %>
<% carousel.with_item(classes: "basis-1/2 lg:basis-1/3") do %>
<div class="flex aspect-square items-center justify-center rounded-md border bg-muted text-2xl font-semibold">
<%= n + 1 %>
</div>
<% end %>
<% end %>
<% end %>
Spacing
<%# The spacing trio: track_classes swaps the track's negative margin, and
each item swaps its gutter padding AND the matching snap scroll-margin -
the two must always move together. %>
<%= poetry_carousel(label: "Tight gallery", track_classes: "-ml-1",
class: "mx-14 w-full max-w-48 sm:max-w-xs md:max-w-sm") do |carousel| %>
<% 5.times do |n| %>
<% carousel.with_item(classes: "basis-1/2 lg:basis-1/3 pl-1 -scroll-ml-1") do %>
<div class="flex aspect-square items-center justify-center rounded-md border bg-muted text-xl font-semibold">
<%= n + 1 %>
</div>
<% end %>
<% end %>
<% end %>
Vertical
<%= poetry_carousel(label: "Release milestones", orientation: :vertical, class: "mx-auto my-14 grid h-64 w-52") do |carousel| %>
<% ["Draft the plan", "Ship the beta", "Gather feedback", "Fix the papercuts", "Polish the docs", "Cut the release"].each_with_index do |milestone, n| %>
<% carousel.with_item do %>
<div class="flex h-28 flex-col items-center justify-center gap-1 rounded-md border bg-muted p-4 text-center">
<span class="text-xs font-medium text-muted-foreground">Week <%= n + 1 %></span>
<span class="text-sm font-semibold"><%= milestone %></span>
</div>
<% end %>
<% end %>
<% end %>
API
Poetry::Ui::Carousel::Component — options are
constructor keywords (the poetry_* helper forwards them);
slots are composed inside the block. Generated from the gem's source documentation.
| Option | Type | Details | Description |
|---|---|---|---|
| label: | String | required | The carousel region's accessible name - required; rendering without it raises. |
| orientation: | Symbol | one of: horizontal, vertical; defaults to :horizontal |
The scroll axis; snapping, controls, and arrow keys follow it. |
| show_controls: | Boolean | defaults to true |
Renders the prev/next buttons; slides stay reachable by swipe, wheel, and keyboard without them. |
| track_classes: | String | Utility classes for the slide track - change spacing as a trio: track_classes: \"-ml-1\" pairs with item classes \"pl-1 -scroll-ml-1\". |
Slots
| Writer | Description |
|---|---|
| with_item | Declares one slide. The content block is required; classes: sizes the slide (basis-full default). |
Styling
Every part carries a stable data-slot attribute — target
[data-slot=…] from your own CSS to restyle it. State rides
data attributes on the parts below. This contract is verified against rendered DOM in CI.
| Part | Description |
|---|---|
| [data-slot=carousel] | The role=region root - the controller (paging, button state, arrow keys) rides here |
| [data-slot=carousel-content] | The viewport - a real scroll-snap container (tabindex=0); the platform owns the physics |
| [data-slot=carousel-item] | One role=group slide - sized by item classes (basis-full default) |
State attributes
| Part | Attribute | Condition | Values |
|---|---|---|---|
| carousel | data-orientation | the scroll axis | horizontal · vertical |
Wiring
The Stimulus surface each element carries — declared in the component, verified against rendered DOM in CI. Bare actions fire on the element's default event.
| Element | Controller | Wiring |
|---|---|---|
| root | poetry--core--carousel | registers · value orientation · keydown on keydown |
| viewport | poetry--core--carousel | scrolled on scroll · target viewport |
| previous | poetry--core--carousel | previous on click · target previous |
| next | poetry--core--carousel | next on click · target next |