Carousel
---import { Card, CardContent } from "@/components/starwind/card";import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious,} from "@/components/starwind/carousel";---
<Carousel opts={{ align: "start" }} class="mx-auto w-full max-w-xs"> <CarouselContent> { Array.from({ length: 5 }).map((_, index) => ( <CarouselItem> <div class="p-1"> <Card> <CardContent class="flex aspect-square items-center justify-center p-6"> <span class="text-4xl font-semibold">{index + 1}</span> </CardContent> </Card> </div> </CarouselItem> )) } </CarouselContent> <CarouselPrevious /> <CarouselNext /></Carousel>Installation
pnpx starwind@latest add carouselnpx starwind@latest add carouselyarn dlx starwind@latest add carouselUsage
General Notes
The Carousel component is built on top of Embla Carousel and provides a responsive, touch-enabled carousel with smooth animations. It supports both horizontal and vertical orientations, multiple items per view, and various configuration options.
The essential components are Carousel, CarouselContent, and CarouselItem. The CarouselPrevious and CarouselNext components provide navigation controls.
Multiple Items
Show multiple items at once by using responsive basis classes on carousel items.
---import { Card, CardContent } from "@/components/starwind/card";import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious,} from "@/components/starwind/carousel";---
<Carousel opts={{ align: "start" }} class="mx-auto w-full max-w-sm"> <CarouselContent> { Array.from({ length: 5 }).map((_, index) => ( <CarouselItem class="md:basis-1/2 lg:basis-1/3"> <div class="p-1"> <Card> <CardContent class="flex aspect-square items-center justify-center p-6"> <span class="text-2xl font-semibold">{index + 1}</span> </CardContent> </Card> </div> </CarouselItem> )) } </CarouselContent> <CarouselPrevious /> <CarouselNext /></Carousel>Vertical Carousel
Carousels can be oriented vertically by setting the orientation prop.
---import { Card, CardContent } from "@/components/starwind/card";import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious,} from "@/components/starwind/carousel";---
<Carousel opts={{ align: "start" }} orientation="vertical" class="my-10 w-full max-w-xs"> <CarouselContent class="h-[200px] min-w-[140px]"> { Array.from({ length: 5 }).map((_, index) => ( <CarouselItem class="aspect-square pt-1 md:basis-3/4"> <div class="h-full p-1"> <Card class="h-full"> <CardContent class="flex h-full items-center justify-center p-6"> <span class="text-3xl font-semibold">{index + 1}</span> </CardContent> </Card> </div> </CarouselItem> )) } </CarouselContent> <CarouselPrevious /> <CarouselNext /></Carousel>Looping Carousel
Enable infinite looping with the loop option.
---import { Card, CardContent } from "@/components/starwind/card";import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious,} from "@/components/starwind/carousel";---
<Carousel opts={{ align: "start", loop: true }} class="mx-auto w-full max-w-xs"> <CarouselContent> <CarouselItem> <div class="p-1"> <Card class="bg-gradient-to-br from-blue-500 to-purple-600 text-white"> <CardContent class="flex aspect-square items-center justify-center p-6"> <span class="text-4xl font-semibold">∞</span> </CardContent> </Card> </div> </CarouselItem> <CarouselItem> <div class="p-1"> <Card class="bg-gradient-to-br from-green-500 to-blue-600 text-white"> <CardContent class="flex aspect-square items-center justify-center p-6"> <span class="text-4xl font-semibold">Loop</span> </CardContent> </Card> </div> </CarouselItem> <CarouselItem> <div class="p-1"> <Card class="bg-gradient-to-br from-pink-500 to-red-600 text-white"> <CardContent class="flex aspect-square items-center justify-center p-6"> <span class="text-4xl font-semibold">∞</span> </CardContent> </Card> </div> </CarouselItem> </CarouselContent> <CarouselPrevious /> <CarouselNext /></Carousel>Plugins
Extend carousel functionality with Embla Carousel plugins. First install the plugin package, then use manual initialization with the initCarousel function.
Info
You need to set autoInit={false} on the Carousel component, so that you can manually initialize it with your plugins and any additional options.
# Install the autoplay pluginnpm install embla-carousel-autoplay---import { Card, CardContent } from "@/components/starwind/card";import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious,} from "@/components/starwind/carousel";---
<Carousel id="carousel-autoplay" autoInit={false} opts={{ align: "start" }} class="mx-auto w-full max-w-xs"> <CarouselContent> { Array.from({ length: 5 }).map((_, index) => ( <CarouselItem> <div class="p-1"> <Card> <CardContent class="flex aspect-square items-center justify-center p-6"> <span class="text-4xl font-semibold">{index + 1}</span> </CardContent> </Card> </div> </CarouselItem> )) } </CarouselContent> <CarouselPrevious /> <CarouselNext /></Carousel>
<script> import Autoplay from "embla-carousel-autoplay";
import { initCarousel } from "@/components/starwind/carousel";
function initAutoplayCarousel() { const carouselElement = document.getElementById("carousel-autoplay"); if (!carouselElement) return; initCarousel(carouselElement, { plugins: [ Autoplay({ delay: 2000, }), ], }); }
initAutoplayCarousel();
document.addEventListener("astro:after-swap", initAutoplayCarousel);</script>API Reference
Carousel
The root carousel component that manages the carousel state and configuration.
---// Basic carousel with options---<Carousel orientation="horizontal" opts={{ align: "start", loop: false }} autoInit={true} class="w-full max-w-xs"> <!-- Carousel content --></Carousel>Props:
orientation?: "horizontal" | "vertical"- Carousel orientation (default: “horizontal”)opts?: EmblaOptionsType- Embla Carousel options objectautoInit?: boolean- Whether to automatically initialize the carousel (default: true)class?: string- Additional CSS classes to apply
CarouselContent
The scrollable content container that holds all carousel items.
---// Content wrapper with overflow handling---<CarouselContent class="h-[200px]"> <!-- Carousel items go here --></CarouselContent>Props:
class?: string- Additional CSS classes to apply
CarouselItem
Individual carousel slide that can contain any content.
---// Individual carousel slide---<CarouselItem class="md:basis-1/2 lg:basis-1/3"> <div class="p-1"> <!-- Item content --> </div></CarouselItem>Props:
class?: string- Additional CSS classes to apply (useful for responsive sizing)
CarouselPrevious
Navigation button to go to the previous slide.
---// Previous button with customizable styling---<CarouselPrevious variant="outline" size="icon" />Props:
variant?: ButtonVariant- Button variant (inherits from Button component)size?: ButtonSize- Button size (inherits from Button component)class?: string- Additional CSS classes to apply
CarouselNext
Navigation button to go to the next slide.
---// Next button with customizable styling---<CarouselNext variant="outline" size="icon" />Props:
variant?: ButtonVariant- Button variant (inherits from Button component)size?: ButtonSize- Button size (inherits from Button component)class?: string- Additional CSS classes to apply
Configuration Options
The opts prop accepts any Embla Carousel options. Common options include:
---// Common configuration options---<Carousel opts={{ align: "start", // Alignment of slides loop: false, // Enable infinite looping skipSnaps: false, // Allow free scrolling dragFree: false, // Enable drag free scrolling containScroll: "trimSnaps", // Contain scroll behavior slidesToScroll: 1, // Number of slides to scroll startIndex: 0, // Starting slide index}}> <!-- Content --></Carousel>Changelog
v1.0.1
- Add named slot “icon” to
CarouselNextandCarouselPreviousto enable easy icon swapping, and a default slot for thesr-onlylabels
v1.0.0
- Initial release with starwind v1.9.0