Carousel
scrollxui/carouselFreeComponent
A carousel component with card stack visualization for cycling through content.
Live preview
live · rendered by the registry
Rendered by scrollxui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://scrollxui.dev/registry/carousel.jsonSource
1"use client";23import React, { createContext, useContext, useState, useEffect } from "react";4import { ChevronUp, ChevronDown } from "lucide-react";5import { cn } from "@/lib/utils";6import { Button } from "@/components/ui/button";78type CarouselContextProps = {9 activeIndex: number;10 totalCards: number;11 goToPrevious: () => void;12 goToNext: () => void;13 hasPrevious: boolean;14 hasNext: boolean;15 setTotalCards: (total: number) => void;16};1718const CarouselContext = createContext<CarouselContextProps | null>(null);1920function useCarousel() {21 const context = useContext(CarouselContext);22 if (!context) {23 throw new Error("useCarousel must be used within a <Carousel />");24 }25 return context;26}2728function Carousel({29 className,30 children,31 ...props32}: React.ComponentProps<"div">) {33 const [activeIndex, setActiveIndex] = useState(0);34 const [totalCards, setTotalCards] = useState(0);3536 const goToPrevious = React.useCallback(() => {37 setActiveIndex((prev) => Math.max(0, prev - 1));38 }, []);3940 const goToNext = React.useCallback(() => {41 setActiveIndex((prev) => Math.min(totalCards - 1, prev + 1));42 }, [totalCards]);4344 const hasPrevious = activeIndex > 0;45 const hasNext = activeIndex < totalCards - 1;4647 const handleKeyDown = React.useCallback(48 (event: React.KeyboardEvent<HTMLDivElement>) => {49 if (event.key === "ArrowUp") {50 event.preventDefault();51 goToPrevious();52 } else if (event.key === "ArrowDown") {53 event.preventDefault();54 goToNext();55 }56 },57 [goToPrevious, goToNext]58 );5960 return (61 <CarouselContext.Provider62 value={{63 activeIndex,64 totalCards,65 goToPrevious,66 goToNext,67 hasPrevious,68 hasNext,69 setTotalCards,70 }}71 >72 <div73 onKeyDownCapture={handleKeyDown}74 className={cn("relative flex flex-col", className)}75 role="region"76 aria-roledescription="carousel"77 data-slot="carousel"78 {...props}79 >80 {children}81 <div className="flex justify-between mt-4">82 <CarouselPrevious />83 <CarouselNext />84 </div>85 </div>86 </CarouselContext.Provider>87 );88}8990type CarouselContentProps = {91 maxVisible?: number;92 stackOffset?: number;93};9495function CarouselContent({96 maxVisible = 3,97 stackOffset = 20,98 className,99 children,100 ...props101}: React.ComponentProps<"div"> & CarouselContentProps) {102// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from scrollxui
All 180 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | scrollxui | Components | Free | 4 deps | |
| Alert Dialogalert-dialog | scrollxui | Components | Free | 7 deps | |
| Animated Buttonanimated-button | scrollxui | Components | Free | 4 deps | |
| Animated Tabsanimated-tabs | scrollxui | Components | Free | 1 dep | |
| Animated Testimonialsanimated-testimonials | scrollxui | Components | Free | 2 deps | |
| Animated TextGenerateanimated-textgenerate | scrollxui | Components | Free | 3 deps | |
| Announcementannouncement | scrollxui | Components | Free | 5 deps | |
| Aspect Ratioaspect-ratio | scrollxui | Components | Free | 1 dep |
