Carousel
uiable/carouselFreeComponent
Carousel component.
Live preview
live · rendered by the registry
Rendered by uiable on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://uiable.com/r/carousel.jsonSource
1"use client";23import { ComponentProps, KeyboardEvent, createContext, useCallback, useContext, useEffect, useState } from "react";45import useEmblaCarousel, {6 type UseEmblaCarouselType7} from "embla-carousel-react";89import { cn } from "@/lib/utils";10import { Button } from "@/components/ui/button";11import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";1213type CarouselApi = UseEmblaCarouselType[1];14type UseCarouselParameters = Parameters<typeof useEmblaCarousel>;15type CarouselOptions = UseCarouselParameters[0];16type CarouselPlugin = UseCarouselParameters[1];1718type CarouselProps = {19 opts?: CarouselOptions;20 plugins?: CarouselPlugin;21 orientation?: "horizontal" | "vertical";22 setApi?: (api: CarouselApi) => void;23};2425type CarouselContextProps = {26 carouselRef: ReturnType<typeof useEmblaCarousel>[0];27 api: ReturnType<typeof useEmblaCarousel>[1];28 scrollPrev: () => void;29 scrollNext: () => void;30 canScrollPrev: boolean;31 canScrollNext: boolean;32} & CarouselProps;3334const CarouselContext = createContext<CarouselContextProps | null>(null);3536function useCarousel() {37 const context = useContext(CarouselContext);3839 if (!context) {40 throw new Error("useCarousel must be used within a <Carousel />");41 }4243 return context;44}4546function Carousel({47 orientation = "horizontal",48 opts,49 setApi,50 plugins,51 className,52 children,53 ...props54}: ComponentProps<"div"> & CarouselProps) {55 const [carouselRef, api] = useEmblaCarousel(56 {57 ...opts,58 axis: orientation === "horizontal" ? "x" : "y"59 },60 plugins61 );62 const [canScrollPrev, setCanScrollPrev] = useState(false);63 const [canScrollNext, setCanScrollNext] = useState(false);6465 const onSelect = useCallback((api: CarouselApi) => {66 if (!api) return;67 setCanScrollPrev(api.canScrollPrev());68 setCanScrollNext(api.canScrollNext());69 }, []);7071 const scrollPrev = useCallback(() => {72 api?.scrollPrev();73 }, [api]);7475 const scrollNext = useCallback(() => {76 api?.scrollNext();77 }, [api]);7879 const handleKeyDown = useCallback(80 (event: KeyboardEvent<HTMLDivElement>) => {81 if (event.key === "ArrowLeft") {82 event.preventDefault();83 scrollPrev();84 } else if (event.key === "ArrowRight") {85 event.preventDefault();86 scrollNext();87 }88 },89 [scrollPrev, scrollNext]90 );9192 useEffect(() => {93 if (!api || !setApi) return;94// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from uiable
All 712 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | uiable | Components | Free | 2 deps | |
| Alertalert | uiable | Components | Free | 1 dep | |
| Alert Dialogalert-dialog | uiable | Components | Free | 1 dep | |
| Aspect Ratioaspect-ratio | uiable | Components | Free | no deps | |
| Attachmentattachment | uiable | Components | Free | 2 deps | |
| Avataravatar | uiable | Components | Free | 1 dep | |
| Badgebadge | uiable | Components | Free | 2 deps | |
| Breadcrumbbreadcrumb | uiable | Components | Free | 2 deps |
