UNPKG

@neynar/ui

Version:

React UI component library built on shadcn/ui and Tailwind CSS

211 lines (197 loc) 5.41 kB
# Carousel **Type**: component A responsive carousel/slider component for content presentation The Carousel component provides a touch-friendly, keyboard-accessible way to browse through multiple items. Built on Embla Carousel, it supports various configurations including autoplay, loop, drag scrolling, infinite scroll, momentum scrolling, and both horizontal and vertical orientations. Features include responsive breakpoints, plugin system, smooth animations, focus management, RTL support, and extensive customization options. ## JSX Usage ```jsx import { Carousel } from '@neynar/ui'; <Carousel opts={value} plugins={value} orientation={value} setApi={() => {}} className="value" > {/* Your content here */} </Carousel> ``` ## Component Props ### opts - **Type**: `CarouselOptions` - **Required**: No - **Description**: No description available ### plugins - **Type**: `CarouselPlugin` - **Required**: No - **Description**: No description available ### orientation - **Type**: `"horizontal" | "vertical"` - **Required**: No - **Description**: No description available ### setApi - **Type**: `(api: CarouselApi) => void` - **Required**: No - **Description**: No description available ### className - **Type**: `string` - **Required**: No - **Description**: No description available ### children - **Type**: `React.ReactNode` - **Required**: No - **Description**: No description available ## Examples ### Example 1 ```tsx // Basic image carousel <Carousel className="w-full max-w-xs"> <CarouselContent> {images.map((src, index) => ( <CarouselItem key={index}> <img src={src} alt={`Slide ${index + 1}`} className="w-full" /> </CarouselItem> ))} </CarouselContent> <CarouselPrevious /> <CarouselNext /> </Carousel> ``` ### Example 2 ```tsx // Multi-item responsive carousel with custom spacing <Carousel opts={{ align: "start", loop: true, slidesToScroll: "auto", breakpoints: { "(min-width: 768px)": { slidesToScroll: 2 } } }} className="w-full" > <CarouselContent className="-ml-2 md:-ml-4"> {products.map((product, index) => ( <CarouselItem key={index} className="pl-2 md:pl-4 md:basis-1/2 lg:basis-1/3"> <Card> <CardContent className="p-4"> <h3>{product.name}</h3> <p>{product.price}</p> </CardContent> </Card> </CarouselItem> ))} </CarouselContent> <CarouselPrevious /> <CarouselNext /> </Carousel> ``` ### Example 3 ```tsx // Vertical carousel with autoplay plugin import Autoplay from "embla-carousel-autoplay"; <Carousel orientation="vertical" opts={{ loop: true, align: "center" }} plugins={[Autoplay({ delay: 3000, stopOnInteraction: true, stopOnMouseEnter: true })]} className="h-[400px]" > <CarouselContent className="h-full"> {testimonials.map((testimonial, index) => ( <CarouselItem key={index} className="basis-1/2"> <div className="p-6"> <blockquote>{testimonial.quote}</blockquote> <cite>{testimonial.author}</cite> </div> </CarouselItem> ))} </CarouselContent> </Carousel> ``` ### Example 4 ```tsx // Controlled carousel with custom indicators and API access import { useState, useEffect } from "react"; function ControlledCarousel() { const [api, setApi] = useState<CarouselApi>(); const [current, setCurrent] = useState(0); const [count, setCount] = useState(0); useEffect(() => { if (!api) return; setCount(api.scrollSnapList().length); setCurrent(api.selectedScrollSnap() + 1); api.on('select', () => { setCurrent(api.selectedScrollSnap() + 1); }); }, [api]); return ( <div className="space-y-4"> <Carousel setApi={setApi} opts={{ loop: true }}> <CarouselContent> {slides.map((slide, index) => ( <CarouselItem key={index}>{slide.content}</CarouselItem> ))} </CarouselContent> <CarouselPrevious /> <CarouselNext /> </Carousel> // Custom indicators <div className="flex justify-center gap-2"> {Array.from({ length: count }).map((_, i) => ( <button key={i} className={cn( "w-2 h-2 rounded-full transition-colors", current === i + 1 ? "bg-primary" : "bg-muted" )} onClick={() => api?.scrollTo(i)} /> ))} </div> <div className="text-center text-sm text-muted-foreground"> Slide {current} of {count} </div> </div> ); } ``` ### Example 5 ```tsx // Momentum scrolling carousel with drag-free mode <Carousel opts={{ dragFree: true, containScroll: false, skipSnaps: true }} className="w-full" > <CarouselContent> {items.map((item, index) => ( <CarouselItem key={index} className="basis-auto"> <div className="w-32 h-32 bg-muted rounded-lg" /> </CarouselItem> ))} </CarouselContent> </Carousel> ``` ### Example 6 ```tsx // Breakpoint-responsive carousel that disables on larger screens <Carousel opts={{ active: true, breakpoints: { "(min-width: 768px)": { active: false } } }} className="md:hidden" > <CarouselContent> {mobileItems.map((item, index) => ( <CarouselItem key={index}>{item}</CarouselItem> ))} </CarouselContent> <CarouselPrevious /> <CarouselNext /> </Carousel> ```