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 carousel
npx starwind@latest add carousel
yarn dlx starwind@latest add carousel
Usage
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.0
- Initial release