Carousel
weekendsuperhero-io-sistine/carouselFreeComponent
An items-driven carousel, with the glass material system — pass slides as children (no compound CarouselContent/Item/Next/Previous/API parts).
Install it
npx shadcn@latest add https://raw.githubusercontent.com/Weekendsuperhero-io/sistine/main/public/r/carousel.jsonSource
1"use client";23import { CaretLeftIcon, CaretRightIcon } from "@phosphor-icons/react";4import { cva, type VariantProps } from "class-variance-authority";5import * as React from "react";6import { type HoverEffect, hoverEffects } from "@/lib/hover-effects";7import { type MaterialAxisProps, materialSurface, splitAxisProps } from "@/lib/material";8import { cn } from "@/lib/utils";9import { Button } from "./button";1011/* Variant classes carry BEHAVIOR only; the surface comes from materialSurface. */12const carouselVariants = cva("", {13 variants: {14 variant: {15 default: "bg-card text-card-foreground border shadow-sm",16 glass: "text-foreground",17 },18 },19 defaultVariants: {20 variant: "glass",21 },22});2324/* Role: borderless adaptive glass. */25const ROLE = {};2627export interface CarouselProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof carouselVariants>, MaterialAxisProps {28 effect?: HoverEffect;29 autoPlay?: boolean;30 interval?: number;31}3233const Carousel = React.forwardRef<HTMLDivElement, CarouselProps>(34 ({ className, variant = "glass", effect, autoPlay = false, interval = 3000, children, ...props }, ref) => {35 const [axes, rest] = splitAxisProps(props);36 const [currentIndex, setCurrentIndex] = React.useState(0);37 const items = React.Children.toArray(children);38 const totalItems = items.length;3940 React.useEffect(() => {41 if (!autoPlay || totalItems <= 1) return;4243 const timer = setInterval(() => {44 setCurrentIndex((prev) => (prev + 1) % totalItems);45 }, interval);4647 return () => clearInterval(timer);48 }, [49 autoPlay,50 interval,51 totalItems,52 ]);5354 const goToSlide = (index: number) => {55 setCurrentIndex(index);56 };5758 const goToPrevious = () => {59 setCurrentIndex((prev) => (prev - 1 + totalItems) % totalItems);60 };6162 const goToNext = () => {63 setCurrentIndex((prev) => (prev + 1) % totalItems);64 };6566 const m = materialSurface(variant === "default" ? null : ROLE, axes);6768 if (totalItems === 0) return null;6970 return (71 <div72 ref={ref}73 data-material={m?.["data-material"]}74 className={cn(75 m?.className,76 "relative w-full overflow-hidden rounded-lg",77 carouselVariants({78 variant,79 }),80 effect &&81 hoverEffects({82 hover: effect,83 }),84 className,85 )}86 {...rest}87 >88 <div89// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from weekendsuperhero-io/sistine
All 71 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | weekendsuperhero-io/sistine | Components | Free | 5 deps · 4 files | |
| Alertalert | weekendsuperhero-io/sistine | Components | Free | 3 deps · 4 files | |
| Alert Dialogalert-dialog | weekendsuperhero-io/sistine | Components | Free | 4 deps · 4 files | |
| Auto Foregroundauto-foreground | weekendsuperhero-io/sistine | Components | Free | no deps | |
| Avataravatar | weekendsuperhero-io/sistine | Components | Free | 4 deps · 4 files | |
| Badgebadge | weekendsuperhero-io/sistine | Components | Free | 4 deps · 4 files | |
| Breadcrumbbreadcrumb | weekendsuperhero-io/sistine | Components | Free | 5 deps · 4 files | |
| Buttonbutton | weekendsuperhero-io/sistine | Components | Free | 4 deps · 4 files |
