/**
* LoadingSpinner - Animated loading spinner for web
*
* Features:
* - Multiple sizes (sm, md, lg, xl)
* - Optional loading message
* - Full-screen mode option
* - Tailwind CSS styling
*
* @example
* ```tsx
*
*
*
* ```
*/
import { cn } from '@/lib/utils';
interface LoadingSpinnerProps {
size?: 'sm' | 'md' | 'lg' | 'xl';
color?: 'primary' | 'white' | 'gray';
message?: string;
fullScreen?: boolean;
className?: string;
}
// Size mapping for spinner
const sizeClasses = {
sm: 'h-4 w-4 border-2',
md: 'h-8 w-8 border-2',
lg: 'h-12 w-12 border-3',
xl: 'h-16 w-16 border-4',
};
// Color mapping for spinner
const colorClasses = {
primary: 'border-blue-600 border-t-transparent',
white: 'border-white border-t-transparent',
gray: 'border-gray-400 border-t-transparent',
};
// Text size mapping
const textSizeClasses = {
sm: 'text-sm',
md: 'text-base',
lg: 'text-lg',
xl: 'text-xl',
};
export function LoadingSpinner({
size = 'md',
color = 'primary',
message,
fullScreen = false,
className,
}: LoadingSpinnerProps) {
const spinner = (
);
if (fullScreen) {
return (
{spinner}
{message && (
{message}
)}
);
}
if (message) {
return (
);
}
return spinner;
}
/**
* LoadingOverlay - Full-screen loading overlay with backdrop
*
* @example
* ```tsx
* {isLoading && (
*
* )}
* ```
*/
interface LoadingOverlayProps {
message?: string;
backdrop?: 'light' | 'dark' | 'blur';
}
export function LoadingOverlay({
message = 'Loading...',
backdrop = 'blur'
}: LoadingOverlayProps) {
const backdropClasses = {
light: 'bg-white/80',
dark: 'bg-slate-900/80',
blur: 'bg-white/80 backdrop-blur-sm',
};
return (
);
}
/**
* InlineLoader - Small inline loading indicator
*
* @example
* ```tsx
*
* ```
*/
interface InlineLoaderProps {
className?: string;
}
export function InlineLoader({ className }: InlineLoaderProps) {
return (
);
}
/**
* PageLoader - Full page loading state with centered spinner
*
* @example
* ```tsx
* if (isLoading) return ;
* ```
*/
interface PageLoaderProps {
message?: string;
}
export function PageLoader({ message }: PageLoaderProps) {
return (
{message && (
{message}
)}
);
}