{
	"$schema": "https://ui.shadcn.com/schema/registry-item.json",
	"name": "carousel",
	"dependencies": ["embla-carousel", "embla-carousel-react"],
	"registryDependencies": ["@9ui/button"],
	"files": [
		{
			"path": "ui/carousel.tsx",
			"content": "\"use client\"\n\nimport * as React from \"react\"\nimport useEmblaCarousel, {\n\ttype UseEmblaCarouselType,\n} from \"embla-carousel-react\"\nimport { ArrowLeft, ArrowRight } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype CarouselApi = UseEmblaCarouselType[1]\ntype UseCarouselParameters = Parameters<typeof useEmblaCarousel>\ntype CarouselOptions = UseCarouselParameters[0]\ntype CarouselPlugin = UseCarouselParameters[1]\n\ntype CarouselProps = {\n\topts?: CarouselOptions\n\tplugins?: CarouselPlugin\n\torientation?: \"horizontal\" | \"vertical\"\n\tsetApi?: (api: CarouselApi) => void\n}\n\ntype CarouselContextProps = {\n\tcarouselRef: ReturnType<typeof useEmblaCarousel>[0]\n\tapi: ReturnType<typeof useEmblaCarousel>[1]\n\tscrollPrev: () => void\n\tscrollNext: () => void\n\tcanScrollPrev: boolean\n\tcanScrollNext: boolean\n} & CarouselProps\n\nconst CarouselContext = React.createContext<CarouselContextProps | null>(null)\n\nfunction useCarousel() {\n\tconst context = React.useContext(CarouselContext)\n\n\tif (!context) {\n\t\tthrow new Error(\"useCarousel must be used within a <Carousel />\")\n\t}\n\n\treturn context\n}\n\nfunction Carousel({\n\torientation = \"horizontal\",\n\topts,\n\tsetApi,\n\tplugins,\n\tclassName,\n\tchildren,\n\t...props\n}: React.ComponentProps<\"div\"> & CarouselProps) {\n\tconst [carouselRef, api] = useEmblaCarousel(\n\t\t{\n\t\t\t...opts,\n\t\t\taxis: orientation === \"horizontal\" ? \"x\" : \"y\",\n\t\t},\n\t\tplugins\n\t)\n\tconst [canScrollPrev, setCanScrollPrev] = React.useState(false)\n\tconst [canScrollNext, setCanScrollNext] = React.useState(false)\n\n\tconst onSelect = React.useCallback((api: CarouselApi) => {\n\t\tif (!api) return\n\t\tsetCanScrollPrev(api.canScrollPrev())\n\t\tsetCanScrollNext(api.canScrollNext())\n\t}, [])\n\n\tconst scrollPrev = React.useCallback(() => {\n\t\tapi?.scrollPrev()\n\t}, [api])\n\n\tconst scrollNext = React.useCallback(() => {\n\t\tapi?.scrollNext()\n\t}, [api])\n\n\tconst handleKeyDown = React.useCallback(\n\t\t(event: React.KeyboardEvent<HTMLDivElement>) => {\n\t\t\tif (event.key === \"ArrowLeft\") {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tscrollPrev()\n\t\t\t} else if (event.key === \"ArrowRight\") {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tscrollNext()\n\t\t\t}\n\t\t},\n\t\t[scrollPrev, scrollNext]\n\t)\n\n\tReact.useEffect(() => {\n\t\tif (!api || !setApi) return\n\t\tsetApi(api)\n\t}, [api, setApi])\n\n\tReact.useEffect(() => {\n\t\tif (!api) return\n\t\tonSelect(api)\n\t\tapi.on(\"reInit\", onSelect)\n\t\tapi.on(\"select\", onSelect)\n\n\t\treturn () => {\n\t\t\tapi?.off(\"select\", onSelect)\n\t\t}\n\t}, [api, onSelect])\n\n\treturn (\n\t\t<CarouselContext.Provider\n\t\t\tvalue={{\n\t\t\t\tcarouselRef,\n\t\t\t\tapi: api,\n\t\t\t\topts,\n\t\t\t\torientation:\n\t\t\t\t\torientation || (opts?.axis === \"y\" ? \"vertical\" : \"horizontal\"),\n\t\t\t\tscrollPrev,\n\t\t\t\tscrollNext,\n\t\t\t\tcanScrollPrev,\n\t\t\t\tcanScrollNext,\n\t\t\t}}\n\t\t>\n\t\t\t<div\n\t\t\t\tonKeyDownCapture={handleKeyDown}\n\t\t\t\tclassName={cn(\"relative\", className)}\n\t\t\t\trole=\"region\"\n\t\t\t\taria-roledescription=\"carousel\"\n\t\t\t\tdata-slot=\"carousel\"\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t</CarouselContext.Provider>\n\t)\n}\n\nfunction CarouselContent({ className, ...props }: React.ComponentProps<\"div\">) {\n\tconst { carouselRef, orientation } = useCarousel()\n\n\treturn (\n\t\t<div\n\t\t\tref={carouselRef}\n\t\t\tclassName=\"overflow-hidden\"\n\t\t\tdata-slot=\"carousel-content\"\n\t\t>\n\t\t\t<div\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"flex\",\n\t\t\t\t\torientation === \"horizontal\" ? \"-ml-4\" : \"-mt-4 flex-col\",\n\t\t\t\t\tclassName\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t</div>\n\t)\n}\n\nfunction CarouselItem({ className, ...props }: React.ComponentProps<\"div\">) {\n\tconst { orientation } = useCarousel()\n\n\treturn (\n\t\t<div\n\t\t\trole=\"group\"\n\t\t\taria-roledescription=\"slide\"\n\t\t\tdata-slot=\"carousel-item\"\n\t\t\tclassName={cn(\n\t\t\t\t\"min-w-0 shrink-0 grow-0 basis-full\",\n\t\t\t\torientation === \"horizontal\" ? \"pl-4\" : \"pt-4\",\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\n\nfunction CarouselPrevious({\n\tclassName,\n\tvariant = \"ghost\",\n\tsize = \"icon\",\n\t...props\n}: React.ComponentProps<typeof Button>) {\n\tconst { orientation, scrollPrev, canScrollPrev } = useCarousel()\n\n\treturn (\n\t\t<Button\n\t\t\tdata-slot=\"carousel-previous\"\n\t\t\tvariant={variant}\n\t\t\tsize={size}\n\t\t\tclassName={cn(\n\t\t\t\t\"absolute\",\n\t\t\t\torientation === \"horizontal\"\n\t\t\t\t\t? \"top-1/2 -left-12 -translate-y-1/2\"\n\t\t\t\t\t: \"-top-12 left-1/2 -translate-x-1/2 rotate-90\",\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\tdisabled={!canScrollPrev}\n\t\t\tonClick={scrollPrev}\n\t\t\t{...props}\n\t\t>\n\t\t\t<ArrowLeft />\n\t\t\t<span className=\"sr-only\">Previous slide</span>\n\t\t</Button>\n\t)\n}\n\nfunction CarouselNext({\n\tclassName,\n\tvariant = \"ghost\",\n\tsize = \"icon\",\n\t...props\n}: React.ComponentProps<typeof Button>) {\n\tconst { orientation, scrollNext, canScrollNext } = useCarousel()\n\n\treturn (\n\t\t<Button\n\t\t\tdata-slot=\"carousel-next\"\n\t\t\tvariant={variant}\n\t\t\tsize={size}\n\t\t\tclassName={cn(\n\t\t\t\t\"absolute\",\n\t\t\t\torientation === \"horizontal\"\n\t\t\t\t\t? \"top-1/2 -right-12 -translate-y-1/2\"\n\t\t\t\t\t: \"-bottom-12 left-1/2 -translate-x-1/2 rotate-90\",\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\tdisabled={!canScrollNext}\n\t\t\tonClick={scrollNext}\n\t\t\t{...props}\n\t\t>\n\t\t\t<ArrowRight />\n\t\t\t<span className=\"sr-only\">Next slide</span>\n\t\t</Button>\n\t)\n}\n\nexport {\n\ttype CarouselApi,\n\tCarousel,\n\tCarouselContent,\n\tCarouselItem,\n\tCarouselPrevious,\n\tCarouselNext,\n}\n",
			"type": "registry:ui",
			"target": ""
		}
	],
	"type": "registry:ui"
}
