UNPKG

lightswind

Version:

A collection of beautifully crafted React Components, Blocks & Templates for Modern Developers. Create stunning web applications effortlessly by using our 160+ professional and animated react components.

116 lines 5.97 kB
"use strict"; "use client"; Object.defineProperty(exports, "__esModule", { value: true }); const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const utils_1 = require("@/components/lib/utils"); // Optional utility for className merging const SlidingCards = ({ cards, className = "", cardSize = "w-24 h-24", onCardClick, autoPlay = false, autoPlayInterval = 3000, }) => { const cardStackRef = (0, react_1.useRef)(null); const cardsRef = (0, react_1.useRef)([]); (0, react_1.useEffect)(() => { const cardStack = cardStackRef.current; if (!cardStack) return; cardsRef.current = Array.from(cardStack.querySelectorAll(".card")); let isSwiping = false; let startX = 0; let currentX = 0; let animationFrameId = null; const getDuration = () => 300; const getActiveCard = () => cardsRef.current[0]; const updatePositions = () => { cardsRef.current.forEach((card, i) => { const offset = i + 1; card.style.zIndex = `${100 - offset}`; card.style.transform = `perspective(700px) translateZ(${-12 * offset}px) translateY(${7 * offset}px) translateX(0px) rotateY(0deg)`; card.style.opacity = `1`; }); }; const applySwipeStyles = (deltaX) => { const card = getActiveCard(); if (!card) return; const rotate = deltaX * 0.2; const opacity = 1 - Math.min(Math.abs(deltaX) / 100, 1) * 0.75; card.style.transform = `perspective(700px) translateZ(-12px) translateY(7px) translateX(${deltaX}px) rotateY(${rotate}deg)`; card.style.opacity = `${opacity}`; }; const handleStart = (clientX) => { if (isSwiping) return; isSwiping = true; startX = currentX = clientX; const card = getActiveCard(); card && (card.style.transition = "none"); }; const handleMove = (clientX) => { if (!isSwiping) return; if (animationFrameId) cancelAnimationFrame(animationFrameId); animationFrameId = requestAnimationFrame(() => { currentX = clientX; const deltaX = currentX - startX; applySwipeStyles(deltaX); if (Math.abs(deltaX) > 50) handleEnd(); }); }; const handleEnd = () => { if (!isSwiping) return; if (animationFrameId) cancelAnimationFrame(animationFrameId); const deltaX = currentX - startX; const threshold = 50; const duration = getDuration(); const card = getActiveCard(); if (card) { card.style.transition = `transform ${duration}ms ease, opacity ${duration}ms ease`; if (Math.abs(deltaX) > threshold) { const direction = Math.sign(deltaX); card.style.transform = `perspective(700px) translateZ(-12px) translateY(7px) translateX(${direction * 300}px) rotateY(${direction * 20}deg)`; setTimeout(() => { card.style.transform = `perspective(700px) translateZ(-12px) translateY(7px) translateX(${direction * 300}px) rotateY(${-direction * 20}deg)`; }, duration / 2); setTimeout(() => { cardsRef.current = [...cardsRef.current.slice(1), card]; updatePositions(); }, duration); } else { applySwipeStyles(0); } } isSwiping = false; startX = currentX = 0; }; const autoSlide = () => { const card = getActiveCard(); if (!card) return; const duration = getDuration(); card.style.transition = `transform ${duration}ms ease, opacity ${duration}ms ease`; card.style.transform = `perspective(700px) translateZ(-12px) translateY(7px) translateX(300px) rotateY(20deg)`; setTimeout(() => { cardsRef.current = [...cardsRef.current.slice(1), card]; updatePositions(); }, duration); }; let intervalId = null; if (autoPlay) { intervalId = setInterval(autoSlide, autoPlayInterval); } cardStack.addEventListener("pointerdown", (e) => handleStart(e.clientX)); cardStack.addEventListener("pointermove", (e) => handleMove(e.clientX)); cardStack.addEventListener("pointerup", handleEnd); updatePositions(); return () => { if (intervalId) clearInterval(intervalId); }; }, [autoPlay, autoPlayInterval]); return ((0, jsx_runtime_1.jsx)("section", { ref: cardStackRef, className: (0, utils_1.cn)("relative w-64 h-[22rem] grid place-content-center touch-none select-none", className), children: cards.map(({ id, icon, bgClass = "bg-gradient-to-br from-pink-300 to-orange-200" }, index) => ((0, jsx_runtime_1.jsx)("article", { onClick: () => onCardClick?.(index), className: (0, utils_1.cn)("card absolute inset-4 grid place-content-center rounded-xl border border-gray-400 shadow-md cursor-grab transition-transform ease-in-out", bgClass), children: (0, jsx_runtime_1.jsx)("span", { className: (0, utils_1.cn)("aspect-square grid place-content-center", cardSize), children: icon || ((0, jsx_runtime_1.jsx)("svg", { className: "w-full h-full fill-white drop-shadow-md", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", children: (0, jsx_runtime_1.jsx)("circle", { cx: "8", cy: "8", r: "6" }) })) }) }, id))) })); }; exports.default = SlidingCards; //# sourceMappingURL=sliding-cards.js.map