Carousel
blode-ui/carouselFreeComponent
A slideshow component for cycling through a set of content.
Install it
npx shadcn@latest add https://raw.githubusercontent.com/mblode/blode-ui/main/public/r/carousel.jsonSource
1"use client";23import { ArrowLeft, ArrowRight } from "blode-icons-react";4import useEmblaCarousel from "embla-carousel-react";5import type { UseEmblaCarouselType } from "embla-carousel-react";6import type * as React from "react";7import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react";89import { cn } from "@/lib/utils";10import { Button } from "@/components/ui/button";1112type CarouselApi = UseEmblaCarouselType[1];13type UseCarouselParameters = Parameters<typeof useEmblaCarousel>;14type CarouselOptions = UseCarouselParameters[0];15type CarouselPlugin = UseCarouselParameters[1];1617interface CarouselProps {18 opts?: CarouselOptions;19 orientation?: "horizontal" | "vertical";20 plugins?: CarouselPlugin;21 setApi?: (api: CarouselApi) => void;22}2324type CarouselContextProps = {25 carouselRef: ReturnType<typeof useEmblaCarousel>[0];26 api: ReturnType<typeof useEmblaCarousel>[1];27 scrollPrev: () => void;28 scrollNext: () => void;29 canScrollPrev: boolean;30 canScrollNext: boolean;31} & CarouselProps;3233const CarouselContext = createContext<CarouselContextProps | null>(null);3435const useCarousel = () => {36 const context = useContext(CarouselContext);3738 if (!context) {39 throw new Error("useCarousel must be used within a <Carousel />");40 }4142 return context;43};4445const Carousel = ({46 orientation = "horizontal",47 opts,48 setApi,49 plugins,50 className,51 children,52 ...props53}: React.ComponentProps<"div"> & CarouselProps) => {54 const [carouselRef, api] = useEmblaCarousel(55 {56 ...opts,57 axis: orientation === "horizontal" ? "x" : "y",58 },59 plugins,60 );61 const [canScrollPrev, setCanScrollPrev] = useState(false);62 const [canScrollNext, setCanScrollNext] = useState(false);6364 const onSelect = useCallback((emblaApi: CarouselApi) => {65 if (!emblaApi) {66 return;67 }68 setCanScrollPrev(emblaApi.canScrollPrev());69 setCanScrollNext(emblaApi.canScrollNext());70 }, []);7172 const scrollPrev = useCallback(() => {73 api?.scrollPrev();74 }, [api]);7576 const scrollNext = useCallback(() => {77 api?.scrollNext();78 }, [api]);7980 const handleKeyDown = useCallback(81 (event: React.KeyboardEvent<HTMLDivElement>) => {82 if (event.key === "ArrowLeft") {83 event.preventDefault();84 scrollPrev();85 } else if (event.key === "ArrowRight") {86 event.preventDefault();87 scrollNext();88 }89 },90 [scrollPrev, scrollNext],91 );9293 useEffect(() => {94 if (!(api && setApi)) {95// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from blode/ui
All 85 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | blode/ui | Components | Free | 2 deps | |
| Alertalert | blode/ui | Components | Free | no deps | |
| Alert Dialogalert-dialog | blode/ui | Components | Free | 1 dep | |
| Ask User Questionsask-user-questions | blode/ui | Components | Free | 1 dep | |
| Aspect Ratioaspect-ratio | blode/ui | Components | Free | 1 dep | |
| Attachmentattachment | blode/ui | Components | Free | 1 dep | |
| Autocompleteautocomplete | blode/ui | Components | Free | 1 dep | |
| Avataravatar | blode/ui | Components | Free | 1 dep |
