Carousel
blok/carouselFreeComponent
A carousel component for displaying a series of items in a sliding manner.
Install it
npx shadcn@latest add https://blok.sitecore.com/r/carousel.jsonSource
1"use client";23import { Icon } from "@/lib/icon";4import { mdiArrowLeft, mdiArrowRight } from "@mdi/js";5import useEmblaCarousel, {6 type UseEmblaCarouselType,7} from "embla-carousel-react";8import * as React from "react";910import { Button } from "@/components/ui/button";11import { 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?: 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 React.useEffect(() => {98 if (!api) return;99// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from blok
All 72 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | blok | Components | Free | 2 deps · 2 files | |
| Action baraction-bar | blok | Components | Free | 1 dep · 2 files | |
| Alertalert | blok | Components | Free | 2 deps · 2 files | |
| Alert dialogalert-dialog | blok | Components | Free | 2 deps | |
| Aspect ratioaspect-ratio | blok | Components | Free | 1 dep | |
| Avataravatar | blok | Components | Free | 1 dep | |
| Badgebadge | blok | Components | Free | 2 deps | |
| All componentsblok-components | blok | Components | Free | no deps |
