{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "credit-card-shadcnui", "type": "registry:component", "title": "Credit Card", "description": "3D animated credit card with flip animation to show CVV", "dependencies": [ "framer-motion", "react" ], "files": [ { "path": "@uitripled/react-shadcn/src/components/components/cards/shadcnui/credit-card.tsx", "content": "\"use client\";\n\nimport {\n motion,\n useMotionValue,\n useReducedMotion,\n useSpring,\n useTransform,\n} from \"framer-motion\";\nimport { CreditCard as CreditCardIcon } from \"lucide-react\";\nimport { useMemo, useState } from \"react\";\ninterface CreditCardProps {\n cardNumber?: string;\n cardholderName?: string;\n expiryDate?: string;\n cvv?: string;\n}\n\nconst gradients = {\n front:\n \"linear-gradient(145deg, hsl(var(--primary) / 0.45), hsl(var(--primary) / 0.18))\",\n back: \"linear-gradient(145deg, hsl(var(--primary) / 0.45), hsl(var(--primary) / 0.18))\",\n};\n\nconst overlayLights = [\n \"radial-gradient(circle at 20% 30%, hsl(var(--foreground) / 0.12), transparent 55%)\",\n \"radial-gradient(circle at 80% 20%, hsl(var(--primary) / 0.22), transparent 60%)\",\n \"radial-gradient(circle at 50% 80%, hsl(var(--accent) / 0.28), transparent 65%)\",\n];\n\nexport function CreditCard({\n cardNumber = \"4532 1234 5678 9010\",\n cardholderName = \"JORDAN PARK\",\n expiryDate = \"09/27\",\n cvv = \"123\",\n}: CreditCardProps) {\n const [isFlipped, setIsFlipped] = useState(false);\n\n const x = useMotionValue(0);\n const y = useMotionValue(0);\n\n const rotateX = useSpring(useTransform(y, [-0.5, 0.5], [6, -6]), {\n stiffness: 280,\n damping: 28,\n });\n const rotateY = useSpring(useTransform(x, [-0.5, 0.5], [-6, 6]), {\n stiffness: 280,\n damping: 28,\n });\n\n const shouldReduceMotion = useReducedMotion();\n\n const overlayGradient = useMemo(() => overlayLights.join(\",\"), []);\n\n const handleMouseMove = (event: React.MouseEvent) => {\n if (shouldReduceMotion) return;\n const rect = event.currentTarget.getBoundingClientRect();\n const width = rect.width;\n const height = rect.height;\n const mouseX = event.clientX - rect.left;\n const mouseY = event.clientY - rect.top;\n const xPct = mouseX / width - 0.5;\n const yPct = mouseY / height - 0.5;\n x.set(xPct);\n y.set(yPct);\n };\n\n const handleMouseLeave = () => {\n x.set(0);\n y.set(0);\n };\n\n const formatCardNumber = (number: string) => {\n return number.replace(/(.{4})/g, \"$1 \").trim();\n };\n\n return (\n
\n setIsFlipped(!isFlipped)}\n className=\"relative h-[240px] w-[380px] cursor-pointer\"\n style={{\n rotateX,\n rotateY,\n transformStyle: \"preserve-3d\",\n }}\n whileHover={shouldReduceMotion ? undefined : { scale: 1.015 }}\n transition={{ type: \"spring\", stiffness: 260, damping: 26 }}\n >\n
\n {/* Front */}\n \n \n
\n
\n
\n
\n
\n
\n
\n
\n\n
\n \n Card Number\n \n

\n {formatCardNumber(cardNumber)}\n

\n
\n\n
\n
\n \n Cardholder\n \n

\n {cardholderName}\n

\n
\n
\n \n Expires\n \n

\n {expiryDate}\n

\n
\n
\n \n\n {/* Back */}\n \n \n \n\n
\n
\n \n CVV\n \n \n {cvv}\n \n
\n

\n Contact support if you notice unauthorized activity.\n

\n
\n\n
\n \n
\n \n \n
\n );\n}\n", "type": "registry:component", "target": "components/uitripled/credit-card-shadcnui.tsx" } ] }