carousel
9ui/carouselFreeComponent
9ui publishes no description for this item.
Live preview
live · rendered by the registry
Rendered by 9ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://9ui.dev/r/carousel.jsonSource
1"use client"23import * as React from "react"4import useEmblaCarousel, {5 type UseEmblaCarouselType,6} from "embla-carousel-react"7import { ArrowLeft, ArrowRight } from "lucide-react"89import { Button } from "@/components/ui/button"1011import { cn } from "@/lib/utils"1213type CarouselApi = UseEmblaCarouselType[1]14type UseCarouselParameters = Parameters<typeof useEmblaCarousel>15type CarouselOptions = UseCarouselParameters[0]16type CarouselPlugin = UseCarouselParameters[1]1718type CarouselProps = {19 opts?: CarouselOptions20 plugins?: CarouselPlugin21 orientation?: "horizontal" | "vertical"22 setApi?: (api: CarouselApi) => void23}2425type CarouselContextProps = {26 carouselRef: ReturnType<typeof useEmblaCarousel>[0]27 api: ReturnType<typeof useEmblaCarousel>[1]28 scrollPrev: () => void29 scrollNext: () => void30 canScrollPrev: boolean31 canScrollNext: boolean32} & CarouselProps3334const 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 context44}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 plugins61 )62 const [canScrollPrev, setCanScrollPrev] = React.useState(false)63 const [canScrollNext, setCanScrollNext] = React.useState(false)6465 const onSelect = React.useCallback((api: CarouselApi) => {66 if (!api) return67 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) return94 setApi(api)95 }, [api, setApi])9697 React.useEffect(() => {98 if (!api) return99 onSelect(api)100 api.on("reInit", onSelect)101 api.on("select", onSelect)102103 return () => {104 api?.off("select", onSelect)105 }106 }, [api, onSelect])107108 return (109// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from 9ui
All 56 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| accordionaccordion | 9ui | Components | Free | no deps | |
| alertalert | 9ui | Components | Free | no deps | |
| alert-dialogalert-dialog | 9ui | Components | Free | no deps | |
| aspect-ratioaspect-ratio | 9ui | Components | Free | no deps | |
| autocompleteautocomplete | 9ui | Components | Free | no deps | |
| avataravatar | 9ui | Components | Free | no deps | |
| badgebadge | 9ui | Components | Free | no deps | |
| breadcrumbsbreadcrumbs | 9ui | Components | Free | no deps |
