veza/apps/web/src/features/tracks/components/TrackCardSkeleton.tsx
senke 13476dda6e feat(ui): Sidebar refactor, premium skeletons, ContentFadeIn transitions
- Sidebar: useSidebarNavigation hook, ARIA, token-based layout
- Layout: lg:ml-main-expanded/collapsed (replace arbitrary ml-64)
- TrackCardSkeleton + PlaylistCardSkeleton: KŌDŌ tokens, min-heights for CLS
- ContentFadeIn: 200ms fade-in with --ease-out
- TrackGrid, PlaylistList, LibraryPage: integrate skeletons + fade-in
- Player: player-bar subcomponents, useAudioAnalyser
- Tests: TrackGrid wrapper (QueryClient, ToastProvider)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 22:51:51 +01:00

39 lines
1.3 KiB
TypeScript

/**
* TrackCardSkeleton — Skeleton pour TrackCard.
* Utilise les primitives KŌDŌ (aspect-square, p-4) pour éviter le layout shift.
* Hauteurs minimales fixes pour préserver le CLS (Cumulative Layout Shift).
*/
import { Skeleton } from '@/components/ui/skeleton';
import { cn } from '@/lib/utils';
export interface TrackCardSkeletonProps {
className?: string;
}
export function TrackCardSkeleton({ className }: TrackCardSkeletonProps) {
return (
<div
className={cn(
'rounded-xl overflow-hidden border-0 shadow-lg bg-card',
'min-h-0',
className,
)}
role="status"
aria-label="Chargement du morceau"
>
{/* Cover — aspect-square comme TrackCard (CLS: hauteur déterministe) */}
<div className="aspect-square w-full min-h-0">
<Skeleton className="w-full h-full rounded-t-[var(--radius-xl)] rounded-b-none" />
</div>
{/* Info — p-4 space-y-1 comme TrackCard, min-h-14 évite layout shift */}
<div className="p-4 space-y-1 min-h-14">
<Skeleton className="h-4 w-4/5 rounded-md" />
<Skeleton className="h-3 w-3/5 rounded-md" />
<Skeleton className="h-3 w-16 rounded-md pt-1" />
</div>
<span className="sr-only">Chargement...</span>
</div>
);
}