import React from 'react'; import { clsx } from 'clsx'; export interface LoadingSpinnerProps { size?: 'sm' | 'md' | 'lg' | 'xl'; variant?: 'primary' | 'secondary' | 'accent' | 'muted'; overlay?: boolean; text?: string; className?: string; } /** * Reusable loading spinner with glassmorphism styling * Provides smooth animations and multiple size/variant options */ export function LoadingSpinner({ size = 'md', variant = 'primary', overlay = false, text, className }: LoadingSpinnerProps) { const sizeClasses = { sm: 'w-4 h-4', md: 'w-6 h-6', lg: 'w-8 h-8', xl: 'w-12 h-12' }; const variantClasses = { primary: 'text-primary-500', secondary: 'text-secondary-500', accent: 'text-gold-500', muted: 'text-text-muted' }; const textSizeClasses = { sm: 'text-sm', md: 'text-base', lg: 'text-lg', xl: 'text-xl' }; const spinnerElement = (
{/* Spinner SVG */} {/* Loading Text */} {text && (

{text}

)}
); // Render as overlay if specified if (overlay) { return (
{spinnerElement}
); } return spinnerElement; } /** * Pulse animation component for skeleton loading states */ export function PulseLoader({ className }: { className?: string }) { return (
); } /** * Shimmer effect component for advanced skeleton loading */ export function ShimmerLoader({ className, children }: { className?: string; children?: React.ReactNode; }) { return (
{children}
); } /** * Dots loading animation */ export function DotsLoader({ size = 'md', variant = 'primary', className }: Pick) { const dotSizeClasses = { sm: 'w-1 h-1', md: 'w-2 h-2', lg: 'w-3 h-3', xl: 'w-4 h-4' }; const variantClasses = { primary: 'bg-primary-500', secondary: 'bg-secondary-500', accent: 'bg-gold-500', muted: 'bg-text-muted' }; return (
{[0, 1, 2].map((index) => (
))}
); } export default LoadingSpinner;