UNPKG

react-pdf

Version:

Display PDFs in your React app as easily as if they were images.

134 lines (133 loc) 5.9 kB
'use client'; import { jsx as _jsx } from "react/jsx-runtime"; import { useEffect, useMemo, useRef } from 'react'; import makeCancellable from 'make-cancellable-promise'; import clsx from 'clsx'; import invariant from 'tiny-invariant'; import warning from 'warning'; import * as pdfjs from 'pdfjs-dist'; import useDocumentContext from '../shared/hooks/useDocumentContext.js'; import usePageContext from '../shared/hooks/usePageContext.js'; import useResolver from '../shared/hooks/useResolver.js'; import { cancelRunningTask } from '../shared/utils.js'; export default function AnnotationLayer() { const documentContext = useDocumentContext(); const pageContext = usePageContext(); invariant(pageContext, 'Unable to find Page context.'); const mergedProps = Object.assign(Object.assign({}, documentContext), pageContext); const { imageResourcesPath, linkService, onGetAnnotationsError: onGetAnnotationsErrorProps, onGetAnnotationsSuccess: onGetAnnotationsSuccessProps, onRenderAnnotationLayerError: onRenderAnnotationLayerErrorProps, onRenderAnnotationLayerSuccess: onRenderAnnotationLayerSuccessProps, page, pdf, renderForms, rotate, scale = 1, } = mergedProps; invariant(pdf, 'Attempted to load page annotations, but no document was specified. Wrap <Page /> in a <Document /> or pass explicit `pdf` prop.'); invariant(page, 'Attempted to load page annotations, but no page was specified.'); invariant(linkService, 'Attempted to load page annotations, but no linkService was specified.'); const [annotationsState, annotationsDispatch] = useResolver(); const { value: annotations, error: annotationsError } = annotationsState; const layerElement = useRef(null); warning(Number.parseInt(window.getComputedStyle(document.body).getPropertyValue('--react-pdf-annotation-layer'), 10) === 1, 'AnnotationLayer styles not found. Read more: https://github.com/wojtekmaj/react-pdf#support-for-annotations'); function onLoadSuccess() { if (!annotations) { // Impossible, but TypeScript doesn't know that return; } if (onGetAnnotationsSuccessProps) { onGetAnnotationsSuccessProps(annotations); } } function onLoadError() { if (!annotationsError) { // Impossible, but TypeScript doesn't know that return; } warning(false, annotationsError.toString()); if (onGetAnnotationsErrorProps) { onGetAnnotationsErrorProps(annotationsError); } } // biome-ignore lint/correctness/useExhaustiveDependencies: useEffect intentionally triggered on page change useEffect(function resetAnnotations() { annotationsDispatch({ type: 'RESET' }); }, [annotationsDispatch, page]); useEffect(function loadAnnotations() { if (!page) { return; } const cancellable = makeCancellable(page.getAnnotations()); const runningTask = cancellable; cancellable.promise .then((nextAnnotations) => { annotationsDispatch({ type: 'RESOLVE', value: nextAnnotations }); }) .catch((error) => { annotationsDispatch({ type: 'REJECT', error }); }); return () => { cancelRunningTask(runningTask); }; }, [annotationsDispatch, page]); // biome-ignore lint/correctness/useExhaustiveDependencies: Ommitted callbacks so they are not called every time they change useEffect(() => { if (annotations === undefined) { return; } if (annotations === false) { onLoadError(); return; } onLoadSuccess(); }, [annotations]); function onRenderSuccess() { if (onRenderAnnotationLayerSuccessProps) { onRenderAnnotationLayerSuccessProps(); } } function onRenderError(error) { warning(false, `${error}`); if (onRenderAnnotationLayerErrorProps) { onRenderAnnotationLayerErrorProps(error); } } const viewport = useMemo(() => page.getViewport({ scale, rotation: rotate }), [page, rotate, scale]); // biome-ignore lint/correctness/useExhaustiveDependencies: Ommitted callbacks so they are not called every time they change useEffect(function renderAnnotationLayer() { if (!pdf || !page || !linkService || !annotations) { return; } const { current: layer } = layerElement; if (!layer) { return; } const clonedViewport = viewport.clone({ dontFlip: true }); const annotationLayerParameters = { accessibilityManager: null, // TODO: Implement this annotationCanvasMap: null, // TODO: Implement this annotationEditorUIManager: null, // TODO: Implement this div: layer, l10n: null, // TODO: Implement this page, structTreeLayer: null, // TODO: Implement this viewport: clonedViewport, }; const renderParameters = { annotations, annotationStorage: pdf.annotationStorage, div: layer, imageResourcesPath, linkService, page, renderForms, viewport: clonedViewport, }; layer.innerHTML = ''; try { new pdfjs.AnnotationLayer(annotationLayerParameters).render(renderParameters); // Intentional immediate callback onRenderSuccess(); } catch (error) { onRenderError(error); } return () => { // TODO: Cancel running task? }; }, [annotations, imageResourcesPath, linkService, page, pdf, renderForms, viewport]); return (_jsx("div", { className: clsx('react-pdf__Page__annotations', 'annotationLayer'), ref: layerElement })); }