Petal Pro is the full SaaS app this is built for

Auth, billing, admin, and Claude Code integration included. One purchase, unlimited projects.

Carousel

A customizable carousel component for displaying slides with navigation controls, indicators, and multiple transition effects.

A simple carousel with default fade transition and overlay navigation buttons.

<.carousel id="basic-carousel">
<:slide image="https://images.unsplash.com/photo-1517694712202-14dd9538aa97" />
<:slide image="https://images.unsplash.com/photo-1498050108023-c5249f4df085" />
<:slide image="https://images.unsplash.com/photo-1461749280684-dccba630e2f6" />
</.carousel>
With Title and Description

Add titles and descriptions to provide context for each slide.

<.carousel id="content-carousel">
<:slide
title="Modern Design"
description="Clean and beautiful interfaces"
image="https://images.unsplash.com/photo-1517694712202-14dd9538aa97"
/>
<:slide
title="Easy Integration"
description="Drop-in components"
image="https://images.unsplash.com/photo-1498050108023-c5249f4df085"
/>
</.carousel>
Slide Transition

Use slide transitions instead of fade for horizontal movement between slides.

<.carousel id="slide-carousel" transition_type="slide" rounded="xl">
<:slide
title="First Slide"
description="Smooth horizontal transitions"
image="https://images.unsplash.com/photo-1557804506-669a67965ba0"
/>
</.carousel>
With Autoplay

Enable autoplay to automatically cycle through slides. Hover to pause.

<.carousel
id="autoplay-carousel"
autoplay={true}
autoplay_interval={3000}
rounded="2xl"
>
<:slide image="https://images.unsplash.com/photo-1542291026-7eec264c27ff" />
</.carousel>
Button Styles

Choose from overlay, below, sides, or no buttons.

Overlay Buttons (default)

Below Buttons

Side Buttons

No Buttons

<!-- Overlay Buttons (default) -->
<.carousel id="overlay-buttons" button_style="overlay" rounded="lg">
<:slide image="https://images.unsplash.com/photo-1491553895911-0055eca6402d" />
<:slide image="https://images.unsplash.com/photo-1560343090-f0409e92791a" />
</.carousel>
<!-- Below Buttons -->
<.carousel id="below-buttons" button_style="below" rounded="lg">
<:slide image="https://images.unsplash.com/photo-1600185365926-3a2ce3cdb9eb" />
<:slide image="https://images.unsplash.com/photo-1525966222134-fcfa99b8ae77" />
</.carousel>
<!-- Side Buttons -->
<.carousel id="sides-buttons" button_style="sides" rounded="lg">
<:slide image="https://images.unsplash.com/photo-1554412933-514a83d2f3c8" />
<:slide image="https://images.unsplash.com/photo-1515886657613-9f3515b0c78f" />
</.carousel>
<!-- No Buttons -->
<.carousel id="no-buttons" button_style="none" indicator={true} rounded="lg">
<:slide image="https://images.unsplash.com/photo-1490481651871-ab68de25d43d" />
<:slide image="https://images.unsplash.com/photo-1483985988355-763728e1935b" />
</.carousel>
Indicators

Show slide indicators with bars or dots style.

Bar Indicators (default)

Dot Indicators

<!-- Bar Indicators (default) -->
<.carousel id="bar-indicators" indicator={true} indicator_style="bars" rounded="lg">
<:slide image="https://images.unsplash.com/photo-1551434678-e076c223a692" />
<:slide image="https://images.unsplash.com/photo-1499951360447-b19be8fe80f5" />
<:slide image="https://images.unsplash.com/photo-1518655048521-f130df041f66" />
</.carousel>
<!-- Dot Indicators -->
<.carousel id="dot-indicators" indicator={true} indicator_style="dots" rounded="lg">
<:slide image="https://images.unsplash.com/photo-1487958449943-2429e8be8625" />
<:slide image="https://images.unsplash.com/photo-1502672260266-1c1ef2d93688" />
<:slide image="https://images.unsplash.com/photo-1484154218962-a197022b5858" />
</.carousel>
Rounded Corners

Apply different border radius values from sm to 3xl.

Rounded SM

Rounded LG

Rounded 3XL

<!-- Rounded SM -->
<.carousel id="rounded-sm" rounded="sm">
<:slide image="https://images.unsplash.com/photo-1531545514256-b1400bc00f31" />
<:slide image="https://images.unsplash.com/photo-1531403009284-440f080d1e12" />
<:slide image="https://images.unsplash.com/photo-1552664730-d307ca884978" />
</.carousel>
<!-- Rounded LG -->
<.carousel id="rounded-lg" rounded="lg">
<:slide image="https://images.unsplash.com/photo-1531403009284-440f080d1e12" />
<:slide image="https://images.unsplash.com/photo-1552664730-d307ca884978" />
<:slide image="https://images.unsplash.com/photo-1531545514256-b1400bc00f31" />
</.carousel>
<!-- Rounded 3XL -->
<.carousel id="rounded-3xl" rounded="3xl">
<:slide image="https://images.unsplash.com/photo-1552664730-d307ca884978" />
<:slide image="https://images.unsplash.com/photo-1531545514256-b1400bc00f31" />
<:slide image="https://images.unsplash.com/photo-1531403009284-440f080d1e12" />
</.carousel>
Multi-Slide View

Show multiple slides at once with responsive breakpoints.

<.carousel
id="multi-slide"
transition_type="slide"
indicator={true}
button_style="sides"
slides_per_view={3}
gap="1.5rem"
rounded="lg"
>
<:slide image="https://images.unsplash.com/photo-1542291026-7eec264c27ff" />
<:slide image="https://images.unsplash.com/photo-1460353581641-37baddab0fa2" />
<:slide image="https://images.unsplash.com/photo-1595950653106-6c9ebd614d3a" />
<:slide image="https://images.unsplash.com/photo-1491553895911-0055eca6402d" />
<:slide image="https://images.unsplash.com/photo-1560343090-f0409e92791a" />
<:slide image="https://images.unsplash.com/photo-1600185365926-3a2ce3cdb9eb" />
</.carousel>
With Gradient Overlay

Add edge gradients to hint at more content in multi-slide carousels.

<.carousel
id="gradient-overlay"
transition_type="slide"
indicator={true}
button_style="sides"
slides_per_view={3}
gap="1.5rem"
rounded="lg"
overlay_gradient={true}
>
<:slide image="https://images.unsplash.com/photo-1512941937669-90a1b58e7e9c" />
<:slide image="https://images.unsplash.com/photo-1574944985070-8f3ebc6b79d2" />
<:slide image="https://images.unsplash.com/photo-1519389950473-47ba0277781c" />
<:slide image="https://images.unsplash.com/photo-1550745165-9bc0b252726f" />
<:slide image="https://images.unsplash.com/photo-1593642532400-2682810df593" />
</.carousel>
Vertical Orientation

Display slides vertically with up and down navigation.

<.carousel
id="vertical-carousel"
orientation="vertical"
transition_type="slide"
indicator={true}
button_style="sides"
rounded="xl"
>
<:slide
title="Vertical Slides"
description="Perfect for mobile app screenshots or tall content"
image="https://images.unsplash.com/photo-1506905925346-21bda4d32df4"
/>
<:slide
title="Swipe Enabled"
description="Touch-friendly vertical scrolling on all devices"
image="https://images.unsplash.com/photo-1514565131-fce0801e5785"
/>
<:slide
title="Snap Scrolling"
description="Automatically snaps to each slide position"
image="https://images.unsplash.com/photo-1441974231531-c6227db76b6e"
/>
</.carousel>
Non-Looping

Disable looping for a definitive start and end. Buttons disable at boundaries.

<.carousel
id="non-looping"
transition_type="slide"
indicator={true}
button_style="sides"
rounded="xl"
loop={false}
>
<:slide
title="Step One"
description="Navigation disabled when at first slide"
image="https://images.unsplash.com/photo-1531545514256-b1400bc00f31"
/>
<:slide
title="Step Two"
description="Both navigation buttons are active here"
image="https://images.unsplash.com/photo-1531403009284-440f080d1e12"
/>
<:slide
title="Step Three"
description="Navigation disabled when at last slide"
image="https://images.unsplash.com/photo-1552664730-d307ca884978"
/>
</.carousel>
Brightness Control

Adjust image brightness behind text content (1-10 scale).

Brightness 2 (darker)

Brightness 8 (lighter)

<!-- Brightness 2 (darker) -->
<.carousel id="brightness-dark" brightness={2} rounded="lg">
<:slide
title="Dark Overlay"
description="Better readability with darker background overlay"
image="https://images.unsplash.com/photo-1633356122544-f134324a6cee"
/>
<:slide
title="Professional Look"
description="Darker overlays create a sophisticated aesthetic"
image="https://images.unsplash.com/photo-1486312338219-ce68d2c6f44d"
/>
<:slide
title="Enhanced Text"
description="Text pops against the darker background"
image="https://images.unsplash.com/photo-1504384308090-c894fdcc538d"
/>
</.carousel>
<!-- Brightness 8 (lighter) -->
<.carousel id="brightness-light" brightness={8} rounded="lg">
<:slide
title="Light Overlay"
description="Subtle overlay lets image shine through more"
image="https://images.unsplash.com/photo-1506905925346-21bda4d32df4"
/>
<:slide
title="Natural Look"
description="Lighter overlays preserve the original image beauty"
image="https://images.unsplash.com/photo-1511707171634-5f897ff02aa9"
/>
<:slide
title="Airy Feel"
description="Creates a bright and welcoming atmosphere"
image="https://images.unsplash.com/photo-1515378791036-0648a3ef77b2"
/>
</.carousel>
Content Position

Position slide content at start, center, or end.

Content Position: Start

Content Position: Center

Content Position: End

<!-- Content Position: Start -->
<.carousel id="position-start" rounded="lg">
<:slide
content_position="start"
title="Left Aligned"
description="Title and description aligned to the left"
image="https://images.unsplash.com/photo-1517694712202-14dd9538aa97"
/>
<:slide
content_position="start"
title="Start Position"
description="Perfect for left-to-right reading patterns"
image="https://images.unsplash.com/photo-1498050108023-c5249f4df085"
/>
<:slide
content_position="start"
title="Natural Flow"
description="Consistent alignment across all slides"
image="https://images.unsplash.com/photo-1461749280684-dccba630e2f6"
/>
</.carousel>
<!-- Content Position: Center -->
<.carousel id="position-center" rounded="lg">
<:slide
content_position="center"
title="Centered"
description="Title and description centered on the slide"
image="https://images.unsplash.com/photo-1498050108023-c5249f4df085"
/>
<:slide
content_position="center"
title="Balanced Layout"
description="Great for hero sections and featured content"
image="https://images.unsplash.com/photo-1557804506-669a67965ba0"
/>
<:slide
content_position="center"
title="Symmetrical Design"
description="Creates a professional and polished appearance"
image="https://images.unsplash.com/photo-1522071820081-009f0129c71c"
/>
</.carousel>
<!-- Content Position: End -->
<.carousel id="position-end" rounded="lg">
<:slide
content_position="end"
title="Right Aligned"
description="Title and description aligned to the right"
image="https://images.unsplash.com/photo-1461749280684-dccba630e2f6"
/>
<:slide
content_position="end"
title="End Position"
description="Ideal for right-to-left languages or unique layouts"
image="https://images.unsplash.com/photo-1573497019940-1c28c88b4f3e"
/>
<:slide
content_position="end"
title="Alternative Style"
description="Stand out with unconventional text alignment"
image="https://images.unsplash.com/photo-1551434678-e076c223a692"
/>
</.carousel>
Clickable Slides

Make slides clickable with navigate for internal routes or href for external links.

<.carousel id="clickable-carousel" rounded="lg">
<:slide
title="Internal Link"
description="Navigate to another page in your app"
image="https://images.unsplash.com/photo-1551434678-e076c223a692"
navigate="/components"
/>
<:slide
title="External Link"
description="Opens in a new tab for external sites"
image="https://images.unsplash.com/photo-1499951360447-b19be8fe80f5"
href="https://github.com/petalframework/petal_components"
/>
</.carousel>
Properties
Attribute Type Default Description
active_index integer 0 Index of the active slide (starts at 0)
aspect string nil Height derives from width at a fixed ratio - 16:9 (video), 4:3 (photo) or 1:1 (square) - instead of the default fixed responsive heights. Constrain the width with a wrapper (e.g. max-w-sm) for the compact product-card look; thumbnails match the ratio
one of: nil, "video", "photo", "square"
autoplay boolean false Enable or disable autoplay functionality
autoplay_interval integer 5000 Time between slides in ms
brightness integer 5 Controls image brightness behind text content (1-10, where 10 is brightest and 1 is darkest)
button_style string "overlay" Button placement: 'overlay' (floating on the frame), 'below' (under the carousel), 'outside' (flanking the frame along the travel axis - left/right when horizontal, above/below when vertical), or 'none'
class string nil Custom CSS class for additional styling
control boolean true Determines whether to show navigation controls
gap string "1rem" Gap between slides when slides_per_view > 1
id string A unique identifier is used to manage state and interaction
indicator boolean false Specifies whether to show element indicators
indicator_position string "overlay" overlay floats the indicators on the imagery; below places them under the frame in page colours
one of: "overlay", "below"
indicator_style string "bars" Style of indicators: 'bars' (horizontal bars) or 'dots' (circular dots)
loop boolean true Enable infinite looping (when false, carousel has definitive start/end)
orientation string "horizontal" Orientation of the carousel: 'horizontal' (default) or 'vertical'
one of: "horizontal", "vertical"
overlay_gradient boolean false Add gradient overlay at edges (especially useful for multi-slide views)
padding string "medium" Determines padding for items
rest global Global attributes can define defaults
rounded string nil Border radius for slides. Unset derives from the --pc-radius theme token - amplified for the large surface and clamped at 24px so a full-radius theme gets a media-card corner, never a stadium. 'none' forces square corners; or pin one of 'sm', 'md', 'lg', 'xl', '2xl', '3xl', 'full'
size string "large" Determines the overall size of the elements
slides_per_view integer 1 Number of slides visible at once (1 for single slide, 3 for multi-slide gallery view)
swipe boolean true Enable touch swipe navigation on mobile devices (only applies to slide transitions)
text_position string "center" Determines the element's text position
thumbnails boolean false Synced thumbnail strip below the carousel - image slides show their image, others a numbered chip. Click to jump; the active thumbnail follows the carousel
transition_duration integer 500 Duration of transition in milliseconds
transition_type string "fade" Type of transition between slides (fade or slide)
:slide slot slot