feat: add pdf image renderer (#2554)

## Description

Replace the PDF renderer with an custom image renderer.

This allows us to remove the "react-pdf" dependency and allows us to use
a virtual list to improve performance.
This commit is contained in:
David Nguyen
2026-03-06 12:39:03 +11:00
committed by GitHub
parent 0ce909a298
commit 6faa01d384
82 changed files with 2581 additions and 1365 deletions
@@ -0,0 +1,46 @@
import { type RefObject, useEffect } from 'react';
/**
* Watch for `data-scroll-to-page` attribute changes on a container element.
*
* When set (by `validateFieldsInserted`, `handleOnNextFieldClick`, or similar),
* scroll the virtual list to the requested page and clear the attribute.
*
* This is the communication bridge between field validation logic (which knows
* which page to scroll to) and the virtual list (which knows how to scroll).
*/
export const useScrollToPage = (
contentRef: RefObject<HTMLElement | null>,
scrollToItem: (index: number) => void,
) => {
useEffect(() => {
const el = contentRef.current;
if (!el) {
return;
}
const observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
if (mutation.type === 'attributes' && mutation.attributeName === 'data-scroll-to-page') {
const raw = el.getAttribute('data-scroll-to-page');
if (raw) {
const pageNumber = parseInt(raw, 10);
if (!isNaN(pageNumber) && pageNumber >= 1) {
// Pages are 1-indexed, virtual list items are 0-indexed.
scrollToItem(pageNumber - 1);
}
el.removeAttribute('data-scroll-to-page');
}
}
}
});
observer.observe(el, { attributes: true, attributeFilter: ['data-scroll-to-page'] });
return () => observer.disconnect();
}, [contentRef, scrollToItem]);
};