72 lines
1.8 KiB
TypeScript
72 lines
1.8 KiB
TypeScript
import { motion } from "framer-motion";
|
|
import { SkeletonItem } from "../../../presentation/Skeleton";
|
|
|
|
interface LoadingCardProps {
|
|
count?: number;
|
|
className?: string;
|
|
}
|
|
|
|
export function LoadingCard({ count = 3, className = "" }: LoadingCardProps) {
|
|
return (
|
|
<div className={`space-y-4 mt-6 ${className}`}>
|
|
{[...Array(count)].map((_, i) => (
|
|
<motion.div
|
|
key={i}
|
|
initial={{ opacity: 0, y: 20 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
transition={{
|
|
duration: 0.5,
|
|
delay: i * 0.1,
|
|
ease: [0.4, 0, 0.2, 1],
|
|
}}
|
|
className="relative overflow-hidden rounded-lg bg-white border border-slate-200 p-4">
|
|
{/* 闪光扫描效果 */}
|
|
<motion.div
|
|
className="absolute inset-0 w-full h-full"
|
|
animate={{
|
|
background: [
|
|
"linear-gradient(90deg, transparent 0%, rgba(0,48,143,0.05) 50%, transparent 100%)",
|
|
"linear-gradient(90deg, transparent 0%, rgba(0,48,143,0.05) 50%, transparent 100%)",
|
|
],
|
|
x: ["-100%", "100%"],
|
|
}}
|
|
transition={{
|
|
duration: 1.5,
|
|
repeat: Infinity,
|
|
ease: "linear",
|
|
}}
|
|
/>
|
|
|
|
{/* 内容骨架 */}
|
|
<div className="space-y-3">
|
|
<div className="flex items-center space-x-3">
|
|
<SkeletonItem
|
|
className="w-10 h-10 rounded-full"
|
|
delay={i * 0.1}
|
|
/>
|
|
<div className="space-y-2 flex-1">
|
|
<SkeletonItem
|
|
className="h-4 w-1/4"
|
|
delay={i * 0.1 + 0.1}
|
|
/>
|
|
<SkeletonItem
|
|
className="h-3 w-1/6"
|
|
delay={i * 0.1 + 0.2}
|
|
/>
|
|
</div>
|
|
</div>
|
|
<SkeletonItem
|
|
className="h-4 w-3/4"
|
|
delay={i * 0.1 + 0.3}
|
|
/>
|
|
<SkeletonItem
|
|
className="h-4 w-1/2"
|
|
delay={i * 0.1 + 0.4}
|
|
/>
|
|
</div>
|
|
</motion.div>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|