feat(ui): shared card grid with max six columns and virtualization

Add cardGridLayout helpers, useCardGridMetrics, useRemeasureGridVirtualizer, and VirtualCardGrid (TanStack row virtualization, always remeasure on layout changes).

Apply to Artists (grid + list unchanged policy), Albums, Composers grid, playlists, radio stations, offline library, and album-heavy browse/detail pages. Respect disableMainstageVirtualLists for a non-virtual grid with the same column rules.

Includes vitest coverage for column cap.
This commit is contained in:
Maxim Isaev
2026-05-15 02:05:34 +03:00
parent 778c9e00fd
commit 7c6d3694d4
20 changed files with 601 additions and 202 deletions
+24
View File
@@ -0,0 +1,24 @@
import { useEffect } from 'react';
import type { Virtualizer } from '@tanstack/react-virtual';
/** When grid column count or row height estimate changes, TanStack can keep stale offsets until scroll — force a remeasure. */
export function useRemeasureGridVirtualizer<TScroll extends Element, TItem extends Element>(
virtualizer: Virtualizer<TScroll, TItem>,
args: {
active: boolean;
gridCols: number;
rowHeightEst: number;
virtualRowCount: number;
},
): void {
useEffect(() => {
if (!args.active || args.virtualRowCount === 0) return;
virtualizer.measure();
}, [
args.active,
args.gridCols,
args.rowHeightEst,
args.virtualRowCount,
virtualizer,
]);
}