import { type CSSProperties } from 'react'; export type SkeletonVariant = 'text' | 'avatar' | 'card' | 'list' | 'bento'; export interface SkeletonProps { /** * Variant of skeleton * - text: Single line of text * - avatar: Circular avatar * - card: Full card with header and content * - list: Multiple list items * - bento: Bento card style (original BentoSkeleton) */ variant?: SkeletonVariant; /** * Number of skeleton items to render */ count?: number; /** * Width (for text variant) */ width?: string | number; /** * Height (for custom sizing) */ height?: string | number; /** * Additional CSS classes */ className?: string; /** * Whether to animate * @default true */ animate?: boolean; } const baseClasses = 'bg-dark-800/50 rounded'; const animateClasses = 'animate-pulse'; export function Skeleton({ variant = 'text', count = 1, width, height, className = '', animate = true, }: SkeletonProps) { const animation = animate ? animateClasses : ''; const renderSkeleton = (index: number) => { const style: CSSProperties = { '--stagger': index, width: width, height: height, } as CSSProperties; switch (variant) { case 'text': return (
); case 'avatar': return (
); case 'card': return (
{/* Header */}
{/* Content */}
); case 'list': return (
); case 'bento': default: return (
); } }; if (count > 1) { return <>{Array.from({ length: count }).map((_, i) => renderSkeleton(i))}; } return renderSkeleton(0); } // Convenience components for common use cases export function TextSkeleton({ lines = 1, className = '', lastLineWidth = '60%', }: { lines?: number; className?: string; lastLineWidth?: string; }) { return (
{Array.from({ length: lines }).map((_, i) => ( ))}
); } export function AvatarSkeleton({ size = 40, className = '', }: { size?: number; className?: string; }) { return ; } export function CardSkeleton({ count = 1, className = '', }: { count?: number; className?: string; }) { return ; } export function ListSkeleton({ count = 3, className = '', }: { count?: number; className?: string; }) { return (
); } export function BentoSkeleton({ count = 1, className = '', }: { count?: number; className?: string; }) { return ; } // Default export for backwards compatibility export default BentoSkeleton;