53 lines
1.1 KiB
TypeScript
53 lines
1.1 KiB
TypeScript
import { cn } from '@/lib/utils';
|
|
|
|
interface SkeletonProps {
|
|
className?: string;
|
|
variant?: 'text' | 'circular' | 'rectangular';
|
|
width?: string | number;
|
|
height?: string | number;
|
|
animation?: 'pulse' | 'wave' | 'none';
|
|
}
|
|
|
|
export function Skeleton({
|
|
className,
|
|
variant = 'rectangular',
|
|
width,
|
|
height,
|
|
animation = 'pulse',
|
|
}: SkeletonProps) {
|
|
const variantClasses = {
|
|
text: 'rounded',
|
|
circular: 'rounded-full',
|
|
rectangular: 'rounded',
|
|
};
|
|
|
|
const animationClasses = {
|
|
pulse: 'animate-pulse',
|
|
wave: 'shimmer',
|
|
none: '',
|
|
};
|
|
|
|
const style: React.CSSProperties = {};
|
|
if (width) {
|
|
style.width = typeof width === 'number' ? `${width}px` : width;
|
|
}
|
|
if (height) {
|
|
style.height = typeof height === 'number' ? `${height}px` : height;
|
|
}
|
|
|
|
return (
|
|
<div
|
|
className={cn(
|
|
'bg-gray-200 dark:bg-gray-700',
|
|
variantClasses[variant],
|
|
animationClasses[animation],
|
|
className,
|
|
)}
|
|
style={style}
|
|
role="status"
|
|
aria-label="Chargement..."
|
|
>
|
|
<span className="sr-only">Chargement...</span>
|
|
</div>
|
|
);
|
|
}
|