This commit is contained in:
Nathan Vasse
2026-04-24 17:31:39 +02:00
parent cf57c9e4bb
commit 4cc2e6a0e7
4 changed files with 19 additions and 16 deletions

View File

@@ -75,9 +75,11 @@ export function PdfPageViewer({
const rowHeightForIndex = useCallback(
(index: number) => {
const h = width * getRatio(index) * zoom;
// No trailing gap on the last row
if (index === numPages - 1) return h;
return h + PAGE_GAP * zoom;
const gap = PAGE_GAP * zoom;
// Every row reserves a gap above the page via paddingTop. The last
// row additionally reserves a gap below it so the final page has
// breathing room matching the space above every other page.
return index === numPages - 1 ? h + 2 * gap : h + gap;
},
[width, getRatio, zoom, numPages],
);
@@ -153,13 +155,12 @@ export function PdfPageViewer({
for (let i = 0; i < page - 1; i++) {
const d = dimensions.get(i + 1);
const ratio = d ? d.h / d.w : FALLBACK_RATIO;
const h = width * ratio * zoom;
offset += i === numPages - 1 ? h : h + PAGE_GAP * zoom;
offset += width * ratio * zoom + PAGE_GAP * zoom;
}
listRef.current.scrollToPosition(offset);
});
},
[ensurePageDimensions, width, zoom, numPages],
[ensurePageDimensions, width, zoom],
);
useImperativeHandle(ref, () => ({ scrollToPage }), [scrollToPage]);
@@ -210,6 +211,7 @@ export function PdfPageViewer({
display: "flex",
justifyContent: "center",
paddingTop: PAGE_GAP * zoom,
paddingBottom: index === numPages - 1 ? PAGE_GAP * zoom : 0,
}}
>
<Page

View File

@@ -72,7 +72,6 @@
width: 150px;
overflow: hidden;
padding: 12px 0;
border-right: 1px solid var(--c--contextuals--border--surface--primary);
background: var(--c--contextuals--background--surface--primary);
transform: translateX(0);

View File

@@ -9,10 +9,7 @@ import {
THUMBNAIL_WIDTH,
TRANSITION_DELAY,
} from "./pdfConsts";
import {
FALLBACK_RATIO,
type PageDimensionsMap,
} from "./usePdfPageDimensions";
import { FALLBACK_RATIO, type PageDimensionsMap } from "./usePdfPageDimensions";
interface PdfThumbnailSidebarProps {
numPages: number;
@@ -94,8 +91,11 @@ export function PdfThumbnailSidebarContent({
const rowHeight = useCallback(
({ index }: { index: number }) => {
const thumbH = THUMBNAIL_WIDTH * getRatio(index);
const base = thumbH + THUMBNAIL_LABEL_SPACE;
return index < numPages - 1 ? base + THUMBNAIL_GAP : base;
const base = thumbH + THUMBNAIL_LABEL_SPACE + THUMBNAIL_GAP;
// Every row reserves a gap above via paddingTop. The last row also
// reserves one below so the final thumbnail has matching breathing
// room at the bottom of the sidebar.
return index === numPages - 1 ? base + THUMBNAIL_GAP : base;
},
[getRatio, numPages],
);
@@ -135,7 +135,8 @@ export function PdfThumbnailSidebarContent({
key={key}
style={{
...style,
paddingBottom: index < numPages - 1 ? THUMBNAIL_GAP : 0,
paddingTop: THUMBNAIL_GAP,
paddingBottom: index === numPages - 1 ? THUMBNAIL_GAP : 0,
boxSizing: "border-box",
}}
>

View File

@@ -247,9 +247,10 @@ test.describe("PDF Preview — mixed page sizes", () => {
const h = await gridInner.evaluate((el) =>
parseFloat(getComputedStyle(el as HTMLElement).height),
);
// Add vertical gaps (PAGE_GAP=16 between rows, no trailing gap).
// Every row reserves PAGE_GAP=16 above (paddingTop); the last row
// additionally reserves PAGE_GAP below it → N+1 gaps total.
const expectedTotal =
expectedContentHeight + 16 * (EXPECTED_RATIOS.length - 1);
expectedContentHeight + 16 * (EXPECTED_RATIOS.length + 1);
// 5% tolerance: react-pdf canvas rounding + scroll-anchor jitter.
expect(Math.abs(h - expectedTotal) / expectedTotal).toBeLessThanOrEqual(
0.05,