Carousel
motion-primitives/carouselFreeComponent
A component for cycling through elements with smooth transitions.
Install it
npx shadcn@latest add https://raw.githubusercontent.com/ibelick/motion-primitives/HEAD/public/c/carousel.jsonSource
1'use client';2import {3 Children,4 ReactNode,5 createContext,6 useContext,7 useEffect,8 useRef,9 useState,10} from 'react';11import { motion, Transition, useMotionValue } from 'motion/react';12import { cn } from '@/lib/utils';13import { ChevronLeft, ChevronRight } from 'lucide-react';1415export type CarouselContextType = {16 index: number;17 setIndex: (newIndex: number) => void;18 itemsCount: number;19 setItemsCount: (newItemsCount: number) => void;20 disableDrag: boolean;21};2223const CarouselContext = createContext<CarouselContextType | undefined>(24 undefined25);2627function useCarousel() {28 const context = useContext(CarouselContext);29 if (!context) {30 throw new Error('useCarousel must be used within an CarouselProvider');31 }32 return context;33}3435export type CarouselProviderProps = {36 children: ReactNode;37 initialIndex?: number;38 onIndexChange?: (newIndex: number) => void;39 disableDrag?: boolean;40};4142function CarouselProvider({43 children,44 initialIndex = 0,45 onIndexChange,46 disableDrag = false,47}: CarouselProviderProps) {48 const [index, setIndex] = useState<number>(initialIndex);49 const [itemsCount, setItemsCount] = useState<number>(0);5051 const handleSetIndex = (newIndex: number) => {52 setIndex(newIndex);53 onIndexChange?.(newIndex);54 };5556 useEffect(() => {57 setIndex(initialIndex);58 }, [initialIndex]);5960 return (61 <CarouselContext.Provider62 value={{63 index,64 setIndex: handleSetIndex,65 itemsCount,66 setItemsCount,67 disableDrag,68 }}69 >70 {children}71 </CarouselContext.Provider>72 );73}7475export type CarouselProps = {76 children: ReactNode;77 className?: string;78 initialIndex?: number;79 index?: number;80 onIndexChange?: (newIndex: number) => void;81 disableDrag?: boolean;82};8384function Carousel({85 children,86 className,87 initialIndex = 0,88 index: externalIndex,89 onIndexChange,90 disableDrag = false,91}: CarouselProps) {92 const [internalIndex, setInternalIndex] = useState<number>(initialIndex);93 const isControlled = externalIndex !== undefined;94 const currentIndex = isControlled ? externalIndex : internalIndex;9596 const handleIndexChange = (newIndex: number) => {97 if (!isControlled) {98 setInternalIndex(newIndex);99 }100 onIndexChange?.(newIndex);101 };102103 return (104 <CarouselProvider105 initialIndex={currentIndex}106 onIndexChange={handleIndexChange}107 disableDrag={disableDrag}108 >109 <div className={cn('group/hover relative', className)}>110// … truncated
What it pulls in
npm packages
Files it writes
More from motion-primitives
All 33 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | motion-primitives | Components | Free | 1 dep | |
| Animated Backgroundanimated-background | motion-primitives | Components | Free | 1 dep | |
| Animated Groupanimated-group | motion-primitives | Components | Free | 1 dep | |
| Animated Numberanimated-number | motion-primitives | Components | Free | 1 dep | |
| Border Trailborder-trail | motion-primitives | Components | Free | 1 dep | |
| Cursorcursor | motion-primitives | Components | Free | 1 dep | |
| Dialogdialog | motion-primitives | Components | Free | 1 dep · 2 files | |
| Disclosuredisclosure | motion-primitives | Components | Free | 1 dep |
