UNPKG

reactbits-mcp-server

Version:

MCP Server for React Bits - Access 99+ React components with animations, backgrounds, and UI elements

116 lines (109 loc) 3.44 kB
import { motion, useMotionValue, useTransform } from "framer-motion"; import { useState } from "react"; function CardRotate({ children, onSendToBack, sensitivity }) { const x = useMotionValue(0); const y = useMotionValue(0); const rotateX = useTransform(y, [-100, 100], [60, -60]); const rotateY = useTransform(x, [-100, 100], [-60, 60]); function handleDragEnd(_, info) { if ( Math.abs(info.offset.x) > sensitivity || Math.abs(info.offset.y) > sensitivity ) { onSendToBack(); } else { x.set(0); y.set(0); } } return ( <motion.div className="absolute cursor-grab" style={{ x, y, rotateX, rotateY }} drag dragConstraints={{ top: 0, right: 0, bottom: 0, left: 0 }} dragElastic={0.6} whileTap={{ cursor: "grabbing" }} onDragEnd={handleDragEnd} > {children} </motion.div> ); } export default function Stack({ randomRotation = false, sensitivity = 200, cardDimensions = { width: 208, height: 208 }, cardsData = [], animationConfig = { stiffness: 260, damping: 20 }, sendToBackOnClick = false }) { const [cards, setCards] = useState( cardsData.length ? cardsData : [ { id: 1, img: "https://images.unsplash.com/photo-1480074568708-e7b720bb3f09?q=80&w=500&auto=format" }, { id: 2, img: "https://images.unsplash.com/photo-1449844908441-8829872d2607?q=80&w=500&auto=format" }, { id: 3, img: "https://images.unsplash.com/photo-1452626212852-811d58933cae?q=80&w=500&auto=format" }, { id: 4, img: "https://images.unsplash.com/photo-1572120360610-d971b9d7767c?q=80&w=500&auto=format" } ] ); const sendToBack = (id) => { setCards((prev) => { const newCards = [...prev]; const index = newCards.findIndex((card) => card.id === id); const [card] = newCards.splice(index, 1); newCards.unshift(card); return newCards; }); }; return ( <div className="relative" style={{ width: cardDimensions.width, height: cardDimensions.height, perspective: 600, }} > {cards.map((card, index) => { const randomRotate = randomRotation ? Math.random() * 10 - 5 : 0; return ( <CardRotate key={card.id} onSendToBack={() => sendToBack(card.id)} sensitivity={sensitivity} > <motion.div className="rounded-2xl overflow-hidden border-4 border-white" onClick={() => sendToBackOnClick && sendToBack(card.id)} animate={{ rotateZ: (cards.length - index - 1) * 4 + randomRotate, scale: 1 + index * 0.06 - cards.length * 0.06, transformOrigin: "90% 90%", }} initial={false} transition={{ type: "spring", stiffness: animationConfig.stiffness, damping: animationConfig.damping, }} style={{ width: cardDimensions.width, height: cardDimensions.height, }} > <img src={card.img} alt={`card-${card.id}`} className="w-full h-full object-cover pointer-events-none" /> </motion.div> </CardRotate> ); })} </div> ); }