Carousel (Tailwind)
roi-ui/carousel-tailwindFreeItem
A slideshow component for cycling through content.
Install it
npx shadcn@latest add https://roiui.com/r/carousel-tailwind.jsonSource
1"use client";23import { useControlled } from "@base-ui/utils/useControlled";4import { createContext, useCallback, useContext, useEffect, useId, useRef, useState } from "react";5import { cn } from "@/lib/utils";67type CarouselContextValue = {8 currentIndex: number;9 setCurrentIndex: (index: number) => void;10 totalItems: number;11 gap: number;12 variant: "default" | "inset";13 goToIndex: (index: number) => void;14 nextSlide: () => void;15 prevSlide: () => void;16 canGoNext: boolean;17 canGoPrev: boolean;18 viewportRef: React.RefObject<HTMLDivElement | null>;19 slidesId: string;20};2122const CarouselContext = createContext<CarouselContextValue | null>(null);2324function useCarousel() {25 const context = useContext(CarouselContext);26 if (!context) {27 throw new Error("Carousel components must be used within Carousel.Root");28 }29 return context;30}3132export type CarouselRootProps = React.ComponentProps<"div"> & {33 totalItems: number;34 gap?: number;35 index?: number;36 defaultIndex?: number;37 onIndexChange?: (index: number) => void;38 align?: "start" | "center";39 variant?: "default" | "inset";40};4142export function Root({43 children,44 totalItems,45 gap = 16,46 index: indexProp,47 defaultIndex = 0,48 onIndexChange,49 align = "start",50 variant = "default",51 className,52 ...props53}: CarouselRootProps) {54 const [currentIndex, setCurrentIndexInternal] = useControlled({55 controlled: indexProp,56 default: defaultIndex,57 name: "Carousel",58 state: "index",59 });6061 const viewportRef = useRef<HTMLDivElement>(null);62 const bleedRefFromContext = useBleedRef();63 const [insetPaddingLeft, setInsetPaddingLeft] = useState(0);64 const [insetPaddingRight, setInsetPaddingRight] = useState(0);65 const slidesId = `${useId()}-slides`;6667 const maxIndex = totalItems - 1;6869 const setCurrentIndex = useCallback(70 (index: number) => {71 setCurrentIndexInternal(index);72 onIndexChange?.(index);73 },74 [setCurrentIndexInternal, onIndexChange]75 );7677 const goToIndex = useCallback(78 (index: number) => {79 const viewport = viewportRef.current;80 if (!viewport) {81 return;82 }8384 const slides = viewport.querySelectorAll('[role="group"]');85 const targetSlide = slides[index] as HTMLElement;8687 if (targetSlide) {88 let targetScroll = targetSlide.offsetLeft;8990 if (variant === "inset" && bleedRefFromContext?.current) {91 const parent = bleedRefFromContext.current.parentElement;92 if (parent) {93// … truncated
Files it writes
More from Roi UI
All 123 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | Roi UI | Other | Free | no deps · 2 files | |
| Accordion (Tailwind)accordion-tailwind | Roi UI | Other | Free | no deps | |
| AI Chatai-chat | Roi UI | Other | Free | no deps · 2 files | |
| AI Chat (Tailwind)ai-chat-tailwind | Roi UI | Other | Free | no deps | |
| Alertalert | Roi UI | Other | Free | 1 dep · 2 files | |
| Alert Dialogalert-dialog | Roi UI | Other | Free | no deps · 2 files | |
| Alert Dialog (Tailwind)alert-dialog-tailwind | Roi UI | Other | Free | no deps | |
| Alert (Tailwind)alert-tailwind | Roi UI | Other | Free | 1 dep |
