Carousel
cubby-ui/carouselFreeComponent
A carousel component.
Live preview
live · rendered by the registry
Rendered by cubby-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://cubby-ui.dev/r/carousel.jsonSource
1"use client";23import * as React from "react";4import useEmblaCarousel, {5 type UseEmblaCarouselType,6} from "embla-carousel-react";7import { Button } from "@/registry/default/button/button";89import { cn } from "@/lib/utils";1011import { HugeiconsIcon } from "@hugeicons/react";12import { ArrowLeft01Icon, ArrowRight01Icon } from "@hugeicons/core-free-icons";13type 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 = React.createContext<CarouselContextProps | null>(null);3536function useCarousel() {37 const context = React.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}: React.ComponentProps<"div"> & CarouselProps) {55 const [carouselRef, api] = useEmblaCarousel(56 {57 ...opts,58 axis: orientation === "horizontal" ? "x" : "y",59 },60 plugins,61 );62 const [canScrollPrev, setCanScrollPrev] = React.useState(false);63 const [canScrollNext, setCanScrollNext] = React.useState(false);6465 const onSelect = React.useCallback((api: CarouselApi) => {66 if (!api) return;67 setCanScrollPrev(api.canScrollPrev());68 setCanScrollNext(api.canScrollNext());69 }, []);7071 const scrollPrev = React.useCallback(() => {72 api?.scrollPrev();73 }, [api]);7475 const scrollNext = React.useCallback(() => {76 api?.scrollNext();77 }, [api]);7879 const handleKeyDown = React.useCallback(80 (event: React.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 React.useEffect(() => {93 if (!api || !setApi) return;94 setApi(api);95 }, [api, setApi]);9697// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from cubby-ui
All 79 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | cubby-ui | Components | Free | 2 deps | |
| Alertalert | cubby-ui | Components | Free | 1 dep | |
| Alert-dialogalert-dialog | cubby-ui | Components | Free | 2 deps | |
| Aspect-ratioaspect-ratio | cubby-ui | Components | Free | no deps | |
| Autocompleteautocomplete | cubby-ui | Components | Free | 2 deps | |
| Avataravatar | cubby-ui | Components | Free | 1 dep | |
| Badgebadge | cubby-ui | Components | Free | 1 dep | |
| Base Drawerbase-drawer | cubby-ui | Components | Free | 2 deps |
