44 lines
832 B
TypeScript
44 lines
832 B
TypeScript
// components/presentation/Skeleton.tsx
|
|
import { motion } from "framer-motion";
|
|
import React from "react";
|
|
|
|
export const SkeletonItem = ({
|
|
className,
|
|
delay = 0,
|
|
}: {
|
|
className: string;
|
|
delay?: number;
|
|
}) => (
|
|
<motion.div
|
|
className={`bg-gray-200 rounded-md ${className}`}
|
|
animate={{ opacity: [0.4, 0.7, 0.4] }}
|
|
transition={{
|
|
duration: 1.5,
|
|
repeat: Infinity,
|
|
delay,
|
|
}}
|
|
/>
|
|
);
|
|
|
|
export const SkeletonSection = ({
|
|
title,
|
|
items,
|
|
gridCols = false,
|
|
}: {
|
|
title?: boolean;
|
|
items: number;
|
|
gridCols?: boolean;
|
|
}) => (
|
|
<div>
|
|
{title && <SkeletonItem className="h-6 w-32 mb-4" />}
|
|
<div
|
|
className={
|
|
gridCols ? "grid grid-cols-1 md:grid-cols-2 gap-4" : "space-y-2"
|
|
}>
|
|
{Array.from({ length: items }).map((_, i) => (
|
|
<SkeletonItem key={i} className="h-4" delay={i * 0.2} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|