veza/apps/web/src/features/player/components/PlayerLoading.tsx

75 lines
1.6 KiB
TypeScript
Raw Normal View History

/**
* Composant PlayerLoading
* Affiche un état de chargement pour le player avec spinner et message
*/
import React from 'react';
import { Loader2 } from 'lucide-react';
import { cn } from '@/lib/utils';
export interface PlayerLoadingProps {
isLoading: boolean;
message?: string;
size?: 'sm' | 'md' | 'lg';
className?: string;
fullScreen?: boolean;
}
export function PlayerLoading({
isLoading,
message = 'Chargement...',
size = 'md',
className,
fullScreen = false,
}: PlayerLoadingProps) {
if (!isLoading) {
return null;
}
const sizeClasses = {
sm: 'h-4 w-4',
md: 'h-6 w-6',
lg: 'h-8 w-8',
};
const textSizeClasses = {
sm: 'text-xs',
md: 'text-sm',
lg: 'text-base',
};
const containerClasses = fullScreen
? 'fixed inset-0 flex items-center justify-center bg-black/50 dark:bg-black/70 z-50'
: 'flex items-center justify-center p-4';
return (
<div
className={cn(containerClasses, className)}
role="status"
aria-live="polite"
aria-label={message}
>
<div className="flex flex-col items-center gap-2">
<Loader2
className={cn(sizeClasses[size], 'animate-spin text-blue-600 dark:text-blue-400')}
aria-hidden="true"
/>
{message && (
<p
className={cn(
textSizeClasses[size],
'text-gray-700 dark:text-gray-300 text-center'
)}
>
{message}
</p>
)}
</div>
<span className="sr-only">{message}</span>
</div>
);
}
export default PlayerLoading;