File size: 2,008 Bytes
a566fb0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
import React, { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { Sparkles, ChevronDown } from 'lucide-react';
export default function ClickReveal({ title, children, color = "blue" }) {
const [isRevealed, setIsRevealed] = useState(false);
const colors = {
blue: "from-blue-500/20 to-cyan-500/20 border-blue-500/30 hover:border-blue-400/50",
purple: "from-purple-500/20 to-pink-500/20 border-purple-500/30 hover:border-purple-400/50",
green: "from-emerald-500/20 to-teal-500/20 border-emerald-500/30 hover:border-emerald-400/50",
yellow: "from-yellow-500/20 to-orange-500/20 border-yellow-500/30 hover:border-yellow-400/50"
};
return (
<motion.div
className={`rounded-2xl bg-gradient-to-br ${colors[color]} backdrop-blur-sm border-2 overflow-hidden cursor-pointer transition-all duration-300`}
onClick={() => setIsRevealed(!isRevealed)}
whileHover={{ scale: 1.01 }}
whileTap={{ scale: 0.99 }}
>
<div className="p-5 flex items-center justify-between">
<div className="flex items-center gap-3">
<Sparkles className="w-5 h-5 text-yellow-400" />
<span className="font-semibold text-white">{title}</span>
</div>
<motion.div
animate={{ rotate: isRevealed ? 180 : 0 }}
transition={{ duration: 0.3 }}
>
<ChevronDown className="w-5 h-5 text-white/60" />
</motion.div>
</div>
<AnimatePresence>
{isRevealed && (
<motion.div
initial={{ height: 0, opacity: 0 }}
animate={{ height: "auto", opacity: 1 }}
exit={{ height: 0, opacity: 0 }}
transition={{ duration: 0.3 }}
>
<div className="px-5 pb-5 text-white/80 border-t border-white/10 pt-4">
{children}
</div>
</motion.div>
)}
</AnimatePresence>
</motion.div>
);
} |