veza/apps/web/src/features/player/components/PlayerLoading.tsx
senke fa8cef26f0 feat(ui): semantic tokens in loading states, header, sidebar, navbar
- LoadingState: bg-kodo-slate → bg-muted for skeleton variant
- PlayerLoading: fullScreen overlay bg-black/50 → bg-background/80 backdrop-blur-sm
- Header: bg-white/5 → bg-muted/30, border-white/* → border-border, focus:ring-ring
- Sidebar: overlay bg-black/60 → bg-background/80, hover:text-white → hover:text-foreground
- Navbar: text-white → text-foreground, ring-white/5 → ring-border

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 09:28:43 +01:00

75 lines
1.6 KiB
TypeScript

/**
* Composant PlayerLoading
* Affiche un état de chargement pour le player avec spinner et message
*/
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-background/80 backdrop-blur-sm 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-muted-foreground',
)}
aria-hidden="true"
/>
{message && (
<p
className={cn(
textSizeClasses[size],
'text-foreground text-center',
)}
>
{message}
</p>
)}
</div>
<span className="sr-only">{message}</span>
</div>
);
}
export default PlayerLoading;