From c264fd551d6a1f327fe447751888760eda983e57 Mon Sep 17 00:00:00 2001 From: tigeren Date: Thu, 28 Aug 2025 15:30:57 +0000 Subject: [PATCH] feat: enhance responsive layout for media grid component - Introduced dynamic column count and width calculations based on container size to improve responsiveness. - Added container width state management and resize event handling for better adaptability to different screen sizes. - Updated rendering logic to ensure proper display of media items based on calculated dimensions. --- src/components/virtualized-media-grid.tsx | 62 ++++++++++++++++------- 1 file changed, 45 insertions(+), 17 deletions(-) diff --git a/src/components/virtualized-media-grid.tsx b/src/components/virtualized-media-grid.tsx index e5a9b80..904a057 100644 --- a/src/components/virtualized-media-grid.tsx +++ b/src/components/virtualized-media-grid.tsx @@ -52,9 +52,11 @@ export default function VirtualizedMediaGrid({ hasMore: true }); const [isLoadingMore, setIsLoadingMore] = useState(false); + const [containerWidth, setContainerWidth] = useState(0); const observerTarget = useRef(null); const loadingRef = useRef(false); + const containerRef = useRef(null); const formatFileSize = (bytes: number) => { if (bytes === 0) return '0 Bytes'; @@ -146,6 +148,38 @@ export default function VirtualizedMediaGrid({ } }, [pagination, searchTerm, fetchItems]); + // Calculate responsive column count and width + const getColumnCount = useCallback(() => { + if (containerWidth === 0) return 6; + if (containerWidth < 640) return 2; + if (containerWidth < 768) return 3; + if (containerWidth < 1024) return 4; + if (containerWidth < 1280) return 5; + if (containerWidth < 1536) return 6; + return 7; + }, [containerWidth]); + + const getColumnWidth = useCallback(() => { + const cols = getColumnCount(); + // Account for padding (16px on each side) and gaps between cards (16px total per row) + const availableWidth = containerWidth - 32; // 16px padding on each side + const gapWidth = (cols - 1) * 16; // 16px gap between each column + return Math.floor((availableWidth - gapWidth) / cols); + }, [containerWidth, getColumnCount]); + + // Update container width on resize + useEffect(() => { + const updateWidth = () => { + if (containerRef.current) { + setContainerWidth(containerRef.current.offsetWidth); + } + }; + + updateWidth(); + window.addEventListener('resize', updateWidth); + return () => window.removeEventListener('resize', updateWidth); + }, []); + useEffect(() => { setLoading(true); fetchItems(0, searchTerm); @@ -169,7 +203,7 @@ export default function VirtualizedMediaGrid({ }, [loadMoreItems, pagination.hasMore]); const Cell = ({ columnIndex, rowIndex, style }: any) => { - const columnCount = 6; + const columnCount = getColumnCount(); const index = rowIndex * columnCount + columnIndex; const item = items[index]; @@ -245,18 +279,8 @@ export default function VirtualizedMediaGrid({ ); }; - const getColumnCount = () => { - if (typeof window === 'undefined') return 6; - const width = window.innerWidth; - if (width < 640) return 2; - if (width < 768) return 3; - if (width < 1024) return 4; - if (width < 1280) return 5; - if (width < 1536) return 6; - return 7; - }; - const columnCount = getColumnCount(); + const columnWidth = getColumnWidth(); const rowCount = Math.ceil(items.length / columnCount); if (loading && items.length === 0) { @@ -281,7 +305,7 @@ export default function VirtualizedMediaGrid({ return (
-
+
{/* Header */}
@@ -320,15 +344,15 @@ export default function VirtualizedMediaGrid({
{/* Media Grid */} - {items.length > 0 ? ( + {items.length > 0 && containerWidth > 0 ? (
{Cell} @@ -340,7 +364,7 @@ export default function VirtualizedMediaGrid({
)}
- ) : ( + ) : items.length === 0 ? (
@@ -356,6 +380,10 @@ export default function VirtualizedMediaGrid({

+ ) : ( +
+
+
)}