@matangot/react-pdf-viewer 0.1.0
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.
- package/LICENSE +21 -0
- package/README.md +152 -0
- package/dist/index.d.ts +234 -0
- package/dist/index.js +2148 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.css +1022 -0
- package/package.json +49 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Root.tsx","../src/context.tsx","../src/hooks/use-pdf-document.ts","../src/constants.ts","../src/hooks/use-keyboard-shortcuts.ts","../src/components/Toolbar.tsx","../src/components/Navigation.tsx","../src/icons.tsx","../src/components/DropdownMenu.tsx","../src/components/Zoom.tsx","../src/components/Search.tsx","../src/components/Separator.tsx","../src/components/Rotate.tsx","../src/components/Download.tsx","../src/components/Print.tsx","../src/components/FullScreen.tsx","../src/components/ThumbnailToggle.tsx","../src/components/CursorModeToggle.tsx","../src/components/ThumbnailSidebar.tsx","../src/components/Pages.tsx","../src/components/Page.tsx","../src/components/MoreMenu.tsx","../src/components/DocumentPropertiesModal.tsx","../src/components/PdfViewer.tsx","../src/hooks/use-pdf-viewer.ts"],"sourcesContent":["import { useRef } from 'react';\nimport { PdfViewerProvider, usePdfViewerContext } from '../context';\nimport { useKeyboardShortcuts } from '../hooks/use-keyboard-shortcuts';\nimport type { PdfViewerRootProps, Theme } from '../types';\n\ninterface RootInnerProps {\n className?: string;\n theme: Theme;\n children: React.ReactNode;\n}\n\nfunction RootInner({ className, theme, children }: RootInnerProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const ctx = usePdfViewerContext();\n\n useKeyboardShortcuts(containerRef, ctx);\n\n const classNames = [\n 'pdf-viewer',\n ctx.isLoading && 'pdf-viewer--loading',\n ctx.error && 'pdf-viewer--error',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div\n ref={containerRef}\n className={classNames}\n data-theme={theme}\n tabIndex={-1}\n >\n {ctx.error ? (\n <div className=\"pdf-viewer__error\">\n <p>{ctx.error.message}</p>\n </div>\n ) : (\n children\n )}\n </div>\n );\n}\n\nexport function Root({\n src,\n defaultPage,\n defaultZoom,\n defaultCursorMode,\n defaultSidebarOpen,\n theme = 'system',\n onPageChange,\n onDocumentLoad,\n className,\n children,\n}: PdfViewerRootProps) {\n return (\n <PdfViewerProvider\n src={src}\n defaultPage={defaultPage}\n defaultZoom={defaultZoom}\n defaultCursorMode={defaultCursorMode}\n defaultSidebarOpen={defaultSidebarOpen}\n onPageChange={onPageChange}\n onDocumentLoad={onDocumentLoad}\n >\n <RootInner className={className} theme={theme}>\n {children}\n </RootInner>\n </PdfViewerProvider>\n );\n}\n","import {\n createContext,\n useContext,\n useState,\n useCallback,\n useMemo,\n useRef,\n type ReactNode,\n} from 'react';\nimport { usePdfDocument } from './hooks/use-pdf-document';\nimport { DEFAULT_ZOOM, MIN_ZOOM, MAX_ZOOM, ZOOM_STEP } from './constants';\nimport type {\n PdfSource,\n PdfViewerContextValue,\n ZoomMode,\n ZoomValue,\n CursorMode,\n ViewMode,\n ScrollMode,\n LayoutMode,\n SearchMatch,\n DocumentInfo,\n DocumentProperties,\n} from './types';\n\nconst PdfViewerContext = createContext<PdfViewerContextValue | null>(null);\n\nexport function usePdfViewerContext(): PdfViewerContextValue {\n const ctx = useContext(PdfViewerContext);\n if (!ctx) {\n throw new Error(\n 'usePdfViewerContext must be used within a PdfViewerProvider'\n );\n }\n return ctx;\n}\n\nexport interface PdfViewerProviderProps {\n src: PdfSource;\n defaultPage?: number;\n defaultZoom?: ZoomValue;\n defaultCursorMode?: CursorMode;\n defaultSidebarOpen?: boolean;\n onPageChange?: (page: number) => void;\n onDocumentLoad?: (info: DocumentInfo) => void;\n children: ReactNode;\n}\n\nexport function PdfViewerProvider({\n src,\n defaultPage = 1,\n defaultZoom = DEFAULT_ZOOM,\n defaultCursorMode = 'select',\n defaultSidebarOpen = false,\n onPageChange,\n onDocumentLoad,\n children,\n}: PdfViewerProviderProps) {\n const { document, isLoading, error } = usePdfDocument(src, onDocumentLoad);\n\n const totalPages = document?.numPages ?? 0;\n\n const containerRef = useRef<HTMLElement | null>(null);\n const scrollToPageRef = useRef<((page: number) => void) | null>(null);\n\n const [currentPage, setCurrentPage] = useState(defaultPage);\n const isMobile = typeof window !== 'undefined' && window.innerWidth <= 640;\n const [zoomLevel, setZoomLevel] = useState(\n typeof defaultZoom === 'number' ? defaultZoom : DEFAULT_ZOOM\n );\n const [zoomMode, setZoomMode] = useState<ZoomMode | null>(\n typeof defaultZoom === 'string' ? defaultZoom : (isMobile ? 'fit-width' : null)\n );\n const [rotation, setRotation] = useState(0);\n const [isThumbnailsOpen, setIsThumbnailsOpen] = useState(defaultSidebarOpen);\n const [searchQuery, setSearchQuery] = useState('');\n const [searchMatches, setSearchMatches] = useState<SearchMatch[]>([]);\n const [currentMatchIndex, setCurrentMatchIndex] = useState(-1);\n const [cursorMode, setCursorModeState] = useState<CursorMode>(defaultCursorMode);\n const [viewMode, setViewModeState] = useState<ViewMode>('single');\n const [scrollMode, setScrollModeState] = useState<ScrollMode>('vertical');\n const [isDocPropertiesOpen, setIsDocPropertiesOpen] = useState(false);\n const [docProperties, setDocProperties] = useState<DocumentProperties | null>(null);\n const [isPrinting, setIsPrinting] = useState(false);\n\n const currentPageRef = useRef(defaultPage);\n\n // Internal: just update the page state (used by scroll tracking)\n const _setCurrentPage = useCallback(\n (page: number) => {\n const clamped = Math.max(1, Math.min(page, totalPages));\n if (currentPageRef.current === clamped) return;\n currentPageRef.current = clamped;\n setCurrentPage(clamped);\n onPageChange?.(clamped);\n },\n [totalPages, onPageChange]\n );\n\n // Public: navigate to page AND scroll to it\n const goToPage = useCallback(\n (page: number) => {\n const clamped = Math.max(1, Math.min(page, totalPages));\n currentPageRef.current = clamped;\n setCurrentPage(clamped);\n onPageChange?.(clamped);\n // Scroll to the page (the ref is set by Pages component)\n scrollToPageRef.current?.(clamped);\n },\n [totalPages, onPageChange]\n );\n\n // Stable references — don't depend on currentPage\n const nextPage = useCallback(() => {\n goToPage(currentPageRef.current + 1);\n }, [goToPage]);\n\n const prevPage = useCallback(() => {\n goToPage(currentPageRef.current - 1);\n }, [goToPage]);\n\n const zoomIn = useCallback(() => {\n setZoomLevel((prev) => Math.min(prev + ZOOM_STEP, MAX_ZOOM));\n setZoomMode(null);\n }, []);\n\n const zoomOut = useCallback(() => {\n setZoomLevel((prev) => Math.max(prev - ZOOM_STEP, MIN_ZOOM));\n setZoomMode(null);\n }, []);\n\n const zoomTo = useCallback((value: ZoomValue) => {\n if (typeof value === 'number') {\n setZoomLevel(Math.max(MIN_ZOOM, Math.min(value, MAX_ZOOM)));\n setZoomMode(null);\n } else {\n setZoomMode(value);\n }\n }, []);\n\n // Internal: set zoom level without clearing zoomMode (used by fit-zoom computation)\n const _setZoomLevel = useCallback((level: number) => {\n setZoomLevel(Math.max(MIN_ZOOM, Math.min(level, MAX_ZOOM)));\n }, []);\n\n const rotate = useCallback((degrees: number = 90) => {\n setRotation((prev) => (prev + degrees) % 360);\n }, []);\n\n const toggleThumbnails = useCallback(() => {\n setIsThumbnailsOpen((prev) => !prev);\n }, []);\n\n const search = useCallback(async (query: string) => {\n setSearchQuery(query);\n if (!query || !document) {\n setSearchMatches([]);\n setCurrentMatchIndex(-1);\n return;\n }\n\n const matches: SearchMatch[] = [];\n const lowerQuery = query.toLowerCase();\n\n for (let i = 1; i <= document.numPages; i++) {\n const page = await document.getPage(i);\n const textContent = await page.getTextContent();\n const pageText = textContent.items\n .map((item: any) => item.str)\n .join(' ')\n .toLowerCase();\n\n let startIndex = 0;\n let matchIdx = 0;\n while ((startIndex = pageText.indexOf(lowerQuery, startIndex)) !== -1) {\n matches.push({ pageIndex: i - 1, matchIndex: matchIdx++ });\n startIndex += lowerQuery.length;\n }\n }\n\n setSearchMatches(matches);\n setCurrentMatchIndex(matches.length > 0 ? 0 : -1);\n }, [document]);\n\n const navigateToMatch = useCallback((matchIndex: number) => {\n if (matchIndex < 0 || matchIndex >= searchMatches.length) return;\n const match = searchMatches[matchIndex];\n // Navigate to the page containing this match (pageIndex is 0-based)\n goToPage(match.pageIndex + 1);\n // Scroll the highlighted element into view after render\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n const el = containerRef?.current?.querySelector('.pdf-viewer__search-hit--current');\n el?.scrollIntoView({ block: 'center', behavior: 'instant' });\n });\n });\n }, [searchMatches, goToPage, containerRef]);\n\n const nextMatch = useCallback(() => {\n if (searchMatches.length === 0) return;\n setCurrentMatchIndex((prev) => {\n const next = (prev + 1) % searchMatches.length;\n navigateToMatch(next);\n return next;\n });\n }, [searchMatches.length, navigateToMatch]);\n\n const prevMatch = useCallback(() => {\n if (searchMatches.length === 0) return;\n setCurrentMatchIndex((prev) => {\n const next = (prev - 1 + searchMatches.length) % searchMatches.length;\n navigateToMatch(next);\n return next;\n });\n }, [searchMatches.length, navigateToMatch]);\n\n const clearSearch = useCallback(() => {\n setSearchQuery('');\n setSearchMatches([]);\n setCurrentMatchIndex(-1);\n }, []);\n\n const download = useCallback(\n async (fileName?: string) => {\n if (!document) return;\n const data = await document.getData();\n const blob = new Blob([data], { type: 'application/pdf' });\n const url = URL.createObjectURL(blob);\n const a = window.document.createElement('a');\n a.href = url;\n a.download = fileName ?? 'document.pdf';\n window.document.body.appendChild(a);\n a.click();\n window.document.body.removeChild(a);\n URL.revokeObjectURL(url);\n },\n [document]\n );\n\n const print = useCallback(async () => {\n if (!document) return;\n const total = document.numPages;\n\n // Set isPrinting to force all pages to render\n setIsPrinting(true);\n\n // Wait for all pages to finish rendering their canvases\n await new Promise<void>((resolve) => {\n const checkInterval = setInterval(() => {\n const container = containerRef.current;\n if (!container) return;\n const canvases = container.querySelectorAll('.pdf-viewer__page-canvas');\n let rendered = 0;\n canvases.forEach((c) => {\n const canvas = c as HTMLCanvasElement;\n if (canvas.width > 0 && canvas.height > 0) rendered++;\n });\n if (rendered >= total) {\n clearInterval(checkInterval);\n resolve();\n }\n }, 100);\n\n // Safety timeout after 10s\n setTimeout(() => { clearInterval(checkInterval); resolve(); }, 10000);\n });\n\n // Print via hidden iframe to bypass host page layout constraints\n const container = containerRef.current;\n if (!container) { setIsPrinting(false); return; }\n\n const canvases = Array.from(container.querySelectorAll('.pdf-viewer__page-canvas')) as HTMLCanvasElement[];\n const iframe = window.document.createElement('iframe');\n iframe.style.position = 'fixed';\n iframe.style.top = '-10000px';\n iframe.style.left = '-10000px';\n iframe.style.width = '0';\n iframe.style.height = '0';\n window.document.body.appendChild(iframe);\n\n const iframeDoc = iframe.contentDocument || iframe.contentWindow?.document;\n if (!iframeDoc) { setIsPrinting(false); return; }\n\n iframeDoc.open();\n iframeDoc.write(`<!DOCTYPE html><html><head><style>\n * { margin: 0; padding: 0; }\n body { background: white; }\n img { display: block; width: 100%; height: auto; page-break-after: always; }\n img:last-child { page-break-after: auto; }\n </style></head><body></body></html>`);\n iframeDoc.close();\n\n // Convert each canvas to an image in the iframe\n for (const canvas of canvases) {\n const img = iframeDoc.createElement('img');\n img.src = canvas.toDataURL('image/png');\n iframeDoc.body.appendChild(img);\n }\n\n // Wait for images to load, then print\n await new Promise<void>((resolve) => {\n const imgs = iframeDoc.querySelectorAll('img');\n let loaded = 0;\n const onLoad = () => {\n loaded++;\n if (loaded >= imgs.length) resolve();\n };\n imgs.forEach((img) => {\n if (img.complete) { loaded++; } else { img.onload = onLoad; }\n });\n if (loaded >= imgs.length) resolve();\n });\n\n iframe.contentWindow?.print();\n\n // Cleanup after print dialog closes\n setTimeout(() => {\n window.document.body.removeChild(iframe);\n setIsPrinting(false);\n }, 500);\n }, [document]);\n\n const setCursorMode = useCallback((mode: CursorMode) => {\n setCursorModeState(mode);\n }, []);\n\n const toggleCursorMode = useCallback(() => {\n setCursorModeState((prev) => (prev === 'select' ? 'hand' : 'select'));\n }, []);\n\n const goToFirstPage = useCallback(() => {\n goToPage(1);\n }, [goToPage]);\n\n const goToLastPage = useCallback(() => {\n goToPage(totalPages);\n }, [goToPage, totalPages]);\n\n const setViewMode = useCallback((mode: ViewMode) => {\n setViewModeState(mode);\n // Dual page is not allowed with horizontal scrolling\n if (mode === 'dual') {\n setScrollModeState((prev) => prev === 'horizontal' ? 'vertical' : prev);\n }\n }, []);\n\n const setScrollMode = useCallback((mode: ScrollMode) => {\n setScrollModeState(mode);\n // Horizontal scrolling is not allowed with dual page\n if (mode === 'horizontal') {\n setViewModeState('single');\n }\n }, []);\n\n // Derive layoutMode for backward compatibility\n const layoutMode: LayoutMode = scrollMode === 'horizontal' ? 'horizontal' : viewMode === 'dual' ? 'dual' : 'single';\n\n const setLayoutMode = useCallback((mode: LayoutMode) => {\n if (mode === 'horizontal') {\n setScrollModeState('horizontal');\n setViewModeState('single');\n } else if (mode === 'dual') {\n setViewModeState('dual');\n setScrollModeState((prev) => prev === 'horizontal' ? 'vertical' : prev);\n } else {\n setViewModeState('single');\n }\n }, []);\n\n const openDocProperties = useCallback(async () => {\n if (!document) return;\n try {\n const metadata = await document.getMetadata();\n const info = (metadata?.info as Record<string, any>) ?? {};\n const page = await document.getPage(1);\n const viewport = page.getViewport({ scale: 1 });\n const widthIn = (viewport.width / 72).toFixed(1);\n const heightIn = (viewport.height / 72).toFixed(1);\n const widthMm = (viewport.width / 72 * 25.4).toFixed(0);\n const heightMm = (viewport.height / 72 * 25.4).toFixed(0);\n\n const formatDate = (raw: string | undefined) => {\n if (!raw) return '-';\n // PDF dates: D:YYYYMMDDHHmmSS\n const match = raw.match(/D:(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})/);\n if (match) {\n const [, y, m, d, h, min, s] = match;\n return new Date(`${y}-${m}-${d}T${h}:${min}:${s}`).toLocaleString();\n }\n return raw;\n };\n\n const formatFileSize = (bytes: number) => {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n };\n\n const data = await document.getData();\n\n let fileName = '-';\n if (typeof src === 'string') {\n const urlPath = src.split('?')[0].split('#')[0];\n const lastSegment = urlPath.split('/').pop();\n if (lastSegment) fileName = decodeURIComponent(lastSegment);\n } else if (src instanceof File) {\n fileName = src.name;\n }\n\n setDocProperties({\n fileName,\n fileSize: formatFileSize(data.byteLength),\n title: info.Title || '-',\n author: info.Author || '-',\n subject: info.Subject || '-',\n creator: info.Creator || '-',\n producer: info.Producer || '-',\n creationDate: formatDate(info.CreationDate),\n modificationDate: formatDate(info.ModDate),\n pageCount: document.numPages,\n pageSize: `${widthIn} × ${heightIn} in (${widthMm} × ${heightMm} mm)`,\n });\n setIsDocPropertiesOpen(true);\n } catch {\n // ignore metadata errors\n }\n }, [document, src]);\n\n const closeDocProperties = useCallback(() => {\n setIsDocPropertiesOpen(false);\n }, []);\n\n const toggleFullScreen = useCallback(() => {\n if (!window.document.fullscreenElement) {\n // Fullscreen the viewer container, fall back to documentElement\n const el = containerRef.current?.closest('.pdf-viewer') ?? window.document.documentElement;\n (el as HTMLElement).requestFullscreen?.();\n } else {\n window.document.exitFullscreen?.();\n }\n }, []);\n\n const value = useMemo<PdfViewerContextValue>(\n () => ({\n document,\n isLoading,\n error,\n currentPage,\n totalPages,\n zoomLevel,\n zoomMode,\n rotation,\n isThumbnailsOpen,\n searchQuery,\n searchMatches,\n currentMatchIndex,\n isPrinting,\n containerRef,\n scrollToPageRef,\n _setCurrentPage,\n goToPage,\n nextPage,\n prevPage,\n zoomIn,\n zoomOut,\n zoomTo,\n _setZoomLevel,\n rotate,\n toggleThumbnails,\n search,\n nextMatch,\n prevMatch,\n clearSearch,\n download,\n print,\n toggleFullScreen,\n cursorMode,\n setCursorMode,\n toggleCursorMode,\n viewMode,\n scrollMode,\n layoutMode,\n setViewMode,\n setScrollMode,\n setLayoutMode,\n isDocPropertiesOpen,\n docProperties,\n goToFirstPage,\n goToLastPage,\n openDocProperties,\n closeDocProperties,\n }),\n [\n document,\n isLoading,\n error,\n currentPage,\n totalPages,\n zoomLevel,\n zoomMode,\n rotation,\n isThumbnailsOpen,\n searchQuery,\n searchMatches,\n currentMatchIndex,\n isPrinting,\n _setCurrentPage,\n goToPage,\n nextPage,\n prevPage,\n zoomIn,\n zoomOut,\n zoomTo,\n _setZoomLevel,\n rotate,\n toggleThumbnails,\n search,\n nextMatch,\n prevMatch,\n clearSearch,\n download,\n print,\n toggleFullScreen,\n cursorMode,\n setCursorMode,\n toggleCursorMode,\n viewMode,\n scrollMode,\n layoutMode,\n setViewMode,\n setScrollMode,\n setLayoutMode,\n isDocPropertiesOpen,\n docProperties,\n goToFirstPage,\n goToLastPage,\n openDocProperties,\n closeDocProperties,\n ]\n );\n\n return (\n <PdfViewerContext.Provider value={value}>\n {children}\n </PdfViewerContext.Provider>\n );\n}\n","import { useState, useEffect, useRef } from 'react';\nimport { getDocument, type PDFDocumentProxy } from 'pdfjs-dist';\nimport type { PdfSource, DocumentInfo } from '../types';\n\nexport function usePdfDocument(\n src: PdfSource,\n onDocumentLoad?: (info: DocumentInfo) => void\n) {\n const [document, setDocument] = useState<PDFDocumentProxy | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const prevSrcRef = useRef<PdfSource | null>(null);\n const objectUrlRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (src === prevSrcRef.current) return;\n prevSrcRef.current = src;\n\n // Revoke previous object URL if any\n if (objectUrlRef.current) {\n URL.revokeObjectURL(objectUrlRef.current);\n objectUrlRef.current = null;\n }\n\n let cancelled = false;\n setIsLoading(true);\n setError(null);\n\n const init = getDocumentInit(src);\n if (src instanceof File) {\n objectUrlRef.current = init.url as string;\n }\n\n const loadingTask = getDocument(init);\n\n loadingTask.promise\n .then(async (doc) => {\n if (cancelled) {\n doc.destroy();\n return;\n }\n setDocument(doc);\n setIsLoading(false);\n\n const metadata = await doc.getMetadata();\n const info = metadata.info as Record<string, string> | null;\n onDocumentLoad?.({\n numPages: doc.numPages,\n title: info?.Title,\n author: info?.Author,\n });\n })\n .catch((err) => {\n if (cancelled) return;\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsLoading(false);\n });\n\n return () => {\n cancelled = true;\n if (objectUrlRef.current) {\n URL.revokeObjectURL(objectUrlRef.current);\n objectUrlRef.current = null;\n }\n };\n }, [src]);\n\n return { document, isLoading, error };\n}\n\nfunction getDocumentInit(src: PdfSource) {\n if (typeof src === 'string') {\n return { url: src };\n }\n if (src instanceof File) {\n return { url: URL.createObjectURL(src) };\n }\n // ArrayBuffer or Uint8Array\n return { data: src };\n}\n","export const DEFAULT_ZOOM = 1;\nexport const MIN_ZOOM = 0.25;\nexport const MAX_ZOOM = 4;\nexport const ZOOM_STEP = 0.25;\nexport const VIRTUALIZATION_BUFFER = 2;\nexport const THUMBNAIL_SCALE = 0.2;\n","import { useEffect } from 'react';\nimport type { PdfViewerContextValue } from '../types';\n\nexport function useKeyboardShortcuts(\n containerRef: React.RefObject<HTMLElement | null>,\n ctx: PdfViewerContextValue\n) {\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement;\n const isInput = target.tagName === 'INPUT' || target.tagName === 'TEXTAREA';\n\n if (!isInput) {\n if (e.key === 'ArrowRight' || e.key === 'PageDown') {\n e.preventDefault();\n ctx.nextPage();\n }\n if (e.key === 'ArrowLeft' || e.key === 'PageUp') {\n e.preventDefault();\n ctx.prevPage();\n }\n }\n\n if (!isInput && e.key === 'h') {\n e.preventDefault();\n ctx.toggleCursorMode();\n }\n\n if (e.ctrlKey || e.metaKey) {\n if (e.key === '=' || e.key === '+') {\n e.preventDefault();\n ctx.zoomIn();\n }\n if (e.key === '-') {\n e.preventDefault();\n ctx.zoomOut();\n }\n if (e.key === '0') {\n e.preventDefault();\n ctx.zoomTo(1);\n }\n if (e.key === 'f') {\n e.preventDefault();\n const searchInput = el.querySelector<HTMLInputElement>('.pdf-viewer__search-input');\n searchInput?.focus();\n }\n }\n };\n\n el.addEventListener('keydown', handleKeyDown);\n return () => el.removeEventListener('keydown', handleKeyDown);\n }, [containerRef, ctx]);\n}\n","import type { ReactNode } from 'react';\n\nexport interface ToolbarProps {\n className?: string;\n children: ReactNode;\n}\n\nexport function Toolbar({ className, children }: ToolbarProps) {\n const classNames = ['pdf-viewer__toolbar', className]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div className={classNames} role=\"toolbar\">\n {children}\n </div>\n );\n}\n","import { useState, useEffect, useCallback, type KeyboardEvent, type ChangeEvent } from 'react';\nimport { usePdfViewerContext } from '../context';\nimport { ChevronLeft, ChevronRight } from '../icons';\n\nexport interface NavigationProps {\n className?: string;\n}\n\nexport function Navigation({ className }: NavigationProps) {\n const { currentPage, totalPages, goToPage, nextPage, prevPage } =\n usePdfViewerContext();\n const [inputValue, setInputValue] = useState(String(currentPage));\n\n // Keep input in sync when currentPage changes externally\n useEffect(() => {\n setInputValue(String(currentPage));\n }, [currentPage]);\n\n const handleInputChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n setInputValue(e.target.value);\n }, []);\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n const page = parseInt(inputValue, 10);\n if (!isNaN(page)) {\n goToPage(page);\n }\n }\n },\n [inputValue, goToPage]\n );\n\n const handleBlur = useCallback(() => {\n setInputValue(String(currentPage));\n }, [currentPage]);\n\n const classNames = ['pdf-viewer__navigation', className]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div className={classNames}>\n <button\n className=\"pdf-viewer__btn\"\n onClick={prevPage}\n disabled={currentPage <= 1}\n title=\"Previous page\"\n aria-label=\"Previous page\"\n >\n <ChevronLeft />\n </button>\n <input\n className=\"pdf-viewer__page-input\"\n type=\"text\"\n value={inputValue}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onBlur={handleBlur}\n aria-label=\"Page number\"\n />\n <span className=\"pdf-viewer__page-count\">\n <span className=\"pdf-viewer__page-count-desktop\">of {totalPages}</span>\n <span className=\"pdf-viewer__page-count-mobile\">/{totalPages}</span>\n </span>\n <button\n className=\"pdf-viewer__btn\"\n onClick={nextPage}\n disabled={currentPage >= totalPages}\n title=\"Next page\"\n aria-label=\"Next page\"\n >\n <ChevronRight />\n </button>\n </div>\n );\n}\n","/**\n * Local Lucide-style icons — SVG paths from lucide.dev, zero dependencies.\n * All icons use 24x24 viewBox with stroke-based rendering.\n */\n\nimport type { SVGProps } from 'react';\n\ntype IconProps = SVGProps<SVGSVGElement>;\n\nconst defaults: IconProps = {\n width: 18,\n height: 18,\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n};\n\nfunction Icon(props: IconProps & { children: React.ReactNode }) {\n const { children, ...rest } = props;\n return <svg {...defaults} {...rest}>{children}</svg>;\n}\n\n// Navigation\nexport function ChevronLeft(props: IconProps) {\n return <Icon {...props}><path d=\"m15 18-6-6 6-6\" /></Icon>;\n}\n\nexport function ChevronRight(props: IconProps) {\n return <Icon {...props}><path d=\"m9 18 6-6-6-6\" /></Icon>;\n}\n\nexport function ChevronsLeft(props: IconProps) {\n return <Icon {...props}><path d=\"m11 17-5-5 5-5\" /><path d=\"m18 17-5-5 5-5\" /></Icon>;\n}\n\nexport function ChevronsRight(props: IconProps) {\n return <Icon {...props}><path d=\"m6 17 5-5-5-5\" /><path d=\"m13 17 5-5-5-5\" /></Icon>;\n}\n\nexport function ChevronUp(props: IconProps) {\n return <Icon {...props}><path d=\"m18 15-6-6-6 6\" /></Icon>;\n}\n\nexport function ChevronDown(props: IconProps) {\n return <Icon {...props}><path d=\"m6 9 6 6 6-6\" /></Icon>;\n}\n\n// Zoom\nexport function Minus(props: IconProps) {\n return <Icon {...props}><path d=\"M5 12h14\" /></Icon>;\n}\n\nexport function Plus(props: IconProps) {\n return <Icon {...props}><path d=\"M5 12h14\" /><path d=\"M12 5v14\" /></Icon>;\n}\n\nexport function ArrowLeftRight(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M8 3H5a2 2 0 0 0-2 2v3\" />\n <path d=\"M21 8V5a2 2 0 0 0-2-2h-3\" />\n <path d=\"M3 16v3a2 2 0 0 0 2 2h3\" />\n <path d=\"M16 21h3a2 2 0 0 0 2-2v-3\" />\n <path d=\"M7 12h10\" />\n </Icon>\n );\n}\n\nexport function RectangleVertical(props: IconProps) {\n return <Icon {...props}><rect width=\"12\" height=\"18\" x=\"6\" y=\"3\" rx=\"2\" /></Icon>;\n}\n\n// Search\nexport function SearchIcon(props: IconProps) {\n return <Icon {...props}><circle cx=\"11\" cy=\"11\" r=\"8\" /><path d=\"m21 21-4.3-4.3\" /></Icon>;\n}\n\nexport function X(props: IconProps) {\n return <Icon {...props}><path d=\"M18 6 6 18\" /><path d=\"m6 6 12 12\" /></Icon>;\n}\n\n// Actions\nexport function RotateCw(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8\" />\n <path d=\"M21 3v5h-5\" />\n </Icon>\n );\n}\n\nexport function RotateCcw(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\" />\n <path d=\"M3 3v5h5\" />\n </Icon>\n );\n}\n\nexport function Download(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"7 10 12 15 17 10\" />\n <line x1=\"12\" x2=\"12\" y1=\"15\" y2=\"3\" />\n </Icon>\n );\n}\n\nexport function Printer(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2\" />\n <path d=\"M6 9V3h12v6\" />\n <rect width=\"12\" height=\"8\" x=\"6\" y=\"14\" />\n </Icon>\n );\n}\n\nexport function Maximize(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M8 3H5a2 2 0 0 0-2 2v3\" />\n <path d=\"M21 8V5a2 2 0 0 0-2-2h-3\" />\n <path d=\"M3 16v3a2 2 0 0 0 2 2h3\" />\n <path d=\"M16 21h3a2 2 0 0 0 2-2v-3\" />\n </Icon>\n );\n}\n\nexport function Expand(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"m21 21-6-6m6 6v-4.8m0 4.8h-4.8\" />\n <path d=\"M3 16.2V21m0 0h4.8M3 21l6-6\" />\n <path d=\"M21 7.8V3m0 0h-4.8M21 3l-6 6\" />\n <path d=\"M3 7.8V3m0 0h4.8M3 3l6 6\" />\n </Icon>\n );\n}\n\n// Cursor modes\nexport function Hand(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M18 11V6a2 2 0 0 0-2-2 2 2 0 0 0-2 2\" />\n <path d=\"M14 10V4a2 2 0 0 0-2-2 2 2 0 0 0-2 2v2\" />\n <path d=\"M10 10.5V6a2 2 0 0 0-2-2 2 2 0 0 0-2 2v8\" />\n <path d=\"M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15\" />\n </Icon>\n );\n}\n\nexport function MousePointer(props: IconProps) {\n return <Icon {...props}><path d=\"M3 3l7.07 17 2.51-7.39L20 10.07z\" /></Icon>;\n}\n\n// Layout\nexport function FileText(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\" />\n <path d=\"M14 2v4a2 2 0 0 0 2 2h4\" />\n </Icon>\n );\n}\n\nexport function StickyNote(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M15.5 3H5a2 2 0 0 0-2 2v14c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2V8.5L15.5 3Z\" />\n <path d=\"M14 3v4a2 2 0 0 0 2 2h4\" />\n </Icon>\n );\n}\n\nexport function Columns2(props: IconProps) {\n return (\n <Icon {...props}>\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M12 3v18\" />\n </Icon>\n );\n}\n\nexport function GalleryVertical(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M3 2h18\" />\n <rect width=\"18\" height=\"12\" x=\"3\" y=\"6\" rx=\"2\" />\n <path d=\"M3 22h18\" />\n </Icon>\n );\n}\n\nexport function GalleryHorizontal(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M2 3v18\" />\n <rect width=\"12\" height=\"18\" x=\"6\" y=\"3\" rx=\"2\" />\n <path d=\"M22 3v18\" />\n </Icon>\n );\n}\n\nexport function GalleryThumbnails(props: IconProps) {\n return (\n <Icon {...props}>\n <rect width=\"18\" height=\"14\" x=\"3\" y=\"2\" rx=\"2\" />\n <rect width=\"4\" height=\"2\" x=\"4\" y=\"18\" rx=\"1\" />\n <rect width=\"4\" height=\"2\" x=\"10\" y=\"18\" rx=\"1\" />\n <rect width=\"4\" height=\"2\" x=\"16\" y=\"18\" rx=\"1\" />\n </Icon>\n );\n}\n\nexport function Check(props: IconProps) {\n return <Icon {...props}><path d=\"M20 6 9 17l-5-5\" /></Icon>;\n}\n\n// Misc\nexport function EllipsisVertical(props: IconProps) {\n return (\n <Icon {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"12\" cy=\"5\" r=\"1\" />\n <circle cx=\"12\" cy=\"19\" r=\"1\" />\n </Icon>\n );\n}\n\nexport function Info(props: IconProps) {\n return (\n <Icon {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 16v-4\" />\n <path d=\"M12 8h.01\" />\n </Icon>\n );\n}\n\nexport function PanelLeft(props: IconProps) {\n return (\n <Icon {...props}>\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M9 3v18\" />\n </Icon>\n );\n}\n\nexport function Sun(props: IconProps) {\n return (\n <Icon {...props}>\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <path d=\"M12 2v2\" />\n <path d=\"M12 20v2\" />\n <path d=\"m4.93 4.93 1.41 1.41\" />\n <path d=\"m17.66 17.66 1.41 1.41\" />\n <path d=\"M2 12h2\" />\n <path d=\"M20 12h2\" />\n <path d=\"m6.34 17.66-1.41 1.41\" />\n <path d=\"m19.07 4.93-1.41 1.41\" />\n </Icon>\n );\n}\n\nexport function ArrowDownToLine(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M12 17V3\" />\n <path d=\"m6 11 6 6 6-6\" />\n <path d=\"M19 21H5\" />\n </Icon>\n );\n}\n\nexport function Moon(props: IconProps) {\n return (\n <Icon {...props}>\n <path d=\"M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z\" />\n </Icon>\n );\n}\n","import { useState, useRef, useEffect, useCallback, type ReactNode } from 'react';\nimport { Check } from '../icons';\n\nexport interface DropdownMenuProps {\n trigger: ReactNode;\n children: ReactNode;\n className?: string;\n align?: 'left' | 'right' | 'center';\n title?: string;\n triggerClassName?: string;\n}\n\nexport function DropdownMenu({ trigger, children, className, align = 'right', title = 'More actions', triggerClassName }: DropdownMenuProps) {\n const [open, setOpen] = useState(false);\n const menuRef = useRef<HTMLDivElement>(null);\n\n const close = useCallback(() => setOpen(false), []);\n\n useEffect(() => {\n if (!open) return;\n const handleClickOutside = (e: MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) {\n close();\n }\n };\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape') close();\n };\n window.document.addEventListener('mousedown', handleClickOutside);\n window.document.addEventListener('keydown', handleEscape);\n return () => {\n window.document.removeEventListener('mousedown', handleClickOutside);\n window.document.removeEventListener('keydown', handleEscape);\n };\n }, [open, close]);\n\n const classNames = ['pdf-viewer__dropdown', className].filter(Boolean).join(' ');\n\n return (\n <div ref={menuRef} className={classNames}>\n <button\n className={triggerClassName ?? 'pdf-viewer__btn'}\n onClick={() => setOpen((prev) => !prev)}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n title={title}\n aria-label={title}\n >\n {trigger}\n </button>\n {open && (\n <div\n className={`pdf-viewer__dropdown-content pdf-viewer__dropdown-content--${align}`}\n role=\"menu\"\n onClick={close}\n >\n {children}\n </div>\n )}\n </div>\n );\n}\n\nexport interface DropdownMenuItemProps {\n icon?: ReactNode;\n label: string;\n onClick: () => void;\n disabled?: boolean;\n active?: boolean;\n}\n\nexport function DropdownMenuItem({ icon, label, onClick, disabled, active }: DropdownMenuItemProps) {\n const classNames = [\n 'pdf-viewer__dropdown-item',\n active && 'pdf-viewer__dropdown-item--active',\n disabled && 'pdf-viewer__dropdown-item--disabled',\n ].filter(Boolean).join(' ');\n\n return (\n <button\n className={classNames}\n role=\"menuitem\"\n onClick={disabled ? undefined : onClick}\n disabled={disabled}\n >\n {icon && <span className=\"pdf-viewer__dropdown-item-icon\">{icon}</span>}\n <span className=\"pdf-viewer__dropdown-item-label\">{label}</span>\n {active && <span className=\"pdf-viewer__dropdown-item-check\"><Check /></span>}\n </button>\n );\n}\n\nexport function DropdownMenuSeparator() {\n return <div className=\"pdf-viewer__dropdown-separator\" role=\"separator\" />;\n}\n","import { usePdfViewerContext } from '../context';\nimport { Minus, Plus, ArrowLeftRight, RectangleVertical } from '../icons';\nimport { DropdownMenu, DropdownMenuItem, DropdownMenuSeparator } from './DropdownMenu';\n\nexport interface ZoomProps {\n className?: string;\n}\n\nconst ZOOM_PRESETS = [0.5, 0.75, 1, 1.25, 1.5, 2, 3];\n\nexport function Zoom({ className }: ZoomProps) {\n const { zoomLevel, zoomMode, zoomIn, zoomOut, zoomTo } =\n usePdfViewerContext();\n\n const classNames = ['pdf-viewer__zoom', className]\n .filter(Boolean)\n .join(' ');\n\n const displayPercent = `${Math.round(zoomLevel * 20) * 5}%`;\n\n const isPresetActive = (preset: number) =>\n !zoomMode && Math.abs(zoomLevel - preset) < 0.01;\n\n return (\n <div className={classNames}>\n <button\n className=\"pdf-viewer__btn\"\n onClick={zoomOut}\n title=\"Zoom out\"\n aria-label=\"Zoom out\"\n >\n <Minus />\n </button>\n <DropdownMenu\n trigger={<span className=\"pdf-viewer__zoom-level-text\">{displayPercent}</span>}\n triggerClassName=\"pdf-viewer__zoom-trigger\"\n title=\"Zoom level\"\n align=\"center\"\n className=\"pdf-viewer__zoom-dropdown\"\n >\n {ZOOM_PRESETS.map((preset) => (\n <DropdownMenuItem\n key={preset}\n label={`${Math.round(preset * 100)}%`}\n onClick={() => zoomTo(preset)}\n active={isPresetActive(preset)}\n />\n ))}\n <DropdownMenuSeparator />\n <DropdownMenuItem\n icon={<ArrowLeftRight />}\n label=\"Fit Width\"\n onClick={() => zoomTo('fit-width')}\n active={zoomMode === 'fit-width'}\n />\n <DropdownMenuItem\n icon={<RectangleVertical />}\n label=\"Fit Page\"\n onClick={() => zoomTo('fit-page')}\n active={zoomMode === 'fit-page'}\n />\n </DropdownMenu>\n <button\n className=\"pdf-viewer__btn\"\n onClick={zoomIn}\n title=\"Zoom in\"\n aria-label=\"Zoom in\"\n >\n <Plus />\n </button>\n </div>\n );\n}\n","import { useState, useCallback, useRef, useEffect, type KeyboardEvent, type ChangeEvent } from 'react';\nimport { usePdfViewerContext } from '../context';\nimport { SearchIcon, ChevronUp, ChevronDown, X } from '../icons';\n\nexport interface SearchProps {\n className?: string;\n}\n\nexport function Search({ className }: SearchProps) {\n const {\n searchQuery,\n searchMatches,\n currentMatchIndex,\n search,\n nextMatch,\n prevMatch,\n clearSearch,\n } = usePdfViewerContext();\n\n const [open, setOpen] = useState(false);\n const panelRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement | null>(null);\n\n const handleOpen = useCallback(() => {\n setOpen(true);\n }, []);\n\n const handleClose = useCallback(() => {\n setOpen(false);\n clearSearch();\n }, [clearSearch]);\n\n // Auto-focus input when panel opens\n const inputCallbackRef = useCallback((node: HTMLInputElement | null) => {\n inputRef.current = node;\n node?.focus();\n }, []);\n\n // Close on Escape\n useEffect(() => {\n if (!open) return;\n const handleEscape = (e: globalThis.KeyboardEvent) => {\n if (e.key === 'Escape') handleClose();\n };\n window.document.addEventListener('keydown', handleEscape);\n return () => window.document.removeEventListener('keydown', handleEscape);\n }, [open, handleClose]);\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n search(e.target.value);\n },\n [search]\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n if (e.shiftKey) {\n prevMatch();\n } else {\n nextMatch();\n }\n }\n },\n [nextMatch, prevMatch]\n );\n\n const classNames = ['pdf-viewer__search-toggle', className]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div className={classNames} ref={panelRef}>\n <button\n className=\"pdf-viewer__btn\"\n onClick={handleOpen}\n title=\"Search\"\n aria-label=\"Search in document\"\n >\n <SearchIcon />\n </button>\n {open && (\n <div className=\"pdf-viewer__search-panel\">\n <div className=\"pdf-viewer__search-input-wrapper\">\n <div className=\"pdf-viewer__search-input-icon\">\n <SearchIcon />\n </div>\n <input\n ref={inputCallbackRef}\n className=\"pdf-viewer__search-panel-input\"\n type=\"text\"\n placeholder=\"Search...\"\n aria-label=\"Search in document\"\n value={searchQuery}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n />\n </div>\n <span className=\"pdf-viewer__search-count\">\n {searchQuery && searchMatches.length > 0\n ? `${currentMatchIndex + 1}/${searchMatches.length}`\n : '0/0'}\n </span>\n <button\n className=\"pdf-viewer__btn pdf-viewer__btn--small\"\n onClick={prevMatch}\n disabled={searchMatches.length === 0}\n title=\"Previous match\"\n aria-label=\"Previous match\"\n >\n <ChevronUp />\n </button>\n <button\n className=\"pdf-viewer__btn pdf-viewer__btn--small\"\n onClick={nextMatch}\n disabled={searchMatches.length === 0}\n title=\"Next match\"\n aria-label=\"Next match\"\n >\n <ChevronDown />\n </button>\n <button\n className=\"pdf-viewer__btn pdf-viewer__btn--small\"\n onClick={handleClose}\n title=\"Close search\"\n aria-label=\"Close search\"\n >\n <X />\n </button>\n </div>\n )}\n </div>\n );\n}\n","export interface SeparatorProps {\n className?: string;\n}\n\nexport function Separator({ className }: SeparatorProps) {\n const classNames = ['pdf-viewer__separator', className]\n .filter(Boolean)\n .join(' ');\n\n return <div className={classNames} role=\"separator\" />;\n}\n","import { usePdfViewerContext } from '../context';\nimport { RotateCw } from '../icons';\n\nexport interface RotateProps {\n className?: string;\n}\n\nexport function Rotate({ className }: RotateProps) {\n const { rotate } = usePdfViewerContext();\n\n const classNames = ['pdf-viewer__btn', className]\n .filter(Boolean)\n .join(' ');\n\n return (\n <button\n className={classNames}\n onClick={() => rotate()}\n title=\"Rotate\"\n aria-label=\"Rotate clockwise\"\n >\n <RotateCw />\n </button>\n );\n}\n","import { usePdfViewerContext } from '../context';\nimport { Download as DownloadIcon } from '../icons';\n\nexport interface DownloadProps {\n fileName?: string;\n className?: string;\n}\n\nexport function Download({ fileName, className }: DownloadProps) {\n const { download } = usePdfViewerContext();\n\n const classNames = ['pdf-viewer__btn', className]\n .filter(Boolean)\n .join(' ');\n\n return (\n <button\n className={classNames}\n onClick={() => download(fileName)}\n title=\"Download\"\n aria-label=\"Download PDF\"\n >\n <DownloadIcon />\n </button>\n );\n}\n","import { usePdfViewerContext } from '../context';\nimport { Printer } from '../icons';\n\nexport interface PrintProps {\n className?: string;\n}\n\nexport function Print({ className }: PrintProps) {\n const { print } = usePdfViewerContext();\n\n const classNames = ['pdf-viewer__btn', className]\n .filter(Boolean)\n .join(' ');\n\n return (\n <button\n className={classNames}\n onClick={print}\n title=\"Print\"\n aria-label=\"Print PDF\"\n >\n <Printer />\n </button>\n );\n}\n","import { usePdfViewerContext } from '../context';\nimport { Expand } from '../icons';\n\nexport interface FullScreenProps {\n className?: string;\n}\n\nexport function FullScreen({ className }: FullScreenProps) {\n const { toggleFullScreen } = usePdfViewerContext();\n\n const classNames = ['pdf-viewer__btn', className]\n .filter(Boolean)\n .join(' ');\n\n return (\n <button\n className={classNames}\n onClick={toggleFullScreen}\n title=\"Full screen\"\n aria-label=\"Toggle full screen\"\n >\n <Expand />\n </button>\n );\n}\n","import { usePdfViewerContext } from '../context';\nimport { PanelLeft } from '../icons';\n\nexport interface ThumbnailToggleProps {\n className?: string;\n}\n\nexport function ThumbnailToggle({ className }: ThumbnailToggleProps) {\n const { toggleThumbnails, isThumbnailsOpen } = usePdfViewerContext();\n\n const classNames = [\n 'pdf-viewer__btn',\n isThumbnailsOpen ? 'pdf-viewer__btn--active' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <button\n className={classNames}\n onClick={toggleThumbnails}\n title=\"Toggle sidebar\"\n aria-label=\"Toggle thumbnails\"\n aria-pressed={isThumbnailsOpen}\n >\n <PanelLeft />\n </button>\n );\n}\n","import { usePdfViewerContext } from '../context';\nimport { Hand, MousePointer } from '../icons';\n\nexport interface CursorModeToggleProps {\n className?: string;\n}\n\nexport function CursorModeToggle({ className }: CursorModeToggleProps) {\n const { cursorMode, toggleCursorMode } = usePdfViewerContext();\n\n const classNames = ['pdf-viewer__btn', className].filter(Boolean).join(' ');\n\n return (\n <button\n className={classNames}\n onClick={toggleCursorMode}\n title={cursorMode === 'select' ? 'Hand Tool' : 'Selection Mode'}\n aria-label={cursorMode === 'select' ? 'Hand Tool' : 'Selection Mode'}\n >\n {cursorMode === 'select' ? <Hand /> : <MousePointer />}\n </button>\n );\n}\n","import { useEffect, useRef, useState, useCallback } from 'react';\nimport { usePdfViewerContext } from '../context';\nimport { THUMBNAIL_SCALE } from '../constants';\n\nexport interface ThumbnailSidebarProps {\n className?: string;\n}\n\nexport function ThumbnailSidebar({ className }: ThumbnailSidebarProps) {\n const { document, totalPages, currentPage, goToPage, isThumbnailsOpen, rotation } =\n usePdfViewerContext();\n const containerRef = useRef<HTMLDivElement>(null);\n const [visibleThumbnails, setVisibleThumbnails] = useState<Set<number>>(new Set());\n const [renderedThumbnails, setRenderedThumbnails] = useState<Set<number>>(new Set());\n const canvasRefs = useRef<Map<number, HTMLCanvasElement>>(new Map());\n const renderingPages = useRef<Set<number>>(new Set());\n\n const handleIntersection = useCallback(\n (entries: IntersectionObserverEntry[]) => {\n setVisibleThumbnails((prev) => {\n const next = new Set(prev);\n for (const entry of entries) {\n const pageNum = Number(\n (entry.target as HTMLElement).dataset.thumbnailPage\n );\n if (entry.isIntersecting) {\n next.add(pageNum);\n } else {\n next.delete(pageNum);\n }\n }\n return next;\n });\n },\n []\n );\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container || !isThumbnailsOpen) return;\n\n const observer = new IntersectionObserver(handleIntersection, {\n root: container,\n rootMargin: '100px 0px',\n });\n\n const items = container.querySelectorAll('[data-thumbnail-page]');\n items.forEach((el) => observer.observe(el));\n\n return () => observer.disconnect();\n }, [totalPages, isThumbnailsOpen, handleIntersection]);\n\n // Render visible thumbnails — one at a time to avoid pdf.js render races\n useEffect(() => {\n if (!document || !isThumbnailsOpen) return;\n\n let cancelled = false;\n\n async function renderQueue() {\n for (const pageNum of visibleThumbnails) {\n if (cancelled) break;\n if (renderedThumbnails.has(pageNum)) continue;\n if (renderingPages.current.has(pageNum)) continue;\n\n const canvas = canvasRefs.current.get(pageNum);\n if (!canvas) continue;\n\n renderingPages.current.add(pageNum);\n try {\n const page = await document!.getPage(pageNum);\n if (cancelled) break;\n\n const viewport = page.getViewport({ scale: THUMBNAIL_SCALE, rotation });\n const context = canvas.getContext('2d');\n if (!context) { renderingPages.current.delete(pageNum); continue; }\n\n canvas.width = viewport.width;\n canvas.height = viewport.height;\n canvas.style.width = `${viewport.width}px`;\n canvas.style.height = `${viewport.height}px`;\n\n await page.render({ canvasContext: context, viewport }).promise;\n if (!cancelled) {\n setRenderedThumbnails((prev) => new Set(prev).add(pageNum));\n }\n } catch {\n // ignore render errors\n } finally {\n renderingPages.current.delete(pageNum);\n }\n }\n }\n\n renderQueue();\n return () => { cancelled = true; };\n }, [document, visibleThumbnails, renderedThumbnails, isThumbnailsOpen, rotation]);\n\n // Scroll active thumbnail into view when currentPage changes\n const lastClickedRef = useRef<number | null>(null);\n useEffect(() => {\n const container = containerRef.current;\n if (!container || !isThumbnailsOpen) return;\n // Skip if this page change was from clicking a thumbnail\n if (lastClickedRef.current === currentPage) {\n lastClickedRef.current = null;\n return;\n }\n const active = container.querySelector(`[data-thumbnail-page=\"${currentPage}\"]`) as HTMLElement | null;\n if (!active) return;\n const containerTop = container.scrollTop;\n const containerBottom = containerTop + container.clientHeight;\n const elTop = active.offsetTop - container.offsetTop;\n const elBottom = elTop + active.offsetHeight;\n if (elTop < containerTop || elBottom > containerBottom) {\n container.scrollTo({ top: Math.max(0, elTop - 8) });\n }\n }, [currentPage, isThumbnailsOpen]);\n\n // Re-render when rotation changes\n useEffect(() => {\n setRenderedThumbnails(new Set());\n }, [rotation]);\n\n if (!isThumbnailsOpen) return null;\n\n const classNames = ['pdf-viewer__sidebar', className]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div ref={containerRef} className={classNames}>\n {Array.from({ length: totalPages }, (_, i) => {\n const pageNum = i + 1;\n return (\n <button\n key={pageNum}\n className={`pdf-viewer__thumbnail${currentPage === pageNum ? ' pdf-viewer__thumbnail--active' : ''}`}\n data-thumbnail-page={pageNum}\n onClick={() => { lastClickedRef.current = pageNum; goToPage(pageNum); }}\n >\n <canvas\n ref={(el) => {\n if (el) {\n canvasRefs.current.set(pageNum, el);\n } else {\n canvasRefs.current.delete(pageNum);\n }\n }}\n />\n <span>{pageNum}</span>\n </button>\n );\n })}\n </div>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { usePdfViewerContext } from '../context';\nimport { VIRTUALIZATION_BUFFER } from '../constants';\nimport { Page } from './Page';\n\nexport interface PagesProps {\n className?: string;\n}\n\nexport function Pages({ className }: PagesProps) {\n const { totalPages, currentPage, _setCurrentPage, zoomMode, zoomLevel, _setZoomLevel, zoomTo, rotation, document: pdfDoc, containerRef: ctxContainerRef, scrollToPageRef, cursorMode, viewMode, scrollMode, isPrinting } = usePdfViewerContext();\n const containerRef = useRef<HTMLDivElement>(null);\n const visiblePagesRef = useRef<Set<number>>(new Set([1]));\n // Base page dimensions at scale=1 (fetched once from page 1)\n const [baseDims, setBaseDims] = useState<{ width: number; height: number } | null>(null);\n const navigatingRef = useRef(false);\n const lastReportedPageRef = useRef(1);\n const pageUpdateRafRef = useRef(0);\n // Only re-render when the set of pages to render actually changes\n const [renderGeneration, setRenderGeneration] = useState(0);\n\n const computeRenderSet = useCallback((visible: Set<number>): Set<number> => {\n const result = new Set<number>();\n for (const v of visible) {\n for (let offset = -VIRTUALIZATION_BUFFER; offset <= VIRTUALIZATION_BUFFER; offset++) {\n const p = v + offset;\n if (p >= 1 && p <= totalPages) result.add(p);\n }\n }\n return result;\n }, [totalPages]);\n\n const lastRenderSetRef = useRef<Set<number>>(computeRenderSet(new Set([1])));\n const _setCurrentPageRef = useRef(_setCurrentPage);\n _setCurrentPageRef.current = _setCurrentPage;\n\n const handleIntersection = useCallback(\n (entries: IntersectionObserverEntry[]) => {\n const prev = visiblePagesRef.current;\n for (const entry of entries) {\n const pageNum = Number(\n (entry.target as HTMLElement).dataset.pageNumber\n );\n if (entry.isIntersecting) {\n prev.add(pageNum);\n } else {\n prev.delete(pageNum);\n }\n }\n\n // Only trigger re-render if the set of pages we should render changes\n const newRenderSet = computeRenderSet(prev);\n const oldRenderSet = lastRenderSetRef.current;\n if (newRenderSet.size !== oldRenderSet.size || [...newRenderSet].some(p => !oldRenderSet.has(p))) {\n lastRenderSetRef.current = newRenderSet;\n setRenderGeneration(g => g + 1);\n }\n\n // Debounce current page updates — coalesce rapid IO events into one update\n if (navigatingRef.current) return;\n cancelAnimationFrame(pageUpdateRafRef.current);\n pageUpdateRafRef.current = requestAnimationFrame(() => {\n const visible = visiblePagesRef.current;\n if (visible.size > 0) {\n const topmost = Math.min(...visible);\n if (topmost !== lastReportedPageRef.current) {\n lastReportedPageRef.current = topmost;\n _setCurrentPageRef.current(topmost);\n }\n }\n });\n },\n [computeRenderSet]\n );\n\n // Fetch base page dimensions once\n useEffect(() => {\n if (!pdfDoc) return;\n pdfDoc.getPage(1).then((page) => {\n const vp = page.getViewport({ scale: 1, rotation });\n setBaseDims({ width: vp.width, height: vp.height });\n });\n }, [pdfDoc, rotation]);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const observer = new IntersectionObserver(handleIntersection, {\n root: container,\n rootMargin: scrollMode === 'horizontal' ? '0px 200px' : '200px 0px',\n });\n\n const wrappers = container.querySelectorAll('[data-page-number]');\n wrappers.forEach((el) => observer.observe(el));\n\n return () => observer.disconnect();\n }, [totalPages, handleIntersection, scrollMode]);\n\n // Reset navigating flag after programmatic scroll settles\n const navigatingTimerRef = useRef(0);\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n const handleScrollEnd = () => {\n if (navigatingRef.current) {\n // Delay reset to let IO observer fire and be ignored\n clearTimeout(navigatingTimerRef.current);\n navigatingTimerRef.current = window.setTimeout(() => {\n navigatingRef.current = false;\n }, 100);\n }\n };\n container.addEventListener('scrollend', handleScrollEnd);\n return () => {\n container.removeEventListener('scrollend', handleScrollEnd);\n clearTimeout(navigatingTimerRef.current);\n };\n }, []);\n\n // Expose scrollToPage function via context ref — called by programmatic navigation\n useEffect(() => {\n if (!scrollToPageRef) return;\n scrollToPageRef.current = (page: number) => {\n // Sync lastReportedPageRef so the IO observer won't override the navigated page\n lastReportedPageRef.current = page;\n if (scrollMode === 'page') {\n // In page scroll mode, navigation is handled by re-render (active class)\n navigatingRef.current = false;\n return;\n }\n const container = containerRef.current;\n if (!container) return;\n const wrapper = container.querySelector(`[data-page-number=\"${page}\"]`) as HTMLElement | null;\n if (!wrapper) return;\n // In dual mode, scroll to the pair container instead of individual page\n const target = (viewMode === 'dual' ? wrapper.closest('.pdf-viewer__page-pair') as HTMLElement : wrapper) ?? wrapper;\n navigatingRef.current = true;\n // Fallback: if scrollTo doesn't actually scroll (already at position), scrollend won't fire\n clearTimeout(navigatingTimerRef.current);\n navigatingTimerRef.current = window.setTimeout(() => {\n navigatingRef.current = false;\n }, 150);\n if (scrollMode === 'horizontal') {\n container.scrollTo({ left: target.offsetLeft - container.offsetLeft });\n } else {\n container.scrollTo({ top: target.offsetTop - container.offsetTop });\n }\n };\n }, [scrollToPageRef, scrollMode, viewMode]);\n\n // Set the container ref on context for fit-zoom calculations\n useEffect(() => {\n if (containerRef.current && ctxContainerRef) {\n ctxContainerRef.current = containerRef.current;\n }\n });\n\n // Compute fit-zoom when zoomMode changes or on container resize\n useEffect(() => {\n if (!zoomMode || !pdfDoc || !containerRef.current) return;\n\n const computeFitZoom = () => {\n if (!containerRef.current || !pdfDoc) return;\n pdfDoc.getPage(1).then((page) => {\n const viewport = page.getViewport({ scale: 1, rotation: 0 });\n const padding = 32;\n const gap = 16;\n const containerWidth = containerRef.current!.clientWidth - padding;\n const containerHeight = containerRef.current!.clientHeight - padding;\n\n // In dual mode, each page gets half the width minus the gap\n const availableWidth = viewMode === 'dual'\n ? (containerWidth - gap) / 2\n : containerWidth;\n\n if (zoomMode === 'fit-width') {\n const scale = availableWidth / viewport.width;\n _setZoomLevel(scale);\n } else if (zoomMode === 'fit-page') {\n const scaleW = availableWidth / viewport.width;\n const scaleH = containerHeight / viewport.height;\n _setZoomLevel(Math.min(scaleW, scaleH));\n }\n });\n };\n\n computeFitZoom();\n\n const resizeObserver = new ResizeObserver(() => {\n computeFitZoom();\n });\n resizeObserver.observe(containerRef.current);\n\n return () => resizeObserver.disconnect();\n }, [zoomMode, pdfDoc, _setZoomLevel, viewMode]);\n\n // Hand tool: drag-to-scroll\n const isDraggingRef = useRef(false);\n const dragStartRef = useRef({ x: 0, y: 0, scrollLeft: 0, scrollTop: 0 });\n\n const handleMouseDown = useCallback((e: React.MouseEvent) => {\n if (cursorMode !== 'hand') return;\n const container = containerRef.current;\n if (!container) return;\n isDraggingRef.current = true;\n dragStartRef.current = {\n x: e.clientX,\n y: e.clientY,\n scrollLeft: container.scrollLeft,\n scrollTop: container.scrollTop,\n };\n container.style.cursor = 'grabbing';\n e.preventDefault();\n }, [cursorMode]);\n\n useEffect(() => {\n if (cursorMode !== 'hand') return;\n const container = containerRef.current;\n if (!container) return;\n\n const handleMouseMove = (e: MouseEvent) => {\n if (!isDraggingRef.current) return;\n const dx = e.clientX - dragStartRef.current.x;\n const dy = e.clientY - dragStartRef.current.y;\n container.scrollLeft = dragStartRef.current.scrollLeft - dx;\n container.scrollTop = dragStartRef.current.scrollTop - dy;\n };\n\n const handleMouseUp = () => {\n isDraggingRef.current = false;\n container.style.cursor = '';\n };\n\n container.addEventListener('mousemove', handleMouseMove);\n container.addEventListener('mouseup', handleMouseUp);\n container.addEventListener('mouseleave', handleMouseUp);\n\n return () => {\n container.removeEventListener('mousemove', handleMouseMove);\n container.removeEventListener('mouseup', handleMouseUp);\n container.removeEventListener('mouseleave', handleMouseUp);\n };\n }, [cursorMode]);\n\n // Touch gestures: pinch-to-zoom and swipe-to-change-page\n const touchStateRef = useRef<{\n startDistance: number;\n startZoom: number;\n startX: number;\n startY: number;\n startTime: number;\n isPinching: boolean;\n lastScale: number;\n // Pinch center relative to container viewport\n centerX: number;\n centerY: number;\n // Scroll position at pinch start\n scrollLeft: number;\n scrollTop: number;\n } | null>(null);\n // Store latest zoomLevel in a ref so touch handlers don't need it as a dep\n const zoomLevelRef = useRef(zoomLevel);\n zoomLevelRef.current = zoomLevel;\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const getDistance = (t1: Touch, t2: Touch) =>\n Math.hypot(t2.clientX - t1.clientX, t2.clientY - t1.clientY);\n\n const getMidpoint = (t1: Touch, t2: Touch) => ({\n x: (t1.clientX + t2.clientX) / 2,\n y: (t1.clientY + t2.clientY) / 2,\n });\n\n const handleTouchStart = (e: TouchEvent) => {\n if (e.touches.length === 2) {\n e.preventDefault();\n const dist = getDistance(e.touches[0], e.touches[1]);\n const mid = getMidpoint(e.touches[0], e.touches[1]);\n const rect = container.getBoundingClientRect();\n touchStateRef.current = {\n startDistance: dist,\n startZoom: zoomLevelRef.current,\n startX: 0,\n startY: 0,\n startTime: 0,\n isPinching: true,\n lastScale: zoomLevelRef.current,\n centerX: mid.x - rect.left,\n centerY: mid.y - rect.top,\n scrollLeft: container.scrollLeft,\n scrollTop: container.scrollTop,\n };\n } else if (e.touches.length === 1) {\n touchStateRef.current = {\n startDistance: 0,\n startZoom: zoomLevelRef.current,\n startX: e.touches[0].clientX,\n startY: e.touches[0].clientY,\n startTime: Date.now(),\n isPinching: false,\n lastScale: zoomLevelRef.current,\n centerX: 0,\n centerY: 0,\n scrollLeft: 0,\n scrollTop: 0,\n };\n }\n };\n\n const handleTouchMove = (e: TouchEvent) => {\n if (!touchStateRef.current) return;\n\n if (e.touches.length === 2 && touchStateRef.current.isPinching) {\n e.preventDefault();\n const dist = getDistance(e.touches[0], e.touches[1]);\n const scale = dist / touchStateRef.current.startDistance;\n const clamped = Math.max(0.25, Math.min(4, touchStateRef.current.startZoom * scale));\n const visualScale = clamped / touchStateRef.current.startZoom;\n touchStateRef.current.lastScale = clamped;\n // CSS transform for instant visual feedback — no re-render\n container.style.transformOrigin = `${touchStateRef.current.centerX}px ${touchStateRef.current.centerY}px`;\n container.style.transform = `scale(${visualScale})`;\n }\n };\n\n const handleTouchEnd = (e: TouchEvent) => {\n if (!touchStateRef.current) return;\n\n if (touchStateRef.current.isPinching) {\n const { startZoom, lastScale, centerX, centerY, scrollLeft, scrollTop } = touchStateRef.current;\n // Remove CSS transform\n container.style.transform = '';\n container.style.transformOrigin = '';\n touchStateRef.current = null;\n\n // Calculate scroll position to keep pinch center in same place\n const zoomRatio = lastScale / startZoom;\n const contentX = scrollLeft + centerX;\n const contentY = scrollTop + centerY;\n const newScrollLeft = contentX * zoomRatio - centerX;\n const newScrollTop = contentY * zoomRatio - centerY;\n\n // Temporarily lock scroll tracking during zoom transition\n navigatingRef.current = true;\n zoomTo(lastScale);\n // Wait for React to re-render pages at new size, then set scroll\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n container.scrollLeft = Math.max(0, newScrollLeft);\n container.scrollTop = Math.max(0, newScrollTop);\n navigatingRef.current = false;\n });\n });\n return;\n }\n\n touchStateRef.current = null;\n };\n\n container.addEventListener('touchstart', handleTouchStart, { passive: false });\n container.addEventListener('touchmove', handleTouchMove, { passive: false });\n container.addEventListener('touchend', handleTouchEnd);\n\n return () => {\n container.removeEventListener('touchstart', handleTouchStart);\n container.removeEventListener('touchmove', handleTouchMove);\n container.removeEventListener('touchend', handleTouchEnd);\n };\n }, [zoomTo, scrollMode]);\n\n const isPageScroll = scrollMode === 'page';\n\n const shouldRenderPage = (pageNum: number): boolean => {\n if (isPrinting) return true;\n if (isPageScroll) {\n // In page scroll mode, render current page and neighbors for fast switching\n return Math.abs(pageNum - currentPage) <= VIRTUALIZATION_BUFFER;\n }\n // renderGeneration ensures we re-render when this set changes\n void renderGeneration;\n return lastRenderSetRef.current.has(pageNum);\n };\n\n const classNames = [\n 'pdf-viewer__pages',\n `pdf-viewer__pages--scroll-${scrollMode}`,\n viewMode === 'dual' && 'pdf-viewer__pages--dual',\n cursorMode === 'hand' && 'pdf-viewer__pages--hand',\n className,\n ].filter(Boolean).join(' ');\n\n const renderPageWrapper = (pageNum: number) => {\n const isActive = isPageScroll && pageNum === currentPage;\n const wrapperClass = [\n 'pdf-viewer__page-wrapper',\n isActive && 'pdf-viewer__page-wrapper--active',\n ].filter(Boolean).join(' ');\n\n return (\n <div\n key={pageNum}\n className={wrapperClass}\n data-page-number={pageNum}\n >\n {shouldRenderPage(pageNum) ? (\n <Page pageNumber={pageNum} />\n ) : (\n <div\n className=\"pdf-viewer__page-placeholder\"\n style={baseDims ? {\n width: `${baseDims.width * zoomLevel}px`,\n height: `${baseDims.height * zoomLevel}px`,\n } : undefined}\n />\n )}\n </div>\n );\n };\n\n const renderContent = () => {\n const pages = Array.from({ length: totalPages }, (_, i) => i + 1);\n\n if (viewMode === 'dual') {\n const pairs: number[][] = [];\n for (let i = 0; i < pages.length; i += 2) {\n pairs.push(pages.slice(i, i + 2));\n }\n return pairs.map((pair) => {\n const isActive = isPageScroll && pair.includes(currentPage);\n const pairClass = [\n 'pdf-viewer__page-pair',\n isActive && 'pdf-viewer__page-pair--active',\n ].filter(Boolean).join(' ');\n return (\n <div key={pair[0]} className={pairClass}>\n {pair.map(renderPageWrapper)}\n </div>\n );\n });\n }\n\n return pages.map(renderPageWrapper);\n };\n\n return (\n <div ref={containerRef} className={classNames} onMouseDown={handleMouseDown}>\n {renderContent()}\n </div>\n );\n}\n","import { useEffect, useRef, useCallback } from 'react';\nimport { usePdfViewerContext } from '../context';\n\nexport interface PageProps {\n pageNumber: number;\n className?: string;\n}\n\nexport function Page({ pageNumber, className }: PageProps) {\n const { document, zoomLevel, rotation, searchQuery, searchMatches, currentMatchIndex } = usePdfViewerContext();\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const textLayerRef = useRef<HTMLDivElement>(null);\n const renderTaskRef = useRef<{ cancel: () => void } | null>(null);\n const applyHighlightsRef = useRef<(() => void) | null>(null);\n\n const renderPage = useCallback(async () => {\n if (!document || !canvasRef.current) return;\n\n // Cancel any previous render\n if (renderTaskRef.current) {\n renderTaskRef.current.cancel();\n renderTaskRef.current = null;\n }\n\n try {\n const page = await document.getPage(pageNumber);\n const viewport = page.getViewport({ scale: zoomLevel, rotation });\n const canvas = canvasRef.current;\n const context = canvas.getContext('2d');\n if (!context) return;\n\n const dpr = window.devicePixelRatio || 1;\n canvas.width = viewport.width * dpr;\n canvas.height = viewport.height * dpr;\n canvas.style.width = `${viewport.width}px`;\n canvas.style.height = `${viewport.height}px`;\n context.scale(dpr, dpr);\n\n const renderTask = page.render({\n canvasContext: context,\n viewport,\n });\n\n renderTaskRef.current = renderTask;\n\n await renderTask.promise;\n\n // Render text layer\n if (textLayerRef.current) {\n const textLayerDiv = textLayerRef.current;\n textLayerDiv.innerHTML = '';\n // pdf.js v4 TextLayer uses --scale-factor CSS variable for dimensions\n textLayerDiv.style.setProperty('--scale-factor', String(viewport.scale));\n\n const textContent = await page.getTextContent();\n const { TextLayer } = await import('pdfjs-dist');\n\n const textLayer = new TextLayer({\n textContentSource: textContent,\n container: textLayerDiv,\n viewport,\n });\n await textLayer.render();\n // Re-apply search highlights after text layer is ready\n requestAnimationFrame(() => applyHighlightsRef.current?.());\n }\n } catch (err: unknown) {\n // Ignore cancelled render errors\n if (err && typeof err === 'object' && 'name' in err && (err as { name: string }).name === 'RenderingCancelledException') return;\n }\n }, [document, pageNumber, zoomLevel, rotation]);\n\n // Highlight search matches by wrapping matched substrings in <mark> elements\n const applyHighlights = useCallback(() => {\n const textLayer = textLayerRef.current;\n if (!textLayer) return;\n\n // Clear previous highlights — restore original text nodes\n textLayer.querySelectorAll('mark.pdf-viewer__search-hit').forEach((mark) => {\n const parent = mark.parentNode;\n if (parent) {\n parent.replaceChild(window.document.createTextNode(mark.textContent || ''), mark);\n parent.normalize(); // merge adjacent text nodes\n }\n });\n\n if (!searchQuery || searchMatches.length === 0) return;\n\n const pageMatches = searchMatches.filter((m) => m.pageIndex === pageNumber - 1);\n if (pageMatches.length === 0) return;\n\n const lowerQuery = searchQuery.toLowerCase();\n const queryLen = searchQuery.length;\n const spans = Array.from(textLayer.querySelectorAll('span'));\n\n let pageMatchIdx = 0;\n for (const span of spans) {\n const text = span.textContent || '';\n const lowerText = text.toLowerCase();\n let idx = lowerText.indexOf(lowerQuery);\n if (idx === -1) continue;\n\n // Build fragments: text before match, <mark>match</mark>, text after, repeat\n const frag = window.document.createDocumentFragment();\n let lastIdx = 0;\n\n while (idx !== -1) {\n // Text before match\n if (idx > lastIdx) {\n frag.appendChild(window.document.createTextNode(text.slice(lastIdx, idx)));\n }\n\n // The match itself\n const mark = window.document.createElement('mark');\n mark.className = 'pdf-viewer__search-hit';\n mark.textContent = text.slice(idx, idx + queryLen);\n\n // Check if this is the current active match\n if (pageMatchIdx < pageMatches.length) {\n const globalIdx = searchMatches.indexOf(pageMatches[pageMatchIdx]);\n if (globalIdx === currentMatchIndex) {\n mark.classList.add('pdf-viewer__search-hit--current');\n }\n }\n pageMatchIdx++;\n\n frag.appendChild(mark);\n lastIdx = idx + queryLen;\n idx = lowerText.indexOf(lowerQuery, lastIdx);\n }\n\n // Remaining text after last match\n if (lastIdx < text.length) {\n frag.appendChild(window.document.createTextNode(text.slice(lastIdx)));\n }\n\n span.textContent = '';\n span.appendChild(frag);\n }\n }, [searchQuery, searchMatches, currentMatchIndex, pageNumber]);\n\n // Keep ref in sync for use by renderPage callback\n applyHighlightsRef.current = applyHighlights;\n\n // Re-apply highlights when search state changes\n useEffect(() => {\n applyHighlights();\n }, [applyHighlights]);\n\n useEffect(() => {\n renderPage();\n return () => {\n if (renderTaskRef.current) {\n renderTaskRef.current.cancel();\n renderTaskRef.current = null;\n }\n };\n }, [renderPage]);\n\n const classNames = ['pdf-viewer__page', className].filter(Boolean).join(' ');\n\n return (\n <div className={classNames} data-page-number={pageNumber}>\n <canvas ref={canvasRef} className=\"pdf-viewer__page-canvas\" />\n <div ref={textLayerRef} className=\"pdf-viewer__page-text-layer\" />\n </div>\n );\n}\n","import { usePdfViewerContext } from '../context';\nimport { DropdownMenu, DropdownMenuItem, DropdownMenuSeparator } from './DropdownMenu';\nimport {\n ArrowDownToLine,\n RotateCw,\n RotateCcw,\n StickyNote,\n Columns2,\n GalleryThumbnails,\n GalleryVertical,\n GalleryHorizontal,\n Info,\n EllipsisVertical,\n Download as DownloadIcon,\n Printer,\n Maximize,\n} from '../icons';\n\nexport interface MoreMenuProps {\n className?: string;\n}\n\nexport function MoreMenu({ className }: MoreMenuProps) {\n const {\n currentPage,\n totalPages,\n rotate,\n viewMode,\n scrollMode,\n setViewMode,\n setScrollMode,\n goToFirstPage,\n goToLastPage,\n openDocProperties,\n download,\n print,\n toggleFullScreen,\n } = usePdfViewerContext();\n\n return (\n <DropdownMenu trigger={<EllipsisVertical />} className={className} align=\"right\">\n <div className=\"pdf-viewer__show-mobile\">\n <DropdownMenuItem\n icon={<DownloadIcon />}\n label=\"Download\"\n onClick={() => download()}\n />\n <DropdownMenuItem\n icon={<Printer />}\n label=\"Print\"\n onClick={print}\n />\n <DropdownMenuItem\n icon={<Maximize />}\n label=\"Full Screen\"\n onClick={toggleFullScreen}\n />\n <DropdownMenuSeparator />\n </div>\n <DropdownMenuItem\n icon={<ArrowDownToLine style={{ transform: 'rotate(180deg)' }} />}\n label=\"First Page\"\n onClick={goToFirstPage}\n disabled={currentPage <= 1}\n />\n <DropdownMenuItem\n icon={<ArrowDownToLine />}\n label=\"Last Page\"\n onClick={goToLastPage}\n disabled={currentPage >= totalPages}\n />\n <DropdownMenuSeparator />\n <DropdownMenuItem\n icon={<RotateCw />}\n label=\"Rotate Clockwise\"\n onClick={() => rotate(90)}\n />\n <DropdownMenuItem\n icon={<RotateCcw />}\n label=\"Rotate Counterclockwise\"\n onClick={() => rotate(-90)}\n />\n <DropdownMenuSeparator />\n <DropdownMenuItem\n icon={<StickyNote />}\n label=\"Single Page\"\n onClick={() => setViewMode('single')}\n active={viewMode === 'single'}\n />\n <DropdownMenuItem\n icon={<Columns2 />}\n label=\"Dual Page\"\n onClick={() => setViewMode('dual')}\n active={viewMode === 'dual'}\n disabled={scrollMode === 'horizontal'}\n />\n <DropdownMenuSeparator />\n <DropdownMenuItem\n icon={<GalleryThumbnails />}\n label=\"Page Scrolling\"\n onClick={() => setScrollMode('page')}\n active={scrollMode === 'page'}\n />\n <DropdownMenuItem\n icon={<GalleryVertical />}\n label=\"Vertical Scrolling\"\n onClick={() => setScrollMode('vertical')}\n active={scrollMode === 'vertical'}\n />\n <DropdownMenuItem\n icon={<GalleryHorizontal />}\n label=\"Horizontal Scrolling\"\n onClick={() => setScrollMode('horizontal')}\n active={scrollMode === 'horizontal'}\n disabled={viewMode === 'dual'}\n />\n <DropdownMenuSeparator />\n <DropdownMenuItem\n icon={<Info />}\n label=\"Document Properties\"\n onClick={openDocProperties}\n />\n </DropdownMenu>\n );\n}\n","import { useEffect, useRef } from 'react';\nimport { usePdfViewerContext } from '../context';\nimport { X } from '../icons';\n\nexport function DocumentPropertiesModal() {\n const { isDocPropertiesOpen, docProperties, closeDocProperties } = usePdfViewerContext();\n const backdropRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!isDocPropertiesOpen) return;\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape') closeDocProperties();\n };\n window.document.addEventListener('keydown', handleEscape);\n return () => window.document.removeEventListener('keydown', handleEscape);\n }, [isDocPropertiesOpen, closeDocProperties]);\n\n if (!isDocPropertiesOpen || !docProperties) return null;\n\n const rows: [string, string][] = [\n ['Title', docProperties.title],\n ['Author', docProperties.author],\n ['Subject', docProperties.subject],\n ['Creator', docProperties.creator],\n ['Producer', docProperties.producer],\n ['Created', docProperties.creationDate],\n ['Modified', docProperties.modificationDate],\n ['Pages', String(docProperties.pageCount)],\n ['Page Size', docProperties.pageSize],\n ];\n\n return (\n <div\n ref={backdropRef}\n className=\"pdf-viewer__modal-backdrop\"\n onClick={(e) => {\n if (e.target === backdropRef.current) closeDocProperties();\n }}\n >\n <div className=\"pdf-viewer__modal\" role=\"dialog\" aria-label=\"Document Properties\">\n <div className=\"pdf-viewer__modal-header\">\n <h2 className=\"pdf-viewer__modal-title\">Document Properties</h2>\n <button className=\"pdf-viewer__btn\" onClick={closeDocProperties} aria-label=\"Close\" title=\"Close\">\n <X />\n </button>\n </div>\n <div className=\"pdf-viewer__modal-body\">\n <div className=\"pdf-viewer__props-file-info\">\n <span className=\"pdf-viewer__props-file-name\">{docProperties.fileName}</span>\n <span className=\"pdf-viewer__props-file-size\">{docProperties.fileSize}</span>\n </div>\n <table className=\"pdf-viewer__props-table\">\n <tbody>\n {rows.map(([label, value]) => (\n <tr key={label}>\n <td className=\"pdf-viewer__props-label\">{label}</td>\n <td className=\"pdf-viewer__props-value\">{value}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n </div>\n );\n}\n","import { Root } from './Root';\nimport { Toolbar } from './Toolbar';\nimport { Navigation } from './Navigation';\nimport { Zoom } from './Zoom';\nimport { Search } from './Search';\nimport { Separator } from './Separator';\nimport { Rotate } from './Rotate';\nimport { Download } from './Download';\nimport { Print } from './Print';\nimport { FullScreen } from './FullScreen';\nimport { ThumbnailToggle } from './ThumbnailToggle';\nimport { CursorModeToggle } from './CursorModeToggle';\nimport { ThumbnailSidebar } from './ThumbnailSidebar';\nimport { Pages } from './Pages';\nimport { Page } from './Page';\nimport { MoreMenu } from './MoreMenu';\nimport { DropdownMenu, DropdownMenuItem, DropdownMenuSeparator } from './DropdownMenu';\nimport { DocumentPropertiesModal } from './DocumentPropertiesModal';\nimport type { PdfViewerProps } from '../types';\n\nexport function PdfViewer(props: PdfViewerProps) {\n const { className, ...rootProps } = props;\n\n return (\n <Root className={className} {...rootProps}>\n <Toolbar>\n <Navigation />\n <Separator />\n <Zoom />\n <ThumbnailToggle />\n <div className=\"pdf-viewer__toolbar-extras\">\n <Separator />\n <Search />\n <Separator />\n <Rotate />\n <Download />\n <Print />\n <FullScreen />\n <CursorModeToggle />\n </div>\n <MoreMenu />\n </Toolbar>\n <div className=\"pdf-viewer__body\">\n <ThumbnailSidebar />\n <Pages />\n </div>\n <DocumentPropertiesModal />\n </Root>\n );\n}\n\n// Attach compound components\nPdfViewer.Root = Root;\nPdfViewer.Toolbar = Toolbar;\nPdfViewer.Navigation = Navigation;\nPdfViewer.Zoom = Zoom;\nPdfViewer.Search = Search;\nPdfViewer.Separator = Separator;\nPdfViewer.Rotate = Rotate;\nPdfViewer.Download = Download;\nPdfViewer.Print = Print;\nPdfViewer.FullScreen = FullScreen;\nPdfViewer.ThumbnailToggle = ThumbnailToggle;\nPdfViewer.ThumbnailSidebar = ThumbnailSidebar;\nPdfViewer.Pages = Pages;\nPdfViewer.Page = Page;\nPdfViewer.CursorModeToggle = CursorModeToggle;\nPdfViewer.MoreMenu = MoreMenu;\nPdfViewer.DropdownMenu = DropdownMenu;\nPdfViewer.DropdownMenuItem = DropdownMenuItem;\nPdfViewer.DropdownMenuSeparator = DropdownMenuSeparator;\nPdfViewer.DocumentPropertiesModal = DocumentPropertiesModal;\n","import { usePdfViewerContext } from '../context';\n\nexport function usePdfViewer() {\n return usePdfViewerContext();\n}\n"],"mappings":"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","names":["useRef","useState","useRef","useRef","useState","value","container","canvases","useEffect","jsx","useRef","jsx","useState","useEffect","useCallback","jsx","jsx","jsx","jsx","jsx","jsxs","useState","useEffect","useCallback","useState","useRef","useEffect","useCallback","jsx","jsxs","useState","useRef","useCallback","useEffect","jsx","jsxs","useState","useCallback","useRef","useEffect","jsx","jsxs","useState","useRef","useCallback","useEffect","jsx","jsx","jsx","Download","jsx","jsx","jsx","jsx","useEffect","useRef","useState","useCallback","jsx","jsxs","useRef","useState","useCallback","useEffect","useCallback","useEffect","useRef","useState","useEffect","useRef","useCallback","jsx","jsxs","useRef","useCallback","useEffect","jsx","useRef","useState","useCallback","useEffect","jsx","jsxs","useEffect","useRef","jsx","jsxs","useRef","useEffect","jsx","jsxs","Download"]}
|