Intelligently use vertical space in sidebar
This commit is contained in:
parent
a834e07abf
commit
c9fe0bdc99
@ -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<HTMLDivElement>(null);
|
||||
|
||||
const { setSelectedPhotoIds } = useAppState();
|
||||
|
||||
useEffect(
|
||||
@ -24,6 +27,8 @@ export default function PhotoGridPage({
|
||||
[setSelectedPhotoIds],
|
||||
);
|
||||
|
||||
const containerHeight = useElementHeight(ref);
|
||||
|
||||
return (
|
||||
<PhotoGridContainer
|
||||
cacheKey={`page-${PATH_GRID_INFERRED}`}
|
||||
@ -31,6 +36,7 @@ export default function PhotoGridPage({
|
||||
count={photosCount}
|
||||
sidebar={
|
||||
<div
|
||||
ref={ref}
|
||||
className={clsx(
|
||||
'sticky top-0 -mb-5 -mt-5',
|
||||
'max-h-screen h-full',
|
||||
@ -47,6 +53,7 @@ export default function PhotoGridPage({
|
||||
<PhotoGridSidebar {...{
|
||||
...categories,
|
||||
photosCount,
|
||||
containerHeight,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
18
src/utility/useElementHeight.ts
Normal file
18
src/utility/useElementHeight.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
import { RefObject, useEffect } from 'react';
|
||||
|
||||
export default function useElementHeight(
|
||||
element: RefObject<HTMLElement | null>,
|
||||
) {
|
||||
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;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user