diff --git a/src/photo/PhotoGridPage.tsx b/src/photo/PhotoGridPage.tsx index bf5c775f..b5857e3a 100644 --- a/src/photo/PhotoGridPage.tsx +++ b/src/photo/PhotoGridPage.tsx @@ -4,10 +4,11 @@ import { Photo } from '.'; import { PATH_GRID_INFERRED } from '@/app/paths'; import PhotoGridSidebar from './PhotoGridSidebar'; import PhotoGridContainer from './PhotoGridContainer'; -import { useEffect } from 'react'; +import { useEffect, useRef } from 'react'; import { useAppState } from '@/state/AppState'; import clsx from 'clsx/lite'; import { PhotoSetCategories } from '@/category'; +import useElementHeight from '@/utility/useElementHeight'; export default function PhotoGridPage({ photos, @@ -17,6 +18,8 @@ export default function PhotoGridPage({ photos: Photo[] photosCount: number }) { + const ref = useRef(null); + const { setSelectedPhotoIds } = useAppState(); useEffect( @@ -24,6 +27,8 @@ export default function PhotoGridPage({ [setSelectedPhotoIds], ); + const containerHeight = useElementHeight(ref); + return ( diff --git a/src/photo/PhotoGridSidebar.tsx b/src/photo/PhotoGridSidebar.tsx index 0759bd38..3b36904e 100644 --- a/src/photo/PhotoGridSidebar.tsx +++ b/src/photo/PhotoGridSidebar.tsx @@ -30,15 +30,17 @@ import { } from '@/category'; import PhotoFocalLength from '@/focal/PhotoFocalLength'; -const SIDEBAR_ITEM_MAX_COUNT = 28; +const APPROXIMATE_ITEM_HEIGHT = 34; export default function PhotoGridSidebar({ photosCount, photosDateRange, + containerHeight, ...categories }: PhotoSetCategories & { photosCount: number photosDateRange?: PhotoDateRange + containerHeight?: number }) { const { cameras, @@ -49,14 +51,18 @@ export default function PhotoGridSidebar({ focalLengths, } = categories; - const itemsCount = getCategoriesWithItemsCount( + const categoriesCount = getCategoriesWithItemsCount( CATEGORY_VISIBILITY, categories, ); - const maxItemsPerCategory = Math.floor( - SIDEBAR_ITEM_MAX_COUNT / itemsCount, - ); + const maxItemsPerCategory = containerHeight + ? Math.max( + Math.floor(containerHeight / categoriesCount / APPROXIMATE_ITEM_HEIGHT), + // Always show at least 2 items + 2, + ) + : undefined; const { start, end } = dateRangeForPhotos(undefined, photosDateRange); diff --git a/src/utility/useElementHeight.ts b/src/utility/useElementHeight.ts new file mode 100644 index 00000000..8f0d992f --- /dev/null +++ b/src/utility/useElementHeight.ts @@ -0,0 +1,18 @@ +import { useState } from 'react'; + +import { RefObject, useEffect } from 'react'; + +export default function useElementHeight( + element: RefObject, +) { + const [height, setHeight] = useState(element.current?.clientHeight); + + useEffect(() => { + const handleResize = () => setHeight(element.current?.clientHeight); + handleResize(); + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + }, [element]); + + return height; +}