{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "carousel", "type": "registry:ui", "dependencies": [ "embla-carousel-react", "lucide-react" ], "registryDependencies": [ "https://wigggle-ui.vercel.app/r/utils.json", "https://wigggle-ui.vercel.app/r/button.json" ], "files": [ { "path": "registry/default/ui/carousel.tsx", "content": "\"use client\";\r\n\r\nimport * as React from \"react\";\r\nimport useEmblaCarousel, {\r\n type UseEmblaCarouselType,\r\n} from \"embla-carousel-react\";\r\nimport { ArrowLeft, ArrowRight } from \"lucide-react\";\r\n\r\nimport { cn } from \"@/lib/utils\";\r\nimport { Button } from \"@/components/ui/button\";\r\n\r\ntype CarouselApi = UseEmblaCarouselType[1];\r\ntype UseCarouselParameters = Parameters;\r\ntype CarouselOptions = UseCarouselParameters[0];\r\ntype CarouselPlugin = UseCarouselParameters[1];\r\n\r\ntype CarouselProps = {\r\n opts?: CarouselOptions;\r\n plugins?: CarouselPlugin;\r\n orientation?: \"horizontal\" | \"vertical\";\r\n setApi?: (api: CarouselApi) => void;\r\n};\r\n\r\ntype CarouselContextProps = {\r\n carouselRef: ReturnType[0];\r\n api: ReturnType[1];\r\n scrollPrev: () => void;\r\n scrollNext: () => void;\r\n canScrollPrev: boolean;\r\n canScrollNext: boolean;\r\n} & CarouselProps;\r\n\r\nconst CarouselContext = React.createContext(null);\r\n\r\nfunction useCarousel() {\r\n const context = React.useContext(CarouselContext);\r\n\r\n if (!context) {\r\n throw new Error(\"useCarousel must be used within a \");\r\n }\r\n\r\n return context;\r\n}\r\n\r\nfunction Carousel({\r\n orientation = \"horizontal\",\r\n opts,\r\n setApi,\r\n plugins,\r\n className,\r\n children,\r\n ...props\r\n}: React.ComponentProps<\"div\"> & CarouselProps) {\r\n const [carouselRef, api] = useEmblaCarousel(\r\n {\r\n ...opts,\r\n axis: orientation === \"horizontal\" ? \"x\" : \"y\",\r\n },\r\n plugins,\r\n );\r\n const [canScrollPrev, setCanScrollPrev] = React.useState(false);\r\n const [canScrollNext, setCanScrollNext] = React.useState(false);\r\n\r\n const onSelect = React.useCallback((api: CarouselApi) => {\r\n if (!api) return;\r\n setCanScrollPrev(api.canScrollPrev());\r\n setCanScrollNext(api.canScrollNext());\r\n }, []);\r\n\r\n const scrollPrev = React.useCallback(() => {\r\n api?.scrollPrev();\r\n }, [api]);\r\n\r\n const scrollNext = React.useCallback(() => {\r\n api?.scrollNext();\r\n }, [api]);\r\n\r\n const handleKeyDown = React.useCallback(\r\n (event: React.KeyboardEvent) => {\r\n if (event.key === \"ArrowLeft\") {\r\n event.preventDefault();\r\n scrollPrev();\r\n } else if (event.key === \"ArrowRight\") {\r\n event.preventDefault();\r\n scrollNext();\r\n }\r\n },\r\n [scrollPrev, scrollNext],\r\n );\r\n\r\n React.useEffect(() => {\r\n if (!api || !setApi) return;\r\n setApi(api);\r\n }, [api, setApi]);\r\n\r\n React.useEffect(() => {\r\n if (!api) return;\r\n onSelect(api);\r\n api.on(\"reInit\", onSelect);\r\n api.on(\"select\", onSelect);\r\n\r\n return () => {\r\n api?.off(\"select\", onSelect);\r\n };\r\n }, [api, onSelect]);\r\n\r\n return (\r\n \r\n \r\n {children}\r\n \r\n \r\n );\r\n}\r\n\r\nfunction CarouselContent({ className, ...props }: React.ComponentProps<\"div\">) {\r\n const { carouselRef, orientation } = useCarousel();\r\n\r\n return (\r\n \r\n \r\n \r\n );\r\n}\r\n\r\nfunction CarouselItem({ className, ...props }: React.ComponentProps<\"div\">) {\r\n const { orientation } = useCarousel();\r\n\r\n return (\r\n \r\n );\r\n}\r\n\r\nfunction CarouselPrevious({\r\n className,\r\n variant = \"outline\",\r\n size = \"icon\",\r\n ...props\r\n}: React.ComponentProps) {\r\n const { orientation, scrollPrev, canScrollPrev } = useCarousel();\r\n\r\n return (\r\n \r\n \r\n Previous slide\r\n \r\n );\r\n}\r\n\r\nfunction CarouselNext({\r\n className,\r\n variant = \"outline\",\r\n size = \"icon\",\r\n ...props\r\n}: React.ComponentProps) {\r\n const { orientation, scrollNext, canScrollNext } = useCarousel();\r\n\r\n return (\r\n \r\n \r\n Next slide\r\n \r\n );\r\n}\r\n\r\nexport {\r\n type CarouselApi,\r\n Carousel,\r\n CarouselContent,\r\n CarouselItem,\r\n CarouselPrevious,\r\n CarouselNext,\r\n};\r\n", "type": "registry:ui" } ] }