@arbidocs/react 0.3.177 → 0.3.179

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -86,7 +86,8 @@ var INITIAL_LAZY_LOAD_BUFFER = { before: 0, after: 1 };
86
86
  var DEFAULT_ASSETS = {
87
87
  workerSrc: "/pdf.worker.min.mjs",
88
88
  cMapUrl: "/cmaps/",
89
- standardFontDataUrl: "/standard_fonts/"
89
+ standardFontDataUrl: "/standard_fonts/",
90
+ wasmUrl: "/wasm/"
90
91
  };
91
92
  function ensurePdfWorker(workerSrc) {
92
93
  if (reactPdf.pdfjs.GlobalWorkerOptions.workerSrc !== workerSrc) {
@@ -108,6 +109,7 @@ function PdfViewer({
108
109
  const workerSrc = assets?.workerSrc ?? DEFAULT_ASSETS.workerSrc;
109
110
  const cMapUrl = assets?.cMapUrl ?? DEFAULT_ASSETS.cMapUrl;
110
111
  const standardFontDataUrl = assets?.standardFontDataUrl ?? DEFAULT_ASSETS.standardFontDataUrl;
112
+ const wasmUrl = assets?.wasmUrl ?? DEFAULT_ASSETS.wasmUrl;
111
113
  ensurePdfWorker(workerSrc);
112
114
  const [numPages, setNumPages] = react.useState(0);
113
115
  const [containerWidth, setContainerWidth] = react.useState(0);
@@ -254,9 +256,10 @@ function PdfViewer({
254
256
  standardFontDataUrl,
255
257
  cMapUrl,
256
258
  cMapPacked: true,
259
+ wasmUrl,
257
260
  ...disableFontFace && { disableFontFace: true }
258
261
  }),
259
- [standardFontDataUrl, cMapUrl, disableFontFace]
262
+ [standardFontDataUrl, cMapUrl, wasmUrl, disableFontFace]
260
263
  );
261
264
  const handlePageChange = react.useCallback(
262
265
  (pageNumber) => onPageChange?.(pageNumber),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/viewers/usePageIntersectionObserver.ts","../../src/viewers/pdf-viewer-constants.ts","../../src/viewers/PdfViewer.tsx","../../src/viewers/DocxViewer.tsx","../../src/viewers/XlsxViewer.tsx","../../src/viewers/DocumentViewer.tsx"],"names":["useEffect","pdfjs","useState","useRef","useCallback","useMemo","jsx","Document","jsxs","Fragment","Page","useLayoutEffect","useArbi","ImageViewer","AudioViewer","VideoViewer"],"mappings":"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","file":"index.cjs","sourcesContent":["import { useEffect, RefObject } from 'react'\n\n// Page synchronization constants\nconst PAGE_UPDATE_DEBOUNCE_MS = 10 // Delay before updating page number after scroll (10ms)\nconst MIN_VISIBILITY_THRESHOLD = 0.15 // Minimum visibility (15%) to consider page \"visible\"\nconst INTERSECTION_THRESHOLDS = [0, 0.25, 0.5, 0.75, 1.0] // IntersectionObserver thresholds\n\ninterface UsePageIntersectionObserverOptions {\n /** Container element that scrolls */\n containerRef: RefObject<HTMLElement | null>\n /** Ref tracking whether initial scroll has completed */\n scrollCompleteRef: RefObject<boolean>\n /** Whether the observer should be active */\n isEnabled: boolean\n /** Function to get page elements to observe */\n getPageElements: () => Element[]\n /** Function to extract page number from element */\n getPageNumber: (element: Element) => number\n /** Callback when page number changes */\n onPageChange: (pageNumber: number) => void\n /** Optional callback with visibility data for custom logic (e.g., lazy loading) */\n onVisibilityUpdate?: (visibilityMap: Map<number, number>) => void\n}\n\n/**\n * Custom hook to track visible pages using IntersectionObserver.\n * Used for bidirectional page synchronization in document viewers.\n */\nexport function usePageIntersectionObserver({\n containerRef,\n scrollCompleteRef,\n isEnabled,\n getPageElements,\n getPageNumber,\n onPageChange,\n onVisibilityUpdate,\n}: UsePageIntersectionObserverOptions) {\n useEffect(() => {\n if (!isEnabled || !containerRef.current) return\n\n const container = containerRef.current\n const visibilityMap = new Map<number, number>()\n let lastReportedPage: number | null = null\n let updateTimeout: ReturnType<typeof setTimeout> | null = null\n\n const updatePageNumber = () => {\n // Find page with highest visibility\n let mostVisiblePage = 1\n let maxVisibility = 0\n visibilityMap.forEach((ratio, pageNum) => {\n if (ratio > maxVisibility) {\n maxVisibility = ratio\n mostVisiblePage = pageNum\n }\n })\n\n // Only update page number if scroll is complete and page changed\n if (\n scrollCompleteRef.current &&\n mostVisiblePage !== lastReportedPage &&\n maxVisibility > MIN_VISIBILITY_THRESHOLD\n ) {\n lastReportedPage = mostVisiblePage\n onPageChange(mostVisiblePage)\n }\n\n // Call optional visibility update callback (e.g., for lazy loading)\n if (onVisibilityUpdate) {\n onVisibilityUpdate(new Map(visibilityMap))\n }\n }\n\n const observer = new IntersectionObserver(\n (entries) => {\n // Update visibility map\n entries.forEach((entry) => {\n const pageNum = getPageNumber(entry.target)\n if (pageNum > 0) {\n visibilityMap.set(pageNum, entry.intersectionRatio)\n }\n })\n\n // Debounce updates\n if (updateTimeout) {\n clearTimeout(updateTimeout)\n }\n updateTimeout = setTimeout(updatePageNumber, PAGE_UPDATE_DEBOUNCE_MS)\n },\n {\n root: container,\n threshold: INTERSECTION_THRESHOLDS,\n }\n )\n\n // Observe all page elements\n const elements = getPageElements()\n elements.forEach((element) => observer.observe(element))\n\n return () => {\n observer.disconnect()\n if (updateTimeout) {\n clearTimeout(updateTimeout)\n }\n }\n }, [\n containerRef,\n scrollCompleteRef,\n isEnabled,\n getPageElements,\n getPageNumber,\n onPageChange,\n onVisibilityUpdate,\n ])\n}\n","/** Pages to render before the visible area (canvas pre-load buffer) */\nexport const LAZY_LOAD_BUFFER_BEFORE = 2\n\n/** Pages to render after the visible area (canvas pre-load buffer) */\nexport const LAZY_LOAD_BUFFER_AFTER = 5\n\n/**\n * Smaller render window used on the very first paint so time-to-first-visible-page is\n * fast. Expanded to LAZY_LOAD_BUFFER_BEFORE / LAZY_LOAD_BUFFER_AFTER once the browser\n * is idle (via requestIdleCallback / setTimeout fallback).\n */\nexport const INITIAL_LAZY_LOAD_BUFFER = { before: 0, after: 1 }\n","/**\n * PdfViewer — paged PDF rendering with bidirectional page synchronisation.\n *\n * Uses IntersectionObserver to track the visible page and to drive two separate\n * lazy-load windows: a wide canvas buffer (so a page image is ready before the\n * user scrolls to it) and a narrow text-layer window (text spans are expensive\n * DOM, so they only exist for the active reading area).\n *\n * DECOUPLED FOR REUSE: page changes are reported through `onPageChange` rather\n * than written to an app store, and the pdf.js asset URLs are props rather than\n * hardcoded paths, because a consuming app decides where it serves the worker,\n * cmaps and standard fonts from.\n *\n * `react-pdf` and `pdfjs-dist` are OPTIONAL peer dependencies — install them\n * only if you render PDFs. The consuming app must also serve the pdf.js worker\n * (see `assets.workerSrc`).\n */\n\nimport { useState, useEffect, useRef, useCallback, useMemo } from 'react'\nimport { Document, Page, pdfjs } from 'react-pdf'\nimport 'react-pdf/dist/Page/AnnotationLayer.css'\nimport 'react-pdf/dist/Page/TextLayer.css'\nimport { usePageIntersectionObserver } from './usePageIntersectionObserver'\nimport {\n LAZY_LOAD_BUFFER_BEFORE,\n LAZY_LOAD_BUFFER_AFTER,\n INITIAL_LAZY_LOAD_BUFFER,\n} from './pdf-viewer-constants'\n\n/** Where the app serves the pdf.js runtime assets from. */\nexport interface PdfViewerAssets {\n /** pdf.js worker bundle. Default `/pdf.worker.min.mjs`. */\n workerSrc?: string\n /** Directory of pdf.js character maps. Default `/cmaps/`. */\n cMapUrl?: string\n /** Directory of pdf.js standard font data. Default `/standard_fonts/`. */\n standardFontDataUrl?: string\n}\n\nconst DEFAULT_ASSETS: Required<PdfViewerAssets> = {\n workerSrc: '/pdf.worker.min.mjs',\n cMapUrl: '/cmaps/',\n standardFontDataUrl: '/standard_fonts/',\n}\n\n/** Configure the pdf.js worker before any Document mounts; re-set only if it changed. */\nfunction ensurePdfWorker(workerSrc: string) {\n if (pdfjs.GlobalWorkerOptions.workerSrc !== workerSrc) {\n pdfjs.GlobalWorkerOptions.workerSrc = workerSrc\n }\n}\n\n// Page rendering constants\nconst CONTAINER_PADDING_PX = 32 // Total horizontal padding (p-4 = 16px on each side)\nconst PAGE_ASPECT_RATIO = 1.414 // Standard A4 page aspect ratio (√2)\n\n// Text layer is enabled for pages within 1 page of the visible set — enough for smooth\n// scrolling while keeping DOM node count low on large documents.\nconst TEXT_LAYER_BUFFER = 1\n\nexport interface PdfViewerProps {\n file: string | Blob\n currentPage?: number\n onLoadSuccess?: (numPages: number) => void\n /** Incremented to trigger scroll to currentPage */\n scrollTrigger?: number\n /**\n * Called as the user scrolls, with the page occupying most of the viewport.\n * This is the reusable form of the monolith's `setViewingDocumentPage`.\n */\n onPageChange?: (pageNumber: number) => void\n /**\n * Force pdf.js to rasterise fonts onto the canvas instead of using @font-face.\n * Required when rendering into a different document (e.g. a popped-out window),\n * where @font-face rules from the opener do not apply.\n */\n disableFontFace?: boolean\n /** Where the app serves the pdf.js worker, cmaps and standard fonts from. */\n assets?: PdfViewerAssets\n}\n\nexport function PdfViewer({\n file,\n currentPage,\n onLoadSuccess,\n scrollTrigger,\n onPageChange,\n disableFontFace = false,\n assets,\n}: PdfViewerProps) {\n const workerSrc = assets?.workerSrc ?? DEFAULT_ASSETS.workerSrc\n const cMapUrl = assets?.cMapUrl ?? DEFAULT_ASSETS.cMapUrl\n const standardFontDataUrl = assets?.standardFontDataUrl ?? DEFAULT_ASSETS.standardFontDataUrl\n\n // Ensure the pdf.js worker is configured before any Document mounts\n ensurePdfWorker(workerSrc)\n\n const [numPages, setNumPages] = useState<number>(0)\n const [containerWidth, setContainerWidth] = useState<number>(0)\n const [loadError, setLoadError] = useState<Error | null>(null)\n const [documentKey, setDocumentKey] = useState<string>(() => `pdf-${Date.now()}`)\n\n // Initialize with pages around the current page (or first 3 pages if no current page).\n // Start with a small initial buffer so the first paint is cheap; expand to the full\n // buffer lazily via requestIdleCallback after the first render settles.\n const initialPage = currentPage || 1\n const [renderedPages, setRenderedPages] = useState<Set<number>>(\n new Set([\n Math.max(1, initialPage - INITIAL_LAZY_LOAD_BUFFER.before),\n initialPage,\n initialPage + INITIAL_LAZY_LOAD_BUFFER.after,\n ])\n )\n\n // Pages currently in/near the viewport — used to gate the text layer.\n // Keeping this separate from renderedPages lets the canvas still render on buffer pages\n // while text DOM nodes are only created for the user's active reading area.\n const [visiblePages, setVisiblePages] = useState<Set<number>>(new Set([initialPage]))\n\n // Reset document key when file changes to force remount\n useEffect(() => {\n setDocumentKey(`pdf-${Date.now()}`)\n setNumPages(0)\n setLoadError(null)\n }, [file])\n\n const containerRef = useRef<HTMLDivElement>(null)\n const pageRefs = useRef<Map<number, HTMLDivElement>>(new Map())\n\n // Handle document load success\n const onDocumentLoadSuccess = useCallback(\n ({ numPages: n }: { numPages: number }) => {\n setNumPages(n)\n setLoadError(null) // Clear any previous errors\n\n // Expand lazy-load buffer once the main thread is idle after first paint.\n // Falls back to setTimeout(500ms) in environments where requestIdleCallback\n // is not available (e.g. Safari < 16).\n const expand = () => {\n setRenderedPages((prev) => {\n if (prev.size === 0) return prev\n const newSet = new Set(prev)\n // Always include at least the pages around page 1 at full buffer size\n const anchor = currentPage || 1\n for (\n let i = Math.max(1, anchor - LAZY_LOAD_BUFFER_BEFORE);\n i <= Math.min(n, anchor + LAZY_LOAD_BUFFER_AFTER);\n i++\n ) {\n newSet.add(i)\n }\n return newSet\n })\n }\n\n if (typeof requestIdleCallback !== 'undefined') {\n requestIdleCallback(expand, { timeout: 500 })\n } else {\n setTimeout(expand, 500)\n }\n\n try {\n onLoadSuccess?.(n)\n } catch (error) {\n console.error('Error in onLoadSuccess callback:', error)\n }\n },\n [onLoadSuccess, currentPage]\n )\n\n // Handle document load error\n const onDocumentLoadError = useCallback((error: Error) => {\n console.error('PDF loading error:', error)\n setLoadError(error)\n setNumPages(0)\n }, [])\n\n // react-pdf calls this when the PDF is encrypted (reason === 1) or the\n // supplied password was wrong (reason === 2). Default behaviour is a\n // window.prompt() that, when cancelled, never resolves the password\n // callback — pdf.js then leaves the document load Promise pending forever\n // and the viewer is stuck on \"Loading PDF...\".\n //\n // Always call updatePassword exactly once. On cancel we surface a\n // synthetic load error so onLoadError → setLoadError fires the standard\n // error UI instead of the indefinite spinner.\n const onPassword = useCallback((updatePassword: (password: string) => void, reason: number) => {\n const message =\n reason === 2\n ? 'Incorrect password. Enter the password to unlock this PDF:'\n : 'This PDF is password-protected. Enter the password to view it:'\n const password = window.prompt(message)\n if (password === null) {\n // Cancelled. Synthesise a load error so the error UI takes over.\n setLoadError(new Error('Password required to open this PDF'))\n setNumPages(0)\n return\n }\n updatePassword(password)\n }, [])\n\n // Measure container width for responsive sizing using ResizeObserver\n useEffect(() => {\n if (!containerRef.current) return\n\n const updateWidth = () => {\n if (containerRef.current) {\n setContainerWidth(containerRef.current.offsetWidth - CONTAINER_PADDING_PX)\n }\n }\n\n updateWidth()\n\n // Use ResizeObserver to detect container size changes (e.g., panel divider resize)\n const resizeObserver = new ResizeObserver(updateWidth)\n resizeObserver.observe(containerRef.current)\n\n return () => {\n resizeObserver.disconnect()\n }\n }, [])\n\n // Track whether initial scroll has completed to prevent feedback loop\n const scrollCompleteRef = useRef(false)\n\n // Scroll to page ONLY when PDF loads - not when page number updates from scrolling\n useEffect(() => {\n if (numPages === 0) return\n\n // If we already scrolled, don't scroll again\n if (scrollCompleteRef.current) return\n\n // Ensure the target page and surrounding pages are rendered\n if (currentPage) {\n setRenderedPages((prev) => {\n const newSet = new Set(prev)\n for (\n let i = Math.max(1, currentPage - LAZY_LOAD_BUFFER_BEFORE);\n i <= Math.min(numPages, currentPage + LAZY_LOAD_BUFFER_AFTER);\n i++\n ) {\n newSet.add(i)\n }\n return newSet\n })\n\n // Wait for DOM update, then scroll\n requestAnimationFrame(() => {\n const pageElement = pageRefs.current.get(currentPage)\n if (pageElement) {\n pageElement.scrollIntoView({ behavior: 'auto', block: 'start' })\n }\n // Wait for scroll to complete before allowing page number updates\n setTimeout(() => {\n scrollCompleteRef.current = true\n }, 100)\n })\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [numPages]) // Note: currentPage is intentionally NOT a dependency to prevent feedback loop\n\n // Scroll to page when scrollTrigger changes (user entered a page number)\n useEffect(() => {\n if (!scrollTrigger || numPages === 0 || !currentPage) return\n\n // Temporarily disable observer updates during manual scroll\n scrollCompleteRef.current = false\n\n // Ensure the target page and surrounding pages are rendered\n setRenderedPages((prev) => {\n const newSet = new Set(prev)\n for (\n let i = Math.max(1, currentPage - LAZY_LOAD_BUFFER_BEFORE);\n i <= Math.min(numPages, currentPage + LAZY_LOAD_BUFFER_AFTER);\n i++\n ) {\n newSet.add(i)\n }\n return newSet\n })\n\n // Double-rAF: first frame lets React commit the setRenderedPages update so\n // pages before the target are in the DOM at their correct heights; second\n // frame scrolls after layout has settled. Instant scroll avoids a race\n // where smooth-scroll animation is still running when the observer\n // re-enables and reports the wrong page.\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n const pageElement = pageRefs.current.get(currentPage)\n if (pageElement) {\n pageElement.scrollIntoView({ behavior: 'instant', block: 'start' })\n }\n scrollCompleteRef.current = true\n })\n })\n }, [scrollTrigger, currentPage, numPages])\n\n // Handle lazy loading based on visible pages\n const handleVisibilityUpdate = useCallback(\n (visibilityMap: Map<number, number>) => {\n const visiblePageNums = Array.from(visibilityMap.entries())\n .filter(([, ratio]) => ratio > 0)\n .map(([pageNum]) => pageNum)\n\n if (visiblePageNums.length > 0) {\n const minVisible = Math.min(...visiblePageNums)\n const maxVisible = Math.max(...visiblePageNums)\n\n // Update canvas render buffer (wider window for smooth pre-loading)\n const pagesToRender = new Set<number>()\n for (\n let i = Math.max(1, minVisible - LAZY_LOAD_BUFFER_BEFORE);\n i <= Math.min(numPages, maxVisible + LAZY_LOAD_BUFFER_AFTER);\n i++\n ) {\n pagesToRender.add(i)\n }\n setRenderedPages(pagesToRender)\n\n // Update text-layer set (narrow window — text layer is expensive DOM)\n const nearViewport = new Set<number>()\n for (\n let i = Math.max(1, minVisible - TEXT_LAYER_BUFFER);\n i <= Math.min(numPages, maxVisible + TEXT_LAYER_BUFFER);\n i++\n ) {\n nearViewport.add(i)\n }\n setVisiblePages(nearViewport)\n }\n },\n [numPages]\n )\n\n // Memoize options to prevent unnecessary Document reloads.\n // When the options object changes reference, react-pdf reloads the document,\n // which fails if the source Blob's ArrayBuffer was already transferred to the worker.\n const documentOptions = useMemo(\n () => ({\n standardFontDataUrl,\n cMapUrl,\n cMapPacked: true,\n ...(disableFontFace && { disableFontFace: true }),\n }),\n [standardFontDataUrl, cMapUrl, disableFontFace]\n )\n\n // Observer callback is optional for consumers that don't track the page.\n const handlePageChange = useCallback(\n (pageNumber: number) => onPageChange?.(pageNumber),\n [onPageChange]\n )\n\n // Use IntersectionObserver to track visible pages and update page number\n usePageIntersectionObserver({\n containerRef,\n scrollCompleteRef,\n isEnabled: numPages > 0,\n getPageElements: () => Array.from(pageRefs.current.values()),\n getPageNumber: (element) => parseInt(element.getAttribute('data-page-number') ?? '0'),\n onPageChange: handlePageChange,\n onVisibilityUpdate: handleVisibilityUpdate,\n })\n\n return (\n <div\n ref={containerRef}\n className=\"w-full h-full overflow-y-auto overflow-x-hidden bg-muted flex flex-col items-center p-4\"\n role=\"region\"\n aria-label=\"PDF document viewer\"\n data-testid=\"pdf-viewer\"\n >\n <Document\n key={documentKey}\n file={file}\n onLoadSuccess={onDocumentLoadSuccess}\n onLoadError={onDocumentLoadError}\n onPassword={onPassword}\n options={documentOptions}\n loading={\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"text-sm text-muted-foreground\">Loading PDF...</div>\n </div>\n }\n error={\n <div className=\"flex flex-col items-center justify-center h-full gap-4 p-8\">\n <div className=\"text-destructive text-center\">\n {loadError?.message ===\n \"Cannot read properties of null (reading 'sendWithPromise')\" ? (\n <>\n <p className=\"font-semibold mb-2\">PDF viewer initialization failed</p>\n <p className=\"text-sm text-muted-foreground\">Please refresh the page to retry</p>\n </>\n ) : (\n <>\n <p className=\"font-semibold mb-2\">Failed to load PDF</p>\n {loadError && (\n <p className=\"text-sm text-muted-foreground\">{loadError.message}</p>\n )}\n </>\n )}\n </div>\n </div>\n }\n >\n {containerWidth > 0 &&\n Array.from(new Array(numPages), (_, index) => {\n const pageNumber = index + 1\n const shouldRender = renderedPages.has(pageNumber)\n const pageHeight = containerWidth * PAGE_ASPECT_RATIO\n // Only enable the text layer for pages in/near the viewport.\n // Pages in the wider render buffer get a canvas (so the image is ready when\n // the user scrolls to them) but no text spans until they're nearby — this\n // avoids committing thousands of DOM nodes synchronously on large documents.\n const shouldRenderTextLayer = visiblePages.has(pageNumber)\n\n return (\n <div\n key={`page_${pageNumber}`}\n ref={(el) => {\n if (el) {\n pageRefs.current.set(pageNumber, el)\n } else {\n pageRefs.current.delete(pageNumber)\n }\n }}\n data-page-number={pageNumber}\n className=\"mb-6 shadow-xl bg-white border border-border\"\n style={!shouldRender ? { minHeight: pageHeight } : undefined}\n role=\"article\"\n aria-label={`Page ${pageNumber} of ${numPages}`}\n >\n {shouldRender ? (\n <Page\n pageNumber={pageNumber}\n width={containerWidth}\n renderTextLayer={shouldRenderTextLayer}\n renderAnnotationLayer={false}\n // Cap DPR at 2× — retina/hi-DPR displays otherwise render at 3× or\n // higher, multiplying raster work by up to 9× vs 1×. At 2× the\n // quality difference is imperceptible at normal zoom levels.\n devicePixelRatio={Math.min(window.devicePixelRatio || 1, 2)}\n loading={\n <div\n className=\"flex items-center justify-center bg-muted\"\n style={{ width: containerWidth, height: pageHeight }}\n >\n <div className=\"text-sm text-muted-foreground\">\n Loading page {pageNumber}...\n </div>\n </div>\n }\n />\n ) : (\n <div\n className=\"flex items-center justify-center bg-muted\"\n style={{ width: containerWidth, height: pageHeight }}\n >\n <div className=\"text-sm text-muted-foreground\">Page {pageNumber}</div>\n </div>\n )}\n </div>\n )\n })}\n </Document>\n </div>\n )\n}\n","/**\n * DocxViewer\n *\n * Renders DOCX files natively using docx-preview, preserving track changes\n * (shown as strikethrough deletions + inserted text) and inline comments.\n *\n * Pages render at their natural width and are scaled down to fit the\n * container, so the document resizes with the panel instead of clipping.\n *\n * `docx-preview` is an OPTIONAL peer dependency, imported dynamically — a\n * consumer that never renders a .docx does not need it installed. If it is\n * missing the viewer shows a load error rather than crashing the app.\n */\n\nimport { useEffect, useLayoutEffect, useRef, useState } from 'react'\n\nexport interface DocxViewerProps {\n blob: Blob\n}\n\n/** Natural width of the rendered document: widest page plus wrapper padding. */\nfunction measureContentWidth(container: HTMLElement): number {\n let pageWidth = 0\n container.querySelectorAll<HTMLElement>('section.docx').forEach((section) => {\n pageWidth = Math.max(pageWidth, section.offsetWidth)\n })\n if (pageWidth === 0) return 0\n\n const wrapper = container.querySelector<HTMLElement>('.docx-wrapper')\n if (wrapper) {\n const style = window.getComputedStyle(wrapper)\n pageWidth += (parseFloat(style.paddingLeft) || 0) + (parseFloat(style.paddingRight) || 0)\n }\n return pageWidth\n}\n\nexport function DocxViewer({ blob }: DocxViewerProps) {\n const outerRef = useRef<HTMLDivElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const [error, setError] = useState<string | null>(null)\n const [isLoading, setIsLoading] = useState(true)\n const [containerWidth, setContainerWidth] = useState(0)\n const [contentWidth, setContentWidth] = useState(0)\n\n // Track container width so the document rescales when the panel is resized\n useEffect(() => {\n const outer = outerRef.current\n if (!outer) return\n\n const updateWidth = () => setContainerWidth(outer.clientWidth)\n updateWidth()\n\n const resizeObserver = new ResizeObserver(updateWidth)\n resizeObserver.observe(outer)\n return () => resizeObserver.disconnect()\n }, [])\n\n useEffect(() => {\n const container = containerRef.current\n if (!container) return\n\n let cancelled = false\n\n setIsLoading(true)\n setError(null)\n setContentWidth(0)\n container.innerHTML = ''\n\n import('docx-preview')\n .then(({ renderAsync }) => {\n if (cancelled) return\n return renderAsync(blob, container, undefined, {\n ignoreLastRenderedPageBreak: false,\n })\n })\n .then(() => {\n if (!cancelled) setIsLoading(false)\n })\n .catch((err) => {\n if (!cancelled) {\n console.error('DocxViewer render error:', err)\n setError('Failed to render document')\n setIsLoading(false)\n }\n })\n\n return () => {\n cancelled = true\n }\n }, [blob])\n\n // Measure after the body is unhidden — offsetWidth is 0 while `hidden` (display: none)\n useLayoutEffect(() => {\n const container = containerRef.current\n if (isLoading || error || !container) return\n setContentWidth(measureContentWidth(container))\n }, [isLoading, error])\n\n const scale =\n containerWidth > 0 && contentWidth > 0 ? Math.min(1, containerWidth / contentWidth) : 1\n\n return (\n <div ref={outerRef} className=\"w-full h-full overflow-auto bg-muted\" data-testid=\"docx-viewer\">\n {isLoading && (\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"text-sm text-muted-foreground\">Loading document...</div>\n </div>\n )}\n {error && (\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"text-destructive\">{error}</div>\n </div>\n )}\n <div\n ref={containerRef}\n data-testid=\"docx-viewer-body\"\n className={`docx-viewer-body${isLoading || error ? ' hidden' : ''}`}\n style={{ zoom: scale }}\n />\n </div>\n )\n}\n","/**\n * XlsxViewer\n *\n * Renders spreadsheets natively using SheetJS, showing every sheet with a tab\n * bar. Preserves cell data and multiple sheets.\n *\n * `xlsx` is an OPTIONAL peer dependency, imported dynamically — a consumer that\n * never renders a spreadsheet does not need it installed. If it is missing the\n * viewer shows a load error rather than crashing the app.\n */\n\nimport { useEffect, useRef, useState } from 'react'\nimport type { WorkSheet } from 'xlsx'\n\nexport interface XlsxViewerProps {\n blob: Blob\n}\n\ntype WorkbookRef = {\n SheetNames: string[]\n Sheets: Record<string, WorkSheet>\n}\n\nexport function XlsxViewer({ blob }: XlsxViewerProps) {\n const [sheets, setSheets] = useState<string[]>([])\n const [activeSheet, setActiveSheet] = useState<string>('')\n const [rows, setRows] = useState<unknown[][]>([])\n const [error, setError] = useState<string | null>(null)\n const [isLoading, setIsLoading] = useState(true)\n const workbookRef = useRef<WorkbookRef | null>(null)\n\n const renderSheet = async (sheetName: string, wb: WorkbookRef) => {\n const XLSX = await import('xlsx')\n const sheet = wb.Sheets[sheetName]\n const data = XLSX.utils.sheet_to_json<unknown[]>(sheet, { header: 1, defval: '' })\n setRows(data)\n setActiveSheet(sheetName)\n }\n\n useEffect(() => {\n let cancelled = false\n\n blob\n .arrayBuffer()\n .then(async (buffer) => {\n if (cancelled) return\n const XLSX = await import('xlsx')\n const wb = XLSX.read(buffer, { type: 'array' }) as WorkbookRef\n workbookRef.current = wb\n const sheetNames = wb.SheetNames\n setSheets(sheetNames)\n const data = XLSX.utils.sheet_to_json<unknown[]>(wb.Sheets[sheetNames[0]], {\n header: 1,\n defval: '',\n })\n if (!cancelled) {\n setRows(data)\n setActiveSheet(sheetNames[0])\n setIsLoading(false)\n }\n })\n .catch((err) => {\n if (!cancelled) {\n console.error('XlsxViewer error:', err)\n setError('Failed to render spreadsheet')\n setIsLoading(false)\n }\n })\n\n return () => {\n cancelled = true\n }\n }, [blob])\n\n const handleSheetChange = (sheetName: string) => {\n if (workbookRef.current) {\n renderSheet(sheetName, workbookRef.current)\n }\n }\n\n if (isLoading) {\n return (\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"text-sm text-muted-foreground\">Loading spreadsheet...</div>\n </div>\n )\n }\n\n if (error) {\n return (\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"text-destructive\">{error}</div>\n </div>\n )\n }\n\n // Find max columns across all rows for consistent table width\n const colCount = rows.reduce((max, row) => Math.max(max, (row as unknown[]).length), 0)\n\n return (\n <div\n className=\"w-full h-full flex flex-col overflow-hidden bg-background\"\n data-testid=\"xlsx-viewer\"\n >\n {/* Sheet tabs */}\n {sheets.length > 0 && (\n <div className=\"flex-shrink-0 flex items-center gap-0.5 px-2 pt-1 border-b bg-muted overflow-x-auto\">\n {sheets.map((sheet) => (\n <button\n key={sheet}\n onClick={() => handleSheetChange(sheet)}\n className={`px-3 py-1 text-sm font-medium whitespace-nowrap rounded-t transition-colors border-x border-t ${\n sheet === activeSheet\n ? 'bg-background text-primary border-border'\n : 'bg-muted text-muted-foreground border-transparent hover:bg-muted hover:text-foreground'\n }`}\n >\n {sheet}\n </button>\n ))}\n </div>\n )}\n\n {/* Spreadsheet table */}\n <div className=\"flex-1 overflow-auto\">\n <table className=\"text-sm border-collapse min-w-full\">\n <tbody>\n {rows.map((row, rowIdx) => (\n <tr\n key={rowIdx}\n className={rowIdx === 0 ? 'bg-muted font-semibold sticky top-0' : 'hover:bg-accent'}\n >\n {/* Row number gutter */}\n <td className=\"border border-border px-1 text-center text-muted-foreground bg-muted select-none w-8 min-w-[2rem]\">\n {rowIdx + 1}\n </td>\n {Array.from({ length: colCount }).map((_, colIdx) => (\n <td\n key={colIdx}\n className=\"border border-border px-2 py-0.5 whitespace-nowrap max-w-[200px] overflow-hidden text-ellipsis\"\n title={String((row as unknown[])[colIdx] ?? '')}\n >\n {String((row as unknown[])[colIdx] ?? '')}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n {rows.length === 0 && (\n <div className=\"flex items-center justify-center p-8 text-sm text-muted-foreground\">\n Empty sheet\n </div>\n )}\n </div>\n </div>\n )\n}\n","/**\n * DocumentViewer — render an ARBI document as it actually looks.\n *\n * The individual viewers in this module each take a `Blob`. Getting from a\n * document to the right viewer means: work out the file type, download the\n * original, pick a renderer, and handle loading, failure and \"there is no\n * native view for this type\". Every consumer would otherwise write that same\n * dispatch, so it lives here.\n *\n * Pairs with `DocumentReview` from the root entry, which renders the extracted\n * text with AI citation highlighting. A review UI wants both: the native page is\n * what a person must see before making a call on a document; the text view is\n * where citations and search hits live.\n */\n\nimport { useEffect, useMemo, useState, type ReactNode } from 'react'\nimport type { components } from '@arbidocs/client'\n\nimport { useArbi } from '../useArbi'\nimport { PdfViewer, type PdfViewerAssets } from './PdfViewer'\nimport { DocxViewer } from './DocxViewer'\nimport { XlsxViewer } from './XlsxViewer'\nimport { ImageViewer } from './ImageViewer'\nimport { AudioViewer } from './AudioViewer'\nimport { VideoViewer } from './VideoViewer'\n\ntype DocResponse = components['schemas']['DocResponse']\n\n/** Which native renderer a file needs; `none` when there is no native view. */\nexport type NativeViewerKind = 'pdf' | 'docx' | 'xlsx' | 'image' | 'audio' | 'video' | 'none'\n\nconst BY_EXTENSION: Record<string, NativeViewerKind> = {\n pdf: 'pdf',\n doc: 'docx',\n docx: 'docx',\n xls: 'xlsx',\n xlsx: 'xlsx',\n csv: 'xlsx',\n png: 'image',\n jpg: 'image',\n jpeg: 'image',\n gif: 'image',\n webp: 'image',\n bmp: 'image',\n tif: 'image',\n tiff: 'image',\n mp3: 'audio',\n wav: 'audio',\n m4a: 'audio',\n ogg: 'audio',\n mp4: 'video',\n mov: 'video',\n webm: 'video',\n avi: 'video',\n}\n\n/**\n * Which viewer a document needs. Extension first (it is what the user sees and\n * what ARBI preserves), falling back to the sniffed `file_type` — ARBI\n * identifies by digital signature, so a mislabelled file still renders.\n */\nexport function nativeViewerKind(doc: Pick<DocResponse, 'file_name' | 'file_type'> | undefined) {\n const name = (doc?.file_name ?? '').toLowerCase()\n const ext = name.includes('.') ? name.slice(name.lastIndexOf('.') + 1) : ''\n if (BY_EXTENSION[ext]) return BY_EXTENSION[ext]\n\n const type = (doc?.file_type ?? '').toLowerCase()\n if (!type) return 'none'\n if (type.includes('pdf')) return 'pdf'\n if (type.includes('word') || type.includes('officedocument.wordprocessing')) return 'docx'\n if (type.includes('sheet') || type.includes('excel') || type.includes('csv')) return 'xlsx'\n if (type.startsWith('image/')) return 'image'\n if (type.startsWith('audio/')) return 'audio'\n if (type.startsWith('video/')) return 'video'\n return 'none'\n}\n\nexport interface DocumentViewerProps {\n /** The document to render. */\n doc: Pick<DocResponse, 'external_id' | 'file_name' | 'file_type'> | undefined\n /** Where the app serves the pdf.js worker, cmaps and standard fonts from. */\n pdfAssets?: PdfViewerAssets\n /** Reported as the user scrolls a paged document. */\n onPageChange?: (page: number) => void\n /**\n * Page to show. Paired with `scrollTrigger` this drives a page-number control:\n * a viewer without one is an endless scroll with no way to say \"go to 14\".\n */\n currentPage?: number\n /** Increment to scroll to `currentPage` — lets the same value be re-applied. */\n scrollTrigger?: number\n /** Page count, once the document has loaded. Needed to render \"of N\". */\n onLoadSuccess?: (numPages: number) => void\n /** Rendered when the file type has no native viewer. */\n fallback?: ReactNode\n /** Rendered while the original is downloading. */\n loading?: ReactNode\n /** Rendered when the download or decode fails. Receives the message. */\n errorRender?: (message: string) => ReactNode\n className?: string\n}\n\nexport function DocumentViewer({\n doc,\n pdfAssets,\n onPageChange,\n currentPage,\n scrollTrigger,\n onLoadSuccess,\n fallback,\n loading,\n errorRender,\n className,\n}: DocumentViewerProps) {\n const arbi = useArbi()\n const [blob, setBlob] = useState<Blob | null>(null)\n const [error, setError] = useState<string | null>(null)\n\n const kind = useMemo(() => nativeViewerKind(doc), [doc])\n const docId = doc?.external_id\n\n useEffect(() => {\n if (!docId || kind === 'none') {\n setBlob(null)\n return\n }\n let cancelled = false\n setBlob(null)\n setError(null)\n\n arbi.documents\n .download(docId)\n .then((res: Response) => res.blob())\n .then((b) => {\n if (!cancelled) setBlob(b)\n })\n .catch((err: unknown) => {\n if (!cancelled) setError(err instanceof Error ? err.message : 'Could not load the file')\n })\n\n return () => {\n cancelled = true\n }\n }, [arbi, docId, kind])\n\n if (!doc) return null\n\n if (kind === 'none') {\n return (\n <>\n {fallback ?? (\n <div className=\"grid h-full place-items-center p-6 text-center text-sm text-muted-foreground\">\n No native view for this file type. The original is preserved and can be downloaded.\n </div>\n )}\n </>\n )\n }\n\n if (error) {\n return (\n <>\n {errorRender?.(error) ?? (\n <div className=\"grid h-full place-items-center p-6 text-center\">\n <div>\n <p className=\"text-sm font-medium text-destructive\">Could not load the original</p>\n <p className=\"mt-1 text-sm text-muted-foreground\">{error}</p>\n </div>\n </div>\n )}\n </>\n )\n }\n\n if (!blob) {\n return (\n <>\n {loading ?? (\n <div className=\"grid h-full place-items-center text-sm text-muted-foreground\">\n Loading the original…\n </div>\n )}\n </>\n )\n }\n\n const title = doc.file_name ?? doc.external_id\n const body = (() => {\n switch (kind) {\n case 'pdf':\n return (\n <PdfViewer\n file={blob}\n assets={pdfAssets}\n onPageChange={onPageChange}\n currentPage={currentPage}\n scrollTrigger={scrollTrigger}\n onLoadSuccess={onLoadSuccess}\n />\n )\n case 'docx':\n return <DocxViewer blob={blob} />\n case 'xlsx':\n return <XlsxViewer blob={blob} />\n case 'image':\n return <ImageViewer blob={blob} alt={title} />\n case 'audio':\n return <AudioViewer blob={blob} title={title} />\n case 'video':\n return <VideoViewer blob={blob} title={title} />\n default:\n return null\n }\n })()\n\n return className ? (\n <div className={className} data-testid=\"document-viewer\">\n {body}\n </div>\n ) : (\n body\n )\n}\n"]}
1
+ {"version":3,"sources":["../../src/viewers/usePageIntersectionObserver.ts","../../src/viewers/pdf-viewer-constants.ts","../../src/viewers/PdfViewer.tsx","../../src/viewers/DocxViewer.tsx","../../src/viewers/XlsxViewer.tsx","../../src/viewers/DocumentViewer.tsx"],"names":["useEffect","pdfjs","useState","useRef","useCallback","useMemo","jsx","Document","jsxs","Fragment","Page","useLayoutEffect","useArbi","ImageViewer","AudioViewer","VideoViewer"],"mappings":"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","file":"index.cjs","sourcesContent":["import { useEffect, RefObject } from 'react'\n\n// Page synchronization constants\nconst PAGE_UPDATE_DEBOUNCE_MS = 10 // Delay before updating page number after scroll (10ms)\nconst MIN_VISIBILITY_THRESHOLD = 0.15 // Minimum visibility (15%) to consider page \"visible\"\nconst INTERSECTION_THRESHOLDS = [0, 0.25, 0.5, 0.75, 1.0] // IntersectionObserver thresholds\n\ninterface UsePageIntersectionObserverOptions {\n /** Container element that scrolls */\n containerRef: RefObject<HTMLElement | null>\n /** Ref tracking whether initial scroll has completed */\n scrollCompleteRef: RefObject<boolean>\n /** Whether the observer should be active */\n isEnabled: boolean\n /** Function to get page elements to observe */\n getPageElements: () => Element[]\n /** Function to extract page number from element */\n getPageNumber: (element: Element) => number\n /** Callback when page number changes */\n onPageChange: (pageNumber: number) => void\n /** Optional callback with visibility data for custom logic (e.g., lazy loading) */\n onVisibilityUpdate?: (visibilityMap: Map<number, number>) => void\n}\n\n/**\n * Custom hook to track visible pages using IntersectionObserver.\n * Used for bidirectional page synchronization in document viewers.\n */\nexport function usePageIntersectionObserver({\n containerRef,\n scrollCompleteRef,\n isEnabled,\n getPageElements,\n getPageNumber,\n onPageChange,\n onVisibilityUpdate,\n}: UsePageIntersectionObserverOptions) {\n useEffect(() => {\n if (!isEnabled || !containerRef.current) return\n\n const container = containerRef.current\n const visibilityMap = new Map<number, number>()\n let lastReportedPage: number | null = null\n let updateTimeout: ReturnType<typeof setTimeout> | null = null\n\n const updatePageNumber = () => {\n // Find page with highest visibility\n let mostVisiblePage = 1\n let maxVisibility = 0\n visibilityMap.forEach((ratio, pageNum) => {\n if (ratio > maxVisibility) {\n maxVisibility = ratio\n mostVisiblePage = pageNum\n }\n })\n\n // Only update page number if scroll is complete and page changed\n if (\n scrollCompleteRef.current &&\n mostVisiblePage !== lastReportedPage &&\n maxVisibility > MIN_VISIBILITY_THRESHOLD\n ) {\n lastReportedPage = mostVisiblePage\n onPageChange(mostVisiblePage)\n }\n\n // Call optional visibility update callback (e.g., for lazy loading)\n if (onVisibilityUpdate) {\n onVisibilityUpdate(new Map(visibilityMap))\n }\n }\n\n const observer = new IntersectionObserver(\n (entries) => {\n // Update visibility map\n entries.forEach((entry) => {\n const pageNum = getPageNumber(entry.target)\n if (pageNum > 0) {\n visibilityMap.set(pageNum, entry.intersectionRatio)\n }\n })\n\n // Debounce updates\n if (updateTimeout) {\n clearTimeout(updateTimeout)\n }\n updateTimeout = setTimeout(updatePageNumber, PAGE_UPDATE_DEBOUNCE_MS)\n },\n {\n root: container,\n threshold: INTERSECTION_THRESHOLDS,\n }\n )\n\n // Observe all page elements\n const elements = getPageElements()\n elements.forEach((element) => observer.observe(element))\n\n return () => {\n observer.disconnect()\n if (updateTimeout) {\n clearTimeout(updateTimeout)\n }\n }\n }, [\n containerRef,\n scrollCompleteRef,\n isEnabled,\n getPageElements,\n getPageNumber,\n onPageChange,\n onVisibilityUpdate,\n ])\n}\n","/** Pages to render before the visible area (canvas pre-load buffer) */\nexport const LAZY_LOAD_BUFFER_BEFORE = 2\n\n/** Pages to render after the visible area (canvas pre-load buffer) */\nexport const LAZY_LOAD_BUFFER_AFTER = 5\n\n/**\n * Smaller render window used on the very first paint so time-to-first-visible-page is\n * fast. Expanded to LAZY_LOAD_BUFFER_BEFORE / LAZY_LOAD_BUFFER_AFTER once the browser\n * is idle (via requestIdleCallback / setTimeout fallback).\n */\nexport const INITIAL_LAZY_LOAD_BUFFER = { before: 0, after: 1 }\n","/**\n * PdfViewer — paged PDF rendering with bidirectional page synchronisation.\n *\n * Uses IntersectionObserver to track the visible page and to drive two separate\n * lazy-load windows: a wide canvas buffer (so a page image is ready before the\n * user scrolls to it) and a narrow text-layer window (text spans are expensive\n * DOM, so they only exist for the active reading area).\n *\n * DECOUPLED FOR REUSE: page changes are reported through `onPageChange` rather\n * than written to an app store, and the pdf.js asset URLs are props rather than\n * hardcoded paths, because a consuming app decides where it serves the worker,\n * cmaps and standard fonts from.\n *\n * `react-pdf` and `pdfjs-dist` are OPTIONAL peer dependencies — install them\n * only if you render PDFs. The consuming app must also serve the pdf.js worker\n * (see `assets.workerSrc`).\n */\n\nimport { useState, useEffect, useRef, useCallback, useMemo } from 'react'\nimport { Document, Page, pdfjs } from 'react-pdf'\nimport 'react-pdf/dist/Page/AnnotationLayer.css'\nimport 'react-pdf/dist/Page/TextLayer.css'\nimport { usePageIntersectionObserver } from './usePageIntersectionObserver'\nimport {\n LAZY_LOAD_BUFFER_BEFORE,\n LAZY_LOAD_BUFFER_AFTER,\n INITIAL_LAZY_LOAD_BUFFER,\n} from './pdf-viewer-constants'\n\n/** Where the app serves the pdf.js runtime assets from. */\nexport interface PdfViewerAssets {\n /** pdf.js worker bundle. Default `/pdf.worker.min.mjs`. */\n workerSrc?: string\n /** Directory of pdf.js character maps. Default `/cmaps/`. */\n cMapUrl?: string\n /** Directory of pdf.js standard font data. Default `/standard_fonts/`. */\n standardFontDataUrl?: string\n /**\n * Directory of the pdf.js wasm decoders (openjpeg for JPEG 2000, jbig2,\n * qcms). Scanned PDFs routinely embed JPX/JBIG2-compressed page images;\n * without these modules pdf.js fails image decoding with only a console\n * warning and renders blank white pages. Default `/wasm/`.\n */\n wasmUrl?: string\n}\n\nconst DEFAULT_ASSETS: Required<PdfViewerAssets> = {\n workerSrc: '/pdf.worker.min.mjs',\n cMapUrl: '/cmaps/',\n standardFontDataUrl: '/standard_fonts/',\n wasmUrl: '/wasm/',\n}\n\n/** Configure the pdf.js worker before any Document mounts; re-set only if it changed. */\nfunction ensurePdfWorker(workerSrc: string) {\n if (pdfjs.GlobalWorkerOptions.workerSrc !== workerSrc) {\n pdfjs.GlobalWorkerOptions.workerSrc = workerSrc\n }\n}\n\n// Page rendering constants\nconst CONTAINER_PADDING_PX = 32 // Total horizontal padding (p-4 = 16px on each side)\nconst PAGE_ASPECT_RATIO = 1.414 // Standard A4 page aspect ratio (√2)\n\n// Text layer is enabled for pages within 1 page of the visible set — enough for smooth\n// scrolling while keeping DOM node count low on large documents.\nconst TEXT_LAYER_BUFFER = 1\n\nexport interface PdfViewerProps {\n file: string | Blob\n currentPage?: number\n onLoadSuccess?: (numPages: number) => void\n /** Incremented to trigger scroll to currentPage */\n scrollTrigger?: number\n /**\n * Called as the user scrolls, with the page occupying most of the viewport.\n * This is the reusable form of the monolith's `setViewingDocumentPage`.\n */\n onPageChange?: (pageNumber: number) => void\n /**\n * Force pdf.js to rasterise fonts onto the canvas instead of using @font-face.\n * Required when rendering into a different document (e.g. a popped-out window),\n * where @font-face rules from the opener do not apply.\n */\n disableFontFace?: boolean\n /** Where the app serves the pdf.js worker, cmaps and standard fonts from. */\n assets?: PdfViewerAssets\n}\n\nexport function PdfViewer({\n file,\n currentPage,\n onLoadSuccess,\n scrollTrigger,\n onPageChange,\n disableFontFace = false,\n assets,\n}: PdfViewerProps) {\n const workerSrc = assets?.workerSrc ?? DEFAULT_ASSETS.workerSrc\n const cMapUrl = assets?.cMapUrl ?? DEFAULT_ASSETS.cMapUrl\n const standardFontDataUrl = assets?.standardFontDataUrl ?? DEFAULT_ASSETS.standardFontDataUrl\n const wasmUrl = assets?.wasmUrl ?? DEFAULT_ASSETS.wasmUrl\n\n // Ensure the pdf.js worker is configured before any Document mounts\n ensurePdfWorker(workerSrc)\n\n const [numPages, setNumPages] = useState<number>(0)\n const [containerWidth, setContainerWidth] = useState<number>(0)\n const [loadError, setLoadError] = useState<Error | null>(null)\n const [documentKey, setDocumentKey] = useState<string>(() => `pdf-${Date.now()}`)\n\n // Initialize with pages around the current page (or first 3 pages if no current page).\n // Start with a small initial buffer so the first paint is cheap; expand to the full\n // buffer lazily via requestIdleCallback after the first render settles.\n const initialPage = currentPage || 1\n const [renderedPages, setRenderedPages] = useState<Set<number>>(\n new Set([\n Math.max(1, initialPage - INITIAL_LAZY_LOAD_BUFFER.before),\n initialPage,\n initialPage + INITIAL_LAZY_LOAD_BUFFER.after,\n ])\n )\n\n // Pages currently in/near the viewport — used to gate the text layer.\n // Keeping this separate from renderedPages lets the canvas still render on buffer pages\n // while text DOM nodes are only created for the user's active reading area.\n const [visiblePages, setVisiblePages] = useState<Set<number>>(new Set([initialPage]))\n\n // Reset document key when file changes to force remount\n useEffect(() => {\n setDocumentKey(`pdf-${Date.now()}`)\n setNumPages(0)\n setLoadError(null)\n }, [file])\n\n const containerRef = useRef<HTMLDivElement>(null)\n const pageRefs = useRef<Map<number, HTMLDivElement>>(new Map())\n\n // Handle document load success\n const onDocumentLoadSuccess = useCallback(\n ({ numPages: n }: { numPages: number }) => {\n setNumPages(n)\n setLoadError(null) // Clear any previous errors\n\n // Expand lazy-load buffer once the main thread is idle after first paint.\n // Falls back to setTimeout(500ms) in environments where requestIdleCallback\n // is not available (e.g. Safari < 16).\n const expand = () => {\n setRenderedPages((prev) => {\n if (prev.size === 0) return prev\n const newSet = new Set(prev)\n // Always include at least the pages around page 1 at full buffer size\n const anchor = currentPage || 1\n for (\n let i = Math.max(1, anchor - LAZY_LOAD_BUFFER_BEFORE);\n i <= Math.min(n, anchor + LAZY_LOAD_BUFFER_AFTER);\n i++\n ) {\n newSet.add(i)\n }\n return newSet\n })\n }\n\n if (typeof requestIdleCallback !== 'undefined') {\n requestIdleCallback(expand, { timeout: 500 })\n } else {\n setTimeout(expand, 500)\n }\n\n try {\n onLoadSuccess?.(n)\n } catch (error) {\n console.error('Error in onLoadSuccess callback:', error)\n }\n },\n [onLoadSuccess, currentPage]\n )\n\n // Handle document load error\n const onDocumentLoadError = useCallback((error: Error) => {\n console.error('PDF loading error:', error)\n setLoadError(error)\n setNumPages(0)\n }, [])\n\n // react-pdf calls this when the PDF is encrypted (reason === 1) or the\n // supplied password was wrong (reason === 2). Default behaviour is a\n // window.prompt() that, when cancelled, never resolves the password\n // callback — pdf.js then leaves the document load Promise pending forever\n // and the viewer is stuck on \"Loading PDF...\".\n //\n // Always call updatePassword exactly once. On cancel we surface a\n // synthetic load error so onLoadError → setLoadError fires the standard\n // error UI instead of the indefinite spinner.\n const onPassword = useCallback((updatePassword: (password: string) => void, reason: number) => {\n const message =\n reason === 2\n ? 'Incorrect password. Enter the password to unlock this PDF:'\n : 'This PDF is password-protected. Enter the password to view it:'\n const password = window.prompt(message)\n if (password === null) {\n // Cancelled. Synthesise a load error so the error UI takes over.\n setLoadError(new Error('Password required to open this PDF'))\n setNumPages(0)\n return\n }\n updatePassword(password)\n }, [])\n\n // Measure container width for responsive sizing using ResizeObserver\n useEffect(() => {\n if (!containerRef.current) return\n\n const updateWidth = () => {\n if (containerRef.current) {\n setContainerWidth(containerRef.current.offsetWidth - CONTAINER_PADDING_PX)\n }\n }\n\n updateWidth()\n\n // Use ResizeObserver to detect container size changes (e.g., panel divider resize)\n const resizeObserver = new ResizeObserver(updateWidth)\n resizeObserver.observe(containerRef.current)\n\n return () => {\n resizeObserver.disconnect()\n }\n }, [])\n\n // Track whether initial scroll has completed to prevent feedback loop\n const scrollCompleteRef = useRef(false)\n\n // Scroll to page ONLY when PDF loads - not when page number updates from scrolling\n useEffect(() => {\n if (numPages === 0) return\n\n // If we already scrolled, don't scroll again\n if (scrollCompleteRef.current) return\n\n // Ensure the target page and surrounding pages are rendered\n if (currentPage) {\n setRenderedPages((prev) => {\n const newSet = new Set(prev)\n for (\n let i = Math.max(1, currentPage - LAZY_LOAD_BUFFER_BEFORE);\n i <= Math.min(numPages, currentPage + LAZY_LOAD_BUFFER_AFTER);\n i++\n ) {\n newSet.add(i)\n }\n return newSet\n })\n\n // Wait for DOM update, then scroll\n requestAnimationFrame(() => {\n const pageElement = pageRefs.current.get(currentPage)\n if (pageElement) {\n pageElement.scrollIntoView({ behavior: 'auto', block: 'start' })\n }\n // Wait for scroll to complete before allowing page number updates\n setTimeout(() => {\n scrollCompleteRef.current = true\n }, 100)\n })\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [numPages]) // Note: currentPage is intentionally NOT a dependency to prevent feedback loop\n\n // Scroll to page when scrollTrigger changes (user entered a page number)\n useEffect(() => {\n if (!scrollTrigger || numPages === 0 || !currentPage) return\n\n // Temporarily disable observer updates during manual scroll\n scrollCompleteRef.current = false\n\n // Ensure the target page and surrounding pages are rendered\n setRenderedPages((prev) => {\n const newSet = new Set(prev)\n for (\n let i = Math.max(1, currentPage - LAZY_LOAD_BUFFER_BEFORE);\n i <= Math.min(numPages, currentPage + LAZY_LOAD_BUFFER_AFTER);\n i++\n ) {\n newSet.add(i)\n }\n return newSet\n })\n\n // Double-rAF: first frame lets React commit the setRenderedPages update so\n // pages before the target are in the DOM at their correct heights; second\n // frame scrolls after layout has settled. Instant scroll avoids a race\n // where smooth-scroll animation is still running when the observer\n // re-enables and reports the wrong page.\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n const pageElement = pageRefs.current.get(currentPage)\n if (pageElement) {\n pageElement.scrollIntoView({ behavior: 'instant', block: 'start' })\n }\n scrollCompleteRef.current = true\n })\n })\n }, [scrollTrigger, currentPage, numPages])\n\n // Handle lazy loading based on visible pages\n const handleVisibilityUpdate = useCallback(\n (visibilityMap: Map<number, number>) => {\n const visiblePageNums = Array.from(visibilityMap.entries())\n .filter(([, ratio]) => ratio > 0)\n .map(([pageNum]) => pageNum)\n\n if (visiblePageNums.length > 0) {\n const minVisible = Math.min(...visiblePageNums)\n const maxVisible = Math.max(...visiblePageNums)\n\n // Update canvas render buffer (wider window for smooth pre-loading)\n const pagesToRender = new Set<number>()\n for (\n let i = Math.max(1, minVisible - LAZY_LOAD_BUFFER_BEFORE);\n i <= Math.min(numPages, maxVisible + LAZY_LOAD_BUFFER_AFTER);\n i++\n ) {\n pagesToRender.add(i)\n }\n setRenderedPages(pagesToRender)\n\n // Update text-layer set (narrow window — text layer is expensive DOM)\n const nearViewport = new Set<number>()\n for (\n let i = Math.max(1, minVisible - TEXT_LAYER_BUFFER);\n i <= Math.min(numPages, maxVisible + TEXT_LAYER_BUFFER);\n i++\n ) {\n nearViewport.add(i)\n }\n setVisiblePages(nearViewport)\n }\n },\n [numPages]\n )\n\n // Memoize options to prevent unnecessary Document reloads.\n // When the options object changes reference, react-pdf reloads the document,\n // which fails if the source Blob's ArrayBuffer was already transferred to the worker.\n const documentOptions = useMemo(\n () => ({\n standardFontDataUrl,\n cMapUrl,\n cMapPacked: true,\n wasmUrl,\n ...(disableFontFace && { disableFontFace: true }),\n }),\n [standardFontDataUrl, cMapUrl, wasmUrl, disableFontFace]\n )\n\n // Observer callback is optional for consumers that don't track the page.\n const handlePageChange = useCallback(\n (pageNumber: number) => onPageChange?.(pageNumber),\n [onPageChange]\n )\n\n // Use IntersectionObserver to track visible pages and update page number\n usePageIntersectionObserver({\n containerRef,\n scrollCompleteRef,\n isEnabled: numPages > 0,\n getPageElements: () => Array.from(pageRefs.current.values()),\n getPageNumber: (element) => parseInt(element.getAttribute('data-page-number') ?? '0'),\n onPageChange: handlePageChange,\n onVisibilityUpdate: handleVisibilityUpdate,\n })\n\n return (\n <div\n ref={containerRef}\n className=\"w-full h-full overflow-y-auto overflow-x-hidden bg-muted flex flex-col items-center p-4\"\n role=\"region\"\n aria-label=\"PDF document viewer\"\n data-testid=\"pdf-viewer\"\n >\n <Document\n key={documentKey}\n file={file}\n onLoadSuccess={onDocumentLoadSuccess}\n onLoadError={onDocumentLoadError}\n onPassword={onPassword}\n options={documentOptions}\n loading={\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"text-sm text-muted-foreground\">Loading PDF...</div>\n </div>\n }\n error={\n <div className=\"flex flex-col items-center justify-center h-full gap-4 p-8\">\n <div className=\"text-destructive text-center\">\n {loadError?.message ===\n \"Cannot read properties of null (reading 'sendWithPromise')\" ? (\n <>\n <p className=\"font-semibold mb-2\">PDF viewer initialization failed</p>\n <p className=\"text-sm text-muted-foreground\">Please refresh the page to retry</p>\n </>\n ) : (\n <>\n <p className=\"font-semibold mb-2\">Failed to load PDF</p>\n {loadError && (\n <p className=\"text-sm text-muted-foreground\">{loadError.message}</p>\n )}\n </>\n )}\n </div>\n </div>\n }\n >\n {containerWidth > 0 &&\n Array.from(new Array(numPages), (_, index) => {\n const pageNumber = index + 1\n const shouldRender = renderedPages.has(pageNumber)\n const pageHeight = containerWidth * PAGE_ASPECT_RATIO\n // Only enable the text layer for pages in/near the viewport.\n // Pages in the wider render buffer get a canvas (so the image is ready when\n // the user scrolls to them) but no text spans until they're nearby — this\n // avoids committing thousands of DOM nodes synchronously on large documents.\n const shouldRenderTextLayer = visiblePages.has(pageNumber)\n\n return (\n <div\n key={`page_${pageNumber}`}\n ref={(el) => {\n if (el) {\n pageRefs.current.set(pageNumber, el)\n } else {\n pageRefs.current.delete(pageNumber)\n }\n }}\n data-page-number={pageNumber}\n className=\"mb-6 shadow-xl bg-white border border-border\"\n style={!shouldRender ? { minHeight: pageHeight } : undefined}\n role=\"article\"\n aria-label={`Page ${pageNumber} of ${numPages}`}\n >\n {shouldRender ? (\n <Page\n pageNumber={pageNumber}\n width={containerWidth}\n renderTextLayer={shouldRenderTextLayer}\n renderAnnotationLayer={false}\n // Cap DPR at 2× — retina/hi-DPR displays otherwise render at 3× or\n // higher, multiplying raster work by up to 9× vs 1×. At 2× the\n // quality difference is imperceptible at normal zoom levels.\n devicePixelRatio={Math.min(window.devicePixelRatio || 1, 2)}\n loading={\n <div\n className=\"flex items-center justify-center bg-muted\"\n style={{ width: containerWidth, height: pageHeight }}\n >\n <div className=\"text-sm text-muted-foreground\">\n Loading page {pageNumber}...\n </div>\n </div>\n }\n />\n ) : (\n <div\n className=\"flex items-center justify-center bg-muted\"\n style={{ width: containerWidth, height: pageHeight }}\n >\n <div className=\"text-sm text-muted-foreground\">Page {pageNumber}</div>\n </div>\n )}\n </div>\n )\n })}\n </Document>\n </div>\n )\n}\n","/**\n * DocxViewer\n *\n * Renders DOCX files natively using docx-preview, preserving track changes\n * (shown as strikethrough deletions + inserted text) and inline comments.\n *\n * Pages render at their natural width and are scaled down to fit the\n * container, so the document resizes with the panel instead of clipping.\n *\n * `docx-preview` is an OPTIONAL peer dependency, imported dynamically — a\n * consumer that never renders a .docx does not need it installed. If it is\n * missing the viewer shows a load error rather than crashing the app.\n */\n\nimport { useEffect, useLayoutEffect, useRef, useState } from 'react'\n\nexport interface DocxViewerProps {\n blob: Blob\n}\n\n/** Natural width of the rendered document: widest page plus wrapper padding. */\nfunction measureContentWidth(container: HTMLElement): number {\n let pageWidth = 0\n container.querySelectorAll<HTMLElement>('section.docx').forEach((section) => {\n pageWidth = Math.max(pageWidth, section.offsetWidth)\n })\n if (pageWidth === 0) return 0\n\n const wrapper = container.querySelector<HTMLElement>('.docx-wrapper')\n if (wrapper) {\n const style = window.getComputedStyle(wrapper)\n pageWidth += (parseFloat(style.paddingLeft) || 0) + (parseFloat(style.paddingRight) || 0)\n }\n return pageWidth\n}\n\nexport function DocxViewer({ blob }: DocxViewerProps) {\n const outerRef = useRef<HTMLDivElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const [error, setError] = useState<string | null>(null)\n const [isLoading, setIsLoading] = useState(true)\n const [containerWidth, setContainerWidth] = useState(0)\n const [contentWidth, setContentWidth] = useState(0)\n\n // Track container width so the document rescales when the panel is resized\n useEffect(() => {\n const outer = outerRef.current\n if (!outer) return\n\n const updateWidth = () => setContainerWidth(outer.clientWidth)\n updateWidth()\n\n const resizeObserver = new ResizeObserver(updateWidth)\n resizeObserver.observe(outer)\n return () => resizeObserver.disconnect()\n }, [])\n\n useEffect(() => {\n const container = containerRef.current\n if (!container) return\n\n let cancelled = false\n\n setIsLoading(true)\n setError(null)\n setContentWidth(0)\n container.innerHTML = ''\n\n import('docx-preview')\n .then(({ renderAsync }) => {\n if (cancelled) return\n return renderAsync(blob, container, undefined, {\n ignoreLastRenderedPageBreak: false,\n })\n })\n .then(() => {\n if (!cancelled) setIsLoading(false)\n })\n .catch((err) => {\n if (!cancelled) {\n console.error('DocxViewer render error:', err)\n setError('Failed to render document')\n setIsLoading(false)\n }\n })\n\n return () => {\n cancelled = true\n }\n }, [blob])\n\n // Measure after the body is unhidden — offsetWidth is 0 while `hidden` (display: none)\n useLayoutEffect(() => {\n const container = containerRef.current\n if (isLoading || error || !container) return\n setContentWidth(measureContentWidth(container))\n }, [isLoading, error])\n\n const scale =\n containerWidth > 0 && contentWidth > 0 ? Math.min(1, containerWidth / contentWidth) : 1\n\n return (\n <div ref={outerRef} className=\"w-full h-full overflow-auto bg-muted\" data-testid=\"docx-viewer\">\n {isLoading && (\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"text-sm text-muted-foreground\">Loading document...</div>\n </div>\n )}\n {error && (\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"text-destructive\">{error}</div>\n </div>\n )}\n <div\n ref={containerRef}\n data-testid=\"docx-viewer-body\"\n className={`docx-viewer-body${isLoading || error ? ' hidden' : ''}`}\n style={{ zoom: scale }}\n />\n </div>\n )\n}\n","/**\n * XlsxViewer\n *\n * Renders spreadsheets natively using SheetJS, showing every sheet with a tab\n * bar. Preserves cell data and multiple sheets.\n *\n * `xlsx` is an OPTIONAL peer dependency, imported dynamically — a consumer that\n * never renders a spreadsheet does not need it installed. If it is missing the\n * viewer shows a load error rather than crashing the app.\n */\n\nimport { useEffect, useRef, useState } from 'react'\nimport type { WorkSheet } from 'xlsx'\n\nexport interface XlsxViewerProps {\n blob: Blob\n}\n\ntype WorkbookRef = {\n SheetNames: string[]\n Sheets: Record<string, WorkSheet>\n}\n\nexport function XlsxViewer({ blob }: XlsxViewerProps) {\n const [sheets, setSheets] = useState<string[]>([])\n const [activeSheet, setActiveSheet] = useState<string>('')\n const [rows, setRows] = useState<unknown[][]>([])\n const [error, setError] = useState<string | null>(null)\n const [isLoading, setIsLoading] = useState(true)\n const workbookRef = useRef<WorkbookRef | null>(null)\n\n const renderSheet = async (sheetName: string, wb: WorkbookRef) => {\n const XLSX = await import('xlsx')\n const sheet = wb.Sheets[sheetName]\n const data = XLSX.utils.sheet_to_json<unknown[]>(sheet, { header: 1, defval: '' })\n setRows(data)\n setActiveSheet(sheetName)\n }\n\n useEffect(() => {\n let cancelled = false\n\n blob\n .arrayBuffer()\n .then(async (buffer) => {\n if (cancelled) return\n const XLSX = await import('xlsx')\n const wb = XLSX.read(buffer, { type: 'array' }) as WorkbookRef\n workbookRef.current = wb\n const sheetNames = wb.SheetNames\n setSheets(sheetNames)\n const data = XLSX.utils.sheet_to_json<unknown[]>(wb.Sheets[sheetNames[0]], {\n header: 1,\n defval: '',\n })\n if (!cancelled) {\n setRows(data)\n setActiveSheet(sheetNames[0])\n setIsLoading(false)\n }\n })\n .catch((err) => {\n if (!cancelled) {\n console.error('XlsxViewer error:', err)\n setError('Failed to render spreadsheet')\n setIsLoading(false)\n }\n })\n\n return () => {\n cancelled = true\n }\n }, [blob])\n\n const handleSheetChange = (sheetName: string) => {\n if (workbookRef.current) {\n renderSheet(sheetName, workbookRef.current)\n }\n }\n\n if (isLoading) {\n return (\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"text-sm text-muted-foreground\">Loading spreadsheet...</div>\n </div>\n )\n }\n\n if (error) {\n return (\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"text-destructive\">{error}</div>\n </div>\n )\n }\n\n // Find max columns across all rows for consistent table width\n const colCount = rows.reduce((max, row) => Math.max(max, (row as unknown[]).length), 0)\n\n return (\n <div\n className=\"w-full h-full flex flex-col overflow-hidden bg-background\"\n data-testid=\"xlsx-viewer\"\n >\n {/* Sheet tabs */}\n {sheets.length > 0 && (\n <div className=\"flex-shrink-0 flex items-center gap-0.5 px-2 pt-1 border-b bg-muted overflow-x-auto\">\n {sheets.map((sheet) => (\n <button\n key={sheet}\n onClick={() => handleSheetChange(sheet)}\n className={`px-3 py-1 text-sm font-medium whitespace-nowrap rounded-t transition-colors border-x border-t ${\n sheet === activeSheet\n ? 'bg-background text-primary border-border'\n : 'bg-muted text-muted-foreground border-transparent hover:bg-muted hover:text-foreground'\n }`}\n >\n {sheet}\n </button>\n ))}\n </div>\n )}\n\n {/* Spreadsheet table */}\n <div className=\"flex-1 overflow-auto\">\n <table className=\"text-sm border-collapse min-w-full\">\n <tbody>\n {rows.map((row, rowIdx) => (\n <tr\n key={rowIdx}\n className={rowIdx === 0 ? 'bg-muted font-semibold sticky top-0' : 'hover:bg-accent'}\n >\n {/* Row number gutter */}\n <td className=\"border border-border px-1 text-center text-muted-foreground bg-muted select-none w-8 min-w-[2rem]\">\n {rowIdx + 1}\n </td>\n {Array.from({ length: colCount }).map((_, colIdx) => (\n <td\n key={colIdx}\n className=\"border border-border px-2 py-0.5 whitespace-nowrap max-w-[200px] overflow-hidden text-ellipsis\"\n title={String((row as unknown[])[colIdx] ?? '')}\n >\n {String((row as unknown[])[colIdx] ?? '')}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n {rows.length === 0 && (\n <div className=\"flex items-center justify-center p-8 text-sm text-muted-foreground\">\n Empty sheet\n </div>\n )}\n </div>\n </div>\n )\n}\n","/**\n * DocumentViewer — render an ARBI document as it actually looks.\n *\n * The individual viewers in this module each take a `Blob`. Getting from a\n * document to the right viewer means: work out the file type, download the\n * original, pick a renderer, and handle loading, failure and \"there is no\n * native view for this type\". Every consumer would otherwise write that same\n * dispatch, so it lives here.\n *\n * Pairs with `DocumentReview` from the root entry, which renders the extracted\n * text with AI citation highlighting. A review UI wants both: the native page is\n * what a person must see before making a call on a document; the text view is\n * where citations and search hits live.\n */\n\nimport { useEffect, useMemo, useState, type ReactNode } from 'react'\nimport type { components } from '@arbidocs/client'\n\nimport { useArbi } from '../useArbi'\nimport { PdfViewer, type PdfViewerAssets } from './PdfViewer'\nimport { DocxViewer } from './DocxViewer'\nimport { XlsxViewer } from './XlsxViewer'\nimport { ImageViewer } from './ImageViewer'\nimport { AudioViewer } from './AudioViewer'\nimport { VideoViewer } from './VideoViewer'\n\ntype DocResponse = components['schemas']['DocResponse']\n\n/** Which native renderer a file needs; `none` when there is no native view. */\nexport type NativeViewerKind = 'pdf' | 'docx' | 'xlsx' | 'image' | 'audio' | 'video' | 'none'\n\nconst BY_EXTENSION: Record<string, NativeViewerKind> = {\n pdf: 'pdf',\n doc: 'docx',\n docx: 'docx',\n xls: 'xlsx',\n xlsx: 'xlsx',\n csv: 'xlsx',\n png: 'image',\n jpg: 'image',\n jpeg: 'image',\n gif: 'image',\n webp: 'image',\n bmp: 'image',\n tif: 'image',\n tiff: 'image',\n mp3: 'audio',\n wav: 'audio',\n m4a: 'audio',\n ogg: 'audio',\n mp4: 'video',\n mov: 'video',\n webm: 'video',\n avi: 'video',\n}\n\n/**\n * Which viewer a document needs. Extension first (it is what the user sees and\n * what ARBI preserves), falling back to the sniffed `file_type` — ARBI\n * identifies by digital signature, so a mislabelled file still renders.\n */\nexport function nativeViewerKind(doc: Pick<DocResponse, 'file_name' | 'file_type'> | undefined) {\n const name = (doc?.file_name ?? '').toLowerCase()\n const ext = name.includes('.') ? name.slice(name.lastIndexOf('.') + 1) : ''\n if (BY_EXTENSION[ext]) return BY_EXTENSION[ext]\n\n const type = (doc?.file_type ?? '').toLowerCase()\n if (!type) return 'none'\n if (type.includes('pdf')) return 'pdf'\n if (type.includes('word') || type.includes('officedocument.wordprocessing')) return 'docx'\n if (type.includes('sheet') || type.includes('excel') || type.includes('csv')) return 'xlsx'\n if (type.startsWith('image/')) return 'image'\n if (type.startsWith('audio/')) return 'audio'\n if (type.startsWith('video/')) return 'video'\n return 'none'\n}\n\nexport interface DocumentViewerProps {\n /** The document to render. */\n doc: Pick<DocResponse, 'external_id' | 'file_name' | 'file_type'> | undefined\n /** Where the app serves the pdf.js worker, cmaps and standard fonts from. */\n pdfAssets?: PdfViewerAssets\n /** Reported as the user scrolls a paged document. */\n onPageChange?: (page: number) => void\n /**\n * Page to show. Paired with `scrollTrigger` this drives a page-number control:\n * a viewer without one is an endless scroll with no way to say \"go to 14\".\n */\n currentPage?: number\n /** Increment to scroll to `currentPage` — lets the same value be re-applied. */\n scrollTrigger?: number\n /** Page count, once the document has loaded. Needed to render \"of N\". */\n onLoadSuccess?: (numPages: number) => void\n /** Rendered when the file type has no native viewer. */\n fallback?: ReactNode\n /** Rendered while the original is downloading. */\n loading?: ReactNode\n /** Rendered when the download or decode fails. Receives the message. */\n errorRender?: (message: string) => ReactNode\n className?: string\n}\n\nexport function DocumentViewer({\n doc,\n pdfAssets,\n onPageChange,\n currentPage,\n scrollTrigger,\n onLoadSuccess,\n fallback,\n loading,\n errorRender,\n className,\n}: DocumentViewerProps) {\n const arbi = useArbi()\n const [blob, setBlob] = useState<Blob | null>(null)\n const [error, setError] = useState<string | null>(null)\n\n const kind = useMemo(() => nativeViewerKind(doc), [doc])\n const docId = doc?.external_id\n\n useEffect(() => {\n if (!docId || kind === 'none') {\n setBlob(null)\n return\n }\n let cancelled = false\n setBlob(null)\n setError(null)\n\n arbi.documents\n .download(docId)\n .then((res: Response) => res.blob())\n .then((b) => {\n if (!cancelled) setBlob(b)\n })\n .catch((err: unknown) => {\n if (!cancelled) setError(err instanceof Error ? err.message : 'Could not load the file')\n })\n\n return () => {\n cancelled = true\n }\n }, [arbi, docId, kind])\n\n if (!doc) return null\n\n if (kind === 'none') {\n return (\n <>\n {fallback ?? (\n <div className=\"grid h-full place-items-center p-6 text-center text-sm text-muted-foreground\">\n No native view for this file type. The original is preserved and can be downloaded.\n </div>\n )}\n </>\n )\n }\n\n if (error) {\n return (\n <>\n {errorRender?.(error) ?? (\n <div className=\"grid h-full place-items-center p-6 text-center\">\n <div>\n <p className=\"text-sm font-medium text-destructive\">Could not load the original</p>\n <p className=\"mt-1 text-sm text-muted-foreground\">{error}</p>\n </div>\n </div>\n )}\n </>\n )\n }\n\n if (!blob) {\n return (\n <>\n {loading ?? (\n <div className=\"grid h-full place-items-center text-sm text-muted-foreground\">\n Loading the original…\n </div>\n )}\n </>\n )\n }\n\n const title = doc.file_name ?? doc.external_id\n const body = (() => {\n switch (kind) {\n case 'pdf':\n return (\n <PdfViewer\n file={blob}\n assets={pdfAssets}\n onPageChange={onPageChange}\n currentPage={currentPage}\n scrollTrigger={scrollTrigger}\n onLoadSuccess={onLoadSuccess}\n />\n )\n case 'docx':\n return <DocxViewer blob={blob} />\n case 'xlsx':\n return <XlsxViewer blob={blob} />\n case 'image':\n return <ImageViewer blob={blob} alt={title} />\n case 'audio':\n return <AudioViewer blob={blob} title={title} />\n case 'video':\n return <VideoViewer blob={blob} title={title} />\n default:\n return null\n }\n })()\n\n return className ? (\n <div className={className} data-testid=\"document-viewer\">\n {body}\n </div>\n ) : (\n body\n )\n}\n"]}
@@ -10,6 +10,13 @@ interface PdfViewerAssets {
10
10
  cMapUrl?: string;
11
11
  /** Directory of pdf.js standard font data. Default `/standard_fonts/`. */
12
12
  standardFontDataUrl?: string;
13
+ /**
14
+ * Directory of the pdf.js wasm decoders (openjpeg for JPEG 2000, jbig2,
15
+ * qcms). Scanned PDFs routinely embed JPX/JBIG2-compressed page images;
16
+ * without these modules pdf.js fails image decoding with only a console
17
+ * warning and renders blank white pages. Default `/wasm/`.
18
+ */
19
+ wasmUrl?: string;
13
20
  }
14
21
  interface PdfViewerProps {
15
22
  file: string | Blob;
@@ -10,6 +10,13 @@ interface PdfViewerAssets {
10
10
  cMapUrl?: string;
11
11
  /** Directory of pdf.js standard font data. Default `/standard_fonts/`. */
12
12
  standardFontDataUrl?: string;
13
+ /**
14
+ * Directory of the pdf.js wasm decoders (openjpeg for JPEG 2000, jbig2,
15
+ * qcms). Scanned PDFs routinely embed JPX/JBIG2-compressed page images;
16
+ * without these modules pdf.js fails image decoding with only a console
17
+ * warning and renders blank white pages. Default `/wasm/`.
18
+ */
19
+ wasmUrl?: string;
13
20
  }
14
21
  interface PdfViewerProps {
15
22
  file: string | Blob;
@@ -85,7 +85,8 @@ var INITIAL_LAZY_LOAD_BUFFER = { before: 0, after: 1 };
85
85
  var DEFAULT_ASSETS = {
86
86
  workerSrc: "/pdf.worker.min.mjs",
87
87
  cMapUrl: "/cmaps/",
88
- standardFontDataUrl: "/standard_fonts/"
88
+ standardFontDataUrl: "/standard_fonts/",
89
+ wasmUrl: "/wasm/"
89
90
  };
90
91
  function ensurePdfWorker(workerSrc) {
91
92
  if (pdfjs.GlobalWorkerOptions.workerSrc !== workerSrc) {
@@ -107,6 +108,7 @@ function PdfViewer({
107
108
  const workerSrc = assets?.workerSrc ?? DEFAULT_ASSETS.workerSrc;
108
109
  const cMapUrl = assets?.cMapUrl ?? DEFAULT_ASSETS.cMapUrl;
109
110
  const standardFontDataUrl = assets?.standardFontDataUrl ?? DEFAULT_ASSETS.standardFontDataUrl;
111
+ const wasmUrl = assets?.wasmUrl ?? DEFAULT_ASSETS.wasmUrl;
110
112
  ensurePdfWorker(workerSrc);
111
113
  const [numPages, setNumPages] = useState(0);
112
114
  const [containerWidth, setContainerWidth] = useState(0);
@@ -253,9 +255,10 @@ function PdfViewer({
253
255
  standardFontDataUrl,
254
256
  cMapUrl,
255
257
  cMapPacked: true,
258
+ wasmUrl,
256
259
  ...disableFontFace && { disableFontFace: true }
257
260
  }),
258
- [standardFontDataUrl, cMapUrl, disableFontFace]
261
+ [standardFontDataUrl, cMapUrl, wasmUrl, disableFontFace]
259
262
  );
260
263
  const handlePageChange = useCallback(
261
264
  (pageNumber) => onPageChange?.(pageNumber),