import clsx from 'clsx'; import { Skeleton, SkeletonGroup } from '@/components/ui/Skeleton'; import { GalleryContainer, GalleryHeroFrame, MasonryGrid, masonryTileClass } from './GalleryLayout'; // Loading placeholder for the public gallery page. It renders through the same // hero frame, container and masonry grid as the real page (see GalleryLayout), // so replacing it with photos changes only the pixels inside the tiles. // Portrait/landscape/square mix standing in for a real event set. Fixed order // on purpose — a random shuffle would differ between the server and client // render and blow up hydration. const FALLBACK_RATIOS = [3 / 4, 4 / 3, 1, 2 / 3, 3 / 2, 4 / 5, 1, 3 / 4, 16 / 9, 4 / 5, 3 / 4, 4 / 3]; interface GallerySkeletonProps { /** Number of tiles to draw; ignored when `ratios` is given. */ count?: number; /** * Real width/height ratios when the caller already knows them (e.g. a * cached gallery payload). Produces a grid with exactly the right geometry * instead of the guessed mix above. */ ratios?: number[]; } export default function GallerySkeleton({ count = 12, ratios }: GallerySkeletonProps) { const tiles = ratios && ratios.length > 0 ? ratios : Array.from({ length: count }, (_, i) => FALLBACK_RATIOS[i % FALLBACK_RATIOS.length]); return ( {/* Matches the h1 (text-3xl / md:text-5xl) and the pill row below it. */}
{tiles.map((ratio, i) => (