diagonal-carousel
vengenceui/diagonal-carouselFreeComponent
vengenceui publishes no description for this item.
Live preview
live · rendered by the registry
Rendered by vengenceui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://www.vengenceui.com/r/diagonal-carousel.jsonSource
1"use client";23import * as React from "react";4import { motion, type Transition } from "framer-motion";5import { ChevronLeft, ChevronRight } from "lucide-react";6import { cn } from "@/lib/utils";78export interface DiagonalCarouselItem {9 src: string;10 title: string;11 alt?: string;12}1314export interface DiagonalCarouselProps15 extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange"> {16 items: DiagonalCarouselItem[];17 activeIndex?: number;18 defaultActiveIndex?: number;19 onActiveIndexChange?: (index: number) => void;20 loop?: boolean;21 slideSize?: number;22 rotationStep?: number;23 verticalStep?: number;24 inactiveScale?: number;25 transition?: Transition;26 showControls?: boolean;27 showDots?: boolean;28 viewportClassName?: string;29 slideClassName?: string;30 imageClassName?: string;31 labelClassName?: string;32 controlsClassName?: string;33}3435const DEFAULT_TRANSITION: Transition = {36 type: "spring",37 bounce: 0.16,38 duration: 0.85,39};4041const clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max);4243export function DiagonalCarousel({44 items,45 activeIndex,46 defaultActiveIndex = 0,47 onActiveIndexChange,48 loop = false,49 slideSize = 260,50 rotationStep = 30,51 verticalStep = 120,52 inactiveScale = 0.6,53 transition = DEFAULT_TRANSITION,54 showControls = true,55 showDots = true,56 viewportClassName,57 slideClassName,58 imageClassName,59 labelClassName,60 controlsClassName,61 className,62 onKeyDown,63 tabIndex,64 ...props65}: DiagonalCarouselProps) {66 const maxIndex = Math.max(0, items.length - 1);67 const [uncontrolledIndex, setUncontrolledIndex] = React.useState(() =>68 clamp(defaultActiveIndex, 0, maxIndex)69 );70 const currentIndex = clamp(activeIndex ?? uncontrolledIndex, 0, maxIndex);71 const safeSlideSize = Math.max(120, slideSize);72 const safeInactiveScale = clamp(inactiveScale, 0.35, 1);7374 const selectSlide = React.useCallback(75 (nextIndex: number) => {76 if (!items.length) {77 return;78 }7980 const resolvedIndex = loop81 ? (nextIndex + items.length) % items.length82 : clamp(nextIndex, 0, maxIndex);8384 if (activeIndex === undefined) {85 setUncontrolledIndex(resolvedIndex);86 }8788 onActiveIndexChange?.(resolvedIndex);89 },90 [activeIndex, items.length, loop, maxIndex, onActiveIndexChange]91 );9293 const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {94 onKeyDown?.(event);9596 if (event.defaultPrevented) {97 return;98 }99100// … truncated
What it pulls in
npm packages
Files it writes
More from vengenceui
All 128 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| accordionaccordion | vengenceui | Components | Free | 2 deps | |
| agent-bento-gridagent-bento-grid | vengenceui | Components | Free | 1 dep | |
| alertalert | vengenceui | Components | Free | no deps | |
| animated-buttonanimated-button | vengenceui | Components | Free | 1 dep | |
| animated-footeranimated-footer | vengenceui | Components | Free | 2 deps | |
| animated-numberanimated-number | vengenceui | Components | Free | 1 dep | |
| animated-raysanimated-rays | vengenceui | Components | Free | no deps | |
| animated-tooltipanimated-tooltip | vengenceui | Components | Free | 1 dep |
