- 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>
39 lines
1.3 KiB
TypeScript
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>
|
|
);
|
|
}
|