veza/apps/web/src/components/player/audio-player/AudioPlayerSkeleton.tsx
senke b1f5fbf0bf feat(ui): hover cards, Spotify player layout, scrollbar tokens, context menu integration
HoverCard component (new):
- Rich preview cards on hover with framer-motion animation
- Viewport-aware positioning, portal rendering, open/close delays
- UserHoverContent: Discord-style user preview (avatar, bio, stats, follow)
- TrackHoverContent: Spotify-style track preview (cover, stats, play)

Audio player — Spotify-like 3-column layout:
- grid-cols-3 layout: track info | controls | volume+queue
- Progress bar moved to top edge (minimal variant)
- Glassmorphism (bg-background/95 backdrop-blur-md)
- Prominent centered play button (h-10 w-10 rounded-full, active:scale-95)
- Title marquee animation for long track names
- Reduced padding for tighter premium feel

Scrollbar styling:
- Migrated hardcoded rgba() to semantic tokens via color-mix(in oklch)
- Added transition on thumb hover for smooth visual feedback

ContextMenu integration:
- TrackListRow wrapped with ContextMenu (play, like, more actions)
- Dynamic items based on available callbacks

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-09 23:18:46 +01:00

51 lines
1.7 KiB
TypeScript

import { cn } from '@/lib/utils';
import { Skeleton } from '@/components/ui/skeleton';
interface AudioPlayerSkeletonProps {
className?: string;
}
/**
* Skeleton pour l'état Loading du lecteur (barre fixe en bas).
*/
export function AudioPlayerSkeleton({ className }: AudioPlayerSkeletonProps) {
return (
<div
className={cn(
'fixed bottom-0 left-0 right-0 bg-background/95 backdrop-blur-md border-t border-border z-50',
className,
)}
>
{/* Top progress bar skeleton */}
<Skeleton className="w-full h-1 rounded-none" />
<div className="container mx-auto px-4 py-2">
<div className="grid grid-cols-3 items-center gap-4">
{/* Left: Track info */}
<div className="flex items-center gap-3 min-w-0">
<Skeleton className="w-10 h-10 rounded shrink-0" />
<div className="flex-1 space-y-2 min-w-0">
<Skeleton className="h-3 w-3/4 rounded" />
<Skeleton className="h-2 w-1/2 rounded" />
</div>
</div>
{/* Center: Controls */}
<div className="flex items-center justify-center gap-1">
{[1, 2].map((i) => (
<Skeleton key={i} className="h-9 w-9 rounded" />
))}
<Skeleton className="h-10 w-10 rounded-full" />
{[4, 5].map((i) => (
<Skeleton key={i} className="h-9 w-9 rounded" />
))}
</div>
{/* Right: Volume + Queue */}
<div className="flex items-center justify-end gap-2">
<Skeleton className="h-9 w-9 rounded" />
<Skeleton className="w-24 h-2 rounded" />
<Skeleton className="h-9 w-9 rounded" />
</div>
</div>
</div>
</div>
);
}