react-pdf-highlighter-plus 1.0.6 → 1.0.8
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/dist/esm/index.js.map +1 -1
- package/package.json +3 -3
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/PdfHighlighter.tsx","../../src/contexts/PdfHighlighterContext.ts","../../src/lib/coordinates.ts","../../src/lib/get-bounding-rect.ts","../../src/lib/optimize-client-rects.ts","../../src/lib/get-client-rects.ts","../../src/lib/group-highlights-by-page.ts","../../src/lib/pdfjs-dom.ts","../../src/components/DrawingCanvas.tsx","../../src/components/HighlightLayer.tsx","../../src/contexts/HighlightContext.ts","../../src/lib/screenshot.ts","../../src/components/MouseSelection.tsx","../../src/components/ShapeCanvas.tsx","../../src/components/TipContainer.tsx","../../src/components/TextHighlight.tsx","../../src/components/MonitoredHighlightContainer.tsx","../../src/components/MouseMonitor.tsx","../../src/components/AreaHighlight.tsx","../../src/components/FreetextHighlight.tsx","../../src/components/ImageHighlight.tsx","../../src/components/SignaturePad.tsx","../../src/components/DrawingHighlight.tsx","../../src/components/ShapeHighlight.tsx","../../src/components/PdfLoader.tsx","../../src/lib/export-pdf.ts"],"sourcesContent":["import debounce from \"lodash.debounce\";\nimport { PDFDocumentProxy } from \"pdfjs-dist\";\nimport React, {\n CSSProperties,\n PointerEventHandler,\n ReactNode,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport {\n PdfHighlighterContext,\n PdfHighlighterUtils,\n} from \"../contexts/PdfHighlighterContext\";\nimport { scaledToViewport, viewportPositionToScaled } from \"../lib/coordinates\";\nimport getBoundingRect from \"../lib/get-bounding-rect\";\nimport getClientRects from \"../lib/get-client-rects\";\nimport groupHighlightsByPage from \"../lib/group-highlights-by-page\";\nimport {\n asElement,\n findOrCreateContainerLayer,\n getPageFromElement,\n getPagesFromRange,\n getWindow,\n isHTMLElement,\n} from \"../lib/pdfjs-dom\";\nimport {\n Content,\n DrawingStroke,\n GhostHighlight,\n Highlight,\n HighlightBindings,\n PdfScaleValue,\n PdfSelection,\n ScaledPosition,\n ShapeData,\n ShapeType,\n Tip,\n ViewportPosition,\n} from \"../types\";\nimport { DrawingCanvas } from \"./DrawingCanvas\";\nimport { HighlightLayer } from \"./HighlightLayer\";\nimport { MouseSelection } from \"./MouseSelection\";\nimport { ShapeCanvas } from \"./ShapeCanvas\";\nimport { TipContainer } from \"./TipContainer\";\n\nimport type { EventBus as TEventBus, PDFLinkService as TPDFLinkService, PDFViewer as TPDFViewer } from \"pdfjs-dist/web/pdf_viewer.mjs\";\n\nlet EventBus: typeof TEventBus, PDFLinkService: typeof TPDFLinkService, PDFViewer: typeof TPDFViewer;\n\n(async () => {\n // Due to breaking changes in PDF.js 4.0.189. See issue #17228\n const pdfjs = await import(\"pdfjs-dist/web/pdf_viewer.mjs\");\n EventBus = pdfjs.EventBus;\n PDFLinkService = pdfjs.PDFLinkService;\n PDFViewer = pdfjs.PDFViewer;\n})();\n\n\nconst SCROLL_MARGIN = 10;\nconst DEFAULT_SCALE_VALUE = \"auto\";\nconst DEFAULT_TEXT_SELECTION_COLOR = \"rgba(153,193,218,255)\";\n\nconst findOrCreateHighlightLayer = (textLayer: HTMLElement) => {\n return findOrCreateContainerLayer(\n textLayer,\n \"PdfHighlighter__highlight-layer\",\n );\n};\n\nconst disableTextSelection = (viewer: InstanceType<typeof PDFViewer>, flag: boolean) => {\n viewer.viewer?.classList.toggle(\"PdfHighlighter--disable-selection\", flag);\n};\n\n/**\n * The props type for {@link PdfHighlighter}.\n *\n * @category Component Properties\n */\nexport interface PdfHighlighterProps {\n /**\n * Array of all highlights to be organised and fed through to the child\n * highlight container.\n */\n highlights: Array<Highlight>;\n\n /**\n * Event is called only once whenever the user changes scroll after\n * the autoscroll function, scrollToHighlight, has been called.\n */\n onScrollAway?(): void;\n\n /**\n * What scale to render the PDF at inside the viewer.\n */\n pdfScaleValue?: PdfScaleValue;\n\n /**\n * Callback triggered whenever a user finishes making a mouse selection or has\n * selected text.\n *\n * @param PdfSelection - Content and positioning of the selection. NOTE:\n * `makeGhostHighlight` will not work if the selection disappears.\n */\n onSelection?(PdfSelection: PdfSelection): void;\n\n /**\n * Callback triggered whenever a ghost (non-permanent) highlight is created.\n *\n * @param ghostHighlight - Ghost Highlight that has been created.\n */\n onCreateGhostHighlight?(ghostHighlight: GhostHighlight): void;\n\n /**\n * Callback triggered whenever a ghost (non-permanent) highlight is removed.\n *\n * @param ghostHighlight - Ghost Highlight that has been removed.\n */\n onRemoveGhostHighlight?(ghostHighlight: GhostHighlight): void;\n\n /**\n * Optional element that can be displayed as a tip whenever a user makes a\n * selection.\n */\n selectionTip?: ReactNode;\n\n /**\n * Condition to check before any mouse selection starts.\n *\n * @param event - mouse event associated with the new selection.\n * @returns - `True` if mouse selection should start.\n */\n enableAreaSelection?(event: MouseEvent): boolean;\n\n /**\n * When true, shows crosshair cursor indicating area selection mode is active.\n * Use this when area selection should be persistently enabled (not just on modifier key).\n */\n areaSelectionMode?: boolean;\n\n /**\n * Optional CSS styling for the rectangular mouse selection.\n */\n mouseSelectionStyle?: CSSProperties;\n\n /**\n * PDF document to view and overlay highlights.\n */\n pdfDocument: PDFDocumentProxy;\n\n /**\n * This should be a highlight container/renderer of some sorts. It will be\n * given appropriate context for a single highlight which it can then use to\n * render a TextHighlight, AreaHighlight, etc. in the correct place.\n */\n children: ReactNode;\n\n /**\n * Coloring for unhighlighted, selected text.\n */\n textSelectionColor?: string;\n\n /**\n * Creates a reference to the PdfHighlighterContext above the component.\n *\n * @param pdfHighlighterUtils - various useful tools with a PdfHighlighter.\n * See {@link PdfHighlighterContext} for more description.\n */\n utilsRef(pdfHighlighterUtils: PdfHighlighterUtils): void;\n\n /**\n * Style properties for the PdfHighlighter (scrollbar, background, etc.), NOT\n * the PDF.js viewer it encloses. If you want to edit the latter, use the\n * other style props like `textSelectionColor` or overwrite pdf_viewer.css\n */\n style?: CSSProperties;\n\n /**\n * Condition to check before freetext creation starts.\n *\n * @param event - mouse event associated with the click.\n * @returns - `True` if freetext creation should occur.\n */\n enableFreetextCreation?(event: MouseEvent): boolean;\n\n /**\n * Callback triggered when user clicks to create a freetext annotation.\n *\n * @param position - Scaled position where the click occurred.\n */\n onFreetextClick?(position: ScaledPosition): void;\n\n /**\n * Condition to check before image creation starts.\n *\n * @param event - mouse event associated with the click.\n * @returns - `True` if image creation should occur.\n */\n enableImageCreation?(event: MouseEvent): boolean;\n\n /**\n * Callback triggered when user clicks to create an image annotation.\n *\n * @param position - Scaled position where the click occurred.\n */\n onImageClick?(position: ScaledPosition): void;\n\n /**\n * Whether drawing mode is enabled.\n */\n enableDrawingMode?: boolean;\n\n /**\n * Callback triggered when a drawing is completed.\n *\n * @param dataUrl - The drawing as a PNG data URL.\n * @param position - Scaled position of the drawing on the page.\n * @param strokes - The stroke data for later editing.\n */\n onDrawingComplete?(dataUrl: string, position: ScaledPosition, strokes: DrawingStroke[]): void;\n\n /**\n * Callback triggered when drawing is cancelled.\n */\n onDrawingCancel?(): void;\n\n /**\n * Stroke color for drawing mode.\n * @default \"#000000\"\n */\n drawingStrokeColor?: string;\n\n /**\n * Stroke width for drawing mode.\n * @default 3\n */\n drawingStrokeWidth?: number;\n\n /**\n * The type of shape to create, or null if shape mode is not active.\n */\n enableShapeMode?: ShapeType | null;\n\n /**\n * Callback triggered when a shape is completed.\n *\n * @param position - Scaled position of the shape on the page.\n * @param shape - The shape data (type, color, width).\n */\n onShapeComplete?(position: ScaledPosition, shape: ShapeData): void;\n\n /**\n * Callback triggered when shape creation is cancelled.\n */\n onShapeCancel?(): void;\n\n /**\n * Stroke color for shape mode.\n * @default \"#000000\"\n */\n shapeStrokeColor?: string;\n\n /**\n * Stroke width for shape mode.\n * @default 2\n */\n shapeStrokeWidth?: number;\n}\n\n/**\n * This is a large-scale PDF viewer component designed to facilitate\n * highlighting. It should be used as a child to a {@link PdfLoader} to ensure\n * proper document loading. This does not itself render any highlights, but\n * instead its child should be the container component for each individual\n * highlight. This component will be provided appropriate HighlightContext for\n * rendering.\n *\n * @category Component\n */\nexport const PdfHighlighter = ({\n highlights,\n onScrollAway,\n pdfScaleValue = DEFAULT_SCALE_VALUE,\n onSelection: onSelectionFinished,\n onCreateGhostHighlight,\n onRemoveGhostHighlight,\n selectionTip,\n enableAreaSelection,\n areaSelectionMode,\n mouseSelectionStyle,\n pdfDocument,\n children,\n textSelectionColor = DEFAULT_TEXT_SELECTION_COLOR,\n utilsRef,\n style,\n enableFreetextCreation,\n onFreetextClick,\n enableImageCreation,\n onImageClick,\n enableDrawingMode,\n onDrawingComplete,\n onDrawingCancel,\n drawingStrokeColor = \"#000000\",\n drawingStrokeWidth = 3,\n enableShapeMode,\n onShapeComplete,\n onShapeCancel,\n shapeStrokeColor = \"#000000\",\n shapeStrokeWidth = 2,\n}: PdfHighlighterProps) => {\n // State\n const [tip, setTip] = useState<Tip | null>(null);\n const [isViewerReady, setIsViewerReady] = useState(false);\n\n // Refs\n const containerNodeRef = useRef<HTMLDivElement | null>(null);\n const highlightBindingsRef = useRef<{ [page: number]: HighlightBindings }>(\n {},\n );\n const ghostHighlightRef = useRef<GhostHighlight | null>(null);\n const selectionRef = useRef<PdfSelection | null>(null);\n const scrolledToHighlightIdRef = useRef<string | null>(null);\n const isAreaSelectionInProgressRef = useRef(false);\n const isEditInProgressRef = useRef(false);\n const updateTipPositionRef = useRef(() => { });\n\n const eventBusRef = useRef<InstanceType<typeof EventBus>>(new EventBus());\n const linkServiceRef = useRef<InstanceType<typeof PDFLinkService>>(\n new PDFLinkService({\n eventBus: eventBusRef.current,\n externalLinkTarget: 2,\n }),\n );\n const resizeObserverRef = useRef<ResizeObserver | null>(null);\n const viewerRef = useRef<InstanceType<typeof PDFViewer> | null>(null);\n\n // Initialise PDF Viewer\n useLayoutEffect(() => {\n if (!containerNodeRef.current) return;\n\n const debouncedDocumentInit = debounce(() => {\n viewerRef.current =\n viewerRef.current ||\n new PDFViewer({\n container: containerNodeRef.current!,\n eventBus: eventBusRef.current,\n textLayerMode: 2,\n removePageBorders: true,\n linkService: linkServiceRef.current,\n });\n\n viewerRef.current.setDocument(pdfDocument);\n linkServiceRef.current.setDocument(pdfDocument);\n linkServiceRef.current.setViewer(viewerRef.current);\n setIsViewerReady(true);\n }, 100);\n\n debouncedDocumentInit();\n\n return () => {\n debouncedDocumentInit.cancel();\n };\n }, [document]);\n\n // Initialise viewer event listeners\n useLayoutEffect(() => {\n if (!containerNodeRef.current) return;\n\n resizeObserverRef.current = new ResizeObserver(handleScaleValue);\n resizeObserverRef.current.observe(containerNodeRef.current);\n\n const doc = containerNodeRef.current.ownerDocument;\n\n eventBusRef.current.on(\"textlayerrendered\", renderHighlightLayers);\n eventBusRef.current.on(\"pagesinit\", handleScaleValue);\n doc.addEventListener(\"keydown\", handleKeyDown);\n\n renderHighlightLayers();\n\n return () => {\n eventBusRef.current.off(\"pagesinit\", handleScaleValue);\n eventBusRef.current.off(\"textlayerrendered\", renderHighlightLayers);\n doc.removeEventListener(\"keydown\", handleKeyDown);\n resizeObserverRef.current?.disconnect();\n };\n }, [selectionTip, highlights, onSelectionFinished]);\n\n // Event listeners\n const handleScroll = () => {\n onScrollAway && onScrollAway();\n scrolledToHighlightIdRef.current = null;\n renderHighlightLayers();\n };\n\n const handleMouseUp: PointerEventHandler = () => {\n const container = containerNodeRef.current;\n const selection = getWindow(container).getSelection();\n\n if (!container || !selection || selection.isCollapsed || !viewerRef.current)\n return;\n\n const range = selection.rangeCount > 0 ? selection.getRangeAt(0) : null;\n\n // Check the selected text is in the document, not the tip\n if (!range || !container.contains(range.commonAncestorContainer)) return;\n\n const pages = getPagesFromRange(range);\n if (!pages || pages.length === 0) return;\n\n const rects = getClientRects(range, pages);\n if (rects.length === 0) return;\n\n const viewportPosition: ViewportPosition = {\n boundingRect: getBoundingRect(rects),\n rects,\n };\n\n const scaledPosition = viewportPositionToScaled(\n viewportPosition,\n viewerRef.current,\n );\n\n const content: Content = {\n text: selection.toString().split(\"\\n\").join(\" \"), // Make all line breaks spaces\n };\n\n selectionRef.current = {\n content,\n type: \"text\",\n position: scaledPosition,\n makeGhostHighlight: () => {\n ghostHighlightRef.current = {\n content: content,\n type: \"text\",\n position: scaledPosition,\n };\n\n onCreateGhostHighlight &&\n onCreateGhostHighlight(ghostHighlightRef.current);\n clearTextSelection();\n renderHighlightLayers();\n return ghostHighlightRef.current;\n },\n };\n\n onSelectionFinished && onSelectionFinished(selectionRef.current);\n\n selectionTip &&\n setTip({ position: viewportPosition, content: selectionTip });\n };\n\n const handleMouseDown: PointerEventHandler = (event) => {\n if (\n !isHTMLElement(event.target) ||\n asElement(event.target).closest(\".PdfHighlighter__tip-container\") // Ignore selections on tip container\n ) {\n return;\n }\n\n // Check for freetext creation mode\n if (\n enableFreetextCreation?.(event.nativeEvent) &&\n onFreetextClick &&\n !isEditInProgressRef.current\n ) {\n const target = asElement(event.target);\n const page = getPageFromElement(target);\n\n if (page && viewerRef.current) {\n const pageRect = page.node.getBoundingClientRect();\n const clickX = event.clientX - pageRect.left;\n const clickY = event.clientY - pageRect.top;\n\n // Default size for new freetext note\n const defaultWidth = 150;\n const defaultHeight = 80;\n\n const viewportPosition: ViewportPosition = {\n boundingRect: {\n left: clickX,\n top: clickY,\n width: defaultWidth,\n height: defaultHeight,\n pageNumber: page.number,\n },\n rects: [],\n };\n\n const scaledPosition = viewportPositionToScaled(\n viewportPosition,\n viewerRef.current,\n );\n\n onFreetextClick(scaledPosition);\n return; // Don't proceed with normal mousedown handling\n }\n }\n\n // Check for image creation mode\n if (\n enableImageCreation?.(event.nativeEvent) &&\n onImageClick &&\n !isEditInProgressRef.current\n ) {\n const target = asElement(event.target);\n const page = getPageFromElement(target);\n\n if (page && viewerRef.current) {\n const pageRect = page.node.getBoundingClientRect();\n const clickX = event.clientX - pageRect.left;\n const clickY = event.clientY - pageRect.top;\n\n // Default size for new image\n const defaultWidth = 150;\n const defaultHeight = 100;\n\n const viewportPosition: ViewportPosition = {\n boundingRect: {\n left: clickX,\n top: clickY,\n width: defaultWidth,\n height: defaultHeight,\n pageNumber: page.number,\n },\n rects: [],\n };\n\n const scaledPosition = viewportPositionToScaled(\n viewportPosition,\n viewerRef.current,\n );\n\n onImageClick(scaledPosition);\n return; // Don't proceed with normal mousedown handling\n }\n }\n\n setTip(null);\n clearTextSelection(); // TODO: Check if clearing text selection only if not clicking on tip breaks anything.\n removeGhostHighlight();\n toggleEditInProgress(false);\n };\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.code === \"Escape\") {\n clearTextSelection();\n removeGhostHighlight();\n setTip(null);\n }\n };\n\n const handleScaleValue = () => {\n if (viewerRef.current) {\n viewerRef.current.currentScaleValue = pdfScaleValue.toString();\n }\n };\n\n // Render Highlight layers\n const renderHighlightLayer = (\n highlightBindings: HighlightBindings,\n pageNumber: number,\n ) => {\n if (!viewerRef.current) return;\n\n highlightBindings.reactRoot.render(\n <PdfHighlighterContext.Provider value={pdfHighlighterUtils}>\n <HighlightLayer\n highlightsByPage={groupHighlightsByPage([\n ...highlights,\n ghostHighlightRef.current,\n ])}\n pageNumber={pageNumber}\n scrolledToHighlightId={scrolledToHighlightIdRef.current}\n viewer={viewerRef.current}\n highlightBindings={highlightBindings}\n children={children}\n />\n </PdfHighlighterContext.Provider>,\n );\n };\n\n const renderHighlightLayers = () => {\n if (!viewerRef.current) return;\n\n for (let pageNumber = 1; pageNumber <= pdfDocument.numPages; pageNumber++) {\n const highlightBindings = highlightBindingsRef.current[pageNumber];\n\n // Need to check if container is still attached to the DOM as PDF.js can unload pages.\n if (highlightBindings?.container?.isConnected) {\n renderHighlightLayer(highlightBindings, pageNumber);\n } else {\n const { textLayer } =\n viewerRef.current!.getPageView(pageNumber - 1) || {};\n if (!textLayer) continue; // Viewer hasn't rendered page yet\n\n // textLayer.div for version >=3.0 and textLayer.textLayerDiv otherwise.\n const highlightLayer = findOrCreateHighlightLayer(\n textLayer.div,\n );\n\n if (highlightLayer) {\n const reactRoot = createRoot(highlightLayer);\n highlightBindingsRef.current[pageNumber] = {\n reactRoot,\n container: highlightLayer,\n textLayer: textLayer.div, // textLayer.div for version >=3.0 and textLayer.textLayerDiv otherwise.\n };\n\n renderHighlightLayer(\n highlightBindingsRef.current[pageNumber],\n pageNumber,\n );\n }\n }\n }\n };\n\n // Utils\n const isEditingOrHighlighting = () => {\n return (\n Boolean(selectionRef.current) ||\n Boolean(ghostHighlightRef.current) ||\n isAreaSelectionInProgressRef.current ||\n isEditInProgressRef.current\n );\n };\n\n const toggleEditInProgress = (flag?: boolean) => {\n if (flag !== undefined) {\n isEditInProgressRef.current = flag;\n } else {\n isEditInProgressRef.current = !isEditInProgressRef.current;\n }\n\n // Disable text selection\n if (viewerRef.current)\n viewerRef.current.viewer?.classList.toggle(\n \"PdfHighlighter--disable-selection\",\n isEditInProgressRef.current,\n );\n };\n\n const removeGhostHighlight = () => {\n if (onRemoveGhostHighlight && ghostHighlightRef.current)\n onRemoveGhostHighlight(ghostHighlightRef.current);\n ghostHighlightRef.current = null;\n renderHighlightLayers();\n };\n\n const clearTextSelection = () => {\n selectionRef.current = null;\n\n const container = containerNodeRef.current;\n const selection = getWindow(container).getSelection();\n if (!container || !selection) return;\n selection.removeAllRanges();\n };\n\n const scrollToHighlight = (highlight: Highlight) => {\n const { boundingRect, usePdfCoordinates } = highlight.position;\n const pageNumber = boundingRect.pageNumber;\n\n // Remove scroll listener in case user auto-scrolls in succession.\n viewerRef.current!.container.removeEventListener(\"scroll\", handleScroll);\n\n const pageViewport = viewerRef.current!.getPageView(\n pageNumber - 1,\n ).viewport;\n\n viewerRef.current!.scrollPageIntoView({\n pageNumber,\n destArray: [\n null, // null since we pass pageNumber already as an arg\n { name: \"XYZ\" },\n ...pageViewport.convertToPdfPoint(\n 0, // Default x coord\n scaledToViewport(boundingRect, pageViewport, usePdfCoordinates).top -\n SCROLL_MARGIN,\n ),\n 0, // Default z coord\n ],\n });\n\n scrolledToHighlightIdRef.current = highlight.id;\n renderHighlightLayers();\n\n // wait for scrolling to finish\n setTimeout(() => {\n viewerRef.current!.container.addEventListener(\"scroll\", handleScroll, {\n once: true,\n });\n }, 100);\n };\n\n const pdfHighlighterUtils: PdfHighlighterUtils = {\n isEditingOrHighlighting,\n getCurrentSelection: () => selectionRef.current,\n getGhostHighlight: () => ghostHighlightRef.current,\n removeGhostHighlight,\n toggleEditInProgress,\n isEditInProgress: () => isEditInProgressRef.current,\n isSelectionInProgress: () =>\n Boolean(selectionRef.current) || isAreaSelectionInProgressRef.current,\n scrollToHighlight,\n getViewer: () => viewerRef.current,\n getTip: () => tip,\n setTip,\n updateTipPosition: updateTipPositionRef.current,\n };\n\n utilsRef(pdfHighlighterUtils);\n\n // Check if freetext or image mode is active for cursor styling\n const isFreetextMode = enableFreetextCreation?.({} as MouseEvent) ?? false;\n const isImageMode = enableImageCreation?.({} as MouseEvent) ?? false;\n\n // Build class name based on active modes\n let containerClassName = 'PdfHighlighter';\n if (isFreetextMode) containerClassName += ' PdfHighlighter--freetext-mode';\n if (isImageMode) containerClassName += ' PdfHighlighter--image-mode';\n if (enableDrawingMode) containerClassName += ' PdfHighlighter--drawing-mode';\n if (enableShapeMode) containerClassName += ' PdfHighlighter--shape-mode';\n if (areaSelectionMode) containerClassName += ' PdfHighlighter--area-mode';\n\n return (\n <PdfHighlighterContext.Provider value={pdfHighlighterUtils}>\n <div\n ref={containerNodeRef}\n className={containerClassName}\n onPointerDown={handleMouseDown}\n onPointerUp={handleMouseUp}\n style={style}\n >\n <div className=\"pdfViewer\" />\n <style>\n {`\n .textLayer ::selection {\n background: ${textSelectionColor};\n }\n `}\n </style>\n {isViewerReady && (\n <TipContainer\n viewer={viewerRef.current!}\n updateTipPositionRef={updateTipPositionRef}\n />\n )}\n {isViewerReady && enableAreaSelection && (\n <MouseSelection\n viewer={viewerRef.current!}\n onChange={(isVisible) =>\n (isAreaSelectionInProgressRef.current = isVisible)\n }\n enableAreaSelection={enableAreaSelection}\n style={mouseSelectionStyle}\n onDragStart={() => disableTextSelection(viewerRef.current!, true)}\n onReset={() => {\n selectionRef.current = null;\n disableTextSelection(viewerRef.current!, false);\n }}\n onSelection={(\n viewportPosition,\n scaledPosition,\n image,\n resetSelection,\n ) => {\n selectionRef.current = {\n content: { image },\n type: \"area\",\n position: scaledPosition,\n makeGhostHighlight: () => {\n ghostHighlightRef.current = {\n position: scaledPosition,\n type: \"area\",\n content: { image },\n };\n onCreateGhostHighlight &&\n onCreateGhostHighlight(ghostHighlightRef.current);\n resetSelection();\n renderHighlightLayers();\n return ghostHighlightRef.current;\n },\n };\n\n onSelectionFinished && onSelectionFinished(selectionRef.current);\n selectionTip &&\n setTip({ position: viewportPosition, content: selectionTip });\n }}\n />\n )}\n {isViewerReady && enableDrawingMode && (\n <DrawingCanvas\n isActive={enableDrawingMode}\n strokeColor={drawingStrokeColor}\n strokeWidth={drawingStrokeWidth}\n viewer={viewerRef.current!}\n onComplete={(dataUrl, position, strokes) => {\n console.log(\"PdfHighlighter: Drawing complete\");\n onDrawingComplete?.(dataUrl, position, strokes);\n }}\n onCancel={() => {\n console.log(\"PdfHighlighter: Drawing cancelled\");\n onDrawingCancel?.();\n }}\n />\n )}\n {isViewerReady && enableShapeMode && (\n <ShapeCanvas\n isActive={!!enableShapeMode}\n shapeType={enableShapeMode}\n strokeColor={shapeStrokeColor}\n strokeWidth={shapeStrokeWidth}\n viewer={viewerRef.current!}\n onComplete={(position, shape) => {\n console.log(\"PdfHighlighter: Shape complete\", shape.shapeType);\n onShapeComplete?.(position, shape);\n }}\n onCancel={() => {\n console.log(\"PdfHighlighter: Shape cancelled\");\n onShapeCancel?.();\n }}\n />\n )}\n </div>\n </PdfHighlighterContext.Provider>\n );\n};\n","import { createContext, useContext } from \"react\";\nimport { GhostHighlight, Highlight, PdfSelection, Tip } from \"../types\";\nimport { PDFViewer } from \"pdfjs-dist/types/web/pdf_viewer\";\n\n/**\n * A set of utilities for to control the behaviour of {@link PdfHighlighter}.\n *\n * @category Context\n */\nexport type PdfHighlighterUtils = {\n /**\n * Checks whether a selection is progress, a ghost highlight, or an edit.\n *\n * @returns - `true` if editing, ghost highlighting, or selecting.\n */\n isEditingOrHighlighting(): boolean;\n\n /**\n * Get currently selected area or text selection.\n *\n * @returns - current selection or `null` if no selection is being made.\n */\n getCurrentSelection(): PdfSelection | null;\n\n /**\n * Get the currently present ghost highlight.\n *\n * @return - currently present ghost highlight or `null` if non-existent.\n */\n getGhostHighlight(): GhostHighlight | null;\n\n /**\n * Cancel any ghost highlight.\n * The selected area will stay selected until the user clicks away.\n */\n removeGhostHighlight(): void;\n /**\n * If enabled, automatic tips/popups inside of a PdfHighlighter will be disabled.\n * Additional niceties will also be provided to prevent new highlights being made.\n */\n toggleEditInProgress(flag?: boolean): void;\n\n /**\n * Whether an AreaHighlight is being moved/resized, or a manual highlight edit has\n * been toggled.\n *\n * @returns - `true` if AreaHighlight is being edited or edit mode was set.\n */\n isEditInProgress(): boolean;\n\n /**\n * Whether a mouse selection or text selection is currently being performed.\n *\n * @returns - `true` if mouse selection or text selection is being performed.\n */\n isSelectionInProgress(): boolean;\n\n /**\n * Scroll to a highlight in this viewer.\n *\n * @param highlight - A highlight provided to the {@link PdfHighlighter} to\n * scroll to.\n */\n scrollToHighlight(highlight: Highlight): void;\n\n /**\n * Get a reference to the currently used instance of a PDF Viewer.\n *\n * @returns - The currently active PDF Viewer.\n */\n getViewer(): PDFViewer | null;\n\n /**\n * Get the currently active tip, if any.\n *\n * @returns - the currently active tip or `null` if inactive.\n */\n getTip(): Tip | null;\n\n /**\n * Set a tip to be displayed in the current PDF Viewer.\n *\n * @param tip - tip to be displayed, or `null` to hide any tip.\n */\n setTip(tip: Tip | null): void;\n\n /**\n * Callback to update any currently active tip's position. This will make sure\n * the tip is visible above/below its highlight.\n */\n updateTipPosition(): void;\n};\n\nexport const PdfHighlighterContext = createContext<\n PdfHighlighterUtils | undefined\n>(undefined);\n\n/**\n * Custom hook for providing {@link PdfHighlighterUtils}. Must be used\n * within a child of {@link PdfHighlighter}.\n *\n * @category Context\n */\nexport const usePdfHighlighterContext = () => {\n const pdfHighlighterUtils = useContext(PdfHighlighterContext);\n\n if (pdfHighlighterUtils === undefined) {\n throw new Error(\n \"usePdfHighlighterContext must be used within PdfHighlighter!\",\n );\n }\n\n return pdfHighlighterUtils;\n};\n","import { PDFViewer } from \"pdfjs-dist/types/web/pdf_viewer\";\nimport type { LTWHP, ViewportPosition, Scaled, ScaledPosition } from \"../types\";\nimport { PageViewport } from \"pdfjs-dist\";\n\ninterface WIDTH_HEIGHT {\n width: number;\n height: number;\n}\n\n/** @category Utilities */\nexport const viewportToScaled = (\n rect: LTWHP,\n { width, height }: WIDTH_HEIGHT,\n): Scaled => {\n return {\n x1: rect.left,\n y1: rect.top,\n\n x2: rect.left + rect.width,\n y2: rect.top + rect.height,\n\n width,\n height,\n\n pageNumber: rect.pageNumber,\n };\n};\n\n/** @category Utilities */\nexport const viewportPositionToScaled = (\n { boundingRect, rects }: ViewportPosition,\n viewer: PDFViewer,\n): ScaledPosition => {\n const pageNumber = boundingRect.pageNumber;\n const viewport = viewer.getPageView(pageNumber - 1).viewport; // Account for 1 indexing of PDF documents\n const scale = (obj: LTWHP) => viewportToScaled(obj, viewport);\n\n return {\n boundingRect: scale(boundingRect),\n rects: (rects || []).map(scale),\n };\n};\n\nconst pdfToViewport = (pdf: Scaled, viewport: PageViewport): LTWHP => {\n const [x1, y1, x2, y2] = viewport.convertToViewportRectangle([\n pdf.x1,\n pdf.y1,\n pdf.x2,\n pdf.y2,\n ]);\n\n return {\n left: Math.min(x1, x2),\n top: Math.min(y1, y2),\n\n width: Math.abs(x2 - x1),\n height: Math.abs(y1 - y2),\n\n pageNumber: pdf.pageNumber,\n };\n};\n\n/** @category Utilities */\nexport const scaledToViewport = (\n scaled: Scaled,\n viewport: PageViewport,\n usePdfCoordinates: boolean = false,\n): LTWHP => {\n const { width, height } = viewport;\n\n if (usePdfCoordinates) {\n return pdfToViewport(scaled, viewport);\n }\n\n if (scaled.x1 === undefined) {\n throw new Error(\"You are using old position format, please update\");\n }\n\n const x1 = (width * scaled.x1) / scaled.width;\n const y1 = (height * scaled.y1) / scaled.height;\n\n const x2 = (width * scaled.x2) / scaled.width;\n const y2 = (height * scaled.y2) / scaled.height;\n\n return {\n left: x1,\n top: y1,\n width: x2 - x1,\n height: y2 - y1,\n pageNumber: scaled.pageNumber,\n };\n};\n\n/** @category Utilities */\nexport const scaledPositionToViewport = (\n { boundingRect, rects, usePdfCoordinates }: ScaledPosition,\n viewer: PDFViewer,\n): ViewportPosition => {\n const pageNumber = boundingRect.pageNumber;\n const viewport = viewer.getPageView(pageNumber - 1).viewport; // Account for 1 indexing of PDF documents\n const scale = (obj: Scaled) =>\n scaledToViewport(obj, viewport, usePdfCoordinates);\n\n return {\n boundingRect: scale(boundingRect),\n rects: (rects || []).map(scale),\n };\n};\n","import type { LTWHP } from \"../types\";\n\nconst getBoundingRect = (clientRects: Array<LTWHP>): LTWHP => {\n const rects = Array.from(clientRects).map((rect) => {\n const { left, top, width, height, pageNumber } = rect;\n\n const X0 = left;\n const X1 = left + width;\n\n const Y0 = top;\n const Y1 = top + height;\n\n return { X0, X1, Y0, Y1, pageNumber };\n });\n\n let firstPageNumber = Number.MAX_SAFE_INTEGER;\n\n rects.forEach((rect) => {\n firstPageNumber = Math.min(\n firstPageNumber,\n rect.pageNumber ?? firstPageNumber,\n );\n });\n\n const rectsWithSizeOnFirstPage = rects.filter(\n (rect) =>\n (rect.X0 > 0 || rect.X1 > 0 || rect.Y0 > 0 || rect.Y1 > 0) &&\n rect.pageNumber === firstPageNumber,\n );\n\n const optimal = rectsWithSizeOnFirstPage.reduce((res, rect) => {\n return {\n X0: Math.min(res.X0, rect.X0),\n X1: Math.max(res.X1, rect.X1),\n\n Y0: Math.min(res.Y0, rect.Y0),\n Y1: Math.max(res.Y1, rect.Y1),\n\n pageNumber: firstPageNumber,\n };\n }, rectsWithSizeOnFirstPage[0]);\n\n const { X0, X1, Y0, Y1, pageNumber } = optimal;\n\n return {\n left: X0,\n top: Y0,\n width: X1 - X0,\n height: Y1 - Y0,\n pageNumber,\n };\n};\n\nexport default getBoundingRect;\n","import type { LTWHP } from \"../types.js\";\n\nconst sort = (rects: Array<LTWHP>) =>\n rects.sort((A, B) => {\n const top = (A.pageNumber || 0) * A.top - (B.pageNumber || 0) * B.top;\n\n if (top === 0) {\n return A.left - B.left;\n }\n\n return top;\n });\n\nconst overlaps = (A: LTWHP, B: LTWHP) =>\n A.pageNumber === B.pageNumber &&\n A.left <= B.left &&\n B.left <= A.left + A.width;\n\nconst sameLine = (A: LTWHP, B: LTWHP, yMargin = 5) =>\n A.pageNumber === B.pageNumber &&\n Math.abs(A.top - B.top) < yMargin &&\n Math.abs(A.height - B.height) < yMargin;\n\nconst inside = (A: LTWHP, B: LTWHP) =>\n A.pageNumber === B.pageNumber &&\n A.top > B.top &&\n A.left > B.left &&\n A.top + A.height < B.top + B.height &&\n A.left + A.width < B.left + B.width;\n\nconst nextTo = (A: LTWHP, B: LTWHP, xMargin = 10) => {\n const Aright = A.left + A.width;\n const Bright = B.left + B.width;\n\n return (\n A.pageNumber === B.pageNumber &&\n A.left <= B.left &&\n Aright <= Bright &&\n B.left - Aright <= xMargin\n );\n};\n\nconst extendWidth = (A: LTWHP, B: LTWHP) => {\n // extend width of A to cover B\n A.width = Math.max(B.width - A.left + B.left, A.width);\n};\n\nconst optimizeClientRects = (clientRects: Array<LTWHP>): Array<LTWHP> => {\n const rects = sort(clientRects);\n\n const toRemove = new Set();\n\n const firstPass = rects.filter((rect) => {\n return rects.every((otherRect) => {\n return !inside(rect, otherRect);\n });\n });\n\n let passCount = 0;\n\n while (passCount <= 2) {\n firstPass.forEach((A) => {\n firstPass.forEach((B) => {\n if (A === B || toRemove.has(A) || toRemove.has(B)) {\n return;\n }\n\n if (!sameLine(A, B)) {\n return;\n }\n\n if (overlaps(A, B)) {\n extendWidth(A, B);\n A.height = Math.max(A.height, B.height);\n\n toRemove.add(B);\n }\n\n if (nextTo(A, B)) {\n extendWidth(A, B);\n\n toRemove.add(B);\n }\n });\n });\n passCount += 1;\n }\n\n return firstPass.filter((rect) => !toRemove.has(rect));\n};\n\nexport default optimizeClientRects;\n","import type { LTWHP, Page } from \"../types\";\n\nimport optimizeClientRects from \"./optimize-client-rects\";\n\nconst isClientRectInsidePageRect = (clientRect: DOMRect, pageRect: DOMRect) => {\n if (clientRect.top < pageRect.top) {\n return false;\n }\n if (clientRect.bottom > pageRect.bottom) {\n return false;\n }\n if (clientRect.right > pageRect.right) {\n return false;\n }\n if (clientRect.left < pageRect.left) {\n return false;\n }\n\n return true;\n};\n\nconst getClientRects = (\n range: Range,\n pages: Page[],\n shouldOptimize: boolean = true,\n): Array<LTWHP> => {\n const clientRects = Array.from(range.getClientRects());\n\n const rects: LTWHP[] = [];\n\n for (const clientRect of clientRects) {\n for (const page of pages) {\n const pageRect = page.node.getBoundingClientRect();\n\n if (\n isClientRectInsidePageRect(clientRect, pageRect) &&\n clientRect.width > 0 &&\n clientRect.height > 0 &&\n clientRect.width < pageRect.width &&\n clientRect.left > pageRect.left &&\n clientRect.height < pageRect.height\n ) {\n const highlightedRect = {\n top: clientRect.top + page.node.scrollTop - pageRect.top,\n left: clientRect.left + page.node.scrollLeft - pageRect.left,\n width: clientRect.width,\n height: clientRect.height,\n pageNumber: page.number,\n } as LTWHP;\n\n rects.push(highlightedRect);\n }\n }\n }\n\n return shouldOptimize ? optimizeClientRects(rects) : rects;\n};\n\nexport default getClientRects;\n","import { GhostHighlight, Highlight } from \"../types\";\n\ntype GroupedHighlights = {\n [pageNumber: number]: Array<Highlight | GhostHighlight>;\n};\n\nconst groupHighlightsByPage = (\n highlights: Array<Highlight | GhostHighlight | null>,\n): GroupedHighlights =>\n highlights.reduce<GroupedHighlights>((acc, highlight) => {\n if (!highlight) {\n return acc;\n }\n const pageNumbers = [\n highlight.position.boundingRect.pageNumber,\n ...highlight.position.rects.map((rect) => rect.pageNumber || 0),\n ];\n\n pageNumbers.forEach((pageNumber) => {\n acc[pageNumber] ||= [];\n const pageSpecificHighlight = {\n ...highlight,\n position: {\n ...highlight.position,\n rects: highlight.position.rects.filter(\n (rect) => pageNumber === rect.pageNumber,\n ),\n },\n };\n acc[pageNumber].push(pageSpecificHighlight);\n });\n\n return acc;\n }, {});\n\nexport default groupHighlightsByPage;\n","import { Page } from \"../types\";\n\nexport const getDocument = (elm: any): Document =>\n (elm || {}).ownerDocument || document;\n\nexport const getWindow = (elm: any): typeof window =>\n (getDocument(elm) || {}).defaultView || window;\n\nexport const isHTMLElement = (elm: any) =>\n elm instanceof HTMLElement || elm instanceof getWindow(elm).HTMLElement;\n\nexport const isHTMLCanvasElement = (elm: any) =>\n elm instanceof HTMLCanvasElement ||\n elm instanceof getWindow(elm).HTMLCanvasElement;\n\nexport const asElement = (x: any): HTMLElement => x;\n\nexport const getPageFromElement = (target: HTMLElement): Page | null => {\n const node = asElement(target.closest(\".page\"));\n\n if (!node || !isHTMLElement(node)) {\n return null;\n }\n\n const number = Number(asElement(node).dataset.pageNumber);\n\n return { node, number } as Page;\n};\n\nexport const getPagesFromRange = (range: Range): Page[] => {\n const startParentElement = range.startContainer.parentElement;\n const endParentElement = range.endContainer.parentElement;\n\n if (!isHTMLElement(startParentElement) || !isHTMLElement(endParentElement)) {\n return [] as Page[];\n }\n\n const startPage = getPageFromElement(asElement(startParentElement));\n const endPage = getPageFromElement(asElement(endParentElement));\n\n if (!startPage?.number || !endPage?.number) {\n return [] as Page[];\n }\n\n if (startPage.number === endPage.number) {\n return [startPage] as Page[];\n }\n\n if (startPage.number === endPage.number - 1) {\n return [startPage, endPage] as Page[];\n }\n\n const pages: Page[] = [];\n\n let currentPageNumber = startPage.number;\n\n const document = startPage.node.ownerDocument;\n\n while (currentPageNumber <= endPage.number) {\n const currentPage = getPageFromElement(\n document.querySelector(\n `[data-page-number='${currentPageNumber}'`,\n ) as HTMLElement,\n );\n if (currentPage) {\n pages.push(currentPage);\n }\n currentPageNumber++;\n }\n\n return pages as Page[];\n};\n\nexport const findOrCreateContainerLayer = (\n container: HTMLElement,\n className: string,\n) => {\n const doc = getDocument(container);\n let layer = container.querySelector(`.${className}`);\n\n // To ensure predictable zIndexing, wait until the pdfjs element has children.\n if (!layer && container.children.length) {\n layer = doc.createElement(\"div\");\n layer.className = className;\n container.appendChild(layer);\n }\n\n return layer;\n};\n","import React, {\n useRef,\n useEffect,\n useCallback,\n useState,\n MouseEvent as ReactMouseEvent,\n TouchEvent as ReactTouchEvent,\n} from \"react\";\nimport { viewportPositionToScaled } from \"../lib/coordinates\";\nimport { DrawingStroke, ScaledPosition, ViewportPosition } from \"../types\";\n\nimport type { PDFViewer as TPDFViewer } from \"pdfjs-dist/web/pdf_viewer.mjs\";\n\n/**\n * The props type for {@link DrawingCanvas}.\n *\n * @category Component Properties\n */\nexport interface DrawingCanvasProps {\n /**\n * Whether drawing mode is active.\n */\n isActive: boolean;\n\n /**\n * Stroke color for drawing.\n * @default \"#000000\"\n */\n strokeColor?: string;\n\n /**\n * Stroke width for drawing.\n * @default 3\n */\n strokeWidth?: number;\n\n /**\n * The PDF viewer instance.\n */\n viewer: InstanceType<typeof TPDFViewer>;\n\n /**\n * Callback when drawing is complete.\n *\n * @param dataUrl - The drawing as a PNG data URL.\n * @param position - Scaled position of the drawing on the page.\n * @param strokes - The stroke data for later editing.\n */\n onComplete: (dataUrl: string, position: ScaledPosition, strokes: DrawingStroke[]) => void;\n\n /**\n * Callback when drawing is cancelled.\n */\n onCancel: () => void;\n}\n\ninterface Point {\n x: number;\n y: number;\n}\n\ninterface Stroke {\n points: Point[];\n color: string;\n width: number;\n}\n\n/**\n * A transparent overlay canvas for freehand drawing on PDF pages.\n * Supports mouse and touch input.\n *\n * @category Component\n */\nexport const DrawingCanvas = ({\n isActive,\n strokeColor = \"#000000\",\n strokeWidth = 3,\n viewer,\n onComplete,\n onCancel,\n}: DrawingCanvasProps) => {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const [strokes, setStrokes] = useState<Stroke[]>([]);\n const [currentStroke, setCurrentStroke] = useState<Stroke | null>(null);\n const isDrawingRef = useRef(false);\n const [pageNumber, setPageNumber] = useState<number | null>(null);\n const [pageElement, setPageElement] = useState<HTMLElement | null>(null);\n\n // Find which page the user is drawing on\n const findPageFromPoint = useCallback(\n (clientX: number, clientY: number) => {\n if (!viewer) return null;\n\n for (let i = 0; i < viewer.pagesCount; i++) {\n const pageView = viewer.getPageView(i);\n if (!pageView?.div) continue;\n\n const rect = pageView.div.getBoundingClientRect();\n if (\n clientX >= rect.left &&\n clientX <= rect.right &&\n clientY >= rect.top &&\n clientY <= rect.bottom\n ) {\n return {\n pageNumber: i + 1,\n element: pageView.div as HTMLElement,\n rect,\n };\n }\n }\n return null;\n },\n [viewer]\n );\n\n // Redraw all strokes\n const redrawCanvas = useCallback(() => {\n const canvas = canvasRef.current;\n const ctx = canvas?.getContext(\"2d\");\n if (!ctx || !canvas) return;\n\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n // Draw all completed strokes with their own color/width\n strokes.forEach((stroke) => {\n if (stroke.points.length < 2) return;\n\n ctx.strokeStyle = stroke.color;\n ctx.lineWidth = stroke.width;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n\n ctx.beginPath();\n ctx.moveTo(stroke.points[0].x, stroke.points[0].y);\n stroke.points.slice(1).forEach((point) => {\n ctx.lineTo(point.x, point.y);\n });\n ctx.stroke();\n });\n\n // Draw current stroke with current color/width\n if (currentStroke && currentStroke.points.length >= 2) {\n ctx.strokeStyle = currentStroke.color;\n ctx.lineWidth = currentStroke.width;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n\n ctx.beginPath();\n ctx.moveTo(currentStroke.points[0].x, currentStroke.points[0].y);\n currentStroke.points.slice(1).forEach((point) => {\n ctx.lineTo(point.x, point.y);\n });\n ctx.stroke();\n }\n }, [strokes, currentStroke]);\n\n // Redraw when strokes change\n useEffect(() => {\n redrawCanvas();\n }, [redrawCanvas]);\n\n // Handle mouse/touch down\n const handleStart = useCallback(\n (clientX: number, clientY: number) => {\n const pageInfo = findPageFromPoint(clientX, clientY);\n if (!pageInfo) return;\n\n console.log(\"DrawingCanvas: Started drawing on page\", pageInfo.pageNumber);\n\n // Set page context if not already set\n if (pageNumber === null) {\n setPageNumber(pageInfo.pageNumber);\n setPageElement(pageInfo.element);\n\n // Resize canvas to match page\n const canvas = canvasRef.current;\n if (canvas) {\n canvas.width = pageInfo.rect.width;\n canvas.height = pageInfo.rect.height;\n canvas.style.left = `${pageInfo.rect.left}px`;\n canvas.style.top = `${pageInfo.rect.top}px`;\n }\n } else if (pageInfo.pageNumber !== pageNumber) {\n // User trying to draw on different page - ignore\n console.log(\"DrawingCanvas: Ignoring - different page\");\n return;\n }\n\n isDrawingRef.current = true;\n const pos = {\n x: clientX - pageInfo.rect.left,\n y: clientY - pageInfo.rect.top,\n };\n setCurrentStroke({ points: [pos], color: strokeColor, width: strokeWidth });\n },\n [pageNumber, findPageFromPoint, strokeColor, strokeWidth]\n );\n\n // Handle mouse/touch move\n const handleMove = useCallback(\n (clientX: number, clientY: number) => {\n if (!isDrawingRef.current || !pageElement) return;\n\n const rect = pageElement.getBoundingClientRect();\n const pos = {\n x: clientX - rect.left,\n y: clientY - rect.top,\n };\n\n setCurrentStroke((prev) => {\n if (!prev) return null;\n return { ...prev, points: [...prev.points, pos] };\n });\n },\n [pageElement]\n );\n\n // Handle mouse/touch end\n const handleEnd = useCallback(() => {\n if (!isDrawingRef.current) return;\n isDrawingRef.current = false;\n\n if (currentStroke && currentStroke.points.length >= 2) {\n setStrokes((prev) => [...prev, currentStroke]);\n }\n setCurrentStroke(null);\n }, [currentStroke]);\n\n // Mouse event handlers\n const handleMouseDown = useCallback(\n (e: ReactMouseEvent) => {\n e.preventDefault();\n handleStart(e.clientX, e.clientY);\n },\n [handleStart]\n );\n\n const handleMouseMove = useCallback(\n (e: ReactMouseEvent) => {\n handleMove(e.clientX, e.clientY);\n },\n [handleMove]\n );\n\n const handleMouseUp = useCallback(() => {\n handleEnd();\n }, [handleEnd]);\n\n // Touch event handlers\n const handleTouchStart = useCallback(\n (e: ReactTouchEvent) => {\n e.preventDefault();\n if (e.touches.length > 0) {\n handleStart(e.touches[0].clientX, e.touches[0].clientY);\n }\n },\n [handleStart]\n );\n\n const handleTouchMove = useCallback(\n (e: ReactTouchEvent) => {\n e.preventDefault();\n if (e.touches.length > 0) {\n handleMove(e.touches[0].clientX, e.touches[0].clientY);\n }\n },\n [handleMove]\n );\n\n const handleTouchEnd = useCallback(() => {\n handleEnd();\n }, [handleEnd]);\n\n // Handle keyboard events\n useEffect(() => {\n if (!isActive) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.code === \"Escape\") {\n console.log(\"DrawingCanvas: Cancelled via Escape\");\n onCancel();\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [isActive, onCancel]);\n\n // Clear drawing\n const handleClear = () => {\n console.log(\"DrawingCanvas: Cleared strokes\");\n setStrokes([]);\n setCurrentStroke(null);\n setPageNumber(null);\n setPageElement(null);\n };\n\n // Complete drawing\n const handleDone = () => {\n if (strokes.length === 0 || pageNumber === null || !pageElement || !viewer) {\n console.log(\"DrawingCanvas: No strokes to save\");\n onCancel();\n return;\n }\n\n console.log(\"DrawingCanvas: Completing drawing with\", strokes.length, \"strokes\");\n\n // Calculate bounding box of all strokes\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n\n strokes.forEach((stroke) => {\n stroke.points.forEach((point) => {\n minX = Math.min(minX, point.x);\n minY = Math.min(minY, point.y);\n maxX = Math.max(maxX, point.x);\n maxY = Math.max(maxY, point.y);\n });\n });\n\n // Find max stroke width for padding\n const maxStrokeWidth = Math.max(...strokes.map(s => s.width));\n const padding = maxStrokeWidth * 2;\n minX = Math.max(0, minX - padding);\n minY = Math.max(0, minY - padding);\n maxX = maxX + padding;\n maxY = maxY + padding;\n\n const width = maxX - minX;\n const height = maxY - minY;\n\n // Create a new canvas with just the drawing (cropped to bounding box)\n const outputCanvas = document.createElement(\"canvas\");\n outputCanvas.width = width;\n outputCanvas.height = height;\n const outputCtx = outputCanvas.getContext(\"2d\");\n\n if (!outputCtx) {\n console.error(\"DrawingCanvas: Could not get output canvas context\");\n onCancel();\n return;\n }\n\n // Draw all strokes offset by bounding box origin, using per-stroke color/width\n strokes.forEach((stroke) => {\n if (stroke.points.length < 2) return;\n\n outputCtx.strokeStyle = stroke.color;\n outputCtx.lineWidth = stroke.width;\n outputCtx.lineCap = \"round\";\n outputCtx.lineJoin = \"round\";\n\n outputCtx.beginPath();\n outputCtx.moveTo(stroke.points[0].x - minX, stroke.points[0].y - minY);\n stroke.points.slice(1).forEach((point) => {\n outputCtx.lineTo(point.x - minX, point.y - minY);\n });\n outputCtx.stroke();\n });\n\n const dataUrl = outputCanvas.toDataURL(\"image/png\");\n\n // Create viewport position\n const viewportPosition: ViewportPosition = {\n boundingRect: {\n left: minX,\n top: minY,\n width: width,\n height: height,\n pageNumber: pageNumber,\n },\n rects: [],\n };\n\n const scaledPosition = viewportPositionToScaled(viewportPosition, viewer);\n\n // Normalize strokes relative to bounding box for storage\n const normalizedStrokes: DrawingStroke[] = strokes.map((stroke) => ({\n ...stroke,\n points: stroke.points.map((point) => ({\n x: point.x - minX,\n y: point.y - minY,\n })),\n }));\n\n console.log(\"DrawingCanvas: Created drawing at position\", scaledPosition);\n onComplete(dataUrl, scaledPosition, normalizedStrokes);\n\n // Reset state\n setStrokes([]);\n setCurrentStroke(null);\n setPageNumber(null);\n setPageElement(null);\n };\n\n if (!isActive) return null;\n\n return (\n <>\n <canvas\n ref={canvasRef}\n className=\"DrawingCanvas\"\n style={{\n width: pageElement ? pageElement.getBoundingClientRect().width : \"100%\",\n height: pageElement ? pageElement.getBoundingClientRect().height : \"100%\",\n position: \"fixed\",\n }}\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n />\n <div className=\"DrawingCanvas__controls\">\n <button\n type=\"button\"\n className=\"DrawingCanvas__clearButton\"\n onClick={handleClear}\n >\n Clear\n </button>\n <button\n type=\"button\"\n className=\"DrawingCanvas__cancelButton\"\n onClick={onCancel}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"DrawingCanvas__doneButton\"\n onClick={handleDone}\n >\n Done\n </button>\n </div>\n </>\n );\n};\n","import { PDFViewer } from \"pdfjs-dist/types/web/pdf_viewer\";\nimport React, { ReactNode } from \"react\";\nimport {\n HighlightContainerUtils,\n HighlightContext,\n} from \"../contexts/HighlightContext\";\nimport { scaledPositionToViewport, viewportToScaled } from \"../lib/coordinates\";\nimport screenshot from \"../lib/screenshot\";\nimport {\n GhostHighlight,\n Highlight,\n HighlightBindings,\n LTWH,\n LTWHP,\n ViewportHighlight,\n} from \"../types\";\n\nconst EMPTY_ID = \"empty-id\";\n\n/**\n * The props type for {@link HighlightLayer}.\n *\n * @category Component Properties\n * @internal\n */\nexport interface HighlightLayerProps {\n /**\n * Highlights and GhostHighlights organised by page number.\n */\n highlightsByPage: { [pageNumber: number]: Array<Highlight | GhostHighlight> };\n\n /**\n * The page number of the PDF document to highlight (1 indexed).\n */\n pageNumber: number;\n\n /**\n * ID of the highlight that the parent PDF Highlighter is trying to autoscroll to.\n */\n scrolledToHighlightId?: string | null;\n\n /**\n * The PDFViewer instance containing the HighlightLayer\n */\n viewer: PDFViewer;\n\n /**\n * Group of DOM refs for all the highlights on this layer.\n */\n highlightBindings: HighlightBindings;\n\n /**\n * The Highlight container that should be used to render highlights for this layer.\n * It will be given appropriate context for a single highlight, allowing it to render\n * a single {@link TextHighlight}, {@link AreaHighlight}, etc., in the correct place.\n */\n children: ReactNode;\n}\n\n/**\n * A component responsible for managing all the highlights and ghost highlights\n * for a single page of a PDF document. It does not render each highlight\n * but it provides context for a highlight container to do so.\n * Its rendering should be controlled by a {@link PdfHighlighter}.\n *\n * @category Component\n * @internal\n */\nexport const HighlightLayer = ({\n highlightsByPage,\n pageNumber,\n scrolledToHighlightId,\n viewer,\n highlightBindings,\n children,\n}: HighlightLayerProps) => {\n const currentHighlights = highlightsByPage[pageNumber] || [];\n\n return (\n <div>\n {currentHighlights.map((highlight, index) => {\n const viewportHighlight: ViewportHighlight = {\n ...highlight,\n id: \"id\" in highlight ? highlight.id : EMPTY_ID, // Give Empty ID to GhostHighlight\n position: scaledPositionToViewport(highlight.position, viewer),\n };\n\n const isScrolledTo = Boolean(\n scrolledToHighlightId === viewportHighlight.id,\n );\n\n const highlightUtils: HighlightContainerUtils = {\n highlight: viewportHighlight,\n viewportToScaled: (rect: LTWHP) => {\n const viewport = viewer.getPageView(\n (rect.pageNumber || pageNumber) - 1, // Convert to 0 index\n ).viewport;\n\n return viewportToScaled(rect, viewport);\n },\n screenshot: (boundingRect: LTWH) =>\n screenshot(boundingRect, pageNumber, viewer),\n isScrolledTo: isScrolledTo,\n highlightBindings,\n };\n\n return (\n <HighlightContext.Provider value={highlightUtils} key={index}>\n {children}\n </HighlightContext.Provider>\n );\n })}\n </div>\n );\n};\n","import { createContext, useContext } from \"react\";\nimport {\n Highlight,\n HighlightBindings,\n LTWH,\n LTWHP,\n Scaled,\n ViewportHighlight,\n} from \"../types\";\n\n/**\n * A set of utilities for rendering highlights. Designed to be used within a\n * highlight container.\n *\n * @category Context\n */\nexport type HighlightContainerUtils<T extends Highlight = Highlight> = {\n /**\n * The highlight being rendered at this component.\n */\n highlight: ViewportHighlight<T>;\n\n /**\n * Convert a Viewport rectangle to a scaled rectangle. Can be used\n * for storing and updating area selection highlights, for example.\n *\n * @returns - Scaled/display agnostic rectangle.\n */\n viewportToScaled(rect: LTWHP): Scaled;\n\n /**\n * Capture a PNG data url of a viewport rectangle.\n *\n * @returns - PNG data url. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs\n */\n screenshot(position: LTWH): string;\n\n /**\n * Whether the highlight has been autoscrolled to.\n */\n isScrolledTo: boolean;\n\n /**\n * All the DOM refs for the highlights shared on the same page\n * as `highlight`\n */\n highlightBindings: HighlightBindings;\n};\n\nexport const HighlightContext = createContext<\n HighlightContainerUtils | undefined\n>(undefined);\n\n/**\n * Custom hook for providing {@link HighlightContainerUtils}. Must be used\n * within a child of {@link PdfHighlighter}.\n *\n * @category Context\n */\nexport const useHighlightContainerContext = <\n T extends Highlight = Highlight,\n>() => {\n const highlightContainerUtils = useContext(HighlightContext);\n\n if (highlightContainerUtils === undefined) {\n throw new Error(\n \"useHighlightContainerContext must be used within a child of PdfHighlighter!\",\n );\n }\n\n return highlightContainerUtils as HighlightContainerUtils<T>;\n};\n","import { PDFViewer } from \"pdfjs-dist/types/web/pdf_viewer\";\nimport type { LTWH } from \"../types\";\nimport { isHTMLCanvasElement } from \"./pdfjs-dom\";\n\nconst getAreaAsPng = (canvas: HTMLCanvasElement, position: LTWH): string => {\n const { left, top, width, height } = position;\n\n const doc = canvas ? canvas.ownerDocument : null;\n // @TODO: cache this?\n const newCanvas = doc && doc.createElement(\"canvas\");\n\n if (!newCanvas || !isHTMLCanvasElement(newCanvas)) {\n return \"\";\n }\n\n newCanvas.width = width;\n newCanvas.height = height;\n\n const newCanvasContext = newCanvas.getContext(\"2d\");\n\n if (!newCanvasContext || !canvas) {\n return \"\";\n }\n\n const dpr: number = window.devicePixelRatio;\n\n newCanvasContext.drawImage(\n canvas,\n left * dpr,\n top * dpr,\n width * dpr,\n height * dpr,\n 0,\n 0,\n width,\n height,\n );\n\n return newCanvas.toDataURL(\"image/png\");\n};\n\nconst screenshot = (position: LTWH, pageNumber: number, viewer: PDFViewer) => {\n return getAreaAsPng(viewer.getPageView(pageNumber - 1).canvas, position);\n};\n\nexport default screenshot;\n","import React, { CSSProperties, useEffect, useRef, useState } from \"react\";\n\nimport { asElement, getPageFromElement, isHTMLElement } from \"../lib/pdfjs-dom\";\n\nimport { PDFViewer } from \"pdfjs-dist/types/web/pdf_viewer\";\nimport { viewportPositionToScaled } from \"../lib/coordinates\";\nimport screenshot from \"../lib/screenshot\";\nimport type { LTWH, LTWHP, ScaledPosition, ViewportPosition } from \"../types\";\n\ntype Coords = {\n x: number;\n y: number;\n};\n\nconst getBoundingRect = (start: Coords, end: Coords): LTWH => {\n return {\n left: Math.min(end.x, start.x),\n top: Math.min(end.y, start.y),\n\n width: Math.abs(end.x - start.x),\n height: Math.abs(end.y - start.y),\n };\n};\n\nconst getContainerCoords = (\n container: HTMLElement,\n pageX: number,\n pageY: number,\n) => {\n const containerBoundingRect = container.getBoundingClientRect();\n return {\n x: pageX - containerBoundingRect.left + container.scrollLeft,\n y: pageY - containerBoundingRect.top + container.scrollTop - window.scrollY,\n };\n};\n\n/**\n * The props type for {@link MouseSelection}.\n *\n * @category Component Properties\n * @internal\n */\nexport interface MouseSelectionProps {\n /**\n * The PDFViewer instance containing this MouseSelection.\n */\n viewer: PDFViewer;\n\n /**\n * Callback triggered whenever the user stops dragging their mouse and a valid\n * mouse selection is made. In general, this will only be called if a mouse\n * selection is rendered.\n *\n * @param viewportPosition - viewport position of the mouse selection.\n * @param scaledPosition - scaled position of the mouse selection.\n * @param image - PNG screenshot of the mouse selection.\n * @param resetSelection - Callback to reset the current selection.\n * @param event - Mouse event associated with ending the selection.\n */\n onSelection?(\n viewportPosition: ViewportPosition,\n scaledPosition: ScaledPosition,\n image: string,\n resetSelection: () => void,\n event: MouseEvent,\n ): void;\n\n /**\n * Callback triggered whenever the current mouse selection is reset.\n * This includes when dragging ends but the selection is invalid.\n */\n onReset?(): void;\n\n /**\n * Callback triggered whenever a new valid mouse selection begins.\n *\n * @param event - mouse event associated with the new selection.\n */\n onDragStart?(event: MouseEvent): void;\n\n /**\n * Condition to check before any mouse selection starts.\n *\n * @param event - mouse event associated with the new selection.\n * @returns - `True` if mouse selection should start.\n */\n enableAreaSelection(event: MouseEvent): boolean;\n\n /**\n * Callback whenever the mouse selection area changes.\n *\n * @param isVisible - Whether the mouse selection is rendered (i.e., non-zero area)\n */\n onChange?(isVisible: boolean): void;\n\n /**\n * Optional style props for the mouse selection rectangle.\n */\n style?: CSSProperties;\n}\n\n/**\n * A component that enables the creation of rectangular and interactive mouse\n * selections within a given container. NOTE: This does not disable selection in\n * whatever container the component is placed in. That must be handled through\n * the component's events.\n *\n * @category Component\n * @internal\n */\nexport const MouseSelection = ({\n viewer,\n onSelection,\n onReset,\n onDragStart,\n enableAreaSelection,\n onChange,\n style,\n}: MouseSelectionProps) => {\n const [start, setStart] = useState<Coords | null>(null);\n const [end, setEnd] = useState<Coords | null>(null);\n const [locked, setLocked] = useState(false);\n const rootRef = useRef<HTMLDivElement | null>(null);\n\n // Needed in order to grab the page info of a mouse selection\n const startTargetRef = useRef<HTMLElement | null>(null);\n\n const reset = () => {\n onReset && onReset();\n setStart(null);\n setEnd(null);\n setLocked(false);\n };\n\n // Register event listeners onChange\n useEffect(() => {\n onChange && onChange(Boolean(start && end));\n if (!rootRef.current) return;\n\n // Should be the PdfHighlighter\n const container = asElement(rootRef.current.parentElement);\n\n const handleMouseUp = (event: MouseEvent) => {\n if (!start || !end || !startTargetRef.current) return;\n\n const boundingRect = getBoundingRect(start, end);\n\n // Check if the bounding rectangle has a minimum width and height\n // to prevent recording selections with 0 area\n const shouldEnd = boundingRect.width >= 1 && boundingRect.height >= 1;\n\n if (!container.contains(asElement(event.target)) || !shouldEnd) {\n reset();\n return;\n }\n\n setLocked(true);\n\n const page = getPageFromElement(startTargetRef.current);\n if (!page) return;\n\n const pageBoundingRect: LTWHP = {\n ...boundingRect,\n top: boundingRect.top - page.node.offsetTop,\n left: boundingRect.left - page.node.offsetLeft,\n pageNumber: page.number,\n };\n\n const viewportPosition: ViewportPosition = {\n boundingRect: pageBoundingRect,\n rects: [],\n };\n\n const scaledPosition = viewportPositionToScaled(viewportPosition, viewer);\n\n const image = screenshot(\n pageBoundingRect,\n pageBoundingRect.pageNumber,\n viewer,\n );\n\n onSelection &&\n onSelection(viewportPosition, scaledPosition, image, reset, event);\n };\n\n const handleMouseMove = (event: MouseEvent) => {\n if (!rootRef.current || !start || locked) return;\n setEnd(getContainerCoords(container, event.pageX, event.pageY));\n };\n\n const handleMouseDown = (event: MouseEvent) => {\n const shouldStart = (event: MouseEvent) =>\n enableAreaSelection(event) &&\n isHTMLElement(event.target) &&\n Boolean(asElement(event.target).closest(\".page\"));\n\n // If the user clicks anywhere outside a tip, reset the selection\n const shouldReset = (event: MouseEvent) =>\n start &&\n !asElement(event.target).closest(\".PdfHighlighter__tip-container\");\n\n if (!shouldStart(event)) {\n if (shouldReset(event)) reset();\n return;\n }\n\n startTargetRef.current = asElement(event.target);\n onDragStart && onDragStart(event);\n setStart(getContainerCoords(container, event.pageX, event.pageY));\n setEnd(null);\n setLocked(false);\n };\n\n /**\n * Although we register the event listeners on the PdfHighlighter component, we encapsulate\n * them in this separate component to enhance maintainability and prevent unnecessary\n * rerenders of the PdfHighlighter itself. While synthetic events on PdfHighlighter would\n * be preferable, we need to register \"mouseup\" on the entire document anyway. Therefore,\n * we can't avoid using useEffect. We must re-register all events on state changes, as\n * custom event listeners may otherwise receive stale state.\n */\n container.addEventListener(\"mousemove\", handleMouseMove);\n container.addEventListener(\"mousedown\", handleMouseDown);\n\n document.addEventListener(\"mouseup\", handleMouseUp);\n\n return () => {\n container.removeEventListener(\"mousemove\", handleMouseMove);\n container.removeEventListener(\"mousedown\", handleMouseDown);\n document.removeEventListener(\"mouseup\", handleMouseUp);\n };\n }, [start, end, enableAreaSelection]);\n\n return (\n <div className=\"MouseSelection-container\" ref={rootRef}>\n {start && end && (\n <div\n className=\"MouseSelection\"\n style={{ ...getBoundingRect(start, end), ...style }}\n />\n )}\n </div>\n );\n};\n","import React, {\n useRef,\n useEffect,\n useCallback,\n useState,\n MouseEvent as ReactMouseEvent,\n TouchEvent as ReactTouchEvent,\n} from \"react\";\nimport { viewportPositionToScaled } from \"../lib/coordinates\";\nimport { ShapeType, ShapeData, ScaledPosition, ViewportPosition } from \"../types\";\n\nimport type { PDFViewer as TPDFViewer } from \"pdfjs-dist/web/pdf_viewer.mjs\";\n\n/**\n * The props type for {@link ShapeCanvas}.\n *\n * @category Component Properties\n */\nexport interface ShapeCanvasProps {\n /**\n * Whether shape mode is active.\n */\n isActive: boolean;\n\n /**\n * The type of shape to create.\n */\n shapeType: ShapeType;\n\n /**\n * Stroke color for the shape.\n * @default \"#000000\"\n */\n strokeColor?: string;\n\n /**\n * Stroke width for the shape.\n * @default 2\n */\n strokeWidth?: number;\n\n /**\n * The PDF viewer instance.\n */\n viewer: InstanceType<typeof TPDFViewer>;\n\n /**\n * Callback when shape creation is complete.\n *\n * @param position - Scaled position of the shape on the page.\n * @param shape - The shape data.\n */\n onComplete: (position: ScaledPosition, shape: ShapeData) => void;\n\n /**\n * Callback when shape creation is cancelled.\n */\n onCancel: () => void;\n}\n\ninterface Point {\n x: number;\n y: number;\n}\n\n/**\n * A transparent overlay for creating shape annotations on PDF pages.\n * Supports mouse and touch input with click-and-drag to define shape bounds.\n *\n * @category Component\n */\nexport const ShapeCanvas = ({\n isActive,\n shapeType,\n strokeColor = \"#000000\",\n strokeWidth = 2,\n viewer,\n onComplete,\n onCancel,\n}: ShapeCanvasProps) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const [startPoint, setStartPoint] = useState<Point | null>(null);\n const [currentPoint, setCurrentPoint] = useState<Point | null>(null);\n const [pageNumber, setPageNumber] = useState<number | null>(null);\n const [pageRect, setPageRect] = useState<DOMRect | null>(null);\n const isDrawingRef = useRef(false);\n\n // Find which page the user is drawing on\n const findPageFromPoint = useCallback(\n (clientX: number, clientY: number) => {\n if (!viewer) return null;\n\n for (let i = 0; i < viewer.pagesCount; i++) {\n const pageView = viewer.getPageView(i);\n if (!pageView?.div) continue;\n\n const rect = pageView.div.getBoundingClientRect();\n if (\n clientX >= rect.left &&\n clientX <= rect.right &&\n clientY >= rect.top &&\n clientY <= rect.bottom\n ) {\n return {\n pageNumber: i + 1,\n element: pageView.div as HTMLElement,\n rect,\n };\n }\n }\n return null;\n },\n [viewer]\n );\n\n // Handle mouse/touch down\n const handleStart = useCallback(\n (clientX: number, clientY: number) => {\n const pageInfo = findPageFromPoint(clientX, clientY);\n if (!pageInfo) return;\n\n console.log(\"ShapeCanvas: Started drawing on page\", pageInfo.pageNumber);\n\n setPageNumber(pageInfo.pageNumber);\n setPageRect(pageInfo.rect);\n\n isDrawingRef.current = true;\n const pos = {\n x: clientX - pageInfo.rect.left,\n y: clientY - pageInfo.rect.top,\n };\n setStartPoint(pos);\n setCurrentPoint(pos);\n },\n [findPageFromPoint]\n );\n\n // Handle mouse/touch move\n const handleMove = useCallback(\n (clientX: number, clientY: number) => {\n if (!isDrawingRef.current || !pageRect) return;\n\n const pos = {\n x: clientX - pageRect.left,\n y: clientY - pageRect.top,\n };\n setCurrentPoint(pos);\n },\n [pageRect]\n );\n\n // Handle mouse/touch end\n const handleEnd = useCallback(() => {\n if (!isDrawingRef.current || !startPoint || !currentPoint || pageNumber === null || !viewer) {\n isDrawingRef.current = false;\n setStartPoint(null);\n setCurrentPoint(null);\n return;\n }\n\n isDrawingRef.current = false;\n\n // Calculate bounding box\n const minX = Math.min(startPoint.x, currentPoint.x);\n const minY = Math.min(startPoint.y, currentPoint.y);\n const maxX = Math.max(startPoint.x, currentPoint.x);\n const maxY = Math.max(startPoint.y, currentPoint.y);\n\n const width = maxX - minX;\n const height = maxY - minY;\n\n // Minimum size check\n if (width < 10 || height < 10) {\n console.log(\"ShapeCanvas: Shape too small, ignoring\");\n setStartPoint(null);\n setCurrentPoint(null);\n return;\n }\n\n console.log(\"ShapeCanvas: Creating shape\", shapeType, \"at\", { minX, minY, width, height });\n\n // Create viewport position\n const viewportPosition: ViewportPosition = {\n boundingRect: {\n left: minX,\n top: minY,\n width: width,\n height: height,\n pageNumber: pageNumber,\n },\n rects: [],\n };\n\n const scaledPosition = viewportPositionToScaled(viewportPosition, viewer);\n\n // For arrows, calculate start/end points as percentages within the bounding box\n let shapeData: ShapeData = {\n shapeType,\n strokeColor,\n strokeWidth,\n };\n\n if (shapeType === \"arrow\") {\n // Calculate start and end points relative to bounding box (0-1 range)\n shapeData.startPoint = {\n x: (startPoint.x - minX) / width,\n y: (startPoint.y - minY) / height,\n };\n shapeData.endPoint = {\n x: (currentPoint.x - minX) / width,\n y: (currentPoint.y - minY) / height,\n };\n console.log(\"ShapeCanvas: Arrow points\", shapeData.startPoint, \"->\", shapeData.endPoint);\n }\n\n console.log(\"ShapeCanvas: Created shape at position\", scaledPosition);\n onComplete(scaledPosition, shapeData);\n\n // Reset state\n setStartPoint(null);\n setCurrentPoint(null);\n setPageNumber(null);\n setPageRect(null);\n }, [startPoint, currentPoint, pageNumber, viewer, shapeType, strokeColor, strokeWidth, onComplete]);\n\n // Mouse event handlers\n const handleMouseDown = useCallback(\n (e: ReactMouseEvent) => {\n e.preventDefault();\n handleStart(e.clientX, e.clientY);\n },\n [handleStart]\n );\n\n const handleMouseMove = useCallback(\n (e: ReactMouseEvent) => {\n handleMove(e.clientX, e.clientY);\n },\n [handleMove]\n );\n\n const handleMouseUp = useCallback(() => {\n handleEnd();\n }, [handleEnd]);\n\n // Touch event handlers\n const handleTouchStart = useCallback(\n (e: ReactTouchEvent) => {\n e.preventDefault();\n if (e.touches.length > 0) {\n handleStart(e.touches[0].clientX, e.touches[0].clientY);\n }\n },\n [handleStart]\n );\n\n const handleTouchMove = useCallback(\n (e: ReactTouchEvent) => {\n e.preventDefault();\n if (e.touches.length > 0) {\n handleMove(e.touches[0].clientX, e.touches[0].clientY);\n }\n },\n [handleMove]\n );\n\n const handleTouchEnd = useCallback(() => {\n handleEnd();\n }, [handleEnd]);\n\n // Handle keyboard events\n useEffect(() => {\n if (!isActive) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.code === \"Escape\") {\n console.log(\"ShapeCanvas: Cancelled via Escape\");\n onCancel();\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [isActive, onCancel]);\n\n // Render shape preview\n const renderShapePreview = () => {\n if (!startPoint || !currentPoint || !pageRect) return null;\n\n const minX = Math.min(startPoint.x, currentPoint.x);\n const minY = Math.min(startPoint.y, currentPoint.y);\n const width = Math.abs(currentPoint.x - startPoint.x);\n const height = Math.abs(currentPoint.y - startPoint.y);\n\n const svgStyle: React.CSSProperties = {\n position: \"fixed\",\n left: pageRect.left,\n top: pageRect.top,\n width: pageRect.width,\n height: pageRect.height,\n pointerEvents: \"none\",\n zIndex: 1001,\n };\n\n return (\n <svg style={svgStyle}>\n {shapeType === \"rectangle\" && (\n <rect\n x={minX}\n y={minY}\n width={width}\n height={height}\n stroke={strokeColor}\n strokeWidth={strokeWidth}\n fill=\"none\"\n />\n )}\n {shapeType === \"circle\" && (\n <ellipse\n cx={minX + width / 2}\n cy={minY + height / 2}\n rx={width / 2}\n ry={height / 2}\n stroke={strokeColor}\n strokeWidth={strokeWidth}\n fill=\"none\"\n />\n )}\n {shapeType === \"arrow\" && (\n <>\n <defs>\n <marker\n id=\"shape-canvas-arrowhead\"\n markerWidth=\"10\"\n markerHeight=\"7\"\n refX=\"9\"\n refY=\"3.5\"\n orient=\"auto\"\n >\n <polygon points=\"0 0, 10 3.5, 0 7\" fill={strokeColor} />\n </marker>\n </defs>\n <line\n x1={startPoint.x}\n y1={startPoint.y}\n x2={currentPoint.x}\n y2={currentPoint.y}\n stroke={strokeColor}\n strokeWidth={strokeWidth}\n markerEnd=\"url(#shape-canvas-arrowhead)\"\n />\n </>\n )}\n </svg>\n );\n };\n\n if (!isActive) return null;\n\n return (\n <>\n <div\n ref={containerRef}\n className=\"ShapeCanvas\"\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n />\n {renderShapePreview()}\n <div className=\"ShapeCanvas__controls\">\n <div className=\"ShapeCanvas__hint\">\n Click and drag to draw a {shapeType}. Press Escape to cancel.\n </div>\n <button\n type=\"button\"\n className=\"ShapeCanvas__cancelButton\"\n onClick={onCancel}\n >\n Cancel\n </button>\n </div>\n </>\n );\n};\n","import { PDFViewer } from \"pdfjs-dist/types/web/pdf_viewer\";\nimport React, {\n MutableRefObject,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { usePdfHighlighterContext } from \"../contexts/PdfHighlighterContext\";\n\nconst clamp = (value: number, left: number, right: number) =>\n Math.min(Math.max(value, left), right);\n\nconst VERTICAL_PADDING = 5;\n\n/**\n * The props type for {@link TipContainer}.\n *\n * @category Component Properties\n * @internal\n */\nexport interface TipContainerProps {\n /**\n * The PDFViewer instance containing the HighlightLayer\n */\n viewer: PDFViewer;\n\n /**\n * Reference to the callback to update the tip's position.This should be\n * managed by the PdfHighlighter.\n */\n updateTipPositionRef: MutableRefObject<() => void>;\n}\n\n/**\n * A component that manages rendering and placement of a tip around a highlight.\n * It does not automatically update the tip's position if it resizes.\n *\n * @category Component\n * @internal\n */\nexport const TipContainer = ({\n viewer,\n updateTipPositionRef,\n}: TipContainerProps) => {\n const [height, setHeight] = useState(0);\n const [width, setWidth] = useState(0);\n const containerRef = useRef<HTMLDivElement | null>(null);\n\n const updatePosition = () => {\n if (!containerRef.current) return;\n const { offsetHeight, offsetWidth } = containerRef.current;\n setHeight(offsetHeight);\n setWidth(offsetWidth);\n };\n\n updateTipPositionRef.current = updatePosition;\n\n // useLayoutEffect ensures state is updated before re-render, preventing flickering\n useLayoutEffect(() => {\n updatePosition();\n }, [updatePosition]);\n\n const { getTip } = usePdfHighlighterContext();\n const currentTip = getTip();\n if (!currentTip) return null;\n\n // Destructuring current tip's position and content\n const { position, content } = currentTip;\n const { boundingRect } = position;\n const pageNumber = boundingRect.pageNumber;\n const pageNode = viewer.getPageView(pageNumber - 1).div; // Account for 1 indexing of pdf documents\n const pageBoundingClientRect = pageNode.getBoundingClientRect();\n const { left: pageLeft, width: pageWidth } = pageBoundingClientRect;\n\n // Calculate the position and dimensions of the tip container\n const scrollTop = viewer.container.scrollTop; // How much the viewer has been scrolled vertically\n const left = pageNode.offsetLeft + boundingRect.left + boundingRect.width / 2; // center tip over highlight\n const highlightTop = boundingRect.top + pageNode.offsetTop;\n const highlightBottom = highlightTop + boundingRect.height;\n\n // Determine whether the tip should be moved below the highlight\n const shouldMove = highlightTop - height - VERTICAL_PADDING < scrollTop; // Would the tip render beyond the top of the visible document?\n const top = shouldMove\n ? highlightBottom + VERTICAL_PADDING\n : highlightTop - height - VERTICAL_PADDING;\n\n // Ensure the tip stays within the left edge of the viewer and the right edge of the page\n const clampedLeft = clamp(left - width / 2, 0, pageLeft + pageWidth - width);\n\n return (\n <div\n className=\"PdfHighlighter__tip-container\"\n style={{\n top,\n left: clampedLeft,\n height: \"max-content\",\n width: \"max-content\",\n }}\n ref={containerRef}\n >\n {content}\n </div>\n );\n};\n","import React, {\n CSSProperties,\n MouseEvent,\n ReactNode,\n useState,\n useRef,\n useEffect,\n} from \"react\";\n\nimport type { ViewportHighlight } from \"../types\";\n\n/**\n * Style options for text highlight appearance.\n */\nexport interface TextHighlightStyle {\n highlightColor?: string;\n highlightStyle?: \"highlight\" | \"underline\" | \"strikethrough\";\n}\n\n/**\n * The props type for {@link TextHighlight}.\n *\n * @category Component Properties\n */\nexport interface TextHighlightProps {\n /**\n * Highlight to render over text.\n */\n highlight: ViewportHighlight;\n\n /**\n * Callback triggered whenever the user clicks on the part of a highlight.\n *\n * @param event - Mouse event associated with click.\n */\n onClick?(event: MouseEvent<HTMLDivElement>): void;\n\n /**\n * Callback triggered whenever the user enters the area of a text highlight.\n *\n * @param event - Mouse event associated with movement.\n */\n onMouseOver?(event: MouseEvent<HTMLDivElement>): void;\n\n /**\n * Callback triggered whenever the user leaves the area of a text highlight.\n *\n * @param event - Mouse event associated with movement.\n */\n onMouseOut?(event: MouseEvent<HTMLDivElement>): void;\n\n /**\n * Indicates whether the component is autoscrolled into view, affecting\n * default theming.\n */\n isScrolledTo: boolean;\n\n /**\n * Callback triggered whenever the user tries to open context menu on highlight.\n *\n * @param event - Mouse event associated with click.\n */\n onContextMenu?(event: MouseEvent<HTMLDivElement>): void;\n\n /**\n * Optional CSS styling applied to each TextHighlight part.\n */\n style?: CSSProperties;\n\n /**\n * Background/line color for the highlight.\n * Default: \"rgba(255, 226, 143, 1)\" (yellow)\n */\n highlightColor?: string;\n\n /**\n * Style mode for the highlight.\n * - \"highlight\": Solid background color (default)\n * - \"underline\": Line under the text\n * - \"strikethrough\": Line through the text\n */\n highlightStyle?: \"highlight\" | \"underline\" | \"strikethrough\";\n\n /**\n * Callback triggered when the style changes.\n */\n onStyleChange?(style: TextHighlightStyle): void;\n\n /**\n * Callback triggered when the delete button is clicked.\n */\n onDelete?(): void;\n\n /**\n * Custom style icon. Replaces the default palette icon.\n */\n styleIcon?: ReactNode;\n\n /**\n * Custom delete icon. Replaces the default trash icon.\n */\n deleteIcon?: ReactNode;\n\n /**\n * Custom color presets for the style panel.\n * Default: [\"rgba(255, 226, 143, 1)\", \"#ffcdd2\", \"#c8e6c9\", \"#bbdefb\", \"#e1bee7\"]\n */\n colorPresets?: string[];\n}\n\n// Default icons\nconst DefaultStyleIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z\" />\n </svg>\n);\n\nconst DefaultDeleteIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" />\n </svg>\n);\n\n// Highlight style icons\nconst HighlightIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M6 14l3 3v5h6v-5l3-3V9H6v5zm5-12h2v3h-2V2zM3.5 5.875L4.914 4.46l2.12 2.122L5.622 8 3.5 5.875zm13.46.71l2.123-2.12 1.414 1.414L18.375 8l-1.414-1.414z\" />\n </svg>\n);\n\nconst UnderlineIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z\" />\n </svg>\n);\n\nconst StrikethroughIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M10 19h4v-3h-4v3zM5 4v3h5v3h4V7h5V4H5zM3 14h18v-2H3v2z\" />\n </svg>\n);\n\n// Default color presets\nconst DEFAULT_COLOR_PRESETS = [\n \"rgba(255, 226, 143, 1)\", // Yellow (default)\n \"#ffcdd2\", // Light red\n \"#c8e6c9\", // Light green\n \"#bbdefb\", // Light blue\n \"#e1bee7\", // Light purple\n];\n\n/**\n * A component for displaying a highlighted text area.\n *\n * @category Component\n */\nexport const TextHighlight = ({\n highlight,\n onClick,\n onMouseOver,\n onMouseOut,\n isScrolledTo,\n onContextMenu,\n style,\n highlightColor = \"rgba(255, 226, 143, 1)\",\n highlightStyle = \"highlight\",\n onStyleChange,\n onDelete,\n styleIcon,\n deleteIcon,\n colorPresets = DEFAULT_COLOR_PRESETS,\n}: TextHighlightProps) => {\n const [isStylePanelOpen, setIsStylePanelOpen] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const stylePanelRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Close style panel when clicking outside\n useEffect(() => {\n if (!isStylePanelOpen) return;\n\n const handleClickOutside = (e: globalThis.MouseEvent) => {\n if (\n stylePanelRef.current &&\n !stylePanelRef.current.contains(e.target as Node)\n ) {\n setIsStylePanelOpen(false);\n }\n };\n\n // Delay adding listener to avoid immediate close\n const timeoutId = setTimeout(() => {\n document.addEventListener(\"mousedown\", handleClickOutside);\n }, 0);\n\n return () => {\n clearTimeout(timeoutId);\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [isStylePanelOpen]);\n\n const highlightClass = isScrolledTo ? \"TextHighlight--scrolledTo\" : \"\";\n const { rects } = highlight.position;\n\n // Get the first rect to position the toolbar\n const firstRect = rects[0];\n\n // Build style class based on highlight style\n const getPartStyleClass = () => {\n switch (highlightStyle) {\n case \"underline\":\n return \"TextHighlight__part--underline\";\n case \"strikethrough\":\n return \"TextHighlight__part--strikethrough\";\n default:\n return \"\";\n }\n };\n\n // Build inline style for each part\n const getPartStyle = (rect: typeof firstRect): CSSProperties => {\n const baseStyle: CSSProperties = { ...rect, ...style };\n\n if (highlightStyle === \"highlight\") {\n baseStyle.backgroundColor = highlightColor;\n } else {\n // For underline and strikethrough, use the color for the line\n baseStyle.backgroundColor = \"transparent\";\n baseStyle.color = highlightColor;\n }\n\n return baseStyle;\n };\n\n return (\n <div\n className={`TextHighlight ${highlightClass}`}\n onContextMenu={onContextMenu}\n ref={containerRef}\n >\n {/* Toolbar wrapper - extends down to overlap with highlight */}\n {(onStyleChange || onDelete) && firstRect && (\n <div\n className=\"TextHighlight__toolbar-wrapper\"\n style={{\n position: \"absolute\",\n left: firstRect.left,\n top: firstRect.top - 28,\n paddingBottom: 12,\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n <div\n className={`TextHighlight__toolbar ${isHovered || isStylePanelOpen ? \"TextHighlight__toolbar--visible\" : \"\"}`}\n >\n {onStyleChange && (\n <button\n className=\"TextHighlight__style-button\"\n onClick={(e) => {\n e.stopPropagation();\n setIsStylePanelOpen(!isStylePanelOpen);\n }}\n title=\"Change style\"\n type=\"button\"\n >\n {styleIcon || <DefaultStyleIcon />}\n </button>\n )}\n {onDelete && (\n <button\n className=\"TextHighlight__delete-button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete();\n }}\n title=\"Delete\"\n type=\"button\"\n >\n {deleteIcon || <DefaultDeleteIcon />}\n </button>\n )}\n </div>\n\n {/* Style Panel - inside wrapper */}\n {isStylePanelOpen && onStyleChange && (\n <div\n className=\"TextHighlight__style-panel\"\n ref={stylePanelRef}\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"TextHighlight__style-row\">\n <label>Style</label>\n <div className=\"TextHighlight__style-buttons\">\n <button\n type=\"button\"\n className={`TextHighlight__style-type-button ${highlightStyle === \"highlight\" ? \"active\" : \"\"}`}\n onClick={() =>\n onStyleChange({ highlightStyle: \"highlight\" })\n }\n title=\"Highlight\"\n >\n <HighlightIcon />\n </button>\n <button\n type=\"button\"\n className={`TextHighlight__style-type-button ${highlightStyle === \"underline\" ? \"active\" : \"\"}`}\n onClick={() =>\n onStyleChange({ highlightStyle: \"underline\" })\n }\n title=\"Underline\"\n >\n <UnderlineIcon />\n </button>\n <button\n type=\"button\"\n className={`TextHighlight__style-type-button ${highlightStyle === \"strikethrough\" ? \"active\" : \"\"}`}\n onClick={() =>\n onStyleChange({ highlightStyle: \"strikethrough\" })\n }\n title=\"Strikethrough\"\n >\n <StrikethroughIcon />\n </button>\n </div>\n </div>\n <div className=\"TextHighlight__style-row\">\n <label>Color</label>\n <div className=\"TextHighlight__color-options\">\n <div className=\"TextHighlight__color-presets\">\n {colorPresets.map((c) => (\n <button\n key={c}\n type=\"button\"\n className={`TextHighlight__color-preset ${highlightColor === c ? \"active\" : \"\"}`}\n style={{ backgroundColor: c }}\n onClick={() => onStyleChange({ highlightColor: c })}\n title={c}\n />\n ))}\n </div>\n <input\n type=\"color\"\n value={highlightColor}\n onChange={(e) => {\n onStyleChange({ highlightColor: e.target.value });\n }}\n />\n </div>\n </div>\n </div>\n )}\n </div>\n )}\n\n <div\n className=\"TextHighlight__parts\"\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n {rects.map((rect, index) => (\n <div\n onMouseOver={onMouseOver}\n onMouseOut={onMouseOut}\n onClick={onClick}\n key={index}\n style={getPartStyle(rect)}\n className={`TextHighlight__part ${getPartStyleClass()}`}\n />\n ))}\n </div>\n </div>\n );\n};\n","import React, { ReactNode, useRef } from \"react\";\nimport { usePdfHighlighterContext } from \"../contexts/PdfHighlighterContext\";\nimport { Tip } from \"../types\";\nimport { MouseMonitor } from \"./MouseMonitor\";\n\n/**\n * The props type for {@link MonitoredHighlightContainer}.\n *\n * @category Component Properties\n */\nexport interface MonitoredHighlightContainerProps {\n /**\n * A callback triggered whenever the mouse hovers over a highlight.\n */\n onMouseEnter?(): void;\n\n /**\n * What tip to automatically display whenever a mouse hovers over a highlight.\n * The tip will persist even as the user puts their mouse over it and not the\n * highlight, but will disappear once it no longer hovers both.\n */\n highlightTip?: Tip;\n\n /**\n * A callback triggered whenever the mouse completely moves out from both the\n * highlight (children) and any highlightTip.\n */\n onMouseLeave?(): void;\n\n /**\n * Component to monitor mouse activity over. This should be a highlight within the {@link PdfHighlighter}.\n */\n children: ReactNode;\n}\n\n/**\n * A container for a highlight component that monitors whether a mouse is over a\n * highlight and over some secondary highlight tip. It will display the tip\n * whenever the mouse is over the highlight and it will hide the tip only when\n * the mouse has left the highlight AND the tip.\n *\n * @category Component\n */\nexport const MonitoredHighlightContainer = ({\n onMouseEnter,\n highlightTip,\n onMouseLeave,\n children,\n}: MonitoredHighlightContainerProps) => {\n const mouseInRef = useRef(false); // Whether the mouse is over the child (highlight)\n\n const { setTip, isEditingOrHighlighting } = usePdfHighlighterContext();\n\n return (\n <div\n onMouseEnter={() => {\n mouseInRef.current = true;\n onMouseEnter && onMouseEnter();\n\n if (isEditingOrHighlighting()) return;\n\n if (highlightTip) {\n // MouseMonitor the highlightTip to prevent it from disappearing if the mouse is over it and not the highlight.\n const monitoredHighlightTip = (\n <MouseMonitor\n onMoveAway={() => {\n // The event will keep triggering if the mouse is not on the highlightTip,\n // but don't do anything if the mouse is over the highlight.\n if (mouseInRef.current) {\n return;\n }\n\n setTip(null);\n onMouseLeave && onMouseLeave();\n }}\n paddingX={60}\n paddingY={30}\n >\n {highlightTip.content}\n </MouseMonitor>\n );\n\n setTip({\n position: highlightTip.position,\n content: monitoredHighlightTip,\n });\n }\n }}\n onMouseLeave={() => {\n mouseInRef.current = false;\n\n // Trigger onMouseLeave if no highlightTip exists\n !highlightTip && onMouseLeave && onMouseLeave();\n }}\n >\n {children}\n </div>\n );\n};\n","import React, { ReactNode, useEffect, useRef } from \"react\";\n\n/**\n * The props type for {@link MouseMonitor}.\n *\n * @category Component Properties\n * @internal\n */\nexport interface MouseMonitorProps {\n /**\n * Callback triggered whenever the mouse moves not within the bounds of the\n * child component. This will keep triggering as long as the component is\n * rendered.\n */\n onMoveAway(): void;\n\n /**\n * X padding in pixels for the container to monitor mouse activity in.\n */\n paddingX: number;\n\n /**\n * Y padding in pixels for the container to monitor mouse activity in.\n */\n paddingY: number;\n\n /**\n * Component over which mouse activity is monitored.\n */\n children: ReactNode;\n}\n\n/**\n * A component that monitors mouse movements over a child and invisible padded area.\n *\n * @category Component\n * @internal\n */\nexport const MouseMonitor = ({\n onMoveAway,\n paddingX,\n paddingY,\n children,\n}: MouseMonitorProps) => {\n const containerRef = useRef<HTMLDivElement | null>(null);\n\n const onMouseMove = (event: MouseEvent) => {\n if (!containerRef.current) return;\n\n const { clientX, clientY } = event;\n const { left, top, width, height } =\n containerRef.current.getBoundingClientRect();\n\n const inBoundsX =\n clientX > left - paddingX && clientX < left + width + paddingX;\n const inBoundsY =\n clientY > top - paddingY && clientY < top + height + paddingY;\n\n if (!(inBoundsX && inBoundsY)) {\n onMoveAway();\n }\n };\n\n useEffect(() => {\n // TODO: Maybe optimise or throttle?\n document.addEventListener(\"mousemove\", onMouseMove);\n\n return () => {\n document.removeEventListener(\"mousemove\", onMouseMove);\n };\n }, []);\n\n return <div ref={containerRef}>{children}</div>;\n};\n","import React, {\n CSSProperties,\n MouseEvent,\n ReactNode,\n useState,\n useRef,\n useEffect,\n} from \"react\";\n\nimport { getPageFromElement } from \"../lib/pdfjs-dom\";\nimport { Rnd } from \"react-rnd\";\nimport type { LTWHP, ViewportHighlight } from \"../types\";\n\n/**\n * Style options for area highlight appearance.\n */\nexport interface AreaHighlightStyle {\n highlightColor?: string;\n}\n\n/**\n * The props type for {@link AreaHighlight}.\n *\n * @category Component Properties\n */\nexport interface AreaHighlightProps {\n /**\n * The highlight to be rendered as an {@link AreaHighlight}.\n */\n highlight: ViewportHighlight;\n\n /**\n * A callback triggered whenever the highlight area is either finished\n * being moved or resized.\n *\n * @param rect - The updated highlight area.\n */\n onChange?(rect: LTWHP): void;\n\n /**\n * Has the highlight been auto-scrolled into view? By default, this will render the highlight red.\n */\n isScrolledTo?: boolean;\n\n /**\n * react-rnd bounds on the highlight area. This is useful for preventing the user\n * moving the highlight off the viewer/page. See [react-rnd docs](https://github.com/bokuweb/react-rnd).\n */\n bounds?: string | Element;\n\n /**\n * A callback triggered whenever a context menu is opened on the highlight area.\n *\n * @param event - The mouse event associated with the context menu.\n */\n onContextMenu?(event: MouseEvent<HTMLDivElement>): void;\n\n /**\n * Event called whenever the user tries to move or resize an {@link AreaHighlight}.\n */\n onEditStart?(): void;\n\n /**\n * Custom styling to be applied to the {@link AreaHighlight} component.\n */\n style?: CSSProperties;\n\n /**\n * Background color for the highlight.\n * Default: \"rgba(255, 226, 143, 1)\" (yellow)\n */\n highlightColor?: string;\n\n /**\n * Callback triggered when the style changes.\n */\n onStyleChange?(style: AreaHighlightStyle): void;\n\n /**\n * Callback triggered when the delete button is clicked.\n */\n onDelete?(): void;\n\n /**\n * Custom style icon. Replaces the default palette icon.\n */\n styleIcon?: ReactNode;\n\n /**\n * Custom delete icon. Replaces the default trash icon.\n */\n deleteIcon?: ReactNode;\n\n /**\n * Custom color presets for the style panel.\n * Default: [\"rgba(255, 226, 143, 1)\", \"#ffcdd2\", \"#c8e6c9\", \"#bbdefb\", \"#e1bee7\"]\n */\n colorPresets?: string[];\n}\n\n// Default icons\nconst DefaultStyleIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z\" />\n </svg>\n);\n\nconst DefaultDeleteIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" />\n </svg>\n);\n\n// Default color presets\nconst DEFAULT_COLOR_PRESETS = [\n \"rgba(255, 226, 143, 1)\", // Yellow (default)\n \"#ffcdd2\", // Light red\n \"#c8e6c9\", // Light green\n \"#bbdefb\", // Light blue\n \"#e1bee7\", // Light purple\n];\n\n/**\n * Renders a resizeable and interactive rectangular area for a highlight.\n *\n * @category Component\n */\nexport const AreaHighlight = ({\n highlight,\n onChange,\n isScrolledTo,\n bounds,\n onContextMenu,\n onEditStart,\n style,\n highlightColor = \"rgba(255, 226, 143, 1)\",\n onStyleChange,\n onDelete,\n styleIcon,\n deleteIcon,\n colorPresets = DEFAULT_COLOR_PRESETS,\n}: AreaHighlightProps) => {\n const [isStylePanelOpen, setIsStylePanelOpen] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const stylePanelRef = useRef<HTMLDivElement>(null);\n\n // Close style panel when clicking outside\n useEffect(() => {\n if (!isStylePanelOpen) return;\n\n const handleClickOutside = (e: globalThis.MouseEvent) => {\n if (\n stylePanelRef.current &&\n !stylePanelRef.current.contains(e.target as Node)\n ) {\n setIsStylePanelOpen(false);\n }\n };\n\n // Delay adding listener to avoid immediate close\n const timeoutId = setTimeout(() => {\n document.addEventListener(\"mousedown\", handleClickOutside);\n }, 0);\n\n return () => {\n clearTimeout(timeoutId);\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [isStylePanelOpen]);\n\n const highlightClass = isScrolledTo ? \"AreaHighlight--scrolledTo\" : \"\";\n\n // Generate key based on position. This forces a remount (and a defaultpos update)\n // whenever highlight position changes (e.g., when updated, scale changes, etc.)\n // We don't use position as state because when updating Rnd this would happen and cause flickering:\n // User moves Rnd -> Rnd records new pos -> Rnd jumps back -> highlight updates -> Rnd re-renders at new pos\n const key = `${highlight.position.boundingRect.width}${highlight.position.boundingRect.height}${highlight.position.boundingRect.left}${highlight.position.boundingRect.top}`;\n\n // Merge custom style with highlight color\n const mergedStyle: CSSProperties = {\n ...style,\n backgroundColor: highlightColor,\n };\n\n return (\n <div\n className={`AreaHighlight ${highlightClass}`}\n onContextMenu={onContextMenu}\n >\n {/* Toolbar wrapper - extends down to overlap with highlight */}\n {(onStyleChange || onDelete) && (\n <div\n className=\"AreaHighlight__toolbar-wrapper\"\n style={{\n position: \"absolute\",\n left: highlight.position.boundingRect.left,\n top: highlight.position.boundingRect.top - 28,\n paddingBottom: 12,\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n <div\n className={`AreaHighlight__toolbar ${isHovered || isStylePanelOpen ? \"AreaHighlight__toolbar--visible\" : \"\"}`}\n >\n {onStyleChange && (\n <button\n className=\"AreaHighlight__style-button\"\n onClick={(e) => {\n e.stopPropagation();\n setIsStylePanelOpen(!isStylePanelOpen);\n }}\n title=\"Change color\"\n type=\"button\"\n >\n {styleIcon || <DefaultStyleIcon />}\n </button>\n )}\n {onDelete && (\n <button\n className=\"AreaHighlight__delete-button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete();\n }}\n title=\"Delete\"\n type=\"button\"\n >\n {deleteIcon || <DefaultDeleteIcon />}\n </button>\n )}\n </div>\n\n {/* Style Panel - inside wrapper */}\n {isStylePanelOpen && onStyleChange && (\n <div\n className=\"AreaHighlight__style-panel\"\n ref={stylePanelRef}\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"AreaHighlight__style-row\">\n <label>Color</label>\n <div className=\"AreaHighlight__color-options\">\n <div className=\"AreaHighlight__color-presets\">\n {colorPresets.map((c) => (\n <button\n key={c}\n type=\"button\"\n className={`AreaHighlight__color-preset ${highlightColor === c ? \"active\" : \"\"}`}\n style={{ backgroundColor: c }}\n onClick={() => onStyleChange({ highlightColor: c })}\n title={c}\n />\n ))}\n </div>\n <input\n type=\"color\"\n value={highlightColor}\n onChange={(e) => {\n onStyleChange({ highlightColor: e.target.value });\n }}\n />\n </div>\n </div>\n </div>\n )}\n </div>\n )}\n\n <Rnd\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n className=\"AreaHighlight__part\"\n onDragStop={(_, data) => {\n const boundingRect: LTWHP = {\n ...highlight.position.boundingRect,\n top: data.y,\n left: data.x,\n };\n\n onChange && onChange(boundingRect);\n }}\n onResizeStop={(_mouseEvent, _direction, ref, _delta, position) => {\n const boundingRect: LTWHP = {\n top: position.y,\n left: position.x,\n width: ref.offsetWidth,\n height: ref.offsetHeight,\n pageNumber: getPageFromElement(ref)?.number || -1,\n };\n\n onChange && onChange(boundingRect);\n }}\n onDragStart={onEditStart}\n onResizeStart={onEditStart}\n default={{\n x: highlight.position.boundingRect.left,\n y: highlight.position.boundingRect.top,\n width: highlight.position.boundingRect.width,\n height: highlight.position.boundingRect.height,\n }}\n key={key}\n bounds={bounds}\n // Prevevent any event clicks as clicking is already used for movement\n onClick={(event: Event) => {\n event.stopPropagation();\n event.preventDefault();\n }}\n style={mergedStyle}\n />\n </div>\n );\n};\n","import React, {\n CSSProperties,\n MouseEvent,\n ReactNode,\n useState,\n useRef,\n useEffect,\n} from \"react\";\nimport { Rnd } from \"react-rnd\";\nimport { getPageFromElement } from \"../lib/pdfjs-dom\";\nimport type { LTWHP, ViewportHighlight } from \"../types\";\n\n/**\n * Style options for freetext highlight appearance.\n */\nexport interface FreetextStyle {\n color?: string;\n backgroundColor?: string;\n fontFamily?: string;\n fontSize?: string;\n}\n\n/**\n * The props type for {@link FreetextHighlight}.\n *\n * @category Component Properties\n */\nexport interface FreetextHighlightProps {\n /**\n * The highlight to be rendered as a {@link FreetextHighlight}.\n */\n highlight: ViewportHighlight;\n\n /**\n * A callback triggered whenever the highlight position changes (drag).\n *\n * @param rect - The updated highlight area.\n */\n onChange?(rect: LTWHP): void;\n\n /**\n * A callback triggered whenever the text content changes.\n *\n * @param text - The new text content.\n */\n onTextChange?(text: string): void;\n\n /**\n * A callback triggered whenever the style changes.\n *\n * @param style - The new style options.\n */\n onStyleChange?(style: FreetextStyle): void;\n\n /**\n * Has the highlight been auto-scrolled into view?\n */\n isScrolledTo?: boolean;\n\n /**\n * react-rnd bounds on the highlight area.\n */\n bounds?: string | Element;\n\n /**\n * A callback triggered on context menu.\n */\n onContextMenu?(event: MouseEvent<HTMLDivElement>): void;\n\n /**\n * Event called when editing begins (drag or text edit).\n */\n onEditStart?(): void;\n\n /**\n * Event called when editing ends.\n */\n onEditEnd?(): void;\n\n /**\n * Custom styling for the container.\n */\n style?: CSSProperties;\n\n /**\n * Text color.\n */\n color?: string;\n\n /**\n * Background color.\n */\n backgroundColor?: string;\n\n /**\n * Font family.\n */\n fontFamily?: string;\n\n /**\n * Font size (e.g., \"14px\").\n */\n fontSize?: string;\n\n /**\n * Custom drag icon. Receives default icon as child if not provided.\n */\n dragIcon?: ReactNode;\n\n /**\n * Custom edit icon. Receives default icon as child if not provided.\n */\n editIcon?: ReactNode;\n\n /**\n * Custom style/settings icon. Receives default icon as child if not provided.\n */\n styleIcon?: ReactNode;\n\n /**\n * Custom background color presets for the style panel.\n * Default: [\"#ffffc8\", \"#ffcdd2\", \"#c8e6c9\", \"#bbdefb\", \"#e1bee7\"]\n */\n backgroundColorPresets?: string[];\n\n /**\n * Custom text color presets for the style panel.\n * Default: [\"#333333\", \"#d32f2f\", \"#1976d2\", \"#388e3c\", \"#7b1fa2\"]\n */\n textColorPresets?: string[];\n\n /**\n * Callback triggered when the delete button is clicked.\n */\n onDelete?(): void;\n\n /**\n * Custom delete icon. Replaces the default trash icon.\n */\n deleteIcon?: ReactNode;\n}\n\n/**\n * Renders a draggable, editable freetext annotation.\n *\n * @category Component\n */\n// Default icons\nconst DefaultDragIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <circle cx=\"8\" cy=\"6\" r=\"2\" />\n <circle cx=\"16\" cy=\"6\" r=\"2\" />\n <circle cx=\"8\" cy=\"12\" r=\"2\" />\n <circle cx=\"16\" cy=\"12\" r=\"2\" />\n <circle cx=\"8\" cy=\"18\" r=\"2\" />\n <circle cx=\"16\" cy=\"18\" r=\"2\" />\n </svg>\n);\n\nconst DefaultEditIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z\" />\n </svg>\n);\n\nconst DefaultStyleIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z\" />\n </svg>\n);\n\nconst DefaultDeleteIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" />\n </svg>\n);\n\n// Default color presets\nconst DEFAULT_BACKGROUND_PRESETS = [\"transparent\", \"#ffffc8\", \"#ffcdd2\", \"#c8e6c9\", \"#bbdefb\", \"#e1bee7\"];\nconst DEFAULT_TEXT_PRESETS = [\"#333333\", \"#d32f2f\", \"#1976d2\", \"#388e3c\", \"#7b1fa2\"];\n\nexport const FreetextHighlight = ({\n highlight,\n onChange,\n onTextChange,\n onStyleChange,\n isScrolledTo,\n bounds,\n onContextMenu,\n onEditStart,\n onEditEnd,\n style,\n color = \"#333333\",\n backgroundColor = \"#ffffc8\",\n fontFamily = \"inherit\",\n fontSize = \"14px\",\n dragIcon,\n editIcon,\n styleIcon,\n backgroundColorPresets = DEFAULT_BACKGROUND_PRESETS,\n textColorPresets = DEFAULT_TEXT_PRESETS,\n onDelete,\n deleteIcon,\n}: FreetextHighlightProps) => {\n const [isEditing, setIsEditing] = useState(false);\n const [isStylePanelOpen, setIsStylePanelOpen] = useState(false);\n const [text, setText] = useState(highlight.content?.text || \"\");\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const stylePanelRef = useRef<HTMLDivElement>(null);\n\n // Sync text with highlight content when it changes externally\n useEffect(() => {\n setText(highlight.content?.text || \"\");\n }, [highlight.content?.text]);\n\n // Focus textarea when entering edit mode\n useEffect(() => {\n if (isEditing && textareaRef.current) {\n textareaRef.current.focus();\n textareaRef.current.select();\n }\n }, [isEditing]);\n\n // Close style panel when clicking outside\n useEffect(() => {\n if (!isStylePanelOpen) return;\n\n const handleClickOutside = (e: globalThis.MouseEvent) => {\n if (stylePanelRef.current && !stylePanelRef.current.contains(e.target as Node)) {\n setIsStylePanelOpen(false);\n }\n };\n\n // Delay adding listener to avoid immediate close\n const timeoutId = setTimeout(() => {\n document.addEventListener(\"mousedown\", handleClickOutside);\n }, 0);\n\n return () => {\n clearTimeout(timeoutId);\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [isStylePanelOpen]);\n\n const highlightClass = isScrolledTo ? \"FreetextHighlight--scrolledTo\" : \"\";\n const editingClass = isEditing ? \"FreetextHighlight--editing\" : \"\";\n\n // Generate key based on position for Rnd remount on position changes\n const key = `${highlight.position.boundingRect.width}${highlight.position.boundingRect.height}${highlight.position.boundingRect.left}${highlight.position.boundingRect.top}`;\n\n const handleTextClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (!isEditing) {\n setIsEditing(true);\n onEditStart?.();\n }\n };\n\n const handleTextBlur = () => {\n if (isEditing) {\n setIsEditing(false);\n onTextChange?.(text);\n onEditEnd?.();\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n setText(highlight.content?.text || \"\");\n setIsEditing(false);\n onEditEnd?.();\n } else if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n setIsEditing(false);\n onTextChange?.(text);\n onEditEnd?.();\n }\n };\n\n const containerStyle: CSSProperties = {\n backgroundColor,\n color,\n fontFamily,\n fontSize,\n ...style,\n };\n\n return (\n <div\n className={`FreetextHighlight ${highlightClass} ${editingClass}`}\n onContextMenu={onContextMenu}\n >\n <Rnd\n className=\"FreetextHighlight__rnd\"\n onDragStop={(_, data) => {\n const boundingRect: LTWHP = {\n ...highlight.position.boundingRect,\n top: data.y,\n left: data.x,\n };\n onChange?.(boundingRect);\n }}\n onDragStart={() => {\n if (!isEditing) {\n onEditStart?.();\n }\n }}\n default={{\n x: highlight.position.boundingRect.left,\n y: highlight.position.boundingRect.top,\n width: highlight.position.boundingRect.width || 150,\n height: highlight.position.boundingRect.height || 80,\n }}\n minWidth={100}\n minHeight={50}\n key={key}\n bounds={bounds}\n enableResizing={{\n top: false,\n right: true,\n bottom: true,\n left: false,\n topRight: false,\n bottomRight: true,\n bottomLeft: false,\n topLeft: false,\n }}\n onResizeStop={(_e, _direction, ref, _delta, position) => {\n const boundingRect: LTWHP = {\n top: position.y,\n left: position.x,\n width: ref.offsetWidth,\n height: ref.offsetHeight,\n pageNumber:\n getPageFromElement(ref)?.number ||\n highlight.position.boundingRect.pageNumber,\n };\n onChange?.(boundingRect);\n }}\n onResizeStart={() => {\n if (!isEditing) {\n onEditStart?.();\n }\n }}\n cancel=\".FreetextHighlight__text, .FreetextHighlight__input, .FreetextHighlight__edit-button, .FreetextHighlight__style-button, .FreetextHighlight__style-panel, .FreetextHighlight__delete-button\"\n >\n <div className=\"FreetextHighlight__container\" style={containerStyle}>\n <div className=\"FreetextHighlight__toolbar\">\n <div className=\"FreetextHighlight__drag-handle\" title=\"Drag to move\">\n {dragIcon || <DefaultDragIcon />}\n </div>\n <button\n className=\"FreetextHighlight__edit-button\"\n onClick={handleTextClick}\n title=\"Edit text\"\n type=\"button\"\n >\n {editIcon || <DefaultEditIcon />}\n </button>\n <button\n className=\"FreetextHighlight__style-button\"\n onClick={(e) => {\n e.stopPropagation();\n setIsStylePanelOpen(!isStylePanelOpen);\n }}\n title=\"Change style\"\n type=\"button\"\n >\n {styleIcon || <DefaultStyleIcon />}\n </button>\n {onDelete && (\n <button\n className=\"FreetextHighlight__delete-button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete();\n }}\n title=\"Delete\"\n type=\"button\"\n >\n {deleteIcon || <DefaultDeleteIcon />}\n </button>\n )}\n </div>\n {isStylePanelOpen && (\n <div\n className=\"FreetextHighlight__style-panel\"\n ref={stylePanelRef}\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"FreetextHighlight__style-row\">\n <label>Background</label>\n <div className=\"FreetextHighlight__color-options\">\n <div className=\"FreetextHighlight__color-presets\">\n {backgroundColorPresets.map((c) => (\n <button\n key={c}\n type=\"button\"\n className={`FreetextHighlight__color-preset ${c === \"transparent\" ? \"FreetextHighlight__color-preset--transparent\" : \"\"} ${backgroundColor === c ? \"active\" : \"\"}`}\n style={c !== \"transparent\" ? { backgroundColor: c } : undefined}\n onClick={() => onStyleChange?.({ backgroundColor: c })}\n title={c === \"transparent\" ? \"No background\" : c}\n />\n ))}\n </div>\n <input\n type=\"color\"\n value={backgroundColor === \"transparent\" ? \"#ffffff\" : backgroundColor}\n onChange={(e) => {\n onStyleChange?.({ backgroundColor: e.target.value });\n }}\n />\n </div>\n </div>\n <div className=\"FreetextHighlight__style-row\">\n <label\n\n >Text Color</label>\n <div className=\"FreetextHighlight__color-options\">\n <div className=\"FreetextHighlight__color-presets\">\n {textColorPresets.map((c) => (\n <button\n key={c}\n type=\"button\"\n className={`FreetextHighlight__color-preset ${color === c ? \"active\" : \"\"}`}\n style={{ backgroundColor: c }}\n onClick={() => onStyleChange?.({ color: c })}\n title={c}\n />\n ))}\n </div>\n <input\n type=\"color\"\n value={color}\n onChange={(e) => {\n onStyleChange?.({ color: e.target.value });\n }}\n />\n </div>\n </div>\n <div className=\"FreetextHighlight__style-row\">\n <label>Font Size</label>\n <select\n value={fontSize}\n onChange={(e) => {\n onStyleChange?.({ fontSize: e.target.value });\n }}\n >\n <option value=\"10px\">10px</option>\n <option value=\"12px\">12px</option>\n <option value=\"14px\">14px</option>\n <option value=\"16px\">16px</option>\n <option value=\"18px\">18px</option>\n <option value=\"20px\">20px</option>\n <option value=\"24px\">24px</option>\n </select>\n </div>\n <div className=\"FreetextHighlight__style-row\">\n <label>Font</label>\n <select\n value={fontFamily}\n onChange={(e) => {\n onStyleChange?.({ fontFamily: e.target.value });\n }}\n >\n <option value=\"inherit\">Default</option>\n <option value=\"Arial, sans-serif\">Arial</option>\n <option value=\"Georgia, serif\">Georgia</option>\n <option value=\"'Courier New', monospace\">Courier</option>\n <option value=\"'Times New Roman', serif\">Times</option>\n </select>\n </div>\n </div>\n )}\n <div className=\"FreetextHighlight__content\">\n {isEditing ? (\n <textarea\n ref={textareaRef}\n className=\"FreetextHighlight__input\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n onBlur={handleTextBlur}\n onKeyDown={handleKeyDown}\n onClick={(e) => e.stopPropagation()}\n />\n ) : (\n <div className=\"FreetextHighlight__text\">\n {text || \"New note\"}\n </div>\n )}\n </div>\n </div>\n </Rnd>\n </div>\n );\n};\n","import React, { CSSProperties, MouseEvent, ReactNode } from \"react\";\nimport { Rnd } from \"react-rnd\";\nimport { getPageFromElement } from \"../lib/pdfjs-dom\";\nimport type { LTWHP, ViewportHighlight } from \"../types\";\n\n/**\n * The props type for {@link ImageHighlight}.\n *\n * @category Component Properties\n */\nexport interface ImageHighlightProps {\n /**\n * The highlight to be rendered as an {@link ImageHighlight}.\n * The highlight.content.image should contain the image data URL.\n */\n highlight: ViewportHighlight;\n\n /**\n * A callback triggered whenever the highlight position or size changes.\n *\n * @param rect - The updated highlight area.\n */\n onChange?(rect: LTWHP): void;\n\n /**\n * Has the highlight been auto-scrolled into view?\n */\n isScrolledTo?: boolean;\n\n /**\n * react-rnd bounds on the highlight area.\n */\n bounds?: string | Element;\n\n /**\n * A callback triggered on context menu.\n */\n onContextMenu?(event: MouseEvent<HTMLDivElement>): void;\n\n /**\n * Event called when editing begins (drag or resize).\n */\n onEditStart?(): void;\n\n /**\n * Event called when editing ends.\n */\n onEditEnd?(): void;\n\n /**\n * Custom styling for the container.\n */\n style?: CSSProperties;\n\n /**\n * Custom drag icon. Replaces the default 6-dot grid icon.\n */\n dragIcon?: ReactNode;\n\n /**\n * Callback triggered when the delete button is clicked.\n */\n onDelete?(): void;\n\n /**\n * Custom delete icon. Replaces the default trash icon.\n */\n deleteIcon?: ReactNode;\n}\n\n/**\n * Default drag icon - 6 dot grid pattern.\n */\nconst DefaultDragIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <circle cx=\"8\" cy=\"6\" r=\"2\" />\n <circle cx=\"16\" cy=\"6\" r=\"2\" />\n <circle cx=\"8\" cy=\"12\" r=\"2\" />\n <circle cx=\"16\" cy=\"12\" r=\"2\" />\n <circle cx=\"8\" cy=\"18\" r=\"2\" />\n <circle cx=\"16\" cy=\"18\" r=\"2\" />\n </svg>\n);\n\nconst DefaultDeleteIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" />\n </svg>\n);\n\n/**\n * Renders a draggable, resizable image/signature annotation.\n *\n * @category Component\n */\nexport const ImageHighlight = ({\n highlight,\n onChange,\n isScrolledTo,\n bounds,\n onContextMenu,\n onEditStart,\n onEditEnd,\n style,\n dragIcon,\n onDelete,\n deleteIcon,\n}: ImageHighlightProps) => {\n const highlightClass = isScrolledTo ? \"ImageHighlight--scrolledTo\" : \"\";\n\n // Generate key based on position for Rnd remount on position changes\n const key = `${highlight.position.boundingRect.width}${highlight.position.boundingRect.height}${highlight.position.boundingRect.left}${highlight.position.boundingRect.top}`;\n\n const imageUrl = highlight.content?.image;\n\n return (\n <div\n className={`ImageHighlight ${highlightClass}`}\n onContextMenu={onContextMenu}\n >\n <Rnd\n className=\"ImageHighlight__rnd\"\n onDragStop={(_, data) => {\n const boundingRect: LTWHP = {\n ...highlight.position.boundingRect,\n top: data.y,\n left: data.x,\n };\n onChange?.(boundingRect);\n onEditEnd?.();\n }}\n onDragStart={onEditStart}\n onResizeStop={(_e, _direction, ref, _delta, position) => {\n const boundingRect: LTWHP = {\n top: position.y,\n left: position.x,\n width: ref.offsetWidth,\n height: ref.offsetHeight,\n pageNumber:\n getPageFromElement(ref)?.number ||\n highlight.position.boundingRect.pageNumber,\n };\n onChange?.(boundingRect);\n onEditEnd?.();\n }}\n onResizeStart={onEditStart}\n default={{\n x: highlight.position.boundingRect.left,\n y: highlight.position.boundingRect.top,\n width: highlight.position.boundingRect.width || 150,\n height: highlight.position.boundingRect.height || 100,\n }}\n minWidth={50}\n minHeight={50}\n key={key}\n bounds={bounds}\n lockAspectRatio={true}\n dragHandleClassName=\"ImageHighlight__drag-handle\"\n onClick={(event: Event) => {\n event.stopPropagation();\n event.preventDefault();\n }}\n style={style}\n >\n <div className=\"ImageHighlight__container\">\n <div className=\"ImageHighlight__toolbar\">\n <div className=\"ImageHighlight__drag-handle\" title=\"Drag to move\">\n {dragIcon || <DefaultDragIcon />}\n </div>\n {onDelete && (\n <button\n className=\"ImageHighlight__delete-button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete();\n }}\n title=\"Delete\"\n type=\"button\"\n >\n {deleteIcon || <DefaultDeleteIcon />}\n </button>\n )}\n </div>\n <div className=\"ImageHighlight__content\">\n {imageUrl ? (\n <img\n src={imageUrl}\n alt=\"Highlight\"\n className=\"ImageHighlight__image\"\n draggable={false}\n />\n ) : (\n <div className=\"ImageHighlight__placeholder\">No image</div>\n )}\n </div>\n </div>\n </Rnd>\n </div>\n );\n};\n","import React, { useRef, useEffect, useCallback } from \"react\";\n\n/**\n * The props type for {@link SignaturePad}.\n *\n * @category Component Properties\n */\nexport interface SignaturePadProps {\n /**\n * Whether the signature pad modal is open.\n */\n isOpen: boolean;\n\n /**\n * Callback when signature is completed.\n *\n * @param dataUrl - The signature as a PNG data URL.\n */\n onComplete: (dataUrl: string) => void;\n\n /**\n * Callback when the modal is closed/cancelled.\n */\n onClose: () => void;\n\n /**\n * Canvas width in pixels.\n * @default 400\n */\n width?: number;\n\n /**\n * Canvas height in pixels.\n * @default 200\n */\n height?: number;\n}\n\n/**\n * A modal component with a canvas for drawing signatures.\n * Supports both mouse and touch input.\n *\n * @category Component\n */\nexport const SignaturePad = ({\n isOpen,\n onComplete,\n onClose,\n width = 400,\n height = 200,\n}: SignaturePadProps) => {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const isDrawingRef = useRef(false);\n const lastPosRef = useRef({ x: 0, y: 0 });\n\n // Initialize canvas context\n useEffect(() => {\n if (!isOpen || !canvasRef.current) return;\n\n const canvas = canvasRef.current;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n\n // Set up drawing style\n ctx.strokeStyle = \"#000000\";\n ctx.lineWidth = 2;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n\n // Clear canvas\n ctx.fillStyle = \"white\";\n ctx.fillRect(0, 0, width, height);\n }, [isOpen, width, height]);\n\n const getPosition = useCallback(\n (e: MouseEvent | TouchEvent) => {\n const canvas = canvasRef.current;\n if (!canvas) return { x: 0, y: 0 };\n\n const rect = canvas.getBoundingClientRect();\n let clientX: number;\n let clientY: number;\n\n if (\"touches\" in e) {\n clientX = e.touches[0].clientX;\n clientY = e.touches[0].clientY;\n } else {\n clientX = e.clientX;\n clientY = e.clientY;\n }\n\n return {\n x: clientX - rect.left,\n y: clientY - rect.top,\n };\n },\n []\n );\n\n const startDrawing = useCallback(\n (e: MouseEvent | TouchEvent) => {\n e.preventDefault();\n isDrawingRef.current = true;\n lastPosRef.current = getPosition(e);\n },\n [getPosition]\n );\n\n const draw = useCallback(\n (e: MouseEvent | TouchEvent) => {\n if (!isDrawingRef.current) return;\n e.preventDefault();\n\n const canvas = canvasRef.current;\n const ctx = canvas?.getContext(\"2d\");\n if (!ctx) return;\n\n const currentPos = getPosition(e);\n\n ctx.beginPath();\n ctx.moveTo(lastPosRef.current.x, lastPosRef.current.y);\n ctx.lineTo(currentPos.x, currentPos.y);\n ctx.stroke();\n\n lastPosRef.current = currentPos;\n },\n [getPosition]\n );\n\n const stopDrawing = useCallback(() => {\n isDrawingRef.current = false;\n }, []);\n\n // Set up event listeners\n useEffect(() => {\n if (!isOpen) return;\n\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n // Mouse events\n const handleMouseDown = (e: MouseEvent) => startDrawing(e);\n const handleMouseMove = (e: MouseEvent) => draw(e);\n const handleMouseUp = () => stopDrawing();\n const handleMouseLeave = () => stopDrawing();\n\n // Touch events\n const handleTouchStart = (e: TouchEvent) => startDrawing(e);\n const handleTouchMove = (e: TouchEvent) => draw(e);\n const handleTouchEnd = () => stopDrawing();\n\n canvas.addEventListener(\"mousedown\", handleMouseDown);\n canvas.addEventListener(\"mousemove\", handleMouseMove);\n canvas.addEventListener(\"mouseup\", handleMouseUp);\n canvas.addEventListener(\"mouseleave\", handleMouseLeave);\n canvas.addEventListener(\"touchstart\", handleTouchStart, { passive: false });\n canvas.addEventListener(\"touchmove\", handleTouchMove, { passive: false });\n canvas.addEventListener(\"touchend\", handleTouchEnd);\n\n return () => {\n canvas.removeEventListener(\"mousedown\", handleMouseDown);\n canvas.removeEventListener(\"mousemove\", handleMouseMove);\n canvas.removeEventListener(\"mouseup\", handleMouseUp);\n canvas.removeEventListener(\"mouseleave\", handleMouseLeave);\n canvas.removeEventListener(\"touchstart\", handleTouchStart);\n canvas.removeEventListener(\"touchmove\", handleTouchMove);\n canvas.removeEventListener(\"touchend\", handleTouchEnd);\n };\n }, [isOpen, startDrawing, draw, stopDrawing]);\n\n const handleClear = () => {\n const canvas = canvasRef.current;\n const ctx = canvas?.getContext(\"2d\");\n if (!ctx || !canvas) return;\n\n ctx.fillStyle = \"white\";\n ctx.fillRect(0, 0, width, height);\n };\n\n const handleDone = () => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const dataUrl = canvas.toDataURL(\"image/png\");\n onComplete(dataUrl);\n };\n\n const handleOverlayClick = (e: React.MouseEvent) => {\n // Close if clicking the overlay background\n if (e.target === e.currentTarget) {\n onClose();\n }\n };\n\n if (!isOpen) return null;\n\n return (\n <div className=\"SignaturePad__overlay\" onClick={handleOverlayClick}>\n <div className=\"SignaturePad__modal\">\n <h3 className=\"SignaturePad__title\">Draw your signature</h3>\n <canvas\n ref={canvasRef}\n className=\"SignaturePad__canvas\"\n width={width}\n height={height}\n />\n <div className=\"SignaturePad__buttons\">\n <button\n type=\"button\"\n className=\"SignaturePad__button SignaturePad__button--clear\"\n onClick={handleClear}\n >\n Clear\n </button>\n <button\n type=\"button\"\n className=\"SignaturePad__button SignaturePad__button--cancel\"\n onClick={onClose}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"SignaturePad__button SignaturePad__button--done\"\n onClick={handleDone}\n >\n Done\n </button>\n </div>\n </div>\n </div>\n );\n};\n","import React, { CSSProperties, MouseEvent, ReactNode, useState, useCallback, useEffect, useRef } from \"react\";\nimport { Rnd } from \"react-rnd\";\nimport { getPageFromElement } from \"../lib/pdfjs-dom\";\nimport type { DrawingStroke, LTWHP, ViewportHighlight } from \"../types\";\n\n// Drawing style presets (same as toolbar)\nconst DRAWING_COLORS = [\"#000000\", \"#FF0000\", \"#0000FF\", \"#00FF00\", \"#FFFF00\"];\nconst STROKE_WIDTHS = [\n { label: \"Thin\", value: 1 },\n { label: \"Medium\", value: 3 },\n { label: \"Thick\", value: 5 },\n];\n\n/**\n * The props type for {@link DrawingHighlight}.\n *\n * @category Component Properties\n */\nexport interface DrawingHighlightProps {\n /**\n * The highlight to be rendered as a {@link DrawingHighlight}.\n * The highlight.content.image should contain the drawing as a PNG data URL.\n */\n highlight: ViewportHighlight;\n\n /**\n * A callback triggered whenever the highlight position or size changes.\n *\n * @param rect - The updated highlight area.\n */\n onChange?(rect: LTWHP): void;\n\n /**\n * Has the highlight been auto-scrolled into view?\n */\n isScrolledTo?: boolean;\n\n /**\n * react-rnd bounds on the highlight area.\n */\n bounds?: string | Element;\n\n /**\n * A callback triggered on context menu.\n */\n onContextMenu?(event: MouseEvent<HTMLDivElement>): void;\n\n /**\n * Event called when editing begins (drag or resize).\n */\n onEditStart?(): void;\n\n /**\n * Event called when editing ends.\n */\n onEditEnd?(): void;\n\n /**\n * Custom styling for the container.\n */\n style?: CSSProperties;\n\n /**\n * Custom drag icon. Replaces the default 6-dot grid icon.\n */\n dragIcon?: ReactNode;\n\n /**\n * Callback when drawing style changes (color or stroke width).\n * The newImage is the re-rendered PNG data URL with updated styles.\n * The newStrokes contain the updated stroke data.\n */\n onStyleChange?(newImage: string, newStrokes: DrawingStroke[]): void;\n\n /**\n * Callback triggered when the delete button is clicked.\n */\n onDelete?(): void;\n\n /**\n * Custom delete icon. Replaces the default trash icon.\n */\n deleteIcon?: ReactNode;\n}\n\n/**\n * Default drag icon - 6 dot grid pattern.\n */\nconst DefaultDragIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <circle cx=\"8\" cy=\"6\" r=\"2\" />\n <circle cx=\"16\" cy=\"6\" r=\"2\" />\n <circle cx=\"8\" cy=\"12\" r=\"2\" />\n <circle cx=\"16\" cy=\"12\" r=\"2\" />\n <circle cx=\"8\" cy=\"18\" r=\"2\" />\n <circle cx=\"16\" cy=\"18\" r=\"2\" />\n </svg>\n);\n\nconst DefaultDeleteIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" />\n </svg>\n);\n\n/**\n * Re-render strokes to a canvas and return as PNG data URL.\n */\nconst renderStrokesToImage = (\n strokes: DrawingStroke[],\n width: number,\n height: number\n): string => {\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext(\"2d\");\n\n if (!ctx) return \"\";\n\n strokes.forEach((stroke) => {\n if (stroke.points.length < 2) return;\n\n ctx.strokeStyle = stroke.color;\n ctx.lineWidth = stroke.width;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n\n ctx.beginPath();\n ctx.moveTo(stroke.points[0].x, stroke.points[0].y);\n stroke.points.slice(1).forEach((point) => {\n ctx.lineTo(point.x, point.y);\n });\n ctx.stroke();\n });\n\n return canvas.toDataURL(\"image/png\");\n};\n\n/**\n * Renders a draggable, resizable freehand drawing annotation.\n * Drawings are stored as PNG images with transparent backgrounds.\n *\n * @category Component\n */\nexport const DrawingHighlight = ({\n highlight,\n onChange,\n isScrolledTo,\n bounds,\n onContextMenu,\n onEditStart,\n onEditEnd,\n style,\n dragIcon,\n onStyleChange,\n onDelete,\n deleteIcon,\n}: DrawingHighlightProps) => {\n const highlightClass = isScrolledTo ? \"DrawingHighlight--scrolledTo\" : \"\";\n const [showStyleControls, setShowStyleControls] = useState(false);\n const styleControlsRef = useRef<HTMLDivElement>(null);\n\n // Close style controls when clicking outside\n useEffect(() => {\n if (!showStyleControls) return;\n\n const handleClickOutside = (e: globalThis.MouseEvent) => {\n if (styleControlsRef.current && !styleControlsRef.current.contains(e.target as Node)) {\n setShowStyleControls(false);\n }\n };\n\n // Delay adding listener to avoid immediate close\n const timeoutId = setTimeout(() => {\n document.addEventListener(\"mousedown\", handleClickOutside);\n }, 0);\n\n return () => {\n clearTimeout(timeoutId);\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [showStyleControls]);\n\n // Generate key based on position for Rnd remount on position changes\n const key = `${highlight.position.boundingRect.width}${highlight.position.boundingRect.height}${highlight.position.boundingRect.left}${highlight.position.boundingRect.top}`;\n\n const imageUrl = highlight.content?.image;\n const strokes = highlight.content?.strokes;\n\n // Apply new color to all strokes\n const handleColorChange = useCallback((newColor: string) => {\n if (!strokes || !onStyleChange) return;\n\n console.log(\"DrawingHighlight: Changing color to\", newColor);\n const newStrokes = strokes.map((stroke) => ({\n ...stroke,\n color: newColor,\n }));\n\n const newImage = renderStrokesToImage(\n newStrokes,\n highlight.position.boundingRect.width,\n highlight.position.boundingRect.height\n );\n\n onStyleChange(newImage, newStrokes);\n }, [strokes, onStyleChange, highlight.position.boundingRect.width, highlight.position.boundingRect.height]);\n\n // Apply new width to all strokes\n const handleWidthChange = useCallback((newWidth: number) => {\n if (!strokes || !onStyleChange) return;\n\n console.log(\"DrawingHighlight: Changing width to\", newWidth);\n const newStrokes = strokes.map((stroke) => ({\n ...stroke,\n width: newWidth,\n }));\n\n const newImage = renderStrokesToImage(\n newStrokes,\n highlight.position.boundingRect.width,\n highlight.position.boundingRect.height\n );\n\n onStyleChange(newImage, newStrokes);\n }, [strokes, onStyleChange, highlight.position.boundingRect.width, highlight.position.boundingRect.height]);\n\n // Get current color from first stroke (for showing active state)\n const currentColor = strokes?.[0]?.color || \"#000000\";\n const currentWidth = strokes?.[0]?.width || 3;\n\n return (\n <div\n className={`DrawingHighlight ${highlightClass}`}\n onContextMenu={onContextMenu}\n >\n <Rnd\n className=\"DrawingHighlight__rnd\"\n onDragStop={(_, data) => {\n const boundingRect: LTWHP = {\n ...highlight.position.boundingRect,\n top: data.y,\n left: data.x,\n };\n onChange?.(boundingRect);\n onEditEnd?.();\n }}\n onDragStart={onEditStart}\n onResizeStop={(_e, _direction, ref, _delta, position) => {\n const boundingRect: LTWHP = {\n top: position.y,\n left: position.x,\n width: ref.offsetWidth,\n height: ref.offsetHeight,\n pageNumber:\n getPageFromElement(ref)?.number ||\n highlight.position.boundingRect.pageNumber,\n };\n onChange?.(boundingRect);\n onEditEnd?.();\n }}\n onResizeStart={onEditStart}\n default={{\n x: highlight.position.boundingRect.left,\n y: highlight.position.boundingRect.top,\n width: highlight.position.boundingRect.width || 150,\n height: highlight.position.boundingRect.height || 100,\n }}\n minWidth={30}\n minHeight={30}\n key={key}\n bounds={bounds}\n // No aspect ratio lock for drawings - allow free resizing\n lockAspectRatio={false}\n dragHandleClassName=\"DrawingHighlight__drag-handle\"\n onClick={(event: Event) => {\n event.stopPropagation();\n event.preventDefault();\n }}\n style={style}\n >\n <div className=\"DrawingHighlight__container\">\n <div className=\"DrawingHighlight__toolbar\">\n <div className=\"DrawingHighlight__drag-handle\" title=\"Drag to move\">\n {dragIcon || <DefaultDragIcon />}\n </div>\n {/* Style edit button - only show if strokes are available */}\n {strokes && strokes.length > 0 && onStyleChange && (\n <button\n type=\"button\"\n className=\"DrawingHighlight__style-button\"\n title=\"Edit style\"\n onClick={(e) => {\n e.stopPropagation();\n setShowStyleControls(!showStyleControls);\n }}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z\"/>\n </svg>\n </button>\n )}\n {onDelete && (\n <button\n className=\"DrawingHighlight__delete-button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete();\n }}\n title=\"Delete\"\n type=\"button\"\n >\n {deleteIcon || <DefaultDeleteIcon />}\n </button>\n )}\n </div>\n {/* Style controls dropdown */}\n {showStyleControls && strokes && strokes.length > 0 && onStyleChange && (\n <div className=\"DrawingHighlight__style-controls\" ref={styleControlsRef}>\n <div className=\"DrawingHighlight__color-picker\">\n {DRAWING_COLORS.map((color) => (\n <button\n key={color}\n type=\"button\"\n className={`DrawingHighlight__color-button ${currentColor === color ? 'active' : ''}`}\n style={{ backgroundColor: color }}\n onClick={(e) => {\n e.stopPropagation();\n handleColorChange(color);\n }}\n title={`Color: ${color}`}\n />\n ))}\n </div>\n <div className=\"DrawingHighlight__width-picker\">\n {STROKE_WIDTHS.map((w) => (\n <button\n key={w.value}\n type=\"button\"\n className={`DrawingHighlight__width-button ${currentWidth === w.value ? 'active' : ''}`}\n onClick={(e) => {\n e.stopPropagation();\n handleWidthChange(w.value);\n }}\n title={w.label}\n >\n {w.label}\n </button>\n ))}\n </div>\n </div>\n )}\n <div className=\"DrawingHighlight__content\">\n {imageUrl ? (\n <img\n src={imageUrl}\n alt=\"Drawing\"\n className=\"DrawingHighlight__image\"\n draggable={false}\n />\n ) : (\n <div className=\"DrawingHighlight__placeholder\">No drawing</div>\n )}\n </div>\n </div>\n </Rnd>\n </div>\n );\n};\n","import React, {\n CSSProperties,\n MouseEvent,\n ReactNode,\n useState,\n useRef,\n useEffect,\n} from \"react\";\nimport { Rnd } from \"react-rnd\";\nimport { getPageFromElement } from \"../lib/pdfjs-dom\";\nimport type { LTWHP, ShapeType, ViewportHighlight } from \"../types\";\n\n/**\n * Style options for shape highlight appearance.\n */\nexport interface ShapeStyle {\n strokeColor?: string;\n strokeWidth?: number;\n}\n\n/**\n * The props type for {@link ShapeHighlight}.\n *\n * @category Component Properties\n */\nexport interface ShapeHighlightProps {\n /**\n * The highlight to be rendered as a {@link ShapeHighlight}.\n */\n highlight: ViewportHighlight;\n\n /**\n * A callback triggered whenever the highlight position or size changes.\n *\n * @param rect - The updated highlight area.\n */\n onChange?(rect: LTWHP): void;\n\n /**\n * Has the highlight been auto-scrolled into view?\n */\n isScrolledTo?: boolean;\n\n /**\n * react-rnd bounds on the highlight area.\n */\n bounds?: string | Element;\n\n /**\n * A callback triggered on context menu.\n */\n onContextMenu?(event: MouseEvent<HTMLDivElement>): void;\n\n /**\n * Event called when editing begins (drag or resize).\n */\n onEditStart?(): void;\n\n /**\n * Event called when editing ends.\n */\n onEditEnd?(): void;\n\n /**\n * Custom styling for the container.\n */\n style?: CSSProperties;\n\n /**\n * The type of shape to render.\n * @default \"rectangle\"\n */\n shapeType?: ShapeType;\n\n /**\n * Stroke color for the shape.\n * @default \"#000000\"\n */\n strokeColor?: string;\n\n /**\n * Stroke width for the shape.\n * @default 2\n */\n strokeWidth?: number;\n\n /**\n * Callback triggered when the style changes.\n */\n onStyleChange?(style: ShapeStyle): void;\n\n /**\n * Callback triggered when the delete button is clicked.\n */\n onDelete?(): void;\n\n /**\n * Custom style icon. Replaces the default palette icon.\n */\n styleIcon?: ReactNode;\n\n /**\n * Custom delete icon. Replaces the default trash icon.\n */\n deleteIcon?: ReactNode;\n\n /**\n * Custom color presets for the style panel.\n */\n colorPresets?: string[];\n\n /**\n * For arrows: start point as percentage of bounding box (0-1).\n */\n startPoint?: { x: number; y: number };\n\n /**\n * For arrows: end point as percentage of bounding box (0-1).\n */\n endPoint?: { x: number; y: number };\n}\n\n// Default icons\nconst DefaultStyleIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z\" />\n </svg>\n);\n\nconst DefaultDeleteIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" />\n </svg>\n);\n\n// Default color presets for shapes\nconst DEFAULT_COLOR_PRESETS = [\n \"#000000\", // Black\n \"#FF0000\", // Red\n \"#0000FF\", // Blue\n \"#00AA00\", // Green\n \"#FF6600\", // Orange\n];\n\n// Stroke width options\nconst STROKE_WIDTHS = [\n { label: \"Thin\", value: 1 },\n { label: \"Medium\", value: 2 },\n { label: \"Thick\", value: 4 },\n];\n\n/**\n * Renders a draggable, resizable shape annotation.\n * Supports rectangle, circle/ellipse, and arrow shapes.\n *\n * @category Component\n */\nexport const ShapeHighlight = ({\n highlight,\n onChange,\n isScrolledTo,\n bounds,\n onContextMenu,\n onEditStart,\n onEditEnd,\n style,\n shapeType = \"rectangle\",\n strokeColor = \"#000000\",\n strokeWidth = 2,\n onStyleChange,\n onDelete,\n styleIcon,\n deleteIcon,\n colorPresets = DEFAULT_COLOR_PRESETS,\n startPoint,\n endPoint,\n}: ShapeHighlightProps) => {\n const [isStylePanelOpen, setIsStylePanelOpen] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const stylePanelRef = useRef<HTMLDivElement>(null);\n\n // Close style panel when clicking outside\n useEffect(() => {\n if (!isStylePanelOpen) return;\n\n const handleClickOutside = (e: globalThis.MouseEvent) => {\n if (\n stylePanelRef.current &&\n !stylePanelRef.current.contains(e.target as Node)\n ) {\n setIsStylePanelOpen(false);\n }\n };\n\n // Delay adding listener to avoid immediate close\n const timeoutId = setTimeout(() => {\n document.addEventListener(\"mousedown\", handleClickOutside);\n }, 0);\n\n return () => {\n clearTimeout(timeoutId);\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [isStylePanelOpen]);\n\n const highlightClass = isScrolledTo ? \"ShapeHighlight--scrolledTo\" : \"\";\n\n // Generate key based on position for Rnd remount on position changes\n const key = `${highlight.position.boundingRect.width}${highlight.position.boundingRect.height}${highlight.position.boundingRect.left}${highlight.position.boundingRect.top}`;\n\n // Generate unique ID for SVG markers\n const markerId = `arrowhead-${highlight.id}`;\n\n // Render the shape SVG\n const renderShape = (width: number, height: number) => {\n switch (shapeType) {\n case \"rectangle\":\n return (\n <svg\n className=\"ShapeHighlight__svg\"\n width={width}\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n >\n <rect\n x={strokeWidth / 2}\n y={strokeWidth / 2}\n width={width - strokeWidth}\n height={height - strokeWidth}\n stroke={strokeColor}\n strokeWidth={strokeWidth}\n fill=\"none\"\n />\n </svg>\n );\n case \"circle\":\n return (\n <svg\n className=\"ShapeHighlight__svg\"\n width={width}\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n >\n <ellipse\n cx={width / 2}\n cy={height / 2}\n rx={width / 2 - strokeWidth / 2}\n ry={height / 2 - strokeWidth / 2}\n stroke={strokeColor}\n strokeWidth={strokeWidth}\n fill=\"none\"\n />\n </svg>\n );\n case \"arrow\": {\n // Use stored start/end points if available, otherwise default to left-to-right\n const x1 = startPoint ? startPoint.x * width : strokeWidth;\n const y1 = startPoint ? startPoint.y * height : height / 2;\n const x2 = endPoint ? endPoint.x * width : width - strokeWidth - 10;\n const y2 = endPoint ? endPoint.y * height : height / 2;\n\n return (\n <svg\n className=\"ShapeHighlight__svg\"\n width={width}\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n >\n <defs>\n <marker\n id={markerId}\n markerWidth=\"10\"\n markerHeight=\"7\"\n refX=\"9\"\n refY=\"3.5\"\n orient=\"auto\"\n >\n <polygon points=\"0 0, 10 3.5, 0 7\" fill={strokeColor} />\n </marker>\n </defs>\n <line\n x1={x1}\n y1={y1}\n x2={x2}\n y2={y2}\n stroke={strokeColor}\n strokeWidth={strokeWidth}\n markerEnd={`url(#${markerId})`}\n />\n </svg>\n );\n }\n default:\n return null;\n }\n };\n\n return (\n <div\n className={`ShapeHighlight ${highlightClass}`}\n onContextMenu={onContextMenu}\n >\n {/* Toolbar wrapper - extends down to overlap with shape */}\n {(onStyleChange || onDelete) && (\n <div\n className=\"ShapeHighlight__toolbar-wrapper\"\n style={{\n position: \"absolute\",\n left: highlight.position.boundingRect.left,\n top: highlight.position.boundingRect.top - 28,\n paddingBottom: 12,\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n <div\n className={`ShapeHighlight__toolbar ${isHovered || isStylePanelOpen ? \"ShapeHighlight__toolbar--visible\" : \"\"}`}\n >\n {onStyleChange && (\n <button\n className=\"ShapeHighlight__style-button\"\n onClick={(e) => {\n e.stopPropagation();\n setIsStylePanelOpen(!isStylePanelOpen);\n }}\n title=\"Change style\"\n type=\"button\"\n >\n {styleIcon || <DefaultStyleIcon />}\n </button>\n )}\n {onDelete && (\n <button\n className=\"ShapeHighlight__delete-button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete();\n }}\n title=\"Delete\"\n type=\"button\"\n >\n {deleteIcon || <DefaultDeleteIcon />}\n </button>\n )}\n </div>\n\n {/* Style Panel - inside wrapper */}\n {isStylePanelOpen && onStyleChange && (\n <div\n className=\"ShapeHighlight__style-panel\"\n ref={stylePanelRef}\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"ShapeHighlight__style-row\">\n <label>Color</label>\n <div className=\"ShapeHighlight__color-options\">\n <div className=\"ShapeHighlight__color-presets\">\n {colorPresets.map((c) => (\n <button\n key={c}\n type=\"button\"\n className={`ShapeHighlight__color-preset ${strokeColor === c ? \"active\" : \"\"}`}\n style={{ backgroundColor: c }}\n onClick={() => onStyleChange({ strokeColor: c })}\n title={c}\n />\n ))}\n </div>\n <input\n type=\"color\"\n value={strokeColor}\n onChange={(e) => {\n onStyleChange({ strokeColor: e.target.value });\n }}\n />\n </div>\n </div>\n <div className=\"ShapeHighlight__style-row\">\n <label>Width</label>\n <div className=\"ShapeHighlight__width-options\">\n {STROKE_WIDTHS.map((w) => (\n <button\n key={w.value}\n type=\"button\"\n className={`ShapeHighlight__width-button ${strokeWidth === w.value ? \"active\" : \"\"}`}\n onClick={() => onStyleChange({ strokeWidth: w.value })}\n title={w.label}\n >\n {w.label}\n </button>\n ))}\n </div>\n </div>\n </div>\n )}\n </div>\n )}\n\n <Rnd\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n className=\"ShapeHighlight__rnd\"\n onDragStop={(_, data) => {\n const boundingRect: LTWHP = {\n ...highlight.position.boundingRect,\n top: data.y,\n left: data.x,\n };\n onChange?.(boundingRect);\n onEditEnd?.();\n }}\n onDragStart={onEditStart}\n onResizeStop={(_e, _direction, ref, _delta, position) => {\n const boundingRect: LTWHP = {\n top: position.y,\n left: position.x,\n width: ref.offsetWidth,\n height: ref.offsetHeight,\n pageNumber:\n getPageFromElement(ref)?.number ||\n highlight.position.boundingRect.pageNumber,\n };\n onChange?.(boundingRect);\n onEditEnd?.();\n }}\n onResizeStart={onEditStart}\n default={{\n x: highlight.position.boundingRect.left,\n y: highlight.position.boundingRect.top,\n width: highlight.position.boundingRect.width || 100,\n height: highlight.position.boundingRect.height || 100,\n }}\n minWidth={20}\n minHeight={20}\n key={key}\n bounds={bounds}\n lockAspectRatio={shapeType === \"circle\"}\n onClick={(event: Event) => {\n event.stopPropagation();\n event.preventDefault();\n }}\n style={style}\n >\n <div className=\"ShapeHighlight__container\">\n {renderShape(\n highlight.position.boundingRect.width || 100,\n highlight.position.boundingRect.height || 100\n )}\n </div>\n </Rnd>\n </div>\n );\n};\n","import React, { ReactNode, useEffect, useRef, useState } from \"react\";\n\nimport { GlobalWorkerOptions, OnProgressParameters, getDocument, type PDFDocumentLoadingTask, type PDFDocumentProxy } from \"pdfjs-dist\";\nimport { DocumentInitParameters, TypedArray } from \"pdfjs-dist/types/src/display/api\";\n\nconst DEFAULT_BEFORE_LOAD = (progress: OnProgressParameters) => (\n <div style={{ color: \"black\" }}>\n Loading {Math.floor((progress.loaded / progress.total) * 100)}%\n </div>\n);\n\nconst DEFAULT_ERROR_MESSAGE = (error: Error) => (\n <div style={{ color: \"black\" }}>{error.message}</div>\n);\n\nconst DEFAULT_ON_ERROR = (error: Error) => {\n throw new Error(`Error loading PDF document: ${error.message}!`);\n};\n\nconst DEFAULT_WORKER_SRC =\n \"https://unpkg.com/pdfjs-dist@4.4.168/build/pdf.worker.min.mjs\";\n\n/**\n * The props type for {@link PdfLoader}.\n *\n * @category Component Properties\n */\nexport interface PdfLoaderProps {\n /**\n * The document to be loaded by PDF.js.\n * If you need to pass HTTP headers, auth parameters,\n * or other pdf settings, do it through here.\n */\n document: string | URL | TypedArray | DocumentInitParameters;\n\n /**\n * Callback to render content before the PDF document is loaded.\n *\n * @param progress - PDF.js progress status.\n * @returns - Component to be rendered in space of the PDF document while loading.\n */\n beforeLoad?(progress: OnProgressParameters): ReactNode;\n\n /**\n * Component to render in the case of any PDF loading errors.\n *\n * @param error - PDF loading error.\n * @returns - Component to be rendered in space of the PDF document.\n */\n errorMessage?(error: Error): ReactNode;\n\n /**\n * Child components to use/render the loaded PDF document.\n *\n * @param pdfDocument - The loaded PDF document.\n * @returns - Component to render once PDF document is loaded.\n */\n children(pdfDocument: PDFDocumentProxy): ReactNode;\n\n /**\n * Callback triggered whenever an error occurs.\n *\n * @param error - PDF Loading error triggering the event.\n * @returns - Component to be rendered in space of the PDF document.\n */\n onError?(error: Error): void;\n\n /**\n * NOTE: This will be applied to all PdfLoader instances.\n * If you want to only apply a source to this instance, use the document parameters.\n */\n workerSrc?: string;\n}\n\n/**\n * A component for loading a PDF document and passing it to a child.\n *\n * @category Component\n */\nexport const PdfLoader = ({\n document,\n beforeLoad = DEFAULT_BEFORE_LOAD,\n errorMessage = DEFAULT_ERROR_MESSAGE,\n children,\n onError = DEFAULT_ON_ERROR,\n workerSrc = DEFAULT_WORKER_SRC,\n}: PdfLoaderProps) => {\n const pdfLoadingTaskRef = useRef<PDFDocumentLoadingTask | null>(null);\n const pdfDocumentRef = useRef<PDFDocumentProxy | null>(null);\n\n const [error, setError] = useState<Error | null>(null);\n const [loadingProgress, setLoadingProgress] =\n useState<OnProgressParameters | null>(null);\n\n // Intitialise document\n useEffect(() => {\n GlobalWorkerOptions.workerSrc = workerSrc;\n pdfLoadingTaskRef.current = getDocument(document);\n pdfLoadingTaskRef.current.onProgress = (progress: OnProgressParameters) => {\n setLoadingProgress(progress.loaded > progress.total ? null : progress);\n };\n\n pdfLoadingTaskRef.current.promise\n .then((pdfDocument: PDFDocumentProxy) => {\n pdfDocumentRef.current = pdfDocument;\n })\n .catch((error: Error) => {\n if (error.message != \"Worker was destroyed\") {\n setError(error);\n onError(error);\n }\n })\n .finally(() => {\n setLoadingProgress(null);\n });\n\n return () => {\n if (pdfLoadingTaskRef.current) {\n pdfLoadingTaskRef.current.destroy();\n }\n\n if (pdfDocumentRef.current) {\n pdfDocumentRef.current.destroy();\n }\n };\n }, [document]);\n\n return error\n ? errorMessage(error)\n : loadingProgress\n ? beforeLoad(loadingProgress)\n : pdfDocumentRef.current && children(pdfDocumentRef.current);\n};\n","import { PDFDocument, rgb, StandardFonts, PDFPage, PDFFont } from \"pdf-lib\";\nimport type { Scaled, ScaledPosition, ShapeData } from \"../types\";\n\n/**\n * Options for the PDF export function.\n *\n * @category Type\n */\nexport interface ExportPdfOptions {\n /** Default color for text highlights. Default: \"rgba(255, 226, 143, 0.5)\" */\n textHighlightColor?: string;\n /** Default color for area highlights. Default: \"rgba(255, 226, 143, 0.5)\" */\n areaHighlightColor?: string;\n /** Default text color for freetext. Default: \"#333333\" */\n defaultFreetextColor?: string;\n /** Default background for freetext. Default: \"#ffffc8\" */\n defaultFreetextBgColor?: string;\n /** Default font size for freetext. Default: 14 */\n defaultFreetextFontSize?: number;\n /** Progress callback for large PDFs */\n onProgress?: (current: number, total: number) => void;\n}\n\n/**\n * A highlight that can be exported to PDF.\n *\n * @category Type\n */\nexport interface ExportableHighlight {\n id: string;\n type?: \"text\" | \"area\" | \"freetext\" | \"image\" | \"drawing\" | \"shape\";\n content?: {\n text?: string;\n image?: string; // Base64 data URL\n shape?: ShapeData; // Shape data for shape highlights\n };\n position: ScaledPosition;\n /** Per-highlight color override (for text/area highlights) */\n highlightColor?: string;\n /** Style mode for text highlights: \"highlight\" (default), \"underline\", or \"strikethrough\" */\n highlightStyle?: \"highlight\" | \"underline\" | \"strikethrough\";\n /** Text color for freetext highlights */\n color?: string;\n /** Background color for freetext highlights */\n backgroundColor?: string;\n /** Font size for freetext highlights */\n fontSize?: string;\n /** Font family for freetext highlights (not used in export, Helvetica is always used) */\n fontFamily?: string;\n /** Shape type for shape highlights */\n shapeType?: \"rectangle\" | \"circle\" | \"arrow\";\n /** Stroke color for shape highlights */\n strokeColor?: string;\n /** Stroke width for shape highlights */\n strokeWidth?: number;\n}\n\n/**\n * Parse a color string to RGB values (0-1 range).\n */\nfunction parseColor(color: string): {\n r: number;\n g: number;\n b: number;\n a: number;\n} {\n // Handle rgba(r, g, b, a) and rgb(r, g, b)\n const rgbaMatch = color.match(\n /rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*([\\d.]+))?\\)/\n );\n if (rgbaMatch) {\n return {\n r: parseInt(rgbaMatch[1]) / 255,\n g: parseInt(rgbaMatch[2]) / 255,\n b: parseInt(rgbaMatch[3]) / 255,\n a: rgbaMatch[4] ? parseFloat(rgbaMatch[4]) : 1,\n };\n }\n\n // Handle hex (#RRGGBB or #RGB)\n const hex = color.replace(\"#\", \"\");\n if (hex.length === 3) {\n return {\n r: parseInt(hex[0] + hex[0], 16) / 255,\n g: parseInt(hex[1] + hex[1], 16) / 255,\n b: parseInt(hex[2] + hex[2], 16) / 255,\n a: 1,\n };\n }\n if (hex.length === 6) {\n return {\n r: parseInt(hex.slice(0, 2), 16) / 255,\n g: parseInt(hex.slice(2, 4), 16) / 255,\n b: parseInt(hex.slice(4, 6), 16) / 255,\n a: 1,\n };\n }\n\n // Default yellow\n return { r: 1, g: 0.89, b: 0.56, a: 0.5 };\n}\n\n/**\n * Convert ScaledPosition coordinates to PDF points.\n * PDF coordinate system has origin at bottom-left.\n */\nfunction scaledToPdfPoints(\n scaled: Scaled,\n page: PDFPage\n): { x: number; y: number; width: number; height: number } {\n const pdfWidth = page.getWidth();\n const pdfHeight = page.getHeight();\n\n // Calculate position ratios\n const xRatio = pdfWidth / scaled.width;\n const yRatio = pdfHeight / scaled.height;\n\n const x = scaled.x1 * xRatio;\n const width = (scaled.x2 - scaled.x1) * xRatio;\n const height = (scaled.y2 - scaled.y1) * yRatio;\n\n // Flip Y (PDF origin is bottom-left, screen origin is top-left)\n const y = pdfHeight - scaled.y1 * yRatio - height;\n\n return { x, y, width, height };\n}\n\n/**\n * Convert base64 data URL to bytes.\n */\nfunction dataUrlToBytes(dataUrl: string): {\n bytes: Uint8Array;\n type: \"png\" | \"jpg\";\n} {\n const base64 = dataUrl.split(\",\")[1];\n const byteString = atob(base64);\n const bytes = new Uint8Array(byteString.length);\n for (let i = 0; i < byteString.length; i++) {\n bytes[i] = byteString.charCodeAt(i);\n }\n const type = dataUrl.includes(\"image/png\") ? \"png\" : \"jpg\";\n return { bytes, type };\n}\n\n/**\n * Wrap text into multiple lines that fit within maxWidth.\n * Long words are broken character by character (like CSS word-wrap: break-word).\n */\nfunction wrapText(\n text: string,\n font: PDFFont,\n fontSize: number,\n maxWidth: number\n): string[] {\n if (!text || maxWidth <= 0) return [];\n\n const lines: string[] = [];\n\n // Split by newlines first to preserve intentional line breaks\n const paragraphs = text.split(/\\n/);\n\n for (const paragraph of paragraphs) {\n if (!paragraph.trim()) {\n lines.push(\"\");\n continue;\n }\n\n const words = paragraph.split(/\\s+/);\n let currentLine = \"\";\n\n for (const word of words) {\n const testLine = currentLine ? `${currentLine} ${word}` : word;\n const testWidth = font.widthOfTextAtSize(testLine, fontSize);\n\n if (testWidth <= maxWidth) {\n currentLine = testLine;\n } else {\n // Push current line if exists\n if (currentLine) {\n lines.push(currentLine);\n currentLine = \"\";\n }\n\n // Check if word itself is too wide - break it character by character\n if (font.widthOfTextAtSize(word, fontSize) > maxWidth) {\n let remaining = word;\n while (remaining.length > 0) {\n let charCount = 1;\n // Find how many characters fit in maxWidth\n while (\n charCount < remaining.length &&\n font.widthOfTextAtSize(remaining.substring(0, charCount + 1), fontSize) <= maxWidth\n ) {\n charCount++;\n }\n const chunk = remaining.substring(0, charCount);\n remaining = remaining.substring(charCount);\n\n if (remaining.length > 0) {\n // More characters remaining, push this chunk as a complete line\n lines.push(chunk);\n } else {\n // Last chunk, keep it as current line (may combine with next word)\n currentLine = chunk;\n }\n }\n } else {\n currentLine = word;\n }\n }\n }\n if (currentLine) lines.push(currentLine);\n }\n\n return lines;\n}\n\n/**\n * Group highlights by page number.\n */\nfunction groupByPage(\n highlights: ExportableHighlight[]\n): Map<number, ExportableHighlight[]> {\n const map = new Map<number, ExportableHighlight[]>();\n for (const h of highlights) {\n const pageNum = h.position.boundingRect.pageNumber;\n if (!map.has(pageNum)) map.set(pageNum, []);\n map.get(pageNum)!.push(h);\n }\n return map;\n}\n\n/**\n * Render a text highlight (multiple rectangles for multi-line selections).\n * Supports highlight (background), underline, and strikethrough styles.\n */\nasync function renderTextHighlight(\n page: PDFPage,\n highlight: ExportableHighlight,\n options: ExportPdfOptions\n): Promise<void> {\n // Per-highlight color override or fallback to default\n const colorStr =\n highlight.highlightColor ||\n options.textHighlightColor ||\n \"rgba(255, 226, 143, 0.5)\";\n const color = parseColor(colorStr);\n const highlightStyle = highlight.highlightStyle || \"highlight\";\n\n // Text highlights use rects array for multi-line selections\n const rects =\n highlight.position.rects.length > 0\n ? highlight.position.rects\n : [highlight.position.boundingRect];\n\n for (const rect of rects) {\n const { x, y, width, height } = scaledToPdfPoints(rect, page);\n\n if (highlightStyle === \"highlight\") {\n // Draw filled rectangle for background highlight\n page.drawRectangle({\n x,\n y,\n width,\n height,\n color: rgb(color.r, color.g, color.b),\n opacity: color.a,\n });\n } else if (highlightStyle === \"underline\") {\n // Draw line at bottom of rectangle\n const lineThickness = Math.max(1, height * 0.1);\n page.drawRectangle({\n x,\n y,\n width,\n height: lineThickness,\n color: rgb(color.r, color.g, color.b),\n opacity: color.a,\n });\n } else if (highlightStyle === \"strikethrough\") {\n // Draw line through middle of rectangle\n const lineThickness = Math.max(1, height * 0.1);\n const lineY = y + height / 2 - lineThickness / 2;\n page.drawRectangle({\n x,\n y: lineY,\n width,\n height: lineThickness,\n color: rgb(color.r, color.g, color.b),\n opacity: color.a,\n });\n }\n }\n}\n\n/**\n * Render an area highlight (single rectangle).\n */\nasync function renderAreaHighlight(\n page: PDFPage,\n highlight: ExportableHighlight,\n options: ExportPdfOptions\n): Promise<void> {\n // Per-highlight color override or fallback to default\n const colorStr =\n highlight.highlightColor ||\n options.areaHighlightColor ||\n \"rgba(255, 226, 143, 0.5)\";\n const color = parseColor(colorStr);\n const { x, y, width, height } = scaledToPdfPoints(\n highlight.position.boundingRect,\n page\n );\n\n page.drawRectangle({\n x,\n y,\n width,\n height,\n color: rgb(color.r, color.g, color.b),\n opacity: color.a,\n });\n}\n\n/**\n * Render a freetext highlight (background rectangle + text).\n * Text is wrapped to fit within the box.\n */\nasync function renderFreetextHighlight(\n page: PDFPage,\n highlight: ExportableHighlight,\n options: ExportPdfOptions,\n font: PDFFont\n): Promise<void> {\n const text = highlight.content?.text || \"\";\n const textColor = parseColor(\n highlight.color || options.defaultFreetextColor || \"#333333\"\n );\n\n // Get box dimensions in PDF points\n const { x, y, width, height } = scaledToPdfPoints(\n highlight.position.boundingRect,\n page\n );\n\n // Scale font size by the same ratio used for the box coordinates\n // This ensures the font scales proportionally with the box\n const pdfHeight = page.getHeight();\n const yRatio = pdfHeight / highlight.position.boundingRect.height;\n const storedFontSize =\n parseInt(highlight.fontSize || \"\") || options.defaultFreetextFontSize || 14;\n const fontSize = storedFontSize * yRatio;\n\n console.log(\"Freetext export:\", {\n storedFontSize,\n yRatio,\n fontSize,\n boxDimensions: { x, y, width, height },\n text: text.substring(0, 50),\n });\n\n // Draw background (skip if transparent)\n const bgColorValue = highlight.backgroundColor || options.defaultFreetextBgColor || \"#ffffc8\";\n if (bgColorValue !== \"transparent\") {\n const bgColor = parseColor(bgColorValue);\n page.drawRectangle({\n x,\n y,\n width,\n height,\n color: rgb(bgColor.r, bgColor.g, bgColor.b),\n opacity: bgColor.a,\n });\n }\n\n // Draw wrapped text with scaled padding\n const padding = 4 * yRatio;\n const maxWidth = width - padding * 2;\n const lineHeight = fontSize * 1.3;\n\n if (maxWidth > 0 && text) {\n const lines = wrapText(text, font, fontSize, maxWidth);\n let currentY = y + height - fontSize - padding;\n\n for (const line of lines) {\n // Stop if we've run out of vertical space\n if (currentY < y + padding) break;\n\n // Skip empty lines but still move down\n if (line.trim()) {\n page.drawText(line, {\n x: x + padding,\n y: currentY,\n size: fontSize,\n font,\n color: rgb(textColor.r, textColor.g, textColor.b),\n });\n }\n\n currentY -= lineHeight;\n }\n }\n}\n\n/**\n * Transform visual coordinates to raw MediaBox coordinates.\n * pdf-lib's drawImage uses raw MediaBox space, but our coordinates are in visual space.\n */\nfunction transformToRawCoordinates(\n page: PDFPage,\n x: number,\n y: number,\n width: number,\n height: number\n): { x: number; y: number; width: number; height: number } {\n const rotation = page.getRotation().angle;\n const pageWidth = page.getWidth(); // Visual width\n const pageHeight = page.getHeight(); // Visual height\n\n if (rotation === 90) {\n // Visual (x, y) → Raw MediaBox coordinates\n // When rotated 90° CCW, visual top-left maps to raw bottom-left\n return {\n x: y,\n y: pageWidth - x - width,\n width: height,\n height: width,\n };\n } else if (rotation === 180) {\n // Rotated 180°, origin flips to opposite corner\n return {\n x: pageWidth - x - width,\n y: pageHeight - y - height,\n width,\n height,\n };\n } else if (rotation === 270) {\n // When rotated 90° CW (270° CCW)\n return {\n x: pageHeight - y - height,\n y: x,\n width: height,\n height: width,\n };\n }\n\n // No rotation - coordinates are already correct\n return { x, y, width, height };\n}\n\n/**\n * Render an image highlight (embedded image).\n * Handles page rotation by transforming visual coordinates to raw MediaBox space.\n * Image fills the entire bounding box to match the visual wrapper in preview.\n */\nasync function renderImageHighlight(\n pdfDoc: PDFDocument,\n page: PDFPage,\n highlight: ExportableHighlight\n): Promise<void> {\n const imageDataUrl = highlight.content?.image;\n if (!imageDataUrl) return;\n\n try {\n const { bytes, type } = dataUrlToBytes(imageDataUrl);\n const image =\n type === \"png\"\n ? await pdfDoc.embedPng(bytes)\n : await pdfDoc.embedJpg(bytes);\n\n // Calculate coordinates in visual space - use full bounding box dimensions\n const visualCoords = scaledToPdfPoints(\n highlight.position.boundingRect,\n page\n );\n\n // Transform to raw MediaBox coordinates based on page rotation\n const rawCoords = transformToRawCoordinates(\n page,\n visualCoords.x,\n visualCoords.y,\n visualCoords.width,\n visualCoords.height\n );\n\n console.log(\"Image export:\", {\n rotation: page.getRotation().angle,\n visualCoords,\n rawCoords,\n });\n\n // Draw image filling the entire bounding box\n page.drawImage(image, {\n x: rawCoords.x,\n y: rawCoords.y,\n width: rawCoords.width,\n height: rawCoords.height,\n });\n } catch (error) {\n console.error(\"Failed to embed image:\", error);\n }\n}\n\n/**\n * Render a shape highlight (rectangle, circle, or arrow).\n */\nasync function renderShapeHighlight(\n page: PDFPage,\n highlight: ExportableHighlight\n): Promise<void> {\n // Get shape data from content or top-level properties\n const shapeType = highlight.content?.shape?.shapeType || highlight.shapeType || \"rectangle\";\n const strokeColorStr = highlight.content?.shape?.strokeColor || highlight.strokeColor || \"#000000\";\n const strokeWidth = highlight.content?.shape?.strokeWidth || highlight.strokeWidth || 2;\n\n const color = parseColor(strokeColorStr);\n const { x, y, width, height } = scaledToPdfPoints(\n highlight.position.boundingRect,\n page\n );\n\n switch (shapeType) {\n case \"rectangle\":\n page.drawRectangle({\n x,\n y,\n width,\n height,\n borderColor: rgb(color.r, color.g, color.b),\n borderWidth: strokeWidth,\n opacity: color.a,\n });\n break;\n\n case \"circle\":\n page.drawEllipse({\n x: x + width / 2,\n y: y + height / 2,\n xScale: width / 2,\n yScale: height / 2,\n borderColor: rgb(color.r, color.g, color.b),\n borderWidth: strokeWidth,\n opacity: color.a,\n });\n break;\n\n case \"arrow\": {\n // Use stored start/end points if available, otherwise default to left-to-right\n const startPt = highlight.content?.shape?.startPoint;\n const endPt = highlight.content?.shape?.endPoint;\n\n // Calculate actual coordinates\n // Note: PDF coordinates have Y going up, so we need to flip the Y\n const startX = startPt ? x + startPt.x * width : x;\n const startY = startPt ? y + (1 - startPt.y) * height : y + height / 2;\n const endX = endPt ? x + endPt.x * width : x + width;\n const endY = endPt ? y + (1 - endPt.y) * height : y + height / 2;\n\n // Draw the main line\n page.drawLine({\n start: { x: startX, y: startY },\n end: { x: endX, y: endY },\n color: rgb(color.r, color.g, color.b),\n thickness: strokeWidth,\n opacity: color.a,\n });\n\n // Calculate arrowhead direction\n const angle = Math.atan2(endY - startY, endX - startX);\n const arrowSize = Math.min(15, width * 0.2, height * 0.4);\n const arrowAngle = Math.PI / 6; // 30 degrees\n\n // Draw arrowhead (two lines forming a V at the end)\n page.drawLine({\n start: {\n x: endX - arrowSize * Math.cos(angle - arrowAngle),\n y: endY - arrowSize * Math.sin(angle - arrowAngle),\n },\n end: { x: endX, y: endY },\n color: rgb(color.r, color.g, color.b),\n thickness: strokeWidth,\n opacity: color.a,\n });\n page.drawLine({\n start: {\n x: endX - arrowSize * Math.cos(angle + arrowAngle),\n y: endY - arrowSize * Math.sin(angle + arrowAngle),\n },\n end: { x: endX, y: endY },\n color: rgb(color.r, color.g, color.b),\n thickness: strokeWidth,\n opacity: color.a,\n });\n break;\n }\n }\n}\n\n/**\n * Export a PDF with annotations embedded.\n *\n * @param pdfSource - The source PDF as a URL string, Uint8Array, or ArrayBuffer\n * @param highlights - Array of highlights to embed in the PDF\n * @param options - Export options for customizing colors and behavior\n * @returns Promise<Uint8Array> - The modified PDF as bytes\n *\n * @example\n * ```typescript\n * const pdfBytes = await exportPdf(pdfUrl, highlights, {\n * textHighlightColor: \"rgba(255, 255, 0, 0.4)\",\n * onProgress: (current, total) => console.log(`${current}/${total} pages`)\n * });\n *\n * // Download the file\n * const blob = new Blob([pdfBytes], { type: \"application/pdf\" });\n * const url = URL.createObjectURL(blob);\n * const a = document.createElement(\"a\");\n * a.href = url;\n * a.download = \"annotated.pdf\";\n * a.click();\n * URL.revokeObjectURL(url);\n * ```\n *\n * @category Function\n */\nexport async function exportPdf(\n pdfSource: string | Uint8Array | ArrayBuffer,\n highlights: ExportableHighlight[],\n options: ExportPdfOptions = {}\n): Promise<Uint8Array> {\n // Load PDF\n let pdfBytes: ArrayBuffer;\n if (typeof pdfSource === \"string\") {\n const response = await fetch(pdfSource);\n pdfBytes = await response.arrayBuffer();\n } else {\n pdfBytes =\n pdfSource instanceof Uint8Array\n ? pdfSource.buffer.slice(\n pdfSource.byteOffset,\n pdfSource.byteOffset + pdfSource.byteLength\n )\n : pdfSource;\n }\n\n const pdfDoc = await PDFDocument.load(pdfBytes);\n const pages = pdfDoc.getPages();\n const font = await pdfDoc.embedFont(StandardFonts.Helvetica);\n\n // Group by page and render\n const byPage = groupByPage(highlights);\n const totalPages = byPage.size;\n let currentPage = 0;\n\n for (const [pageNum, pageHighlights] of byPage) {\n const page = pages[pageNum - 1]; // 1-indexed to 0-indexed\n if (!page) continue;\n\n for (const highlight of pageHighlights) {\n switch (highlight.type) {\n case \"text\":\n await renderTextHighlight(page, highlight, options);\n break;\n case \"area\":\n await renderAreaHighlight(page, highlight, options);\n break;\n case \"freetext\":\n await renderFreetextHighlight(page, highlight, options, font);\n break;\n case \"image\":\n await renderImageHighlight(pdfDoc, page, highlight);\n break;\n case \"drawing\":\n // Drawings are stored as PNG images, reuse image highlight rendering\n await renderImageHighlight(pdfDoc, page, highlight);\n break;\n case \"shape\":\n await renderShapeHighlight(page, highlight);\n break;\n default:\n // Default to area highlight for backwards compatibility\n await renderAreaHighlight(page, highlight, options);\n }\n }\n\n currentPage++;\n options.onProgress?.(currentPage, totalPages);\n }\n\n return pdfDoc.save();\n}\n"],"mappings":"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","names":["React","useLayoutEffect","useRef","useState","pageNumber","X0","X1","Y0","Y1","document","React","createContext","useContext","React","React","useEffect","useRef","useState","getBoundingRect","useState","useRef","useEffect","event","React","React","useRef","useEffect","useCallback","useState","useRef","useState","useCallback","useEffect","React","React","useRef","useState","useState","useRef","React","useState","useRef","useLayoutEffect","React","React","useState","useRef","useEffect","React","useRef","React","useEffect","useRef","useRef","React","React","useState","useRef","useEffect","DefaultStyleIcon","React","DefaultDeleteIcon","DEFAULT_COLOR_PRESETS","useState","useRef","useEffect","React","useState","useRef","useEffect","Rnd","React","DefaultStyleIcon","DefaultDeleteIcon","useState","useRef","useEffect","Rnd","React","Rnd","DefaultDragIcon","React","DefaultDeleteIcon","Rnd","React","useRef","useEffect","useCallback","React","useState","useCallback","useEffect","useRef","Rnd","DefaultDragIcon","React","DefaultDeleteIcon","useState","useRef","useEffect","useCallback","Rnd","React","useState","useRef","useEffect","Rnd","DefaultStyleIcon","React","DefaultDeleteIcon","DEFAULT_COLOR_PRESETS","STROKE_WIDTHS","useState","useRef","useEffect","Rnd","React","useEffect","useRef","useState","getDocument","document","error"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/PdfHighlighter.tsx","../../src/contexts/PdfHighlighterContext.ts","../../src/lib/coordinates.ts","../../src/lib/get-bounding-rect.ts","../../src/lib/optimize-client-rects.ts","../../src/lib/get-client-rects.ts","../../src/lib/group-highlights-by-page.ts","../../src/lib/pdfjs-dom.ts","../../src/components/DrawingCanvas.tsx","../../src/components/HighlightLayer.tsx","../../src/contexts/HighlightContext.ts","../../src/lib/screenshot.ts","../../src/components/MouseSelection.tsx","../../src/components/ShapeCanvas.tsx","../../src/components/TipContainer.tsx","../../src/components/TextHighlight.tsx","../../src/components/MonitoredHighlightContainer.tsx","../../src/components/MouseMonitor.tsx","../../src/components/AreaHighlight.tsx","../../src/components/FreetextHighlight.tsx","../../src/components/ImageHighlight.tsx","../../src/components/SignaturePad.tsx","../../src/components/DrawingHighlight.tsx","../../src/components/ShapeHighlight.tsx","../../src/components/PdfLoader.tsx","../../src/lib/export-pdf.ts"],"sourcesContent":["import debounce from \"lodash.debounce\";\nimport { PDFDocumentProxy } from \"pdfjs-dist\";\nimport React, {\n CSSProperties,\n PointerEventHandler,\n ReactNode,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport {\n PdfHighlighterContext,\n PdfHighlighterUtils,\n} from \"../contexts/PdfHighlighterContext\";\nimport { scaledToViewport, viewportPositionToScaled } from \"../lib/coordinates\";\nimport getBoundingRect from \"../lib/get-bounding-rect\";\nimport getClientRects from \"../lib/get-client-rects\";\nimport groupHighlightsByPage from \"../lib/group-highlights-by-page\";\nimport {\n asElement,\n findOrCreateContainerLayer,\n getPageFromElement,\n getPagesFromRange,\n getWindow,\n isHTMLElement,\n} from \"../lib/pdfjs-dom\";\nimport {\n Content,\n DrawingStroke,\n GhostHighlight,\n Highlight,\n HighlightBindings,\n PdfScaleValue,\n PdfSelection,\n ScaledPosition,\n ShapeData,\n ShapeType,\n Tip,\n ViewportPosition,\n} from \"../types\";\nimport { DrawingCanvas } from \"./DrawingCanvas\";\nimport { HighlightLayer } from \"./HighlightLayer\";\nimport { MouseSelection } from \"./MouseSelection\";\nimport { ShapeCanvas } from \"./ShapeCanvas\";\nimport { TipContainer } from \"./TipContainer\";\n\nimport type { EventBus as TEventBus, PDFLinkService as TPDFLinkService, PDFViewer as TPDFViewer } from \"pdfjs-dist/web/pdf_viewer.mjs\";\n\nlet EventBus: typeof TEventBus, PDFLinkService: typeof TPDFLinkService, PDFViewer: typeof TPDFViewer;\n\n(async () => {\n // Due to breaking changes in PDF.js 4.0.189. See issue #17228\n const pdfjs = await import(\"pdfjs-dist/web/pdf_viewer.mjs\");\n EventBus = pdfjs.EventBus;\n PDFLinkService = pdfjs.PDFLinkService;\n PDFViewer = pdfjs.PDFViewer;\n})();\n\n\nconst SCROLL_MARGIN = 10;\nconst DEFAULT_SCALE_VALUE = \"auto\";\nconst DEFAULT_TEXT_SELECTION_COLOR = \"rgba(153,193,218,255)\";\n\nconst findOrCreateHighlightLayer = (textLayer: HTMLElement) => {\n return findOrCreateContainerLayer(\n textLayer,\n \"PdfHighlighter__highlight-layer\",\n );\n};\n\nconst disableTextSelection = (viewer: InstanceType<typeof PDFViewer>, flag: boolean) => {\n viewer.viewer?.classList.toggle(\"PdfHighlighter--disable-selection\", flag);\n};\n\n/**\n * The props type for {@link PdfHighlighter}.\n *\n * @category Component Properties\n */\nexport interface PdfHighlighterProps {\n /**\n * Array of all highlights to be organised and fed through to the child\n * highlight container.\n */\n highlights: Array<Highlight>;\n\n /**\n * Event is called only once whenever the user changes scroll after\n * the autoscroll function, scrollToHighlight, has been called.\n */\n onScrollAway?(): void;\n\n /**\n * What scale to render the PDF at inside the viewer.\n */\n pdfScaleValue?: PdfScaleValue;\n\n /**\n * Callback triggered whenever a user finishes making a mouse selection or has\n * selected text.\n *\n * @param PdfSelection - Content and positioning of the selection. NOTE:\n * `makeGhostHighlight` will not work if the selection disappears.\n */\n onSelection?(PdfSelection: PdfSelection): void;\n\n /**\n * Callback triggered whenever a ghost (non-permanent) highlight is created.\n *\n * @param ghostHighlight - Ghost Highlight that has been created.\n */\n onCreateGhostHighlight?(ghostHighlight: GhostHighlight): void;\n\n /**\n * Callback triggered whenever a ghost (non-permanent) highlight is removed.\n *\n * @param ghostHighlight - Ghost Highlight that has been removed.\n */\n onRemoveGhostHighlight?(ghostHighlight: GhostHighlight): void;\n\n /**\n * Optional element that can be displayed as a tip whenever a user makes a\n * selection.\n */\n selectionTip?: ReactNode;\n\n /**\n * Condition to check before any mouse selection starts.\n *\n * @param event - mouse event associated with the new selection.\n * @returns - `True` if mouse selection should start.\n */\n enableAreaSelection?(event: MouseEvent): boolean;\n\n /**\n * When true, shows crosshair cursor indicating area selection mode is active.\n * Use this when area selection should be persistently enabled (not just on modifier key).\n */\n areaSelectionMode?: boolean;\n\n /**\n * Optional CSS styling for the rectangular mouse selection.\n */\n mouseSelectionStyle?: CSSProperties;\n\n /**\n * PDF document to view and overlay highlights.\n */\n pdfDocument: PDFDocumentProxy;\n\n /**\n * This should be a highlight container/renderer of some sorts. It will be\n * given appropriate context for a single highlight which it can then use to\n * render a TextHighlight, AreaHighlight, etc. in the correct place.\n */\n children: ReactNode;\n\n /**\n * Coloring for unhighlighted, selected text.\n */\n textSelectionColor?: string;\n\n /**\n * Creates a reference to the PdfHighlighterContext above the component.\n *\n * @param pdfHighlighterUtils - various useful tools with a PdfHighlighter.\n * See {@link PdfHighlighterContext} for more description.\n */\n utilsRef(pdfHighlighterUtils: PdfHighlighterUtils): void;\n\n /**\n * Style properties for the PdfHighlighter (scrollbar, background, etc.), NOT\n * the PDF.js viewer it encloses. If you want to edit the latter, use the\n * other style props like `textSelectionColor` or overwrite pdf_viewer.css\n */\n style?: CSSProperties;\n\n /**\n * Condition to check before freetext creation starts.\n *\n * @param event - mouse event associated with the click.\n * @returns - `True` if freetext creation should occur.\n */\n enableFreetextCreation?(event: MouseEvent): boolean;\n\n /**\n * Callback triggered when user clicks to create a freetext annotation.\n *\n * @param position - Scaled position where the click occurred.\n */\n onFreetextClick?(position: ScaledPosition): void;\n\n /**\n * Condition to check before image creation starts.\n *\n * @param event - mouse event associated with the click.\n * @returns - `True` if image creation should occur.\n */\n enableImageCreation?(event: MouseEvent): boolean;\n\n /**\n * Callback triggered when user clicks to create an image annotation.\n *\n * @param position - Scaled position where the click occurred.\n */\n onImageClick?(position: ScaledPosition): void;\n\n /**\n * Whether drawing mode is enabled.\n */\n enableDrawingMode?: boolean;\n\n /**\n * Callback triggered when a drawing is completed.\n *\n * @param dataUrl - The drawing as a PNG data URL.\n * @param position - Scaled position of the drawing on the page.\n * @param strokes - The stroke data for later editing.\n */\n onDrawingComplete?(dataUrl: string, position: ScaledPosition, strokes: DrawingStroke[]): void;\n\n /**\n * Callback triggered when drawing is cancelled.\n */\n onDrawingCancel?(): void;\n\n /**\n * Stroke color for drawing mode.\n * @default \"#000000\"\n */\n drawingStrokeColor?: string;\n\n /**\n * Stroke width for drawing mode.\n * @default 3\n */\n drawingStrokeWidth?: number;\n\n /**\n * The type of shape to create, or null if shape mode is not active.\n */\n enableShapeMode?: ShapeType | null;\n\n /**\n * Callback triggered when a shape is completed.\n *\n * @param position - Scaled position of the shape on the page.\n * @param shape - The shape data (type, color, width).\n */\n onShapeComplete?(position: ScaledPosition, shape: ShapeData): void;\n\n /**\n * Callback triggered when shape creation is cancelled.\n */\n onShapeCancel?(): void;\n\n /**\n * Stroke color for shape mode.\n * @default \"#000000\"\n */\n shapeStrokeColor?: string;\n\n /**\n * Stroke width for shape mode.\n * @default 2\n */\n shapeStrokeWidth?: number;\n}\n\n/**\n * This is a large-scale PDF viewer component designed to facilitate\n * highlighting. It should be used as a child to a {@link PdfLoader} to ensure\n * proper document loading. This does not itself render any highlights, but\n * instead its child should be the container component for each individual\n * highlight. This component will be provided appropriate HighlightContext for\n * rendering.\n *\n * @category Component\n */\nexport const PdfHighlighter = ({\n highlights,\n onScrollAway,\n pdfScaleValue = DEFAULT_SCALE_VALUE,\n onSelection: onSelectionFinished,\n onCreateGhostHighlight,\n onRemoveGhostHighlight,\n selectionTip,\n enableAreaSelection,\n areaSelectionMode,\n mouseSelectionStyle,\n pdfDocument,\n children,\n textSelectionColor = DEFAULT_TEXT_SELECTION_COLOR,\n utilsRef,\n style,\n enableFreetextCreation,\n onFreetextClick,\n enableImageCreation,\n onImageClick,\n enableDrawingMode,\n onDrawingComplete,\n onDrawingCancel,\n drawingStrokeColor = \"#000000\",\n drawingStrokeWidth = 3,\n enableShapeMode,\n onShapeComplete,\n onShapeCancel,\n shapeStrokeColor = \"#000000\",\n shapeStrokeWidth = 2,\n}: PdfHighlighterProps) => {\n // State\n const [tip, setTip] = useState<Tip | null>(null);\n const [isViewerReady, setIsViewerReady] = useState(false);\n\n // Refs\n const containerNodeRef = useRef<HTMLDivElement | null>(null);\n const highlightBindingsRef = useRef<{ [page: number]: HighlightBindings }>(\n {},\n );\n const ghostHighlightRef = useRef<GhostHighlight | null>(null);\n const selectionRef = useRef<PdfSelection | null>(null);\n const scrolledToHighlightIdRef = useRef<string | null>(null);\n const isAreaSelectionInProgressRef = useRef(false);\n const isEditInProgressRef = useRef(false);\n const updateTipPositionRef = useRef(() => { });\n\n const eventBusRef = useRef<InstanceType<typeof EventBus>>(new EventBus());\n const linkServiceRef = useRef<InstanceType<typeof PDFLinkService>>(\n new PDFLinkService({\n eventBus: eventBusRef.current,\n externalLinkTarget: 2,\n }),\n );\n const resizeObserverRef = useRef<ResizeObserver | null>(null);\n const viewerRef = useRef<InstanceType<typeof PDFViewer> | null>(null);\n\n // Initialise PDF Viewer\n useLayoutEffect(() => {\n if (!containerNodeRef.current) return;\n\n const debouncedDocumentInit = debounce(() => {\n viewerRef.current =\n viewerRef.current ||\n new PDFViewer({\n container: containerNodeRef.current!,\n eventBus: eventBusRef.current,\n textLayerMode: 2,\n removePageBorders: true,\n linkService: linkServiceRef.current,\n });\n\n viewerRef.current.setDocument(pdfDocument);\n linkServiceRef.current.setDocument(pdfDocument);\n linkServiceRef.current.setViewer(viewerRef.current);\n setIsViewerReady(true);\n }, 100);\n\n debouncedDocumentInit();\n\n return () => {\n debouncedDocumentInit.cancel();\n };\n }, [document]);\n\n // Initialise viewer event listeners\n useLayoutEffect(() => {\n if (!containerNodeRef.current) return;\n\n resizeObserverRef.current = new ResizeObserver(handleScaleValue);\n resizeObserverRef.current.observe(containerNodeRef.current);\n\n const doc = containerNodeRef.current.ownerDocument;\n\n eventBusRef.current.on(\"textlayerrendered\", renderHighlightLayers);\n eventBusRef.current.on(\"pagesinit\", handleScaleValue);\n doc.addEventListener(\"keydown\", handleKeyDown);\n\n renderHighlightLayers();\n\n return () => {\n eventBusRef.current.off(\"pagesinit\", handleScaleValue);\n eventBusRef.current.off(\"textlayerrendered\", renderHighlightLayers);\n doc.removeEventListener(\"keydown\", handleKeyDown);\n resizeObserverRef.current?.disconnect();\n };\n }, [selectionTip, highlights, onSelectionFinished]);\n\n // Event listeners\n const handleScroll = () => {\n onScrollAway && onScrollAway();\n scrolledToHighlightIdRef.current = null;\n renderHighlightLayers();\n };\n\n const handleMouseUp: PointerEventHandler = () => {\n const container = containerNodeRef.current;\n const selection = getWindow(container).getSelection();\n\n if (!container || !selection || selection.isCollapsed || !viewerRef.current)\n return;\n\n const range = selection.rangeCount > 0 ? selection.getRangeAt(0) : null;\n\n // Check the selected text is in the document, not the tip\n if (!range || !container.contains(range.commonAncestorContainer)) return;\n\n const pages = getPagesFromRange(range);\n if (!pages || pages.length === 0) return;\n\n const rects = getClientRects(range, pages);\n if (rects.length === 0) return;\n\n const viewportPosition: ViewportPosition = {\n boundingRect: getBoundingRect(rects),\n rects,\n };\n\n const scaledPosition = viewportPositionToScaled(\n viewportPosition,\n viewerRef.current,\n );\n\n const content: Content = {\n text: selection.toString().split(\"\\n\").join(\" \"), // Make all line breaks spaces\n };\n\n selectionRef.current = {\n content,\n type: \"text\",\n position: scaledPosition,\n makeGhostHighlight: () => {\n ghostHighlightRef.current = {\n content: content,\n type: \"text\",\n position: scaledPosition,\n };\n\n onCreateGhostHighlight &&\n onCreateGhostHighlight(ghostHighlightRef.current);\n clearTextSelection();\n renderHighlightLayers();\n return ghostHighlightRef.current;\n },\n };\n\n onSelectionFinished && onSelectionFinished(selectionRef.current);\n\n selectionTip &&\n setTip({ position: viewportPosition, content: selectionTip });\n };\n\n const handleMouseDown: PointerEventHandler = (event) => {\n if (\n !isHTMLElement(event.target) ||\n asElement(event.target).closest(\".PdfHighlighter__tip-container\") // Ignore selections on tip container\n ) {\n return;\n }\n\n // Check for freetext creation mode\n if (\n enableFreetextCreation?.(event.nativeEvent) &&\n onFreetextClick &&\n !isEditInProgressRef.current\n ) {\n const target = asElement(event.target);\n const page = getPageFromElement(target);\n\n if (page && viewerRef.current) {\n const pageRect = page.node.getBoundingClientRect();\n const clickX = event.clientX - pageRect.left;\n const clickY = event.clientY - pageRect.top;\n\n // Default size for new freetext note\n const defaultWidth = 150;\n const defaultHeight = 80;\n\n const viewportPosition: ViewportPosition = {\n boundingRect: {\n left: clickX,\n top: clickY,\n width: defaultWidth,\n height: defaultHeight,\n pageNumber: page.number,\n },\n rects: [],\n };\n\n const scaledPosition = viewportPositionToScaled(\n viewportPosition,\n viewerRef.current,\n );\n\n onFreetextClick(scaledPosition);\n return; // Don't proceed with normal mousedown handling\n }\n }\n\n // Check for image creation mode\n if (\n enableImageCreation?.(event.nativeEvent) &&\n onImageClick &&\n !isEditInProgressRef.current\n ) {\n const target = asElement(event.target);\n const page = getPageFromElement(target);\n\n if (page && viewerRef.current) {\n const pageRect = page.node.getBoundingClientRect();\n const clickX = event.clientX - pageRect.left;\n const clickY = event.clientY - pageRect.top;\n\n // Default size for new image\n const defaultWidth = 150;\n const defaultHeight = 100;\n\n const viewportPosition: ViewportPosition = {\n boundingRect: {\n left: clickX,\n top: clickY,\n width: defaultWidth,\n height: defaultHeight,\n pageNumber: page.number,\n },\n rects: [],\n };\n\n const scaledPosition = viewportPositionToScaled(\n viewportPosition,\n viewerRef.current,\n );\n\n onImageClick(scaledPosition);\n return; // Don't proceed with normal mousedown handling\n }\n }\n\n setTip(null);\n clearTextSelection(); // TODO: Check if clearing text selection only if not clicking on tip breaks anything.\n removeGhostHighlight();\n toggleEditInProgress(false);\n };\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.code === \"Escape\") {\n clearTextSelection();\n removeGhostHighlight();\n setTip(null);\n }\n };\n\n const handleScaleValue = () => {\n if (viewerRef.current) {\n viewerRef.current.currentScaleValue = pdfScaleValue.toString();\n }\n };\n\n // Render Highlight layers\n const renderHighlightLayer = (\n highlightBindings: HighlightBindings,\n pageNumber: number,\n ) => {\n if (!viewerRef.current) return;\n\n highlightBindings.reactRoot.render(\n <PdfHighlighterContext.Provider value={pdfHighlighterUtils}>\n <HighlightLayer\n highlightsByPage={groupHighlightsByPage([\n ...highlights,\n ghostHighlightRef.current,\n ])}\n pageNumber={pageNumber}\n scrolledToHighlightId={scrolledToHighlightIdRef.current}\n viewer={viewerRef.current}\n highlightBindings={highlightBindings}\n children={children}\n />\n </PdfHighlighterContext.Provider>,\n );\n };\n\n const renderHighlightLayers = () => {\n if (!viewerRef.current) return;\n\n for (let pageNumber = 1; pageNumber <= pdfDocument.numPages; pageNumber++) {\n const highlightBindings = highlightBindingsRef.current[pageNumber];\n\n // Need to check if container is still attached to the DOM as PDF.js can unload pages.\n if (highlightBindings?.container?.isConnected) {\n renderHighlightLayer(highlightBindings, pageNumber);\n } else {\n const { textLayer } =\n viewerRef.current!.getPageView(pageNumber - 1) || {};\n if (!textLayer) continue; // Viewer hasn't rendered page yet\n\n // textLayer.div for version >=3.0 and textLayer.textLayerDiv otherwise.\n const highlightLayer = findOrCreateHighlightLayer(\n textLayer.div,\n );\n\n if (highlightLayer) {\n const reactRoot = createRoot(highlightLayer);\n highlightBindingsRef.current[pageNumber] = {\n reactRoot,\n container: highlightLayer,\n textLayer: textLayer.div, // textLayer.div for version >=3.0 and textLayer.textLayerDiv otherwise.\n };\n\n renderHighlightLayer(\n highlightBindingsRef.current[pageNumber],\n pageNumber,\n );\n }\n }\n }\n };\n\n // Utils\n const isEditingOrHighlighting = () => {\n return (\n Boolean(selectionRef.current) ||\n Boolean(ghostHighlightRef.current) ||\n isAreaSelectionInProgressRef.current ||\n isEditInProgressRef.current\n );\n };\n\n const toggleEditInProgress = (flag?: boolean) => {\n if (flag !== undefined) {\n isEditInProgressRef.current = flag;\n } else {\n isEditInProgressRef.current = !isEditInProgressRef.current;\n }\n\n // Disable text selection\n if (viewerRef.current)\n viewerRef.current.viewer?.classList.toggle(\n \"PdfHighlighter--disable-selection\",\n isEditInProgressRef.current,\n );\n };\n\n const removeGhostHighlight = () => {\n if (onRemoveGhostHighlight && ghostHighlightRef.current)\n onRemoveGhostHighlight(ghostHighlightRef.current);\n ghostHighlightRef.current = null;\n renderHighlightLayers();\n };\n\n const clearTextSelection = () => {\n selectionRef.current = null;\n\n const container = containerNodeRef.current;\n const selection = getWindow(container).getSelection();\n if (!container || !selection) return;\n selection.removeAllRanges();\n };\n\n const scrollToHighlight = (highlight: Highlight) => {\n const { boundingRect, usePdfCoordinates } = highlight.position;\n const pageNumber = boundingRect.pageNumber;\n\n // Remove scroll listener in case user auto-scrolls in succession.\n viewerRef.current!.container.removeEventListener(\"scroll\", handleScroll);\n\n const pageViewport = viewerRef.current!.getPageView(\n pageNumber - 1,\n ).viewport;\n\n viewerRef.current!.scrollPageIntoView({\n pageNumber,\n destArray: [\n null, // null since we pass pageNumber already as an arg\n { name: \"XYZ\" },\n ...pageViewport.convertToPdfPoint(\n 0, // Default x coord\n scaledToViewport(boundingRect, pageViewport, usePdfCoordinates).top -\n SCROLL_MARGIN,\n ),\n 0, // Default z coord\n ],\n });\n\n scrolledToHighlightIdRef.current = highlight.id;\n renderHighlightLayers();\n\n // wait for scrolling to finish\n setTimeout(() => {\n viewerRef.current!.container.addEventListener(\"scroll\", handleScroll, {\n once: true,\n });\n }, 100);\n };\n\n const pdfHighlighterUtils: PdfHighlighterUtils = {\n isEditingOrHighlighting,\n getCurrentSelection: () => selectionRef.current,\n getGhostHighlight: () => ghostHighlightRef.current,\n removeGhostHighlight,\n toggleEditInProgress,\n isEditInProgress: () => isEditInProgressRef.current,\n isSelectionInProgress: () =>\n Boolean(selectionRef.current) || isAreaSelectionInProgressRef.current,\n scrollToHighlight,\n getViewer: () => viewerRef.current,\n getTip: () => tip,\n setTip,\n updateTipPosition: updateTipPositionRef.current,\n };\n\n utilsRef(pdfHighlighterUtils);\n\n // Check if freetext or image mode is active for cursor styling\n const isFreetextMode = enableFreetextCreation?.({} as MouseEvent) ?? false;\n const isImageMode = enableImageCreation?.({} as MouseEvent) ?? false;\n\n // Build class name based on active modes\n let containerClassName = 'PdfHighlighter';\n if (isFreetextMode) containerClassName += ' PdfHighlighter--freetext-mode';\n if (isImageMode) containerClassName += ' PdfHighlighter--image-mode';\n if (enableDrawingMode) containerClassName += ' PdfHighlighter--drawing-mode';\n if (enableShapeMode) containerClassName += ' PdfHighlighter--shape-mode';\n if (areaSelectionMode) containerClassName += ' PdfHighlighter--area-mode';\n\n return (\n <PdfHighlighterContext.Provider value={pdfHighlighterUtils}>\n <div\n ref={containerNodeRef}\n className={containerClassName}\n onPointerDown={handleMouseDown}\n onPointerUp={handleMouseUp}\n style={style}\n >\n <div className=\"pdfViewer\" />\n <style>\n {`\n .textLayer ::selection {\n background: ${textSelectionColor};\n }\n `}\n </style>\n {isViewerReady && (\n <TipContainer\n viewer={viewerRef.current!}\n updateTipPositionRef={updateTipPositionRef}\n />\n )}\n {isViewerReady && enableAreaSelection && (\n <MouseSelection\n viewer={viewerRef.current!}\n onChange={(isVisible) =>\n (isAreaSelectionInProgressRef.current = isVisible)\n }\n enableAreaSelection={enableAreaSelection}\n style={mouseSelectionStyle}\n onDragStart={() => disableTextSelection(viewerRef.current!, true)}\n onReset={() => {\n selectionRef.current = null;\n disableTextSelection(viewerRef.current!, false);\n }}\n onSelection={(\n viewportPosition,\n scaledPosition,\n image,\n resetSelection,\n ) => {\n selectionRef.current = {\n content: { image },\n type: \"area\",\n position: scaledPosition,\n makeGhostHighlight: () => {\n ghostHighlightRef.current = {\n position: scaledPosition,\n type: \"area\",\n content: { image },\n };\n onCreateGhostHighlight &&\n onCreateGhostHighlight(ghostHighlightRef.current);\n resetSelection();\n renderHighlightLayers();\n return ghostHighlightRef.current;\n },\n };\n\n onSelectionFinished && onSelectionFinished(selectionRef.current);\n selectionTip &&\n setTip({ position: viewportPosition, content: selectionTip });\n }}\n />\n )}\n {isViewerReady && enableDrawingMode && (\n <DrawingCanvas\n isActive={enableDrawingMode}\n strokeColor={drawingStrokeColor}\n strokeWidth={drawingStrokeWidth}\n viewer={viewerRef.current!}\n onComplete={(dataUrl, position, strokes) => {\n console.log(\"PdfHighlighter: Drawing complete\");\n onDrawingComplete?.(dataUrl, position, strokes);\n }}\n onCancel={() => {\n console.log(\"PdfHighlighter: Drawing cancelled\");\n onDrawingCancel?.();\n }}\n />\n )}\n {isViewerReady && enableShapeMode && (\n <ShapeCanvas\n isActive={!!enableShapeMode}\n shapeType={enableShapeMode}\n strokeColor={shapeStrokeColor}\n strokeWidth={shapeStrokeWidth}\n viewer={viewerRef.current!}\n onComplete={(position, shape) => {\n console.log(\"PdfHighlighter: Shape complete\", shape.shapeType);\n onShapeComplete?.(position, shape);\n }}\n onCancel={() => {\n console.log(\"PdfHighlighter: Shape cancelled\");\n onShapeCancel?.();\n }}\n />\n )}\n </div>\n </PdfHighlighterContext.Provider>\n );\n};\n","import { createContext, useContext } from \"react\";\nimport { GhostHighlight, Highlight, PdfSelection, Tip } from \"../types\";\nimport { PDFViewer } from \"pdfjs-dist/types/web/pdf_viewer\";\n\n/**\n * A set of utilities for to control the behaviour of {@link PdfHighlighter}.\n *\n * @category Context\n */\nexport type PdfHighlighterUtils = {\n /**\n * Checks whether a selection is progress, a ghost highlight, or an edit.\n *\n * @returns - `true` if editing, ghost highlighting, or selecting.\n */\n isEditingOrHighlighting(): boolean;\n\n /**\n * Get currently selected area or text selection.\n *\n * @returns - current selection or `null` if no selection is being made.\n */\n getCurrentSelection(): PdfSelection | null;\n\n /**\n * Get the currently present ghost highlight.\n *\n * @return - currently present ghost highlight or `null` if non-existent.\n */\n getGhostHighlight(): GhostHighlight | null;\n\n /**\n * Cancel any ghost highlight.\n * The selected area will stay selected until the user clicks away.\n */\n removeGhostHighlight(): void;\n /**\n * If enabled, automatic tips/popups inside of a PdfHighlighter will be disabled.\n * Additional niceties will also be provided to prevent new highlights being made.\n */\n toggleEditInProgress(flag?: boolean): void;\n\n /**\n * Whether an AreaHighlight is being moved/resized, or a manual highlight edit has\n * been toggled.\n *\n * @returns - `true` if AreaHighlight is being edited or edit mode was set.\n */\n isEditInProgress(): boolean;\n\n /**\n * Whether a mouse selection or text selection is currently being performed.\n *\n * @returns - `true` if mouse selection or text selection is being performed.\n */\n isSelectionInProgress(): boolean;\n\n /**\n * Scroll to a highlight in this viewer.\n *\n * @param highlight - A highlight provided to the {@link PdfHighlighter} to\n * scroll to.\n */\n scrollToHighlight(highlight: Highlight): void;\n\n /**\n * Get a reference to the currently used instance of a PDF Viewer.\n *\n * @returns - The currently active PDF Viewer.\n */\n getViewer(): PDFViewer | null;\n\n /**\n * Get the currently active tip, if any.\n *\n * @returns - the currently active tip or `null` if inactive.\n */\n getTip(): Tip | null;\n\n /**\n * Set a tip to be displayed in the current PDF Viewer.\n *\n * @param tip - tip to be displayed, or `null` to hide any tip.\n */\n setTip(tip: Tip | null): void;\n\n /**\n * Callback to update any currently active tip's position. This will make sure\n * the tip is visible above/below its highlight.\n */\n updateTipPosition(): void;\n};\n\nexport const PdfHighlighterContext = createContext<\n PdfHighlighterUtils | undefined\n>(undefined);\n\n/**\n * Custom hook for providing {@link PdfHighlighterUtils}. Must be used\n * within a child of {@link PdfHighlighter}.\n *\n * @category Context\n */\nexport const usePdfHighlighterContext = () => {\n const pdfHighlighterUtils = useContext(PdfHighlighterContext);\n\n if (pdfHighlighterUtils === undefined) {\n throw new Error(\n \"usePdfHighlighterContext must be used within PdfHighlighter!\",\n );\n }\n\n return pdfHighlighterUtils;\n};\n","import { PDFViewer } from \"pdfjs-dist/types/web/pdf_viewer\";\nimport type { LTWHP, ViewportPosition, Scaled, ScaledPosition } from \"../types\";\nimport { PageViewport } from \"pdfjs-dist\";\n\ninterface WIDTH_HEIGHT {\n width: number;\n height: number;\n}\n\n/** @category Utilities */\nexport const viewportToScaled = (\n rect: LTWHP,\n { width, height }: WIDTH_HEIGHT,\n): Scaled => {\n return {\n x1: rect.left,\n y1: rect.top,\n\n x2: rect.left + rect.width,\n y2: rect.top + rect.height,\n\n width,\n height,\n\n pageNumber: rect.pageNumber,\n };\n};\n\n/** @category Utilities */\nexport const viewportPositionToScaled = (\n { boundingRect, rects }: ViewportPosition,\n viewer: PDFViewer,\n): ScaledPosition => {\n const pageNumber = boundingRect.pageNumber;\n const viewport = viewer.getPageView(pageNumber - 1).viewport; // Account for 1 indexing of PDF documents\n const scale = (obj: LTWHP) => viewportToScaled(obj, viewport);\n\n return {\n boundingRect: scale(boundingRect),\n rects: (rects || []).map(scale),\n };\n};\n\nconst pdfToViewport = (pdf: Scaled, viewport: PageViewport): LTWHP => {\n const [x1, y1, x2, y2] = viewport.convertToViewportRectangle([\n pdf.x1,\n pdf.y1,\n pdf.x2,\n pdf.y2,\n ]);\n\n return {\n left: Math.min(x1, x2),\n top: Math.min(y1, y2),\n\n width: Math.abs(x2 - x1),\n height: Math.abs(y1 - y2),\n\n pageNumber: pdf.pageNumber,\n };\n};\n\n/** @category Utilities */\nexport const scaledToViewport = (\n scaled: Scaled,\n viewport: PageViewport,\n usePdfCoordinates: boolean = false,\n): LTWHP => {\n const { width, height } = viewport;\n\n if (usePdfCoordinates) {\n return pdfToViewport(scaled, viewport);\n }\n\n if (scaled.x1 === undefined) {\n throw new Error(\"You are using old position format, please update\");\n }\n\n const x1 = (width * scaled.x1) / scaled.width;\n const y1 = (height * scaled.y1) / scaled.height;\n\n const x2 = (width * scaled.x2) / scaled.width;\n const y2 = (height * scaled.y2) / scaled.height;\n\n return {\n left: x1,\n top: y1,\n width: x2 - x1,\n height: y2 - y1,\n pageNumber: scaled.pageNumber,\n };\n};\n\n/** @category Utilities */\nexport const scaledPositionToViewport = (\n { boundingRect, rects, usePdfCoordinates }: ScaledPosition,\n viewer: PDFViewer,\n): ViewportPosition => {\n const pageNumber = boundingRect.pageNumber;\n const viewport = viewer.getPageView(pageNumber - 1).viewport; // Account for 1 indexing of PDF documents\n const scale = (obj: Scaled) =>\n scaledToViewport(obj, viewport, usePdfCoordinates);\n\n return {\n boundingRect: scale(boundingRect),\n rects: (rects || []).map(scale),\n };\n};\n","import type { LTWHP } from \"../types\";\n\nconst getBoundingRect = (clientRects: Array<LTWHP>): LTWHP => {\n const rects = Array.from(clientRects).map((rect) => {\n const { left, top, width, height, pageNumber } = rect;\n\n const X0 = left;\n const X1 = left + width;\n\n const Y0 = top;\n const Y1 = top + height;\n\n return { X0, X1, Y0, Y1, pageNumber };\n });\n\n let firstPageNumber = Number.MAX_SAFE_INTEGER;\n\n rects.forEach((rect) => {\n firstPageNumber = Math.min(\n firstPageNumber,\n rect.pageNumber ?? firstPageNumber,\n );\n });\n\n const rectsWithSizeOnFirstPage = rects.filter(\n (rect) =>\n (rect.X0 > 0 || rect.X1 > 0 || rect.Y0 > 0 || rect.Y1 > 0) &&\n rect.pageNumber === firstPageNumber,\n );\n\n const optimal = rectsWithSizeOnFirstPage.reduce((res, rect) => {\n return {\n X0: Math.min(res.X0, rect.X0),\n X1: Math.max(res.X1, rect.X1),\n\n Y0: Math.min(res.Y0, rect.Y0),\n Y1: Math.max(res.Y1, rect.Y1),\n\n pageNumber: firstPageNumber,\n };\n }, rectsWithSizeOnFirstPage[0]);\n\n const { X0, X1, Y0, Y1, pageNumber } = optimal;\n\n return {\n left: X0,\n top: Y0,\n width: X1 - X0,\n height: Y1 - Y0,\n pageNumber,\n };\n};\n\nexport default getBoundingRect;\n","import type { LTWHP } from \"../types.js\";\n\nconst sort = (rects: Array<LTWHP>) =>\n rects.sort((A, B) => {\n const top = (A.pageNumber || 0) * A.top - (B.pageNumber || 0) * B.top;\n\n if (top === 0) {\n return A.left - B.left;\n }\n\n return top;\n });\n\nconst overlaps = (A: LTWHP, B: LTWHP) =>\n A.pageNumber === B.pageNumber &&\n A.left <= B.left &&\n B.left <= A.left + A.width;\n\nconst sameLine = (A: LTWHP, B: LTWHP, yMargin = 5) =>\n A.pageNumber === B.pageNumber &&\n Math.abs(A.top - B.top) < yMargin &&\n Math.abs(A.height - B.height) < yMargin;\n\nconst inside = (A: LTWHP, B: LTWHP) =>\n A.pageNumber === B.pageNumber &&\n A.top > B.top &&\n A.left > B.left &&\n A.top + A.height < B.top + B.height &&\n A.left + A.width < B.left + B.width;\n\nconst nextTo = (A: LTWHP, B: LTWHP, xMargin = 10) => {\n const Aright = A.left + A.width;\n const Bright = B.left + B.width;\n\n return (\n A.pageNumber === B.pageNumber &&\n A.left <= B.left &&\n Aright <= Bright &&\n B.left - Aright <= xMargin\n );\n};\n\nconst extendWidth = (A: LTWHP, B: LTWHP) => {\n // extend width of A to cover B\n A.width = Math.max(B.width - A.left + B.left, A.width);\n};\n\nconst optimizeClientRects = (clientRects: Array<LTWHP>): Array<LTWHP> => {\n const rects = sort(clientRects);\n\n const toRemove = new Set();\n\n const firstPass = rects.filter((rect) => {\n return rects.every((otherRect) => {\n return !inside(rect, otherRect);\n });\n });\n\n let passCount = 0;\n\n while (passCount <= 2) {\n firstPass.forEach((A) => {\n firstPass.forEach((B) => {\n if (A === B || toRemove.has(A) || toRemove.has(B)) {\n return;\n }\n\n if (!sameLine(A, B)) {\n return;\n }\n\n if (overlaps(A, B)) {\n extendWidth(A, B);\n A.height = Math.max(A.height, B.height);\n\n toRemove.add(B);\n }\n\n if (nextTo(A, B)) {\n extendWidth(A, B);\n\n toRemove.add(B);\n }\n });\n });\n passCount += 1;\n }\n\n return firstPass.filter((rect) => !toRemove.has(rect));\n};\n\nexport default optimizeClientRects;\n","import type { LTWHP, Page } from \"../types\";\n\nimport optimizeClientRects from \"./optimize-client-rects\";\n\nconst isClientRectInsidePageRect = (clientRect: DOMRect, pageRect: DOMRect) => {\n if (clientRect.top < pageRect.top) {\n return false;\n }\n if (clientRect.bottom > pageRect.bottom) {\n return false;\n }\n if (clientRect.right > pageRect.right) {\n return false;\n }\n if (clientRect.left < pageRect.left) {\n return false;\n }\n\n return true;\n};\n\nconst getClientRects = (\n range: Range,\n pages: Page[],\n shouldOptimize: boolean = true,\n): Array<LTWHP> => {\n const clientRects = Array.from(range.getClientRects());\n\n const rects: LTWHP[] = [];\n\n for (const clientRect of clientRects) {\n for (const page of pages) {\n const pageRect = page.node.getBoundingClientRect();\n\n if (\n isClientRectInsidePageRect(clientRect, pageRect) &&\n clientRect.width > 0 &&\n clientRect.height > 0 &&\n clientRect.width < pageRect.width &&\n clientRect.left > pageRect.left &&\n clientRect.height < pageRect.height\n ) {\n const highlightedRect = {\n top: clientRect.top + page.node.scrollTop - pageRect.top,\n left: clientRect.left + page.node.scrollLeft - pageRect.left,\n width: clientRect.width,\n height: clientRect.height,\n pageNumber: page.number,\n } as LTWHP;\n\n rects.push(highlightedRect);\n }\n }\n }\n\n return shouldOptimize ? optimizeClientRects(rects) : rects;\n};\n\nexport default getClientRects;\n","import { GhostHighlight, Highlight } from \"../types\";\n\ntype GroupedHighlights = {\n [pageNumber: number]: Array<Highlight | GhostHighlight>;\n};\n\nconst groupHighlightsByPage = (\n highlights: Array<Highlight | GhostHighlight | null>,\n): GroupedHighlights =>\n highlights.reduce<GroupedHighlights>((acc, highlight) => {\n if (!highlight) {\n return acc;\n }\n const pageNumbers = [\n highlight.position.boundingRect.pageNumber,\n ...highlight.position.rects.map((rect) => rect.pageNumber || 0),\n ];\n\n pageNumbers.forEach((pageNumber) => {\n acc[pageNumber] ||= [];\n const pageSpecificHighlight = {\n ...highlight,\n position: {\n ...highlight.position,\n rects: highlight.position.rects.filter(\n (rect) => pageNumber === rect.pageNumber,\n ),\n },\n };\n acc[pageNumber].push(pageSpecificHighlight);\n });\n\n return acc;\n }, {});\n\nexport default groupHighlightsByPage;\n","import { Page } from \"../types\";\n\nexport const getDocument = (elm: any): Document =>\n (elm || {}).ownerDocument || document;\n\nexport const getWindow = (elm: any): typeof window =>\n (getDocument(elm) || {}).defaultView || window;\n\nexport const isHTMLElement = (elm: any) =>\n elm instanceof HTMLElement || elm instanceof getWindow(elm).HTMLElement;\n\nexport const isHTMLCanvasElement = (elm: any) =>\n elm instanceof HTMLCanvasElement ||\n elm instanceof getWindow(elm).HTMLCanvasElement;\n\nexport const asElement = (x: any): HTMLElement => x;\n\nexport const getPageFromElement = (target: HTMLElement): Page | null => {\n const node = asElement(target.closest(\".page\"));\n\n if (!node || !isHTMLElement(node)) {\n return null;\n }\n\n const number = Number(asElement(node).dataset.pageNumber);\n\n return { node, number } as Page;\n};\n\nexport const getPagesFromRange = (range: Range): Page[] => {\n const startParentElement = range.startContainer.parentElement;\n const endParentElement = range.endContainer.parentElement;\n\n if (!isHTMLElement(startParentElement) || !isHTMLElement(endParentElement)) {\n return [] as Page[];\n }\n\n const startPage = getPageFromElement(asElement(startParentElement));\n const endPage = getPageFromElement(asElement(endParentElement));\n\n if (!startPage?.number || !endPage?.number) {\n return [] as Page[];\n }\n\n if (startPage.number === endPage.number) {\n return [startPage] as Page[];\n }\n\n if (startPage.number === endPage.number - 1) {\n return [startPage, endPage] as Page[];\n }\n\n const pages: Page[] = [];\n\n let currentPageNumber = startPage.number;\n\n const document = startPage.node.ownerDocument;\n\n while (currentPageNumber <= endPage.number) {\n const currentPage = getPageFromElement(\n document.querySelector(\n `[data-page-number='${currentPageNumber}'`,\n ) as HTMLElement,\n );\n if (currentPage) {\n pages.push(currentPage);\n }\n currentPageNumber++;\n }\n\n return pages as Page[];\n};\n\nexport const findOrCreateContainerLayer = (\n container: HTMLElement,\n className: string,\n) => {\n const doc = getDocument(container);\n let layer = container.querySelector(`.${className}`);\n\n // To ensure predictable zIndexing, wait until the pdfjs element has children.\n if (!layer && container.children.length) {\n layer = doc.createElement(\"div\");\n layer.className = className;\n container.appendChild(layer);\n }\n\n return layer;\n};\n","import React, {\n useRef,\n useEffect,\n useCallback,\n useState,\n MouseEvent as ReactMouseEvent,\n TouchEvent as ReactTouchEvent,\n} from \"react\";\nimport { viewportPositionToScaled } from \"../lib/coordinates\";\nimport { DrawingStroke, ScaledPosition, ViewportPosition } from \"../types\";\n\nimport type { PDFViewer as TPDFViewer } from \"pdfjs-dist/web/pdf_viewer.mjs\";\n\n/**\n * The props type for {@link DrawingCanvas}.\n *\n * @category Component Properties\n */\nexport interface DrawingCanvasProps {\n /**\n * Whether drawing mode is active.\n */\n isActive: boolean;\n\n /**\n * Stroke color for drawing.\n * @default \"#000000\"\n */\n strokeColor?: string;\n\n /**\n * Stroke width for drawing.\n * @default 3\n */\n strokeWidth?: number;\n\n /**\n * The PDF viewer instance.\n */\n viewer: InstanceType<typeof TPDFViewer>;\n\n /**\n * Callback when drawing is complete.\n *\n * @param dataUrl - The drawing as a PNG data URL.\n * @param position - Scaled position of the drawing on the page.\n * @param strokes - The stroke data for later editing.\n */\n onComplete: (dataUrl: string, position: ScaledPosition, strokes: DrawingStroke[]) => void;\n\n /**\n * Callback when drawing is cancelled.\n */\n onCancel: () => void;\n}\n\ninterface Point {\n x: number;\n y: number;\n}\n\ninterface Stroke {\n points: Point[];\n color: string;\n width: number;\n}\n\n/**\n * A transparent overlay canvas for freehand drawing on PDF pages.\n * Supports mouse and touch input.\n *\n * @category Component\n */\nexport const DrawingCanvas = ({\n isActive,\n strokeColor = \"#000000\",\n strokeWidth = 3,\n viewer,\n onComplete,\n onCancel,\n}: DrawingCanvasProps) => {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const [strokes, setStrokes] = useState<Stroke[]>([]);\n const [currentStroke, setCurrentStroke] = useState<Stroke | null>(null);\n const isDrawingRef = useRef(false);\n const [pageNumber, setPageNumber] = useState<number | null>(null);\n const [pageElement, setPageElement] = useState<HTMLElement | null>(null);\n\n // Find which page the user is drawing on\n const findPageFromPoint = useCallback(\n (clientX: number, clientY: number) => {\n if (!viewer) return null;\n\n for (let i = 0; i < viewer.pagesCount; i++) {\n const pageView = viewer.getPageView(i);\n if (!pageView?.div) continue;\n\n const rect = pageView.div.getBoundingClientRect();\n if (\n clientX >= rect.left &&\n clientX <= rect.right &&\n clientY >= rect.top &&\n clientY <= rect.bottom\n ) {\n return {\n pageNumber: i + 1,\n element: pageView.div as HTMLElement,\n rect,\n };\n }\n }\n return null;\n },\n [viewer]\n );\n\n // Redraw all strokes\n const redrawCanvas = useCallback(() => {\n const canvas = canvasRef.current;\n const ctx = canvas?.getContext(\"2d\");\n if (!ctx || !canvas) return;\n\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n // Draw all completed strokes with their own color/width\n strokes.forEach((stroke) => {\n if (stroke.points.length < 2) return;\n\n ctx.strokeStyle = stroke.color;\n ctx.lineWidth = stroke.width;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n\n ctx.beginPath();\n ctx.moveTo(stroke.points[0].x, stroke.points[0].y);\n stroke.points.slice(1).forEach((point) => {\n ctx.lineTo(point.x, point.y);\n });\n ctx.stroke();\n });\n\n // Draw current stroke with current color/width\n if (currentStroke && currentStroke.points.length >= 2) {\n ctx.strokeStyle = currentStroke.color;\n ctx.lineWidth = currentStroke.width;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n\n ctx.beginPath();\n ctx.moveTo(currentStroke.points[0].x, currentStroke.points[0].y);\n currentStroke.points.slice(1).forEach((point) => {\n ctx.lineTo(point.x, point.y);\n });\n ctx.stroke();\n }\n }, [strokes, currentStroke]);\n\n // Redraw when strokes change\n useEffect(() => {\n redrawCanvas();\n }, [redrawCanvas]);\n\n // Handle mouse/touch down\n const handleStart = useCallback(\n (clientX: number, clientY: number) => {\n const pageInfo = findPageFromPoint(clientX, clientY);\n if (!pageInfo) return;\n\n console.log(\"DrawingCanvas: Started drawing on page\", pageInfo.pageNumber);\n\n // Set page context if not already set\n if (pageNumber === null) {\n setPageNumber(pageInfo.pageNumber);\n setPageElement(pageInfo.element);\n\n // Resize canvas to match page\n const canvas = canvasRef.current;\n if (canvas) {\n canvas.width = pageInfo.rect.width;\n canvas.height = pageInfo.rect.height;\n canvas.style.left = `${pageInfo.rect.left}px`;\n canvas.style.top = `${pageInfo.rect.top}px`;\n }\n } else if (pageInfo.pageNumber !== pageNumber) {\n // User trying to draw on different page - ignore\n console.log(\"DrawingCanvas: Ignoring - different page\");\n return;\n }\n\n isDrawingRef.current = true;\n const pos = {\n x: clientX - pageInfo.rect.left,\n y: clientY - pageInfo.rect.top,\n };\n setCurrentStroke({ points: [pos], color: strokeColor, width: strokeWidth });\n },\n [pageNumber, findPageFromPoint, strokeColor, strokeWidth]\n );\n\n // Handle mouse/touch move\n const handleMove = useCallback(\n (clientX: number, clientY: number) => {\n if (!isDrawingRef.current || !pageElement) return;\n\n const rect = pageElement.getBoundingClientRect();\n const pos = {\n x: clientX - rect.left,\n y: clientY - rect.top,\n };\n\n setCurrentStroke((prev) => {\n if (!prev) return null;\n return { ...prev, points: [...prev.points, pos] };\n });\n },\n [pageElement]\n );\n\n // Handle mouse/touch end\n const handleEnd = useCallback(() => {\n if (!isDrawingRef.current) return;\n isDrawingRef.current = false;\n\n if (currentStroke && currentStroke.points.length >= 2) {\n setStrokes((prev) => [...prev, currentStroke]);\n }\n setCurrentStroke(null);\n }, [currentStroke]);\n\n // Mouse event handlers\n const handleMouseDown = useCallback(\n (e: ReactMouseEvent) => {\n e.preventDefault();\n handleStart(e.clientX, e.clientY);\n },\n [handleStart]\n );\n\n const handleMouseMove = useCallback(\n (e: ReactMouseEvent) => {\n handleMove(e.clientX, e.clientY);\n },\n [handleMove]\n );\n\n const handleMouseUp = useCallback(() => {\n handleEnd();\n }, [handleEnd]);\n\n // Touch event handlers\n const handleTouchStart = useCallback(\n (e: ReactTouchEvent) => {\n e.preventDefault();\n if (e.touches.length > 0) {\n handleStart(e.touches[0].clientX, e.touches[0].clientY);\n }\n },\n [handleStart]\n );\n\n const handleTouchMove = useCallback(\n (e: ReactTouchEvent) => {\n e.preventDefault();\n if (e.touches.length > 0) {\n handleMove(e.touches[0].clientX, e.touches[0].clientY);\n }\n },\n [handleMove]\n );\n\n const handleTouchEnd = useCallback(() => {\n handleEnd();\n }, [handleEnd]);\n\n // Handle keyboard events\n useEffect(() => {\n if (!isActive) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.code === \"Escape\") {\n console.log(\"DrawingCanvas: Cancelled via Escape\");\n onCancel();\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [isActive, onCancel]);\n\n // Clear drawing\n const handleClear = () => {\n console.log(\"DrawingCanvas: Cleared strokes\");\n setStrokes([]);\n setCurrentStroke(null);\n setPageNumber(null);\n setPageElement(null);\n };\n\n // Complete drawing\n const handleDone = () => {\n if (strokes.length === 0 || pageNumber === null || !pageElement || !viewer) {\n console.log(\"DrawingCanvas: No strokes to save\");\n onCancel();\n return;\n }\n\n console.log(\"DrawingCanvas: Completing drawing with\", strokes.length, \"strokes\");\n\n // Calculate bounding box of all strokes\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n\n strokes.forEach((stroke) => {\n stroke.points.forEach((point) => {\n minX = Math.min(minX, point.x);\n minY = Math.min(minY, point.y);\n maxX = Math.max(maxX, point.x);\n maxY = Math.max(maxY, point.y);\n });\n });\n\n // Find max stroke width for padding\n const maxStrokeWidth = Math.max(...strokes.map(s => s.width));\n const padding = maxStrokeWidth * 2;\n minX = Math.max(0, minX - padding);\n minY = Math.max(0, minY - padding);\n maxX = maxX + padding;\n maxY = maxY + padding;\n\n const width = maxX - minX;\n const height = maxY - minY;\n\n // Create a new canvas with just the drawing (cropped to bounding box)\n const outputCanvas = document.createElement(\"canvas\");\n outputCanvas.width = width;\n outputCanvas.height = height;\n const outputCtx = outputCanvas.getContext(\"2d\");\n\n if (!outputCtx) {\n console.error(\"DrawingCanvas: Could not get output canvas context\");\n onCancel();\n return;\n }\n\n // Draw all strokes offset by bounding box origin, using per-stroke color/width\n strokes.forEach((stroke) => {\n if (stroke.points.length < 2) return;\n\n outputCtx.strokeStyle = stroke.color;\n outputCtx.lineWidth = stroke.width;\n outputCtx.lineCap = \"round\";\n outputCtx.lineJoin = \"round\";\n\n outputCtx.beginPath();\n outputCtx.moveTo(stroke.points[0].x - minX, stroke.points[0].y - minY);\n stroke.points.slice(1).forEach((point) => {\n outputCtx.lineTo(point.x - minX, point.y - minY);\n });\n outputCtx.stroke();\n });\n\n const dataUrl = outputCanvas.toDataURL(\"image/png\");\n\n // Create viewport position\n const viewportPosition: ViewportPosition = {\n boundingRect: {\n left: minX,\n top: minY,\n width: width,\n height: height,\n pageNumber: pageNumber,\n },\n rects: [],\n };\n\n const scaledPosition = viewportPositionToScaled(viewportPosition, viewer);\n\n // Normalize strokes relative to bounding box for storage\n const normalizedStrokes: DrawingStroke[] = strokes.map((stroke) => ({\n ...stroke,\n points: stroke.points.map((point) => ({\n x: point.x - minX,\n y: point.y - minY,\n })),\n }));\n\n console.log(\"DrawingCanvas: Created drawing at position\", scaledPosition);\n onComplete(dataUrl, scaledPosition, normalizedStrokes);\n\n // Reset state\n setStrokes([]);\n setCurrentStroke(null);\n setPageNumber(null);\n setPageElement(null);\n };\n\n if (!isActive) return null;\n\n return (\n <>\n <canvas\n ref={canvasRef}\n className=\"DrawingCanvas\"\n style={{\n width: pageElement ? pageElement.getBoundingClientRect().width : \"100%\",\n height: pageElement ? pageElement.getBoundingClientRect().height : \"100%\",\n position: \"fixed\",\n }}\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n />\n <div className=\"DrawingCanvas__controls\">\n <button\n type=\"button\"\n className=\"DrawingCanvas__clearButton\"\n onClick={handleClear}\n >\n Clear\n </button>\n <button\n type=\"button\"\n className=\"DrawingCanvas__cancelButton\"\n onClick={onCancel}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"DrawingCanvas__doneButton\"\n onClick={handleDone}\n >\n Done\n </button>\n </div>\n </>\n );\n};\n","import { PDFViewer } from \"pdfjs-dist/types/web/pdf_viewer\";\nimport React, { ReactNode } from \"react\";\nimport {\n HighlightContainerUtils,\n HighlightContext,\n} from \"../contexts/HighlightContext\";\nimport { scaledPositionToViewport, viewportToScaled } from \"../lib/coordinates\";\nimport screenshot from \"../lib/screenshot\";\nimport {\n GhostHighlight,\n Highlight,\n HighlightBindings,\n LTWH,\n LTWHP,\n ViewportHighlight,\n} from \"../types\";\n\nconst EMPTY_ID = \"empty-id\";\n\n/**\n * The props type for {@link HighlightLayer}.\n *\n * @category Component Properties\n * @internal\n */\nexport interface HighlightLayerProps {\n /**\n * Highlights and GhostHighlights organised by page number.\n */\n highlightsByPage: { [pageNumber: number]: Array<Highlight | GhostHighlight> };\n\n /**\n * The page number of the PDF document to highlight (1 indexed).\n */\n pageNumber: number;\n\n /**\n * ID of the highlight that the parent PDF Highlighter is trying to autoscroll to.\n */\n scrolledToHighlightId?: string | null;\n\n /**\n * The PDFViewer instance containing the HighlightLayer\n */\n viewer: PDFViewer;\n\n /**\n * Group of DOM refs for all the highlights on this layer.\n */\n highlightBindings: HighlightBindings;\n\n /**\n * The Highlight container that should be used to render highlights for this layer.\n * It will be given appropriate context for a single highlight, allowing it to render\n * a single {@link TextHighlight}, {@link AreaHighlight}, etc., in the correct place.\n */\n children: ReactNode;\n}\n\n/**\n * A component responsible for managing all the highlights and ghost highlights\n * for a single page of a PDF document. It does not render each highlight\n * but it provides context for a highlight container to do so.\n * Its rendering should be controlled by a {@link PdfHighlighter}.\n *\n * @category Component\n * @internal\n */\nexport const HighlightLayer = ({\n highlightsByPage,\n pageNumber,\n scrolledToHighlightId,\n viewer,\n highlightBindings,\n children,\n}: HighlightLayerProps) => {\n const currentHighlights = highlightsByPage[pageNumber] || [];\n\n return (\n <div>\n {currentHighlights.map((highlight, index) => {\n const viewportHighlight: ViewportHighlight = {\n ...highlight,\n id: \"id\" in highlight ? highlight.id : EMPTY_ID, // Give Empty ID to GhostHighlight\n position: scaledPositionToViewport(highlight.position, viewer),\n };\n\n const isScrolledTo = Boolean(\n scrolledToHighlightId === viewportHighlight.id,\n );\n\n const highlightUtils: HighlightContainerUtils = {\n highlight: viewportHighlight,\n viewportToScaled: (rect: LTWHP) => {\n const viewport = viewer.getPageView(\n (rect.pageNumber || pageNumber) - 1, // Convert to 0 index\n ).viewport;\n\n return viewportToScaled(rect, viewport);\n },\n screenshot: (boundingRect: LTWH) =>\n screenshot(boundingRect, pageNumber, viewer),\n isScrolledTo: isScrolledTo,\n highlightBindings,\n };\n\n return (\n <HighlightContext.Provider value={highlightUtils} key={index}>\n {children}\n </HighlightContext.Provider>\n );\n })}\n </div>\n );\n};\n","import { createContext, useContext } from \"react\";\nimport {\n Highlight,\n HighlightBindings,\n LTWH,\n LTWHP,\n Scaled,\n ViewportHighlight,\n} from \"../types\";\n\n/**\n * A set of utilities for rendering highlights. Designed to be used within a\n * highlight container.\n *\n * @category Context\n */\nexport type HighlightContainerUtils<T extends Highlight = Highlight> = {\n /**\n * The highlight being rendered at this component.\n */\n highlight: ViewportHighlight<T>;\n\n /**\n * Convert a Viewport rectangle to a scaled rectangle. Can be used\n * for storing and updating area selection highlights, for example.\n *\n * @returns - Scaled/display agnostic rectangle.\n */\n viewportToScaled(rect: LTWHP): Scaled;\n\n /**\n * Capture a PNG data url of a viewport rectangle.\n *\n * @returns - PNG data url. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs\n */\n screenshot(position: LTWH): string;\n\n /**\n * Whether the highlight has been autoscrolled to.\n */\n isScrolledTo: boolean;\n\n /**\n * All the DOM refs for the highlights shared on the same page\n * as `highlight`\n */\n highlightBindings: HighlightBindings;\n};\n\nexport const HighlightContext = createContext<\n HighlightContainerUtils | undefined\n>(undefined);\n\n/**\n * Custom hook for providing {@link HighlightContainerUtils}. Must be used\n * within a child of {@link PdfHighlighter}.\n *\n * @category Context\n */\nexport const useHighlightContainerContext = <\n T extends Highlight = Highlight,\n>() => {\n const highlightContainerUtils = useContext(HighlightContext);\n\n if (highlightContainerUtils === undefined) {\n throw new Error(\n \"useHighlightContainerContext must be used within a child of PdfHighlighter!\",\n );\n }\n\n return highlightContainerUtils as HighlightContainerUtils<T>;\n};\n","import { PDFViewer } from \"pdfjs-dist/types/web/pdf_viewer\";\nimport type { LTWH } from \"../types\";\nimport { isHTMLCanvasElement } from \"./pdfjs-dom\";\n\nconst getAreaAsPng = (canvas: HTMLCanvasElement, position: LTWH): string => {\n const { left, top, width, height } = position;\n\n const doc = canvas ? canvas.ownerDocument : null;\n // @TODO: cache this?\n const newCanvas = doc && doc.createElement(\"canvas\");\n\n if (!newCanvas || !isHTMLCanvasElement(newCanvas)) {\n return \"\";\n }\n\n newCanvas.width = width;\n newCanvas.height = height;\n\n const newCanvasContext = newCanvas.getContext(\"2d\");\n\n if (!newCanvasContext || !canvas) {\n return \"\";\n }\n\n const dpr: number = window.devicePixelRatio;\n\n newCanvasContext.drawImage(\n canvas,\n left * dpr,\n top * dpr,\n width * dpr,\n height * dpr,\n 0,\n 0,\n width,\n height,\n );\n\n return newCanvas.toDataURL(\"image/png\");\n};\n\nconst screenshot = (position: LTWH, pageNumber: number, viewer: PDFViewer) => {\n return getAreaAsPng(viewer.getPageView(pageNumber - 1).canvas, position);\n};\n\nexport default screenshot;\n","import React, { CSSProperties, useEffect, useRef, useState } from \"react\";\n\nimport { asElement, getPageFromElement, isHTMLElement } from \"../lib/pdfjs-dom\";\n\nimport { PDFViewer } from \"pdfjs-dist/types/web/pdf_viewer\";\nimport { viewportPositionToScaled } from \"../lib/coordinates\";\nimport screenshot from \"../lib/screenshot\";\nimport type { LTWH, LTWHP, ScaledPosition, ViewportPosition } from \"../types\";\n\ntype Coords = {\n x: number;\n y: number;\n};\n\nconst getBoundingRect = (start: Coords, end: Coords): LTWH => {\n return {\n left: Math.min(end.x, start.x),\n top: Math.min(end.y, start.y),\n\n width: Math.abs(end.x - start.x),\n height: Math.abs(end.y - start.y),\n };\n};\n\nconst getContainerCoords = (\n container: HTMLElement,\n pageX: number,\n pageY: number,\n) => {\n const containerBoundingRect = container.getBoundingClientRect();\n return {\n x: pageX - containerBoundingRect.left + container.scrollLeft,\n y: pageY - containerBoundingRect.top + container.scrollTop - window.scrollY,\n };\n};\n\n/**\n * The props type for {@link MouseSelection}.\n *\n * @category Component Properties\n * @internal\n */\nexport interface MouseSelectionProps {\n /**\n * The PDFViewer instance containing this MouseSelection.\n */\n viewer: PDFViewer;\n\n /**\n * Callback triggered whenever the user stops dragging their mouse and a valid\n * mouse selection is made. In general, this will only be called if a mouse\n * selection is rendered.\n *\n * @param viewportPosition - viewport position of the mouse selection.\n * @param scaledPosition - scaled position of the mouse selection.\n * @param image - PNG screenshot of the mouse selection.\n * @param resetSelection - Callback to reset the current selection.\n * @param event - Mouse event associated with ending the selection.\n */\n onSelection?(\n viewportPosition: ViewportPosition,\n scaledPosition: ScaledPosition,\n image: string,\n resetSelection: () => void,\n event: MouseEvent,\n ): void;\n\n /**\n * Callback triggered whenever the current mouse selection is reset.\n * This includes when dragging ends but the selection is invalid.\n */\n onReset?(): void;\n\n /**\n * Callback triggered whenever a new valid mouse selection begins.\n *\n * @param event - mouse event associated with the new selection.\n */\n onDragStart?(event: MouseEvent): void;\n\n /**\n * Condition to check before any mouse selection starts.\n *\n * @param event - mouse event associated with the new selection.\n * @returns - `True` if mouse selection should start.\n */\n enableAreaSelection(event: MouseEvent): boolean;\n\n /**\n * Callback whenever the mouse selection area changes.\n *\n * @param isVisible - Whether the mouse selection is rendered (i.e., non-zero area)\n */\n onChange?(isVisible: boolean): void;\n\n /**\n * Optional style props for the mouse selection rectangle.\n */\n style?: CSSProperties;\n}\n\n/**\n * A component that enables the creation of rectangular and interactive mouse\n * selections within a given container. NOTE: This does not disable selection in\n * whatever container the component is placed in. That must be handled through\n * the component's events.\n *\n * @category Component\n * @internal\n */\nexport const MouseSelection = ({\n viewer,\n onSelection,\n onReset,\n onDragStart,\n enableAreaSelection,\n onChange,\n style,\n}: MouseSelectionProps) => {\n const [start, setStart] = useState<Coords | null>(null);\n const [end, setEnd] = useState<Coords | null>(null);\n const [locked, setLocked] = useState(false);\n const rootRef = useRef<HTMLDivElement | null>(null);\n\n // Needed in order to grab the page info of a mouse selection\n const startTargetRef = useRef<HTMLElement | null>(null);\n\n const reset = () => {\n onReset && onReset();\n setStart(null);\n setEnd(null);\n setLocked(false);\n };\n\n // Register event listeners onChange\n useEffect(() => {\n onChange && onChange(Boolean(start && end));\n if (!rootRef.current) return;\n\n // Should be the PdfHighlighter\n const container = asElement(rootRef.current.parentElement);\n\n const handleMouseUp = (event: MouseEvent) => {\n if (!start || !end || !startTargetRef.current) return;\n\n const boundingRect = getBoundingRect(start, end);\n\n // Check if the bounding rectangle has a minimum width and height\n // to prevent recording selections with 0 area\n const shouldEnd = boundingRect.width >= 1 && boundingRect.height >= 1;\n\n if (!container.contains(asElement(event.target)) || !shouldEnd) {\n reset();\n return;\n }\n\n setLocked(true);\n\n const page = getPageFromElement(startTargetRef.current);\n if (!page) return;\n\n const pageBoundingRect: LTWHP = {\n ...boundingRect,\n top: boundingRect.top - page.node.offsetTop,\n left: boundingRect.left - page.node.offsetLeft,\n pageNumber: page.number,\n };\n\n const viewportPosition: ViewportPosition = {\n boundingRect: pageBoundingRect,\n rects: [],\n };\n\n const scaledPosition = viewportPositionToScaled(viewportPosition, viewer);\n\n const image = screenshot(\n pageBoundingRect,\n pageBoundingRect.pageNumber,\n viewer,\n );\n\n onSelection &&\n onSelection(viewportPosition, scaledPosition, image, reset, event);\n };\n\n const handleMouseMove = (event: MouseEvent) => {\n if (!rootRef.current || !start || locked) return;\n setEnd(getContainerCoords(container, event.pageX, event.pageY));\n };\n\n const handleMouseDown = (event: MouseEvent) => {\n const shouldStart = (event: MouseEvent) =>\n enableAreaSelection(event) &&\n isHTMLElement(event.target) &&\n Boolean(asElement(event.target).closest(\".page\"));\n\n // If the user clicks anywhere outside a tip, reset the selection\n const shouldReset = (event: MouseEvent) =>\n start &&\n !asElement(event.target).closest(\".PdfHighlighter__tip-container\");\n\n if (!shouldStart(event)) {\n if (shouldReset(event)) reset();\n return;\n }\n\n startTargetRef.current = asElement(event.target);\n onDragStart && onDragStart(event);\n setStart(getContainerCoords(container, event.pageX, event.pageY));\n setEnd(null);\n setLocked(false);\n };\n\n /**\n * Although we register the event listeners on the PdfHighlighter component, we encapsulate\n * them in this separate component to enhance maintainability and prevent unnecessary\n * rerenders of the PdfHighlighter itself. While synthetic events on PdfHighlighter would\n * be preferable, we need to register \"mouseup\" on the entire document anyway. Therefore,\n * we can't avoid using useEffect. We must re-register all events on state changes, as\n * custom event listeners may otherwise receive stale state.\n */\n container.addEventListener(\"mousemove\", handleMouseMove);\n container.addEventListener(\"mousedown\", handleMouseDown);\n\n document.addEventListener(\"mouseup\", handleMouseUp);\n\n return () => {\n container.removeEventListener(\"mousemove\", handleMouseMove);\n container.removeEventListener(\"mousedown\", handleMouseDown);\n document.removeEventListener(\"mouseup\", handleMouseUp);\n };\n }, [start, end, enableAreaSelection]);\n\n return (\n <div className=\"MouseSelection-container\" ref={rootRef}>\n {start && end && (\n <div\n className=\"MouseSelection\"\n style={{ ...getBoundingRect(start, end), ...style }}\n />\n )}\n </div>\n );\n};\n","import React, {\n useRef,\n useEffect,\n useCallback,\n useState,\n MouseEvent as ReactMouseEvent,\n TouchEvent as ReactTouchEvent,\n} from \"react\";\nimport { viewportPositionToScaled } from \"../lib/coordinates\";\nimport { ShapeType, ShapeData, ScaledPosition, ViewportPosition } from \"../types\";\n\nimport type { PDFViewer as TPDFViewer } from \"pdfjs-dist/web/pdf_viewer.mjs\";\n\n/**\n * The props type for {@link ShapeCanvas}.\n *\n * @category Component Properties\n */\nexport interface ShapeCanvasProps {\n /**\n * Whether shape mode is active.\n */\n isActive: boolean;\n\n /**\n * The type of shape to create.\n */\n shapeType: ShapeType;\n\n /**\n * Stroke color for the shape.\n * @default \"#000000\"\n */\n strokeColor?: string;\n\n /**\n * Stroke width for the shape.\n * @default 2\n */\n strokeWidth?: number;\n\n /**\n * The PDF viewer instance.\n */\n viewer: InstanceType<typeof TPDFViewer>;\n\n /**\n * Callback when shape creation is complete.\n *\n * @param position - Scaled position of the shape on the page.\n * @param shape - The shape data.\n */\n onComplete: (position: ScaledPosition, shape: ShapeData) => void;\n\n /**\n * Callback when shape creation is cancelled.\n */\n onCancel: () => void;\n}\n\ninterface Point {\n x: number;\n y: number;\n}\n\n/**\n * A transparent overlay for creating shape annotations on PDF pages.\n * Supports mouse and touch input with click-and-drag to define shape bounds.\n *\n * @category Component\n */\nexport const ShapeCanvas = ({\n isActive,\n shapeType,\n strokeColor = \"#000000\",\n strokeWidth = 2,\n viewer,\n onComplete,\n onCancel,\n}: ShapeCanvasProps) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const [startPoint, setStartPoint] = useState<Point | null>(null);\n const [currentPoint, setCurrentPoint] = useState<Point | null>(null);\n const [pageNumber, setPageNumber] = useState<number | null>(null);\n const [pageRect, setPageRect] = useState<DOMRect | null>(null);\n const isDrawingRef = useRef(false);\n\n // Find which page the user is drawing on\n const findPageFromPoint = useCallback(\n (clientX: number, clientY: number) => {\n if (!viewer) return null;\n\n for (let i = 0; i < viewer.pagesCount; i++) {\n const pageView = viewer.getPageView(i);\n if (!pageView?.div) continue;\n\n const rect = pageView.div.getBoundingClientRect();\n if (\n clientX >= rect.left &&\n clientX <= rect.right &&\n clientY >= rect.top &&\n clientY <= rect.bottom\n ) {\n return {\n pageNumber: i + 1,\n element: pageView.div as HTMLElement,\n rect,\n };\n }\n }\n return null;\n },\n [viewer]\n );\n\n // Handle mouse/touch down\n const handleStart = useCallback(\n (clientX: number, clientY: number) => {\n const pageInfo = findPageFromPoint(clientX, clientY);\n if (!pageInfo) return;\n\n console.log(\"ShapeCanvas: Started drawing on page\", pageInfo.pageNumber);\n\n setPageNumber(pageInfo.pageNumber);\n setPageRect(pageInfo.rect);\n\n isDrawingRef.current = true;\n const pos = {\n x: clientX - pageInfo.rect.left,\n y: clientY - pageInfo.rect.top,\n };\n setStartPoint(pos);\n setCurrentPoint(pos);\n },\n [findPageFromPoint]\n );\n\n // Handle mouse/touch move\n const handleMove = useCallback(\n (clientX: number, clientY: number) => {\n if (!isDrawingRef.current || !pageRect) return;\n\n const pos = {\n x: clientX - pageRect.left,\n y: clientY - pageRect.top,\n };\n setCurrentPoint(pos);\n },\n [pageRect]\n );\n\n // Handle mouse/touch end\n const handleEnd = useCallback(() => {\n if (!isDrawingRef.current || !startPoint || !currentPoint || pageNumber === null || !viewer) {\n isDrawingRef.current = false;\n setStartPoint(null);\n setCurrentPoint(null);\n return;\n }\n\n isDrawingRef.current = false;\n\n // Calculate bounding box\n const minX = Math.min(startPoint.x, currentPoint.x);\n const minY = Math.min(startPoint.y, currentPoint.y);\n const maxX = Math.max(startPoint.x, currentPoint.x);\n const maxY = Math.max(startPoint.y, currentPoint.y);\n\n const width = maxX - minX;\n const height = maxY - minY;\n\n // Minimum size check\n if (width < 10 || height < 10) {\n console.log(\"ShapeCanvas: Shape too small, ignoring\");\n setStartPoint(null);\n setCurrentPoint(null);\n return;\n }\n\n console.log(\"ShapeCanvas: Creating shape\", shapeType, \"at\", { minX, minY, width, height });\n\n // Create viewport position\n const viewportPosition: ViewportPosition = {\n boundingRect: {\n left: minX,\n top: minY,\n width: width,\n height: height,\n pageNumber: pageNumber,\n },\n rects: [],\n };\n\n const scaledPosition = viewportPositionToScaled(viewportPosition, viewer);\n\n // For arrows, calculate start/end points as percentages within the bounding box\n let shapeData: ShapeData = {\n shapeType,\n strokeColor,\n strokeWidth,\n };\n\n if (shapeType === \"arrow\") {\n // Calculate start and end points relative to bounding box (0-1 range)\n shapeData.startPoint = {\n x: (startPoint.x - minX) / width,\n y: (startPoint.y - minY) / height,\n };\n shapeData.endPoint = {\n x: (currentPoint.x - minX) / width,\n y: (currentPoint.y - minY) / height,\n };\n console.log(\"ShapeCanvas: Arrow points\", shapeData.startPoint, \"->\", shapeData.endPoint);\n }\n\n console.log(\"ShapeCanvas: Created shape at position\", scaledPosition);\n onComplete(scaledPosition, shapeData);\n\n // Reset state\n setStartPoint(null);\n setCurrentPoint(null);\n setPageNumber(null);\n setPageRect(null);\n }, [startPoint, currentPoint, pageNumber, viewer, shapeType, strokeColor, strokeWidth, onComplete]);\n\n // Mouse event handlers\n const handleMouseDown = useCallback(\n (e: ReactMouseEvent) => {\n e.preventDefault();\n handleStart(e.clientX, e.clientY);\n },\n [handleStart]\n );\n\n const handleMouseMove = useCallback(\n (e: ReactMouseEvent) => {\n handleMove(e.clientX, e.clientY);\n },\n [handleMove]\n );\n\n const handleMouseUp = useCallback(() => {\n handleEnd();\n }, [handleEnd]);\n\n // Touch event handlers\n const handleTouchStart = useCallback(\n (e: ReactTouchEvent) => {\n e.preventDefault();\n if (e.touches.length > 0) {\n handleStart(e.touches[0].clientX, e.touches[0].clientY);\n }\n },\n [handleStart]\n );\n\n const handleTouchMove = useCallback(\n (e: ReactTouchEvent) => {\n e.preventDefault();\n if (e.touches.length > 0) {\n handleMove(e.touches[0].clientX, e.touches[0].clientY);\n }\n },\n [handleMove]\n );\n\n const handleTouchEnd = useCallback(() => {\n handleEnd();\n }, [handleEnd]);\n\n // Handle keyboard events\n useEffect(() => {\n if (!isActive) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.code === \"Escape\") {\n console.log(\"ShapeCanvas: Cancelled via Escape\");\n onCancel();\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [isActive, onCancel]);\n\n // Render shape preview\n const renderShapePreview = () => {\n if (!startPoint || !currentPoint || !pageRect) return null;\n\n const minX = Math.min(startPoint.x, currentPoint.x);\n const minY = Math.min(startPoint.y, currentPoint.y);\n const width = Math.abs(currentPoint.x - startPoint.x);\n const height = Math.abs(currentPoint.y - startPoint.y);\n\n const svgStyle: React.CSSProperties = {\n position: \"fixed\",\n left: pageRect.left,\n top: pageRect.top,\n width: pageRect.width,\n height: pageRect.height,\n pointerEvents: \"none\",\n zIndex: 1001,\n };\n\n return (\n <svg style={svgStyle}>\n {shapeType === \"rectangle\" && (\n <rect\n x={minX}\n y={minY}\n width={width}\n height={height}\n stroke={strokeColor}\n strokeWidth={strokeWidth}\n fill=\"none\"\n />\n )}\n {shapeType === \"circle\" && (\n <ellipse\n cx={minX + width / 2}\n cy={minY + height / 2}\n rx={width / 2}\n ry={height / 2}\n stroke={strokeColor}\n strokeWidth={strokeWidth}\n fill=\"none\"\n />\n )}\n {shapeType === \"arrow\" && (\n <>\n <defs>\n <marker\n id=\"shape-canvas-arrowhead\"\n markerWidth=\"10\"\n markerHeight=\"7\"\n refX=\"9\"\n refY=\"3.5\"\n orient=\"auto\"\n >\n <polygon points=\"0 0, 10 3.5, 0 7\" fill={strokeColor} />\n </marker>\n </defs>\n <line\n x1={startPoint.x}\n y1={startPoint.y}\n x2={currentPoint.x}\n y2={currentPoint.y}\n stroke={strokeColor}\n strokeWidth={strokeWidth}\n markerEnd=\"url(#shape-canvas-arrowhead)\"\n />\n </>\n )}\n </svg>\n );\n };\n\n if (!isActive) return null;\n\n return (\n <>\n <div\n ref={containerRef}\n className=\"ShapeCanvas\"\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n />\n {renderShapePreview()}\n <div className=\"ShapeCanvas__controls\">\n <div className=\"ShapeCanvas__hint\">\n Click and drag to draw a {shapeType}. Press Escape to cancel.\n </div>\n <button\n type=\"button\"\n className=\"ShapeCanvas__cancelButton\"\n onClick={onCancel}\n >\n Cancel\n </button>\n </div>\n </>\n );\n};\n","import { PDFViewer } from \"pdfjs-dist/types/web/pdf_viewer\";\nimport React, {\n MutableRefObject,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { usePdfHighlighterContext } from \"../contexts/PdfHighlighterContext\";\n\nconst clamp = (value: number, left: number, right: number) =>\n Math.min(Math.max(value, left), right);\n\nconst VERTICAL_PADDING = 5;\n\n/**\n * The props type for {@link TipContainer}.\n *\n * @category Component Properties\n * @internal\n */\nexport interface TipContainerProps {\n /**\n * The PDFViewer instance containing the HighlightLayer\n */\n viewer: PDFViewer;\n\n /**\n * Reference to the callback to update the tip's position.This should be\n * managed by the PdfHighlighter.\n */\n updateTipPositionRef: MutableRefObject<() => void>;\n}\n\n/**\n * A component that manages rendering and placement of a tip around a highlight.\n * It does not automatically update the tip's position if it resizes.\n *\n * @category Component\n * @internal\n */\nexport const TipContainer = ({\n viewer,\n updateTipPositionRef,\n}: TipContainerProps) => {\n const [height, setHeight] = useState(0);\n const [width, setWidth] = useState(0);\n const containerRef = useRef<HTMLDivElement | null>(null);\n\n const updatePosition = () => {\n if (!containerRef.current) return;\n const { offsetHeight, offsetWidth } = containerRef.current;\n setHeight(offsetHeight);\n setWidth(offsetWidth);\n };\n\n updateTipPositionRef.current = updatePosition;\n\n // useLayoutEffect ensures state is updated before re-render, preventing flickering\n useLayoutEffect(() => {\n updatePosition();\n }, [updatePosition]);\n\n const { getTip } = usePdfHighlighterContext();\n const currentTip = getTip();\n if (!currentTip) return null;\n\n // Destructuring current tip's position and content\n const { position, content } = currentTip;\n const { boundingRect } = position;\n const pageNumber = boundingRect.pageNumber;\n const pageNode = viewer.getPageView(pageNumber - 1).div; // Account for 1 indexing of pdf documents\n const pageBoundingClientRect = pageNode.getBoundingClientRect();\n const { left: pageLeft, width: pageWidth } = pageBoundingClientRect;\n\n // Calculate the position and dimensions of the tip container\n const scrollTop = viewer.container.scrollTop; // How much the viewer has been scrolled vertically\n const left = pageNode.offsetLeft + boundingRect.left + boundingRect.width / 2; // center tip over highlight\n const highlightTop = boundingRect.top + pageNode.offsetTop;\n const highlightBottom = highlightTop + boundingRect.height;\n\n // Determine whether the tip should be moved below the highlight\n const shouldMove = highlightTop - height - VERTICAL_PADDING < scrollTop; // Would the tip render beyond the top of the visible document?\n const top = shouldMove\n ? highlightBottom + VERTICAL_PADDING\n : highlightTop - height - VERTICAL_PADDING;\n\n // Ensure the tip stays within the left edge of the viewer and the right edge of the page\n const clampedLeft = clamp(left - width / 2, 0, pageLeft + pageWidth - width);\n\n return (\n <div\n className=\"PdfHighlighter__tip-container\"\n style={{\n top,\n left: clampedLeft,\n height: \"max-content\",\n width: \"max-content\",\n }}\n ref={containerRef}\n >\n {content}\n </div>\n );\n};\n","import React, {\n CSSProperties,\n MouseEvent,\n ReactNode,\n useState,\n useRef,\n useEffect,\n} from \"react\";\n\nimport type { ViewportHighlight } from \"../types\";\n\n/**\n * Style options for text highlight appearance.\n */\nexport interface TextHighlightStyle {\n highlightColor?: string;\n highlightStyle?: \"highlight\" | \"underline\" | \"strikethrough\";\n}\n\n/**\n * The props type for {@link TextHighlight}.\n *\n * @category Component Properties\n */\nexport interface TextHighlightProps {\n /**\n * Highlight to render over text.\n */\n highlight: ViewportHighlight;\n\n /**\n * Callback triggered whenever the user clicks on the part of a highlight.\n *\n * @param event - Mouse event associated with click.\n */\n onClick?(event: MouseEvent<HTMLDivElement>): void;\n\n /**\n * Callback triggered whenever the user enters the area of a text highlight.\n *\n * @param event - Mouse event associated with movement.\n */\n onMouseOver?(event: MouseEvent<HTMLDivElement>): void;\n\n /**\n * Callback triggered whenever the user leaves the area of a text highlight.\n *\n * @param event - Mouse event associated with movement.\n */\n onMouseOut?(event: MouseEvent<HTMLDivElement>): void;\n\n /**\n * Indicates whether the component is autoscrolled into view, affecting\n * default theming.\n */\n isScrolledTo: boolean;\n\n /**\n * Callback triggered whenever the user tries to open context menu on highlight.\n *\n * @param event - Mouse event associated with click.\n */\n onContextMenu?(event: MouseEvent<HTMLDivElement>): void;\n\n /**\n * Optional CSS styling applied to each TextHighlight part.\n */\n style?: CSSProperties;\n\n /**\n * Background/line color for the highlight.\n * Default: \"rgba(255, 226, 143, 1)\" (yellow)\n */\n highlightColor?: string;\n\n /**\n * Style mode for the highlight.\n * - \"highlight\": Solid background color (default)\n * - \"underline\": Line under the text\n * - \"strikethrough\": Line through the text\n */\n highlightStyle?: \"highlight\" | \"underline\" | \"strikethrough\";\n\n /**\n * Callback triggered when the style changes.\n */\n onStyleChange?(style: TextHighlightStyle): void;\n\n /**\n * Callback triggered when the delete button is clicked.\n */\n onDelete?(): void;\n\n /**\n * Custom style icon. Replaces the default palette icon.\n */\n styleIcon?: ReactNode;\n\n /**\n * Custom delete icon. Replaces the default trash icon.\n */\n deleteIcon?: ReactNode;\n\n /**\n * Custom color presets for the style panel.\n * Default: [\"rgba(255, 226, 143, 1)\", \"#ffcdd2\", \"#c8e6c9\", \"#bbdefb\", \"#e1bee7\"]\n */\n colorPresets?: string[];\n}\n\n// Default icons\nconst DefaultStyleIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z\" />\n </svg>\n);\n\nconst DefaultDeleteIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" />\n </svg>\n);\n\n// Highlight style icons\nconst HighlightIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M6 14l3 3v5h6v-5l3-3V9H6v5zm5-12h2v3h-2V2zM3.5 5.875L4.914 4.46l2.12 2.122L5.622 8 3.5 5.875zm13.46.71l2.123-2.12 1.414 1.414L18.375 8l-1.414-1.414z\" />\n </svg>\n);\n\nconst UnderlineIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z\" />\n </svg>\n);\n\nconst StrikethroughIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M10 19h4v-3h-4v3zM5 4v3h5v3h4V7h5V4H5zM3 14h18v-2H3v2z\" />\n </svg>\n);\n\n// Default color presets\nconst DEFAULT_COLOR_PRESETS = [\n \"rgba(255, 226, 143, 1)\", // Yellow (default)\n \"#ffcdd2\", // Light red\n \"#c8e6c9\", // Light green\n \"#bbdefb\", // Light blue\n \"#e1bee7\", // Light purple\n];\n\n/**\n * A component for displaying a highlighted text area.\n *\n * @category Component\n */\nexport const TextHighlight = ({\n highlight,\n onClick,\n onMouseOver,\n onMouseOut,\n isScrolledTo,\n onContextMenu,\n style,\n highlightColor = \"rgba(255, 226, 143, 1)\",\n highlightStyle = \"highlight\",\n onStyleChange,\n onDelete,\n styleIcon,\n deleteIcon,\n colorPresets = DEFAULT_COLOR_PRESETS,\n}: TextHighlightProps) => {\n const [isStylePanelOpen, setIsStylePanelOpen] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const stylePanelRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Close style panel when clicking outside\n useEffect(() => {\n if (!isStylePanelOpen) return;\n\n const handleClickOutside = (e: globalThis.MouseEvent) => {\n if (\n stylePanelRef.current &&\n !stylePanelRef.current.contains(e.target as Node)\n ) {\n setIsStylePanelOpen(false);\n }\n };\n\n // Delay adding listener to avoid immediate close\n const timeoutId = setTimeout(() => {\n document.addEventListener(\"mousedown\", handleClickOutside);\n }, 0);\n\n return () => {\n clearTimeout(timeoutId);\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [isStylePanelOpen]);\n\n const highlightClass = isScrolledTo ? \"TextHighlight--scrolledTo\" : \"\";\n const { rects } = highlight.position;\n\n // Get the first rect to position the toolbar\n const firstRect = rects[0];\n\n // Build style class based on highlight style\n const getPartStyleClass = () => {\n switch (highlightStyle) {\n case \"underline\":\n return \"TextHighlight__part--underline\";\n case \"strikethrough\":\n return \"TextHighlight__part--strikethrough\";\n default:\n return \"\";\n }\n };\n\n // Build inline style for each part\n const getPartStyle = (rect: typeof firstRect): CSSProperties => {\n const baseStyle: CSSProperties = { ...rect, ...style };\n\n if (highlightStyle === \"highlight\") {\n baseStyle.backgroundColor = highlightColor;\n } else {\n // For underline and strikethrough, use the color for the line\n baseStyle.backgroundColor = \"transparent\";\n baseStyle.color = highlightColor;\n }\n\n return baseStyle;\n };\n\n return (\n <div\n className={`TextHighlight ${highlightClass}`}\n onContextMenu={onContextMenu}\n ref={containerRef}\n >\n {/* Toolbar wrapper - extends down to overlap with highlight */}\n {(onStyleChange || onDelete) && firstRect && (\n <div\n className=\"TextHighlight__toolbar-wrapper\"\n style={{\n position: \"absolute\",\n left: firstRect.left,\n top: firstRect.top - 28,\n paddingBottom: 12,\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n <div\n className={`TextHighlight__toolbar ${isHovered || isStylePanelOpen ? \"TextHighlight__toolbar--visible\" : \"\"}`}\n >\n {onStyleChange && (\n <button\n className=\"TextHighlight__style-button\"\n onClick={(e) => {\n e.stopPropagation();\n setIsStylePanelOpen(!isStylePanelOpen);\n }}\n title=\"Change style\"\n type=\"button\"\n >\n {styleIcon || <DefaultStyleIcon />}\n </button>\n )}\n {onDelete && (\n <button\n className=\"TextHighlight__delete-button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete();\n }}\n title=\"Delete\"\n type=\"button\"\n >\n {deleteIcon || <DefaultDeleteIcon />}\n </button>\n )}\n </div>\n\n {/* Style Panel - inside wrapper */}\n {isStylePanelOpen && onStyleChange && (\n <div\n className=\"TextHighlight__style-panel\"\n ref={stylePanelRef}\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"TextHighlight__style-row\">\n <label>Style</label>\n <div className=\"TextHighlight__style-buttons\">\n <button\n type=\"button\"\n className={`TextHighlight__style-type-button ${highlightStyle === \"highlight\" ? \"active\" : \"\"}`}\n onClick={() =>\n onStyleChange({ highlightStyle: \"highlight\" })\n }\n title=\"Highlight\"\n >\n <HighlightIcon />\n </button>\n <button\n type=\"button\"\n className={`TextHighlight__style-type-button ${highlightStyle === \"underline\" ? \"active\" : \"\"}`}\n onClick={() =>\n onStyleChange({ highlightStyle: \"underline\" })\n }\n title=\"Underline\"\n >\n <UnderlineIcon />\n </button>\n <button\n type=\"button\"\n className={`TextHighlight__style-type-button ${highlightStyle === \"strikethrough\" ? \"active\" : \"\"}`}\n onClick={() =>\n onStyleChange({ highlightStyle: \"strikethrough\" })\n }\n title=\"Strikethrough\"\n >\n <StrikethroughIcon />\n </button>\n </div>\n </div>\n <div className=\"TextHighlight__style-row\">\n <label>Color</label>\n <div className=\"TextHighlight__color-options\">\n <div className=\"TextHighlight__color-presets\">\n {colorPresets.map((c) => (\n <button\n key={c}\n type=\"button\"\n className={`TextHighlight__color-preset ${highlightColor === c ? \"active\" : \"\"}`}\n style={{ backgroundColor: c }}\n onClick={() => onStyleChange({ highlightColor: c })}\n title={c}\n />\n ))}\n </div>\n <input\n type=\"color\"\n value={highlightColor}\n onChange={(e) => {\n onStyleChange({ highlightColor: e.target.value });\n }}\n />\n </div>\n </div>\n </div>\n )}\n </div>\n )}\n\n <div\n className=\"TextHighlight__parts\"\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n {rects.map((rect, index) => (\n <div\n onMouseOver={onMouseOver}\n onMouseOut={onMouseOut}\n onClick={onClick}\n key={index}\n style={getPartStyle(rect)}\n className={`TextHighlight__part ${getPartStyleClass()}`}\n />\n ))}\n </div>\n </div>\n );\n};\n","import React, { ReactNode, useRef } from \"react\";\nimport { usePdfHighlighterContext } from \"../contexts/PdfHighlighterContext\";\nimport { Tip } from \"../types\";\nimport { MouseMonitor } from \"./MouseMonitor\";\n\n/**\n * The props type for {@link MonitoredHighlightContainer}.\n *\n * @category Component Properties\n */\nexport interface MonitoredHighlightContainerProps {\n /**\n * A callback triggered whenever the mouse hovers over a highlight.\n */\n onMouseEnter?(): void;\n\n /**\n * What tip to automatically display whenever a mouse hovers over a highlight.\n * The tip will persist even as the user puts their mouse over it and not the\n * highlight, but will disappear once it no longer hovers both.\n */\n highlightTip?: Tip;\n\n /**\n * A callback triggered whenever the mouse completely moves out from both the\n * highlight (children) and any highlightTip.\n */\n onMouseLeave?(): void;\n\n /**\n * Component to monitor mouse activity over. This should be a highlight within the {@link PdfHighlighter}.\n */\n children: ReactNode;\n}\n\n/**\n * A container for a highlight component that monitors whether a mouse is over a\n * highlight and over some secondary highlight tip. It will display the tip\n * whenever the mouse is over the highlight and it will hide the tip only when\n * the mouse has left the highlight AND the tip.\n *\n * @category Component\n */\nexport const MonitoredHighlightContainer = ({\n onMouseEnter,\n highlightTip,\n onMouseLeave,\n children,\n}: MonitoredHighlightContainerProps) => {\n const mouseInRef = useRef(false); // Whether the mouse is over the child (highlight)\n\n const { setTip, isEditingOrHighlighting } = usePdfHighlighterContext();\n\n return (\n <div\n onMouseEnter={() => {\n mouseInRef.current = true;\n onMouseEnter && onMouseEnter();\n\n if (isEditingOrHighlighting()) return;\n\n if (highlightTip) {\n // MouseMonitor the highlightTip to prevent it from disappearing if the mouse is over it and not the highlight.\n const monitoredHighlightTip = (\n <MouseMonitor\n onMoveAway={() => {\n // The event will keep triggering if the mouse is not on the highlightTip,\n // but don't do anything if the mouse is over the highlight.\n if (mouseInRef.current) {\n return;\n }\n\n setTip(null);\n onMouseLeave && onMouseLeave();\n }}\n paddingX={60}\n paddingY={30}\n >\n {highlightTip.content}\n </MouseMonitor>\n );\n\n setTip({\n position: highlightTip.position,\n content: monitoredHighlightTip,\n });\n }\n }}\n onMouseLeave={() => {\n mouseInRef.current = false;\n\n // Trigger onMouseLeave if no highlightTip exists\n !highlightTip && onMouseLeave && onMouseLeave();\n }}\n >\n {children}\n </div>\n );\n};\n","import React, { ReactNode, useEffect, useRef } from \"react\";\n\n/**\n * The props type for {@link MouseMonitor}.\n *\n * @category Component Properties\n * @internal\n */\nexport interface MouseMonitorProps {\n /**\n * Callback triggered whenever the mouse moves not within the bounds of the\n * child component. This will keep triggering as long as the component is\n * rendered.\n */\n onMoveAway(): void;\n\n /**\n * X padding in pixels for the container to monitor mouse activity in.\n */\n paddingX: number;\n\n /**\n * Y padding in pixels for the container to monitor mouse activity in.\n */\n paddingY: number;\n\n /**\n * Component over which mouse activity is monitored.\n */\n children: ReactNode;\n}\n\n/**\n * A component that monitors mouse movements over a child and invisible padded area.\n *\n * @category Component\n * @internal\n */\nexport const MouseMonitor = ({\n onMoveAway,\n paddingX,\n paddingY,\n children,\n}: MouseMonitorProps) => {\n const containerRef = useRef<HTMLDivElement | null>(null);\n\n const onMouseMove = (event: MouseEvent) => {\n if (!containerRef.current) return;\n\n const { clientX, clientY } = event;\n const { left, top, width, height } =\n containerRef.current.getBoundingClientRect();\n\n const inBoundsX =\n clientX > left - paddingX && clientX < left + width + paddingX;\n const inBoundsY =\n clientY > top - paddingY && clientY < top + height + paddingY;\n\n if (!(inBoundsX && inBoundsY)) {\n onMoveAway();\n }\n };\n\n useEffect(() => {\n // TODO: Maybe optimise or throttle?\n document.addEventListener(\"mousemove\", onMouseMove);\n\n return () => {\n document.removeEventListener(\"mousemove\", onMouseMove);\n };\n }, []);\n\n return <div ref={containerRef}>{children}</div>;\n};\n","import React, {\n CSSProperties,\n MouseEvent,\n ReactNode,\n useState,\n useRef,\n useEffect,\n} from \"react\";\n\nimport { getPageFromElement } from \"../lib/pdfjs-dom\";\nimport { Rnd } from \"react-rnd\";\nimport type { LTWHP, ViewportHighlight } from \"../types\";\n\n/**\n * Style options for area highlight appearance.\n */\nexport interface AreaHighlightStyle {\n highlightColor?: string;\n}\n\n/**\n * The props type for {@link AreaHighlight}.\n *\n * @category Component Properties\n */\nexport interface AreaHighlightProps {\n /**\n * The highlight to be rendered as an {@link AreaHighlight}.\n */\n highlight: ViewportHighlight;\n\n /**\n * A callback triggered whenever the highlight area is either finished\n * being moved or resized.\n *\n * @param rect - The updated highlight area.\n */\n onChange?(rect: LTWHP): void;\n\n /**\n * Has the highlight been auto-scrolled into view? By default, this will render the highlight red.\n */\n isScrolledTo?: boolean;\n\n /**\n * react-rnd bounds on the highlight area. This is useful for preventing the user\n * moving the highlight off the viewer/page. See [react-rnd docs](https://github.com/bokuweb/react-rnd).\n */\n bounds?: string | Element;\n\n /**\n * A callback triggered whenever a context menu is opened on the highlight area.\n *\n * @param event - The mouse event associated with the context menu.\n */\n onContextMenu?(event: MouseEvent<HTMLDivElement>): void;\n\n /**\n * Event called whenever the user tries to move or resize an {@link AreaHighlight}.\n */\n onEditStart?(): void;\n\n /**\n * Custom styling to be applied to the {@link AreaHighlight} component.\n */\n style?: CSSProperties;\n\n /**\n * Background color for the highlight.\n * Default: \"rgba(255, 226, 143, 1)\" (yellow)\n */\n highlightColor?: string;\n\n /**\n * Callback triggered when the style changes.\n */\n onStyleChange?(style: AreaHighlightStyle): void;\n\n /**\n * Callback triggered when the delete button is clicked.\n */\n onDelete?(): void;\n\n /**\n * Custom style icon. Replaces the default palette icon.\n */\n styleIcon?: ReactNode;\n\n /**\n * Custom delete icon. Replaces the default trash icon.\n */\n deleteIcon?: ReactNode;\n\n /**\n * Custom color presets for the style panel.\n * Default: [\"rgba(255, 226, 143, 1)\", \"#ffcdd2\", \"#c8e6c9\", \"#bbdefb\", \"#e1bee7\"]\n */\n colorPresets?: string[];\n}\n\n// Default icons\nconst DefaultStyleIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z\" />\n </svg>\n);\n\nconst DefaultDeleteIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" />\n </svg>\n);\n\n// Default color presets\nconst DEFAULT_COLOR_PRESETS = [\n \"rgba(255, 226, 143, 1)\", // Yellow (default)\n \"#ffcdd2\", // Light red\n \"#c8e6c9\", // Light green\n \"#bbdefb\", // Light blue\n \"#e1bee7\", // Light purple\n];\n\n/**\n * Renders a resizeable and interactive rectangular area for a highlight.\n *\n * @category Component\n */\nexport const AreaHighlight = ({\n highlight,\n onChange,\n isScrolledTo,\n bounds,\n onContextMenu,\n onEditStart,\n style,\n highlightColor = \"rgba(255, 226, 143, 1)\",\n onStyleChange,\n onDelete,\n styleIcon,\n deleteIcon,\n colorPresets = DEFAULT_COLOR_PRESETS,\n}: AreaHighlightProps) => {\n const [isStylePanelOpen, setIsStylePanelOpen] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const stylePanelRef = useRef<HTMLDivElement>(null);\n\n // Close style panel when clicking outside\n useEffect(() => {\n if (!isStylePanelOpen) return;\n\n const handleClickOutside = (e: globalThis.MouseEvent) => {\n if (\n stylePanelRef.current &&\n !stylePanelRef.current.contains(e.target as Node)\n ) {\n setIsStylePanelOpen(false);\n }\n };\n\n // Delay adding listener to avoid immediate close\n const timeoutId = setTimeout(() => {\n document.addEventListener(\"mousedown\", handleClickOutside);\n }, 0);\n\n return () => {\n clearTimeout(timeoutId);\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [isStylePanelOpen]);\n\n const highlightClass = isScrolledTo ? \"AreaHighlight--scrolledTo\" : \"\";\n\n // Generate key based on position. This forces a remount (and a defaultpos update)\n // whenever highlight position changes (e.g., when updated, scale changes, etc.)\n // We don't use position as state because when updating Rnd this would happen and cause flickering:\n // User moves Rnd -> Rnd records new pos -> Rnd jumps back -> highlight updates -> Rnd re-renders at new pos\n const key = `${highlight.position.boundingRect.width}${highlight.position.boundingRect.height}${highlight.position.boundingRect.left}${highlight.position.boundingRect.top}`;\n\n // Merge custom style with highlight color\n const mergedStyle: CSSProperties = {\n ...style,\n backgroundColor: highlightColor,\n };\n\n return (\n <div\n className={`AreaHighlight ${highlightClass}`}\n onContextMenu={onContextMenu}\n >\n {/* Toolbar wrapper - extends down to overlap with highlight */}\n {(onStyleChange || onDelete) && (\n <div\n className=\"AreaHighlight__toolbar-wrapper\"\n style={{\n position: \"absolute\",\n left: highlight.position.boundingRect.left,\n top: highlight.position.boundingRect.top - 28,\n paddingBottom: 12,\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n <div\n className={`AreaHighlight__toolbar ${isHovered || isStylePanelOpen ? \"AreaHighlight__toolbar--visible\" : \"\"}`}\n >\n {onStyleChange && (\n <button\n className=\"AreaHighlight__style-button\"\n onClick={(e) => {\n e.stopPropagation();\n setIsStylePanelOpen(!isStylePanelOpen);\n }}\n title=\"Change color\"\n type=\"button\"\n >\n {styleIcon || <DefaultStyleIcon />}\n </button>\n )}\n {onDelete && (\n <button\n className=\"AreaHighlight__delete-button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete();\n }}\n title=\"Delete\"\n type=\"button\"\n >\n {deleteIcon || <DefaultDeleteIcon />}\n </button>\n )}\n </div>\n\n {/* Style Panel - inside wrapper */}\n {isStylePanelOpen && onStyleChange && (\n <div\n className=\"AreaHighlight__style-panel\"\n ref={stylePanelRef}\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"AreaHighlight__style-row\">\n <label>Color</label>\n <div className=\"AreaHighlight__color-options\">\n <div className=\"AreaHighlight__color-presets\">\n {colorPresets.map((c) => (\n <button\n key={c}\n type=\"button\"\n className={`AreaHighlight__color-preset ${highlightColor === c ? \"active\" : \"\"}`}\n style={{ backgroundColor: c }}\n onClick={() => onStyleChange({ highlightColor: c })}\n title={c}\n />\n ))}\n </div>\n <input\n type=\"color\"\n value={highlightColor}\n onChange={(e) => {\n onStyleChange({ highlightColor: e.target.value });\n }}\n />\n </div>\n </div>\n </div>\n )}\n </div>\n )}\n\n <Rnd\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n className=\"AreaHighlight__part\"\n onDragStop={(_, data) => {\n const boundingRect: LTWHP = {\n ...highlight.position.boundingRect,\n top: data.y,\n left: data.x,\n };\n\n onChange && onChange(boundingRect);\n }}\n onResizeStop={(_mouseEvent, _direction, ref, _delta, position) => {\n const boundingRect: LTWHP = {\n top: position.y,\n left: position.x,\n width: ref.offsetWidth,\n height: ref.offsetHeight,\n pageNumber: getPageFromElement(ref)?.number || -1,\n };\n\n onChange && onChange(boundingRect);\n }}\n onDragStart={onEditStart}\n onResizeStart={onEditStart}\n default={{\n x: highlight.position.boundingRect.left,\n y: highlight.position.boundingRect.top,\n width: highlight.position.boundingRect.width,\n height: highlight.position.boundingRect.height,\n }}\n key={key}\n bounds={bounds}\n // Prevevent any event clicks as clicking is already used for movement\n onClick={(event: Event) => {\n event.stopPropagation();\n event.preventDefault();\n }}\n style={mergedStyle}\n />\n </div>\n );\n};\n","import React, {\n CSSProperties,\n MouseEvent,\n ReactNode,\n useState,\n useRef,\n useEffect,\n} from \"react\";\nimport { Rnd } from \"react-rnd\";\nimport { getPageFromElement } from \"../lib/pdfjs-dom\";\nimport type { LTWHP, ViewportHighlight } from \"../types\";\n\n/**\n * Style options for freetext highlight appearance.\n */\nexport interface FreetextStyle {\n color?: string;\n backgroundColor?: string;\n fontFamily?: string;\n fontSize?: string;\n}\n\n/**\n * The props type for {@link FreetextHighlight}.\n *\n * @category Component Properties\n */\nexport interface FreetextHighlightProps {\n /**\n * The highlight to be rendered as a {@link FreetextHighlight}.\n */\n highlight: ViewportHighlight;\n\n /**\n * A callback triggered whenever the highlight position changes (drag).\n *\n * @param rect - The updated highlight area.\n */\n onChange?(rect: LTWHP): void;\n\n /**\n * A callback triggered whenever the text content changes.\n *\n * @param text - The new text content.\n */\n onTextChange?(text: string): void;\n\n /**\n * A callback triggered whenever the style changes.\n *\n * @param style - The new style options.\n */\n onStyleChange?(style: FreetextStyle): void;\n\n /**\n * Has the highlight been auto-scrolled into view?\n */\n isScrolledTo?: boolean;\n\n /**\n * react-rnd bounds on the highlight area.\n */\n bounds?: string | Element;\n\n /**\n * A callback triggered on context menu.\n */\n onContextMenu?(event: MouseEvent<HTMLDivElement>): void;\n\n /**\n * Event called when editing begins (drag or text edit).\n */\n onEditStart?(): void;\n\n /**\n * Event called when editing ends.\n */\n onEditEnd?(): void;\n\n /**\n * Custom styling for the container.\n */\n style?: CSSProperties;\n\n /**\n * Text color.\n */\n color?: string;\n\n /**\n * Background color.\n */\n backgroundColor?: string;\n\n /**\n * Font family.\n */\n fontFamily?: string;\n\n /**\n * Font size (e.g., \"14px\").\n */\n fontSize?: string;\n\n /**\n * Custom drag icon. Receives default icon as child if not provided.\n */\n dragIcon?: ReactNode;\n\n /**\n * Custom edit icon. Receives default icon as child if not provided.\n */\n editIcon?: ReactNode;\n\n /**\n * Custom style/settings icon. Receives default icon as child if not provided.\n */\n styleIcon?: ReactNode;\n\n /**\n * Custom background color presets for the style panel.\n * Default: [\"#ffffc8\", \"#ffcdd2\", \"#c8e6c9\", \"#bbdefb\", \"#e1bee7\"]\n */\n backgroundColorPresets?: string[];\n\n /**\n * Custom text color presets for the style panel.\n * Default: [\"#333333\", \"#d32f2f\", \"#1976d2\", \"#388e3c\", \"#7b1fa2\"]\n */\n textColorPresets?: string[];\n\n /**\n * Callback triggered when the delete button is clicked.\n */\n onDelete?(): void;\n\n /**\n * Custom delete icon. Replaces the default trash icon.\n */\n deleteIcon?: ReactNode;\n}\n\n/**\n * Renders a draggable, editable freetext annotation.\n *\n * @category Component\n */\n// Default icons\nconst DefaultDragIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <circle cx=\"8\" cy=\"6\" r=\"2\" />\n <circle cx=\"16\" cy=\"6\" r=\"2\" />\n <circle cx=\"8\" cy=\"12\" r=\"2\" />\n <circle cx=\"16\" cy=\"12\" r=\"2\" />\n <circle cx=\"8\" cy=\"18\" r=\"2\" />\n <circle cx=\"16\" cy=\"18\" r=\"2\" />\n </svg>\n);\n\nconst DefaultEditIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z\" />\n </svg>\n);\n\nconst DefaultStyleIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z\" />\n </svg>\n);\n\nconst DefaultDeleteIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" />\n </svg>\n);\n\n// Default color presets\nconst DEFAULT_BACKGROUND_PRESETS = [\"transparent\", \"#ffffc8\", \"#ffcdd2\", \"#c8e6c9\", \"#bbdefb\", \"#e1bee7\"];\nconst DEFAULT_TEXT_PRESETS = [\"#333333\", \"#d32f2f\", \"#1976d2\", \"#388e3c\", \"#7b1fa2\"];\n\nexport const FreetextHighlight = ({\n highlight,\n onChange,\n onTextChange,\n onStyleChange,\n isScrolledTo,\n bounds,\n onContextMenu,\n onEditStart,\n onEditEnd,\n style,\n color = \"#333333\",\n backgroundColor = \"#ffffc8\",\n fontFamily = \"inherit\",\n fontSize = \"14px\",\n dragIcon,\n editIcon,\n styleIcon,\n backgroundColorPresets = DEFAULT_BACKGROUND_PRESETS,\n textColorPresets = DEFAULT_TEXT_PRESETS,\n onDelete,\n deleteIcon,\n}: FreetextHighlightProps) => {\n const [isEditing, setIsEditing] = useState(false);\n const [isStylePanelOpen, setIsStylePanelOpen] = useState(false);\n const [text, setText] = useState(highlight.content?.text || \"\");\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const stylePanelRef = useRef<HTMLDivElement>(null);\n\n // Sync text with highlight content when it changes externally\n useEffect(() => {\n setText(highlight.content?.text || \"\");\n }, [highlight.content?.text]);\n\n // Focus textarea when entering edit mode\n useEffect(() => {\n if (isEditing && textareaRef.current) {\n textareaRef.current.focus();\n textareaRef.current.select();\n }\n }, [isEditing]);\n\n // Close style panel when clicking outside\n useEffect(() => {\n if (!isStylePanelOpen) return;\n\n const handleClickOutside = (e: globalThis.MouseEvent) => {\n if (stylePanelRef.current && !stylePanelRef.current.contains(e.target as Node)) {\n setIsStylePanelOpen(false);\n }\n };\n\n // Delay adding listener to avoid immediate close\n const timeoutId = setTimeout(() => {\n document.addEventListener(\"mousedown\", handleClickOutside);\n }, 0);\n\n return () => {\n clearTimeout(timeoutId);\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [isStylePanelOpen]);\n\n const highlightClass = isScrolledTo ? \"FreetextHighlight--scrolledTo\" : \"\";\n const editingClass = isEditing ? \"FreetextHighlight--editing\" : \"\";\n\n // Generate key based on position for Rnd remount on position changes\n const key = `${highlight.position.boundingRect.width}${highlight.position.boundingRect.height}${highlight.position.boundingRect.left}${highlight.position.boundingRect.top}`;\n\n const handleTextClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (!isEditing) {\n setIsEditing(true);\n onEditStart?.();\n }\n };\n\n const handleTextBlur = () => {\n if (isEditing) {\n setIsEditing(false);\n onTextChange?.(text);\n onEditEnd?.();\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n setText(highlight.content?.text || \"\");\n setIsEditing(false);\n onEditEnd?.();\n } else if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n setIsEditing(false);\n onTextChange?.(text);\n onEditEnd?.();\n }\n };\n\n const containerStyle: CSSProperties = {\n backgroundColor,\n color,\n fontFamily,\n fontSize,\n ...style,\n };\n\n return (\n <div\n className={`FreetextHighlight ${highlightClass} ${editingClass}`}\n onContextMenu={onContextMenu}\n >\n <Rnd\n className=\"FreetextHighlight__rnd\"\n onDragStop={(_, data) => {\n const boundingRect: LTWHP = {\n ...highlight.position.boundingRect,\n top: data.y,\n left: data.x,\n };\n onChange?.(boundingRect);\n }}\n onDragStart={() => {\n if (!isEditing) {\n onEditStart?.();\n }\n }}\n default={{\n x: highlight.position.boundingRect.left,\n y: highlight.position.boundingRect.top,\n width: highlight.position.boundingRect.width || 150,\n height: highlight.position.boundingRect.height || 80,\n }}\n minWidth={100}\n minHeight={50}\n key={key}\n bounds={bounds}\n enableResizing={{\n top: false,\n right: true,\n bottom: true,\n left: false,\n topRight: false,\n bottomRight: true,\n bottomLeft: false,\n topLeft: false,\n }}\n onResizeStop={(_e, _direction, ref, _delta, position) => {\n const boundingRect: LTWHP = {\n top: position.y,\n left: position.x,\n width: ref.offsetWidth,\n height: ref.offsetHeight,\n pageNumber:\n getPageFromElement(ref)?.number ||\n highlight.position.boundingRect.pageNumber,\n };\n onChange?.(boundingRect);\n }}\n onResizeStart={() => {\n if (!isEditing) {\n onEditStart?.();\n }\n }}\n cancel=\".FreetextHighlight__text, .FreetextHighlight__input, .FreetextHighlight__edit-button, .FreetextHighlight__style-button, .FreetextHighlight__style-panel, .FreetextHighlight__delete-button\"\n >\n <div className=\"FreetextHighlight__container\" style={containerStyle}>\n <div className=\"FreetextHighlight__toolbar\">\n <div className=\"FreetextHighlight__drag-handle\" title=\"Drag to move\">\n {dragIcon || <DefaultDragIcon />}\n </div>\n <button\n className=\"FreetextHighlight__edit-button\"\n onClick={handleTextClick}\n title=\"Edit text\"\n type=\"button\"\n >\n {editIcon || <DefaultEditIcon />}\n </button>\n <button\n className=\"FreetextHighlight__style-button\"\n onClick={(e) => {\n e.stopPropagation();\n setIsStylePanelOpen(!isStylePanelOpen);\n }}\n title=\"Change style\"\n type=\"button\"\n >\n {styleIcon || <DefaultStyleIcon />}\n </button>\n {onDelete && (\n <button\n className=\"FreetextHighlight__delete-button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete();\n }}\n title=\"Delete\"\n type=\"button\"\n >\n {deleteIcon || <DefaultDeleteIcon />}\n </button>\n )}\n </div>\n {isStylePanelOpen && (\n <div\n className=\"FreetextHighlight__style-panel\"\n ref={stylePanelRef}\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"FreetextHighlight__style-row\">\n <label>Background</label>\n <div className=\"FreetextHighlight__color-options\">\n <div className=\"FreetextHighlight__color-presets\">\n {backgroundColorPresets.map((c) => (\n <button\n key={c}\n type=\"button\"\n className={`FreetextHighlight__color-preset ${c === \"transparent\" ? \"FreetextHighlight__color-preset--transparent\" : \"\"} ${backgroundColor === c ? \"active\" : \"\"}`}\n style={c !== \"transparent\" ? { backgroundColor: c } : undefined}\n onClick={() => onStyleChange?.({ backgroundColor: c })}\n title={c === \"transparent\" ? \"No background\" : c}\n />\n ))}\n </div>\n <input\n type=\"color\"\n value={backgroundColor === \"transparent\" ? \"#ffffff\" : backgroundColor}\n onChange={(e) => {\n onStyleChange?.({ backgroundColor: e.target.value });\n }}\n />\n </div>\n </div>\n <div className=\"FreetextHighlight__style-row\">\n <label\n\n >Text Color</label>\n <div className=\"FreetextHighlight__color-options\">\n <div className=\"FreetextHighlight__color-presets\">\n {textColorPresets.map((c) => (\n <button\n key={c}\n type=\"button\"\n className={`FreetextHighlight__color-preset ${color === c ? \"active\" : \"\"}`}\n style={{ backgroundColor: c }}\n onClick={() => onStyleChange?.({ color: c })}\n title={c}\n />\n ))}\n </div>\n <input\n type=\"color\"\n value={color}\n onChange={(e) => {\n onStyleChange?.({ color: e.target.value });\n }}\n />\n </div>\n </div>\n <div className=\"FreetextHighlight__style-row\">\n <label>Font Size</label>\n <select\n value={fontSize}\n onChange={(e) => {\n onStyleChange?.({ fontSize: e.target.value });\n }}\n >\n <option value=\"10px\">10px</option>\n <option value=\"12px\">12px</option>\n <option value=\"14px\">14px</option>\n <option value=\"16px\">16px</option>\n <option value=\"18px\">18px</option>\n <option value=\"20px\">20px</option>\n <option value=\"24px\">24px</option>\n </select>\n </div>\n <div className=\"FreetextHighlight__style-row\">\n <label>Font</label>\n <select\n value={fontFamily}\n onChange={(e) => {\n onStyleChange?.({ fontFamily: e.target.value });\n }}\n >\n <option value=\"inherit\">Default</option>\n <option value=\"Arial, sans-serif\">Arial</option>\n <option value=\"Georgia, serif\">Georgia</option>\n <option value=\"'Courier New', monospace\">Courier</option>\n <option value=\"'Times New Roman', serif\">Times</option>\n </select>\n </div>\n </div>\n )}\n <div className=\"FreetextHighlight__content\">\n {isEditing ? (\n <textarea\n ref={textareaRef}\n className=\"FreetextHighlight__input\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n onBlur={handleTextBlur}\n onKeyDown={handleKeyDown}\n onClick={(e) => e.stopPropagation()}\n />\n ) : (\n <div className=\"FreetextHighlight__text\">\n {text || \"New note\"}\n </div>\n )}\n </div>\n </div>\n </Rnd>\n </div>\n );\n};\n","import React, { CSSProperties, MouseEvent, ReactNode } from \"react\";\nimport { Rnd } from \"react-rnd\";\nimport { getPageFromElement } from \"../lib/pdfjs-dom\";\nimport type { LTWHP, ViewportHighlight } from \"../types\";\n\n/**\n * The props type for {@link ImageHighlight}.\n *\n * @category Component Properties\n */\nexport interface ImageHighlightProps {\n /**\n * The highlight to be rendered as an {@link ImageHighlight}.\n * The highlight.content.image should contain the image data URL.\n */\n highlight: ViewportHighlight;\n\n /**\n * A callback triggered whenever the highlight position or size changes.\n *\n * @param rect - The updated highlight area.\n */\n onChange?(rect: LTWHP): void;\n\n /**\n * Has the highlight been auto-scrolled into view?\n */\n isScrolledTo?: boolean;\n\n /**\n * react-rnd bounds on the highlight area.\n */\n bounds?: string | Element;\n\n /**\n * A callback triggered on context menu.\n */\n onContextMenu?(event: MouseEvent<HTMLDivElement>): void;\n\n /**\n * Event called when editing begins (drag or resize).\n */\n onEditStart?(): void;\n\n /**\n * Event called when editing ends.\n */\n onEditEnd?(): void;\n\n /**\n * Custom styling for the container.\n */\n style?: CSSProperties;\n\n /**\n * Custom drag icon. Replaces the default 6-dot grid icon.\n */\n dragIcon?: ReactNode;\n\n /**\n * Callback triggered when the delete button is clicked.\n */\n onDelete?(): void;\n\n /**\n * Custom delete icon. Replaces the default trash icon.\n */\n deleteIcon?: ReactNode;\n}\n\n/**\n * Default drag icon - 6 dot grid pattern.\n */\nconst DefaultDragIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <circle cx=\"8\" cy=\"6\" r=\"2\" />\n <circle cx=\"16\" cy=\"6\" r=\"2\" />\n <circle cx=\"8\" cy=\"12\" r=\"2\" />\n <circle cx=\"16\" cy=\"12\" r=\"2\" />\n <circle cx=\"8\" cy=\"18\" r=\"2\" />\n <circle cx=\"16\" cy=\"18\" r=\"2\" />\n </svg>\n);\n\nconst DefaultDeleteIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" />\n </svg>\n);\n\n/**\n * Renders a draggable, resizable image/signature annotation.\n *\n * @category Component\n */\nexport const ImageHighlight = ({\n highlight,\n onChange,\n isScrolledTo,\n bounds,\n onContextMenu,\n onEditStart,\n onEditEnd,\n style,\n dragIcon,\n onDelete,\n deleteIcon,\n}: ImageHighlightProps) => {\n const highlightClass = isScrolledTo ? \"ImageHighlight--scrolledTo\" : \"\";\n\n // Generate key based on position for Rnd remount on position changes\n const key = `${highlight.position.boundingRect.width}${highlight.position.boundingRect.height}${highlight.position.boundingRect.left}${highlight.position.boundingRect.top}`;\n\n const imageUrl = highlight.content?.image;\n\n return (\n <div\n className={`ImageHighlight ${highlightClass}`}\n onContextMenu={onContextMenu}\n >\n <Rnd\n className=\"ImageHighlight__rnd\"\n onDragStop={(_, data) => {\n const boundingRect: LTWHP = {\n ...highlight.position.boundingRect,\n top: data.y,\n left: data.x,\n };\n onChange?.(boundingRect);\n onEditEnd?.();\n }}\n onDragStart={onEditStart}\n onResizeStop={(_e, _direction, ref, _delta, position) => {\n const boundingRect: LTWHP = {\n top: position.y,\n left: position.x,\n width: ref.offsetWidth,\n height: ref.offsetHeight,\n pageNumber:\n getPageFromElement(ref)?.number ||\n highlight.position.boundingRect.pageNumber,\n };\n onChange?.(boundingRect);\n onEditEnd?.();\n }}\n onResizeStart={onEditStart}\n default={{\n x: highlight.position.boundingRect.left,\n y: highlight.position.boundingRect.top,\n width: highlight.position.boundingRect.width || 150,\n height: highlight.position.boundingRect.height || 100,\n }}\n minWidth={50}\n minHeight={50}\n key={key}\n bounds={bounds}\n lockAspectRatio={true}\n dragHandleClassName=\"ImageHighlight__drag-handle\"\n onClick={(event: Event) => {\n event.stopPropagation();\n event.preventDefault();\n }}\n style={style}\n >\n <div className=\"ImageHighlight__container\">\n <div className=\"ImageHighlight__toolbar\">\n <div className=\"ImageHighlight__drag-handle\" title=\"Drag to move\">\n {dragIcon || <DefaultDragIcon />}\n </div>\n {onDelete && (\n <button\n className=\"ImageHighlight__delete-button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete();\n }}\n title=\"Delete\"\n type=\"button\"\n >\n {deleteIcon || <DefaultDeleteIcon />}\n </button>\n )}\n </div>\n <div className=\"ImageHighlight__content\">\n {imageUrl ? (\n <img\n src={imageUrl}\n alt=\"Highlight\"\n className=\"ImageHighlight__image\"\n draggable={false}\n />\n ) : (\n <div className=\"ImageHighlight__placeholder\">No image</div>\n )}\n </div>\n </div>\n </Rnd>\n </div>\n );\n};\n","import React, { useRef, useEffect, useCallback } from \"react\";\n\n/**\n * The props type for {@link SignaturePad}.\n *\n * @category Component Properties\n */\nexport interface SignaturePadProps {\n /**\n * Whether the signature pad modal is open.\n */\n isOpen: boolean;\n\n /**\n * Callback when signature is completed.\n *\n * @param dataUrl - The signature as a PNG data URL.\n */\n onComplete: (dataUrl: string) => void;\n\n /**\n * Callback when the modal is closed/cancelled.\n */\n onClose: () => void;\n\n /**\n * Canvas width in pixels.\n * @default 400\n */\n width?: number;\n\n /**\n * Canvas height in pixels.\n * @default 200\n */\n height?: number;\n}\n\n/**\n * A modal component with a canvas for drawing signatures.\n * Supports both mouse and touch input.\n *\n * @category Component\n */\nexport const SignaturePad = ({\n isOpen,\n onComplete,\n onClose,\n width = 400,\n height = 200,\n}: SignaturePadProps) => {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const isDrawingRef = useRef(false);\n const lastPosRef = useRef({ x: 0, y: 0 });\n\n // Initialize canvas context\n useEffect(() => {\n if (!isOpen || !canvasRef.current) return;\n\n const canvas = canvasRef.current;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n\n // Set up drawing style\n ctx.strokeStyle = \"#000000\";\n ctx.lineWidth = 2;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n\n // Clear canvas\n ctx.fillStyle = \"white\";\n ctx.fillRect(0, 0, width, height);\n }, [isOpen, width, height]);\n\n const getPosition = useCallback(\n (e: MouseEvent | TouchEvent) => {\n const canvas = canvasRef.current;\n if (!canvas) return { x: 0, y: 0 };\n\n const rect = canvas.getBoundingClientRect();\n let clientX: number;\n let clientY: number;\n\n if (\"touches\" in e) {\n clientX = e.touches[0].clientX;\n clientY = e.touches[0].clientY;\n } else {\n clientX = e.clientX;\n clientY = e.clientY;\n }\n\n return {\n x: clientX - rect.left,\n y: clientY - rect.top,\n };\n },\n []\n );\n\n const startDrawing = useCallback(\n (e: MouseEvent | TouchEvent) => {\n e.preventDefault();\n isDrawingRef.current = true;\n lastPosRef.current = getPosition(e);\n },\n [getPosition]\n );\n\n const draw = useCallback(\n (e: MouseEvent | TouchEvent) => {\n if (!isDrawingRef.current) return;\n e.preventDefault();\n\n const canvas = canvasRef.current;\n const ctx = canvas?.getContext(\"2d\");\n if (!ctx) return;\n\n const currentPos = getPosition(e);\n\n ctx.beginPath();\n ctx.moveTo(lastPosRef.current.x, lastPosRef.current.y);\n ctx.lineTo(currentPos.x, currentPos.y);\n ctx.stroke();\n\n lastPosRef.current = currentPos;\n },\n [getPosition]\n );\n\n const stopDrawing = useCallback(() => {\n isDrawingRef.current = false;\n }, []);\n\n // Set up event listeners\n useEffect(() => {\n if (!isOpen) return;\n\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n // Mouse events\n const handleMouseDown = (e: MouseEvent) => startDrawing(e);\n const handleMouseMove = (e: MouseEvent) => draw(e);\n const handleMouseUp = () => stopDrawing();\n const handleMouseLeave = () => stopDrawing();\n\n // Touch events\n const handleTouchStart = (e: TouchEvent) => startDrawing(e);\n const handleTouchMove = (e: TouchEvent) => draw(e);\n const handleTouchEnd = () => stopDrawing();\n\n canvas.addEventListener(\"mousedown\", handleMouseDown);\n canvas.addEventListener(\"mousemove\", handleMouseMove);\n canvas.addEventListener(\"mouseup\", handleMouseUp);\n canvas.addEventListener(\"mouseleave\", handleMouseLeave);\n canvas.addEventListener(\"touchstart\", handleTouchStart, { passive: false });\n canvas.addEventListener(\"touchmove\", handleTouchMove, { passive: false });\n canvas.addEventListener(\"touchend\", handleTouchEnd);\n\n return () => {\n canvas.removeEventListener(\"mousedown\", handleMouseDown);\n canvas.removeEventListener(\"mousemove\", handleMouseMove);\n canvas.removeEventListener(\"mouseup\", handleMouseUp);\n canvas.removeEventListener(\"mouseleave\", handleMouseLeave);\n canvas.removeEventListener(\"touchstart\", handleTouchStart);\n canvas.removeEventListener(\"touchmove\", handleTouchMove);\n canvas.removeEventListener(\"touchend\", handleTouchEnd);\n };\n }, [isOpen, startDrawing, draw, stopDrawing]);\n\n const handleClear = () => {\n const canvas = canvasRef.current;\n const ctx = canvas?.getContext(\"2d\");\n if (!ctx || !canvas) return;\n\n ctx.fillStyle = \"white\";\n ctx.fillRect(0, 0, width, height);\n };\n\n const handleDone = () => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const dataUrl = canvas.toDataURL(\"image/png\");\n onComplete(dataUrl);\n };\n\n const handleOverlayClick = (e: React.MouseEvent) => {\n // Close if clicking the overlay background\n if (e.target === e.currentTarget) {\n onClose();\n }\n };\n\n if (!isOpen) return null;\n\n return (\n <div className=\"SignaturePad__overlay\" onClick={handleOverlayClick}>\n <div className=\"SignaturePad__modal\">\n <h3 className=\"SignaturePad__title\">Draw your signature</h3>\n <canvas\n ref={canvasRef}\n className=\"SignaturePad__canvas\"\n width={width}\n height={height}\n />\n <div className=\"SignaturePad__buttons\">\n <button\n type=\"button\"\n className=\"SignaturePad__button SignaturePad__button--clear\"\n onClick={handleClear}\n >\n Clear\n </button>\n <button\n type=\"button\"\n className=\"SignaturePad__button SignaturePad__button--cancel\"\n onClick={onClose}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"SignaturePad__button SignaturePad__button--done\"\n onClick={handleDone}\n >\n Done\n </button>\n </div>\n </div>\n </div>\n );\n};\n","import React, { CSSProperties, MouseEvent, ReactNode, useState, useCallback, useEffect, useRef } from \"react\";\nimport { Rnd } from \"react-rnd\";\nimport { getPageFromElement } from \"../lib/pdfjs-dom\";\nimport type { DrawingStroke, LTWHP, ViewportHighlight } from \"../types\";\n\n// Drawing style presets (same as toolbar)\nconst DRAWING_COLORS = [\"#000000\", \"#FF0000\", \"#0000FF\", \"#00FF00\", \"#FFFF00\"];\nconst STROKE_WIDTHS = [\n { label: \"Thin\", value: 1 },\n { label: \"Medium\", value: 3 },\n { label: \"Thick\", value: 5 },\n];\n\n/**\n * The props type for {@link DrawingHighlight}.\n *\n * @category Component Properties\n */\nexport interface DrawingHighlightProps {\n /**\n * The highlight to be rendered as a {@link DrawingHighlight}.\n * The highlight.content.image should contain the drawing as a PNG data URL.\n */\n highlight: ViewportHighlight;\n\n /**\n * A callback triggered whenever the highlight position or size changes.\n *\n * @param rect - The updated highlight area.\n */\n onChange?(rect: LTWHP): void;\n\n /**\n * Has the highlight been auto-scrolled into view?\n */\n isScrolledTo?: boolean;\n\n /**\n * react-rnd bounds on the highlight area.\n */\n bounds?: string | Element;\n\n /**\n * A callback triggered on context menu.\n */\n onContextMenu?(event: MouseEvent<HTMLDivElement>): void;\n\n /**\n * Event called when editing begins (drag or resize).\n */\n onEditStart?(): void;\n\n /**\n * Event called when editing ends.\n */\n onEditEnd?(): void;\n\n /**\n * Custom styling for the container.\n */\n style?: CSSProperties;\n\n /**\n * Custom drag icon. Replaces the default 6-dot grid icon.\n */\n dragIcon?: ReactNode;\n\n /**\n * Callback when drawing style changes (color or stroke width).\n * The newImage is the re-rendered PNG data URL with updated styles.\n * The newStrokes contain the updated stroke data.\n */\n onStyleChange?(newImage: string, newStrokes: DrawingStroke[]): void;\n\n /**\n * Callback triggered when the delete button is clicked.\n */\n onDelete?(): void;\n\n /**\n * Custom delete icon. Replaces the default trash icon.\n */\n deleteIcon?: ReactNode;\n}\n\n/**\n * Default drag icon - 6 dot grid pattern.\n */\nconst DefaultDragIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <circle cx=\"8\" cy=\"6\" r=\"2\" />\n <circle cx=\"16\" cy=\"6\" r=\"2\" />\n <circle cx=\"8\" cy=\"12\" r=\"2\" />\n <circle cx=\"16\" cy=\"12\" r=\"2\" />\n <circle cx=\"8\" cy=\"18\" r=\"2\" />\n <circle cx=\"16\" cy=\"18\" r=\"2\" />\n </svg>\n);\n\nconst DefaultDeleteIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" />\n </svg>\n);\n\n/**\n * Re-render strokes to a canvas and return as PNG data URL.\n */\nconst renderStrokesToImage = (\n strokes: DrawingStroke[],\n width: number,\n height: number\n): string => {\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext(\"2d\");\n\n if (!ctx) return \"\";\n\n strokes.forEach((stroke) => {\n if (stroke.points.length < 2) return;\n\n ctx.strokeStyle = stroke.color;\n ctx.lineWidth = stroke.width;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n\n ctx.beginPath();\n ctx.moveTo(stroke.points[0].x, stroke.points[0].y);\n stroke.points.slice(1).forEach((point) => {\n ctx.lineTo(point.x, point.y);\n });\n ctx.stroke();\n });\n\n return canvas.toDataURL(\"image/png\");\n};\n\n/**\n * Renders a draggable, resizable freehand drawing annotation.\n * Drawings are stored as PNG images with transparent backgrounds.\n *\n * @category Component\n */\nexport const DrawingHighlight = ({\n highlight,\n onChange,\n isScrolledTo,\n bounds,\n onContextMenu,\n onEditStart,\n onEditEnd,\n style,\n dragIcon,\n onStyleChange,\n onDelete,\n deleteIcon,\n}: DrawingHighlightProps) => {\n const highlightClass = isScrolledTo ? \"DrawingHighlight--scrolledTo\" : \"\";\n const [showStyleControls, setShowStyleControls] = useState(false);\n const styleControlsRef = useRef<HTMLDivElement>(null);\n\n // Close style controls when clicking outside\n useEffect(() => {\n if (!showStyleControls) return;\n\n const handleClickOutside = (e: globalThis.MouseEvent) => {\n if (styleControlsRef.current && !styleControlsRef.current.contains(e.target as Node)) {\n setShowStyleControls(false);\n }\n };\n\n // Delay adding listener to avoid immediate close\n const timeoutId = setTimeout(() => {\n document.addEventListener(\"mousedown\", handleClickOutside);\n }, 0);\n\n return () => {\n clearTimeout(timeoutId);\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [showStyleControls]);\n\n // Generate key based on position for Rnd remount on position changes\n const key = `${highlight.position.boundingRect.width}${highlight.position.boundingRect.height}${highlight.position.boundingRect.left}${highlight.position.boundingRect.top}`;\n\n const imageUrl = highlight.content?.image;\n const strokes = highlight.content?.strokes;\n\n // Apply new color to all strokes\n const handleColorChange = useCallback((newColor: string) => {\n if (!strokes || !onStyleChange) return;\n\n console.log(\"DrawingHighlight: Changing color to\", newColor);\n const newStrokes = strokes.map((stroke) => ({\n ...stroke,\n color: newColor,\n }));\n\n const newImage = renderStrokesToImage(\n newStrokes,\n highlight.position.boundingRect.width,\n highlight.position.boundingRect.height\n );\n\n onStyleChange(newImage, newStrokes);\n }, [strokes, onStyleChange, highlight.position.boundingRect.width, highlight.position.boundingRect.height]);\n\n // Apply new width to all strokes\n const handleWidthChange = useCallback((newWidth: number) => {\n if (!strokes || !onStyleChange) return;\n\n console.log(\"DrawingHighlight: Changing width to\", newWidth);\n const newStrokes = strokes.map((stroke) => ({\n ...stroke,\n width: newWidth,\n }));\n\n const newImage = renderStrokesToImage(\n newStrokes,\n highlight.position.boundingRect.width,\n highlight.position.boundingRect.height\n );\n\n onStyleChange(newImage, newStrokes);\n }, [strokes, onStyleChange, highlight.position.boundingRect.width, highlight.position.boundingRect.height]);\n\n // Get current color from first stroke (for showing active state)\n const currentColor = strokes?.[0]?.color || \"#000000\";\n const currentWidth = strokes?.[0]?.width || 3;\n\n return (\n <div\n className={`DrawingHighlight ${highlightClass}`}\n onContextMenu={onContextMenu}\n >\n <Rnd\n className=\"DrawingHighlight__rnd\"\n onDragStop={(_, data) => {\n const boundingRect: LTWHP = {\n ...highlight.position.boundingRect,\n top: data.y,\n left: data.x,\n };\n onChange?.(boundingRect);\n onEditEnd?.();\n }}\n onDragStart={onEditStart}\n onResizeStop={(_e, _direction, ref, _delta, position) => {\n const boundingRect: LTWHP = {\n top: position.y,\n left: position.x,\n width: ref.offsetWidth,\n height: ref.offsetHeight,\n pageNumber:\n getPageFromElement(ref)?.number ||\n highlight.position.boundingRect.pageNumber,\n };\n onChange?.(boundingRect);\n onEditEnd?.();\n }}\n onResizeStart={onEditStart}\n default={{\n x: highlight.position.boundingRect.left,\n y: highlight.position.boundingRect.top,\n width: highlight.position.boundingRect.width || 150,\n height: highlight.position.boundingRect.height || 100,\n }}\n minWidth={30}\n minHeight={30}\n key={key}\n bounds={bounds}\n // No aspect ratio lock for drawings - allow free resizing\n lockAspectRatio={false}\n dragHandleClassName=\"DrawingHighlight__drag-handle\"\n onClick={(event: Event) => {\n event.stopPropagation();\n event.preventDefault();\n }}\n style={style}\n >\n <div className=\"DrawingHighlight__container\">\n <div className=\"DrawingHighlight__toolbar\">\n <div className=\"DrawingHighlight__drag-handle\" title=\"Drag to move\">\n {dragIcon || <DefaultDragIcon />}\n </div>\n {/* Style edit button - only show if strokes are available */}\n {strokes && strokes.length > 0 && onStyleChange && (\n <button\n type=\"button\"\n className=\"DrawingHighlight__style-button\"\n title=\"Edit style\"\n onClick={(e) => {\n e.stopPropagation();\n setShowStyleControls(!showStyleControls);\n }}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z\"/>\n </svg>\n </button>\n )}\n {onDelete && (\n <button\n className=\"DrawingHighlight__delete-button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete();\n }}\n title=\"Delete\"\n type=\"button\"\n >\n {deleteIcon || <DefaultDeleteIcon />}\n </button>\n )}\n </div>\n {/* Style controls dropdown */}\n {showStyleControls && strokes && strokes.length > 0 && onStyleChange && (\n <div className=\"DrawingHighlight__style-controls\" ref={styleControlsRef}>\n <div className=\"DrawingHighlight__color-picker\">\n {DRAWING_COLORS.map((color) => (\n <button\n key={color}\n type=\"button\"\n className={`DrawingHighlight__color-button ${currentColor === color ? 'active' : ''}`}\n style={{ backgroundColor: color }}\n onClick={(e) => {\n e.stopPropagation();\n handleColorChange(color);\n }}\n title={`Color: ${color}`}\n />\n ))}\n </div>\n <div className=\"DrawingHighlight__width-picker\">\n {STROKE_WIDTHS.map((w) => (\n <button\n key={w.value}\n type=\"button\"\n className={`DrawingHighlight__width-button ${currentWidth === w.value ? 'active' : ''}`}\n onClick={(e) => {\n e.stopPropagation();\n handleWidthChange(w.value);\n }}\n title={w.label}\n >\n {w.label}\n </button>\n ))}\n </div>\n </div>\n )}\n <div className=\"DrawingHighlight__content\">\n {imageUrl ? (\n <img\n src={imageUrl}\n alt=\"Drawing\"\n className=\"DrawingHighlight__image\"\n draggable={false}\n />\n ) : (\n <div className=\"DrawingHighlight__placeholder\">No drawing</div>\n )}\n </div>\n </div>\n </Rnd>\n </div>\n );\n};\n","import React, {\n CSSProperties,\n MouseEvent,\n ReactNode,\n useState,\n useRef,\n useEffect,\n} from \"react\";\nimport { Rnd } from \"react-rnd\";\nimport { getPageFromElement } from \"../lib/pdfjs-dom\";\nimport type { LTWHP, ShapeType, ViewportHighlight } from \"../types\";\n\n/**\n * Style options for shape highlight appearance.\n */\nexport interface ShapeStyle {\n strokeColor?: string;\n strokeWidth?: number;\n}\n\n/**\n * The props type for {@link ShapeHighlight}.\n *\n * @category Component Properties\n */\nexport interface ShapeHighlightProps {\n /**\n * The highlight to be rendered as a {@link ShapeHighlight}.\n */\n highlight: ViewportHighlight;\n\n /**\n * A callback triggered whenever the highlight position or size changes.\n *\n * @param rect - The updated highlight area.\n */\n onChange?(rect: LTWHP): void;\n\n /**\n * Has the highlight been auto-scrolled into view?\n */\n isScrolledTo?: boolean;\n\n /**\n * react-rnd bounds on the highlight area.\n */\n bounds?: string | Element;\n\n /**\n * A callback triggered on context menu.\n */\n onContextMenu?(event: MouseEvent<HTMLDivElement>): void;\n\n /**\n * Event called when editing begins (drag or resize).\n */\n onEditStart?(): void;\n\n /**\n * Event called when editing ends.\n */\n onEditEnd?(): void;\n\n /**\n * Custom styling for the container.\n */\n style?: CSSProperties;\n\n /**\n * The type of shape to render.\n * @default \"rectangle\"\n */\n shapeType?: ShapeType;\n\n /**\n * Stroke color for the shape.\n * @default \"#000000\"\n */\n strokeColor?: string;\n\n /**\n * Stroke width for the shape.\n * @default 2\n */\n strokeWidth?: number;\n\n /**\n * Callback triggered when the style changes.\n */\n onStyleChange?(style: ShapeStyle): void;\n\n /**\n * Callback triggered when the delete button is clicked.\n */\n onDelete?(): void;\n\n /**\n * Custom style icon. Replaces the default palette icon.\n */\n styleIcon?: ReactNode;\n\n /**\n * Custom delete icon. Replaces the default trash icon.\n */\n deleteIcon?: ReactNode;\n\n /**\n * Custom color presets for the style panel.\n */\n colorPresets?: string[];\n\n /**\n * For arrows: start point as percentage of bounding box (0-1).\n */\n startPoint?: { x: number; y: number };\n\n /**\n * For arrows: end point as percentage of bounding box (0-1).\n */\n endPoint?: { x: number; y: number };\n}\n\n// Default icons\nconst DefaultStyleIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z\" />\n </svg>\n);\n\nconst DefaultDeleteIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" />\n </svg>\n);\n\n// Default color presets for shapes\nconst DEFAULT_COLOR_PRESETS = [\n \"#000000\", // Black\n \"#FF0000\", // Red\n \"#0000FF\", // Blue\n \"#00AA00\", // Green\n \"#FF6600\", // Orange\n];\n\n// Stroke width options\nconst STROKE_WIDTHS = [\n { label: \"Thin\", value: 1 },\n { label: \"Medium\", value: 2 },\n { label: \"Thick\", value: 4 },\n];\n\n/**\n * Renders a draggable, resizable shape annotation.\n * Supports rectangle, circle/ellipse, and arrow shapes.\n *\n * @category Component\n */\nexport const ShapeHighlight = ({\n highlight,\n onChange,\n isScrolledTo,\n bounds,\n onContextMenu,\n onEditStart,\n onEditEnd,\n style,\n shapeType = \"rectangle\",\n strokeColor = \"#000000\",\n strokeWidth = 2,\n onStyleChange,\n onDelete,\n styleIcon,\n deleteIcon,\n colorPresets = DEFAULT_COLOR_PRESETS,\n startPoint,\n endPoint,\n}: ShapeHighlightProps) => {\n const [isStylePanelOpen, setIsStylePanelOpen] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const stylePanelRef = useRef<HTMLDivElement>(null);\n\n // Close style panel when clicking outside\n useEffect(() => {\n if (!isStylePanelOpen) return;\n\n const handleClickOutside = (e: globalThis.MouseEvent) => {\n if (\n stylePanelRef.current &&\n !stylePanelRef.current.contains(e.target as Node)\n ) {\n setIsStylePanelOpen(false);\n }\n };\n\n // Delay adding listener to avoid immediate close\n const timeoutId = setTimeout(() => {\n document.addEventListener(\"mousedown\", handleClickOutside);\n }, 0);\n\n return () => {\n clearTimeout(timeoutId);\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [isStylePanelOpen]);\n\n const highlightClass = isScrolledTo ? \"ShapeHighlight--scrolledTo\" : \"\";\n\n // Generate key based on position for Rnd remount on position changes\n const key = `${highlight.position.boundingRect.width}${highlight.position.boundingRect.height}${highlight.position.boundingRect.left}${highlight.position.boundingRect.top}`;\n\n // Generate unique ID for SVG markers\n const markerId = `arrowhead-${highlight.id}`;\n\n // Render the shape SVG\n const renderShape = (width: number, height: number) => {\n switch (shapeType) {\n case \"rectangle\":\n return (\n <svg\n className=\"ShapeHighlight__svg\"\n width={width}\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n >\n <rect\n x={strokeWidth / 2}\n y={strokeWidth / 2}\n width={width - strokeWidth}\n height={height - strokeWidth}\n stroke={strokeColor}\n strokeWidth={strokeWidth}\n fill=\"none\"\n />\n </svg>\n );\n case \"circle\":\n return (\n <svg\n className=\"ShapeHighlight__svg\"\n width={width}\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n >\n <ellipse\n cx={width / 2}\n cy={height / 2}\n rx={width / 2 - strokeWidth / 2}\n ry={height / 2 - strokeWidth / 2}\n stroke={strokeColor}\n strokeWidth={strokeWidth}\n fill=\"none\"\n />\n </svg>\n );\n case \"arrow\": {\n // Use stored start/end points if available, otherwise default to left-to-right\n const x1 = startPoint ? startPoint.x * width : strokeWidth;\n const y1 = startPoint ? startPoint.y * height : height / 2;\n const x2 = endPoint ? endPoint.x * width : width - strokeWidth - 10;\n const y2 = endPoint ? endPoint.y * height : height / 2;\n\n return (\n <svg\n className=\"ShapeHighlight__svg\"\n width={width}\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n >\n <defs>\n <marker\n id={markerId}\n markerWidth=\"10\"\n markerHeight=\"7\"\n refX=\"9\"\n refY=\"3.5\"\n orient=\"auto\"\n >\n <polygon points=\"0 0, 10 3.5, 0 7\" fill={strokeColor} />\n </marker>\n </defs>\n <line\n x1={x1}\n y1={y1}\n x2={x2}\n y2={y2}\n stroke={strokeColor}\n strokeWidth={strokeWidth}\n markerEnd={`url(#${markerId})`}\n />\n </svg>\n );\n }\n default:\n return null;\n }\n };\n\n return (\n <div\n className={`ShapeHighlight ${highlightClass}`}\n onContextMenu={onContextMenu}\n >\n {/* Toolbar wrapper - extends down to overlap with shape */}\n {(onStyleChange || onDelete) && (\n <div\n className=\"ShapeHighlight__toolbar-wrapper\"\n style={{\n position: \"absolute\",\n left: highlight.position.boundingRect.left,\n top: highlight.position.boundingRect.top - 28,\n paddingBottom: 12,\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n <div\n className={`ShapeHighlight__toolbar ${isHovered || isStylePanelOpen ? \"ShapeHighlight__toolbar--visible\" : \"\"}`}\n >\n {onStyleChange && (\n <button\n className=\"ShapeHighlight__style-button\"\n onClick={(e) => {\n e.stopPropagation();\n setIsStylePanelOpen(!isStylePanelOpen);\n }}\n title=\"Change style\"\n type=\"button\"\n >\n {styleIcon || <DefaultStyleIcon />}\n </button>\n )}\n {onDelete && (\n <button\n className=\"ShapeHighlight__delete-button\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete();\n }}\n title=\"Delete\"\n type=\"button\"\n >\n {deleteIcon || <DefaultDeleteIcon />}\n </button>\n )}\n </div>\n\n {/* Style Panel - inside wrapper */}\n {isStylePanelOpen && onStyleChange && (\n <div\n className=\"ShapeHighlight__style-panel\"\n ref={stylePanelRef}\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"ShapeHighlight__style-row\">\n <label>Color</label>\n <div className=\"ShapeHighlight__color-options\">\n <div className=\"ShapeHighlight__color-presets\">\n {colorPresets.map((c) => (\n <button\n key={c}\n type=\"button\"\n className={`ShapeHighlight__color-preset ${strokeColor === c ? \"active\" : \"\"}`}\n style={{ backgroundColor: c }}\n onClick={() => onStyleChange({ strokeColor: c })}\n title={c}\n />\n ))}\n </div>\n <input\n type=\"color\"\n value={strokeColor}\n onChange={(e) => {\n onStyleChange({ strokeColor: e.target.value });\n }}\n />\n </div>\n </div>\n <div className=\"ShapeHighlight__style-row\">\n <label>Width</label>\n <div className=\"ShapeHighlight__width-options\">\n {STROKE_WIDTHS.map((w) => (\n <button\n key={w.value}\n type=\"button\"\n className={`ShapeHighlight__width-button ${strokeWidth === w.value ? \"active\" : \"\"}`}\n onClick={() => onStyleChange({ strokeWidth: w.value })}\n title={w.label}\n >\n {w.label}\n </button>\n ))}\n </div>\n </div>\n </div>\n )}\n </div>\n )}\n\n <Rnd\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n className=\"ShapeHighlight__rnd\"\n onDragStop={(_, data) => {\n const boundingRect: LTWHP = {\n ...highlight.position.boundingRect,\n top: data.y,\n left: data.x,\n };\n onChange?.(boundingRect);\n onEditEnd?.();\n }}\n onDragStart={onEditStart}\n onResizeStop={(_e, _direction, ref, _delta, position) => {\n const boundingRect: LTWHP = {\n top: position.y,\n left: position.x,\n width: ref.offsetWidth,\n height: ref.offsetHeight,\n pageNumber:\n getPageFromElement(ref)?.number ||\n highlight.position.boundingRect.pageNumber,\n };\n onChange?.(boundingRect);\n onEditEnd?.();\n }}\n onResizeStart={onEditStart}\n default={{\n x: highlight.position.boundingRect.left,\n y: highlight.position.boundingRect.top,\n width: highlight.position.boundingRect.width || 100,\n height: highlight.position.boundingRect.height || 100,\n }}\n minWidth={20}\n minHeight={20}\n key={key}\n bounds={bounds}\n lockAspectRatio={shapeType === \"circle\"}\n onClick={(event: Event) => {\n event.stopPropagation();\n event.preventDefault();\n }}\n style={style}\n >\n <div className=\"ShapeHighlight__container\">\n {renderShape(\n highlight.position.boundingRect.width || 100,\n highlight.position.boundingRect.height || 100\n )}\n </div>\n </Rnd>\n </div>\n );\n};\n","import React, { ReactNode, useEffect, useRef, useState } from \"react\";\n\nimport { GlobalWorkerOptions, OnProgressParameters, getDocument, type PDFDocumentLoadingTask, type PDFDocumentProxy } from \"pdfjs-dist\";\nimport { DocumentInitParameters, TypedArray } from \"pdfjs-dist/types/src/display/api\";\n\nconst DEFAULT_BEFORE_LOAD = (progress: OnProgressParameters) => (\n <div style={{ color: \"black\" }}>\n Loading {Math.floor((progress.loaded / progress.total) * 100)}%\n </div>\n);\n\nconst DEFAULT_ERROR_MESSAGE = (error: Error) => (\n <div style={{ color: \"black\" }}>{error.message}</div>\n);\n\nconst DEFAULT_ON_ERROR = (error: Error) => {\n throw new Error(`Error loading PDF document: ${error.message}!`);\n};\n\n// Default worker source - uses version 4.4.168\n// Users should provide their own workerSrc matching their pdfjs-dist version for best compatibility\nconst DEFAULT_WORKER_SRC =\n \"https://unpkg.com/pdfjs-dist@4.4.168/build/pdf.worker.min.mjs\";\n\n/**\n * The props type for {@link PdfLoader}.\n *\n * @category Component Properties\n */\nexport interface PdfLoaderProps {\n /**\n * The document to be loaded by PDF.js.\n * If you need to pass HTTP headers, auth parameters,\n * or other pdf settings, do it through here.\n */\n document: string | URL | TypedArray | DocumentInitParameters;\n\n /**\n * Callback to render content before the PDF document is loaded.\n *\n * @param progress - PDF.js progress status.\n * @returns - Component to be rendered in space of the PDF document while loading.\n */\n beforeLoad?(progress: OnProgressParameters): ReactNode;\n\n /**\n * Component to render in the case of any PDF loading errors.\n *\n * @param error - PDF loading error.\n * @returns - Component to be rendered in space of the PDF document.\n */\n errorMessage?(error: Error): ReactNode;\n\n /**\n * Child components to use/render the loaded PDF document.\n *\n * @param pdfDocument - The loaded PDF document.\n * @returns - Component to render once PDF document is loaded.\n */\n children(pdfDocument: PDFDocumentProxy): ReactNode;\n\n /**\n * Callback triggered whenever an error occurs.\n *\n * @param error - PDF Loading error triggering the event.\n * @returns - Component to be rendered in space of the PDF document.\n */\n onError?(error: Error): void;\n\n /**\n * NOTE: This will be applied to all PdfLoader instances.\n * If you want to only apply a source to this instance, use the document parameters.\n */\n workerSrc?: string;\n}\n\n/**\n * A component for loading a PDF document and passing it to a child.\n *\n * @category Component\n */\nexport const PdfLoader = ({\n document,\n beforeLoad = DEFAULT_BEFORE_LOAD,\n errorMessage = DEFAULT_ERROR_MESSAGE,\n children,\n onError = DEFAULT_ON_ERROR,\n workerSrc = DEFAULT_WORKER_SRC,\n}: PdfLoaderProps) => {\n const pdfLoadingTaskRef = useRef<PDFDocumentLoadingTask | null>(null);\n const pdfDocumentRef = useRef<PDFDocumentProxy | null>(null);\n\n const [error, setError] = useState<Error | null>(null);\n const [loadingProgress, setLoadingProgress] =\n useState<OnProgressParameters | null>(null);\n\n // Intitialise document\n useEffect(() => {\n GlobalWorkerOptions.workerSrc = workerSrc;\n pdfLoadingTaskRef.current = getDocument(document);\n pdfLoadingTaskRef.current.onProgress = (progress: OnProgressParameters) => {\n setLoadingProgress(progress.loaded > progress.total ? null : progress);\n };\n\n pdfLoadingTaskRef.current.promise\n .then((pdfDocument: PDFDocumentProxy) => {\n pdfDocumentRef.current = pdfDocument;\n })\n .catch((error: Error) => {\n if (error.message != \"Worker was destroyed\") {\n setError(error);\n onError(error);\n }\n })\n .finally(() => {\n setLoadingProgress(null);\n });\n\n return () => {\n if (pdfLoadingTaskRef.current) {\n pdfLoadingTaskRef.current.destroy();\n }\n\n if (pdfDocumentRef.current) {\n pdfDocumentRef.current.destroy();\n }\n };\n }, [document]);\n\n return error\n ? errorMessage(error)\n : loadingProgress\n ? beforeLoad(loadingProgress)\n : pdfDocumentRef.current && children(pdfDocumentRef.current);\n};\n","import { PDFDocument, rgb, StandardFonts, PDFPage, PDFFont } from \"pdf-lib\";\nimport type { Scaled, ScaledPosition, ShapeData } from \"../types\";\n\n/**\n * Options for the PDF export function.\n *\n * @category Type\n */\nexport interface ExportPdfOptions {\n /** Default color for text highlights. Default: \"rgba(255, 226, 143, 0.5)\" */\n textHighlightColor?: string;\n /** Default color for area highlights. Default: \"rgba(255, 226, 143, 0.5)\" */\n areaHighlightColor?: string;\n /** Default text color for freetext. Default: \"#333333\" */\n defaultFreetextColor?: string;\n /** Default background for freetext. Default: \"#ffffc8\" */\n defaultFreetextBgColor?: string;\n /** Default font size for freetext. Default: 14 */\n defaultFreetextFontSize?: number;\n /** Progress callback for large PDFs */\n onProgress?: (current: number, total: number) => void;\n}\n\n/**\n * A highlight that can be exported to PDF.\n *\n * @category Type\n */\nexport interface ExportableHighlight {\n id: string;\n type?: \"text\" | \"area\" | \"freetext\" | \"image\" | \"drawing\" | \"shape\";\n content?: {\n text?: string;\n image?: string; // Base64 data URL\n shape?: ShapeData; // Shape data for shape highlights\n };\n position: ScaledPosition;\n /** Per-highlight color override (for text/area highlights) */\n highlightColor?: string;\n /** Style mode for text highlights: \"highlight\" (default), \"underline\", or \"strikethrough\" */\n highlightStyle?: \"highlight\" | \"underline\" | \"strikethrough\";\n /** Text color for freetext highlights */\n color?: string;\n /** Background color for freetext highlights */\n backgroundColor?: string;\n /** Font size for freetext highlights */\n fontSize?: string;\n /** Font family for freetext highlights (not used in export, Helvetica is always used) */\n fontFamily?: string;\n /** Shape type for shape highlights */\n shapeType?: \"rectangle\" | \"circle\" | \"arrow\";\n /** Stroke color for shape highlights */\n strokeColor?: string;\n /** Stroke width for shape highlights */\n strokeWidth?: number;\n}\n\n/**\n * Parse a color string to RGB values (0-1 range).\n */\nfunction parseColor(color: string): {\n r: number;\n g: number;\n b: number;\n a: number;\n} {\n // Handle rgba(r, g, b, a) and rgb(r, g, b)\n const rgbaMatch = color.match(\n /rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*([\\d.]+))?\\)/\n );\n if (rgbaMatch) {\n return {\n r: parseInt(rgbaMatch[1]) / 255,\n g: parseInt(rgbaMatch[2]) / 255,\n b: parseInt(rgbaMatch[3]) / 255,\n a: rgbaMatch[4] ? parseFloat(rgbaMatch[4]) : 1,\n };\n }\n\n // Handle hex (#RRGGBB or #RGB)\n const hex = color.replace(\"#\", \"\");\n if (hex.length === 3) {\n return {\n r: parseInt(hex[0] + hex[0], 16) / 255,\n g: parseInt(hex[1] + hex[1], 16) / 255,\n b: parseInt(hex[2] + hex[2], 16) / 255,\n a: 1,\n };\n }\n if (hex.length === 6) {\n return {\n r: parseInt(hex.slice(0, 2), 16) / 255,\n g: parseInt(hex.slice(2, 4), 16) / 255,\n b: parseInt(hex.slice(4, 6), 16) / 255,\n a: 1,\n };\n }\n\n // Default yellow\n return { r: 1, g: 0.89, b: 0.56, a: 0.5 };\n}\n\n/**\n * Convert ScaledPosition coordinates to PDF points.\n * PDF coordinate system has origin at bottom-left.\n */\nfunction scaledToPdfPoints(\n scaled: Scaled,\n page: PDFPage\n): { x: number; y: number; width: number; height: number } {\n const pdfWidth = page.getWidth();\n const pdfHeight = page.getHeight();\n\n // Calculate position ratios\n const xRatio = pdfWidth / scaled.width;\n const yRatio = pdfHeight / scaled.height;\n\n const x = scaled.x1 * xRatio;\n const width = (scaled.x2 - scaled.x1) * xRatio;\n const height = (scaled.y2 - scaled.y1) * yRatio;\n\n // Flip Y (PDF origin is bottom-left, screen origin is top-left)\n const y = pdfHeight - scaled.y1 * yRatio - height;\n\n return { x, y, width, height };\n}\n\n/**\n * Convert base64 data URL to bytes.\n */\nfunction dataUrlToBytes(dataUrl: string): {\n bytes: Uint8Array;\n type: \"png\" | \"jpg\";\n} {\n const base64 = dataUrl.split(\",\")[1];\n const byteString = atob(base64);\n const bytes = new Uint8Array(byteString.length);\n for (let i = 0; i < byteString.length; i++) {\n bytes[i] = byteString.charCodeAt(i);\n }\n const type = dataUrl.includes(\"image/png\") ? \"png\" : \"jpg\";\n return { bytes, type };\n}\n\n/**\n * Wrap text into multiple lines that fit within maxWidth.\n * Long words are broken character by character (like CSS word-wrap: break-word).\n */\nfunction wrapText(\n text: string,\n font: PDFFont,\n fontSize: number,\n maxWidth: number\n): string[] {\n if (!text || maxWidth <= 0) return [];\n\n const lines: string[] = [];\n\n // Split by newlines first to preserve intentional line breaks\n const paragraphs = text.split(/\\n/);\n\n for (const paragraph of paragraphs) {\n if (!paragraph.trim()) {\n lines.push(\"\");\n continue;\n }\n\n const words = paragraph.split(/\\s+/);\n let currentLine = \"\";\n\n for (const word of words) {\n const testLine = currentLine ? `${currentLine} ${word}` : word;\n const testWidth = font.widthOfTextAtSize(testLine, fontSize);\n\n if (testWidth <= maxWidth) {\n currentLine = testLine;\n } else {\n // Push current line if exists\n if (currentLine) {\n lines.push(currentLine);\n currentLine = \"\";\n }\n\n // Check if word itself is too wide - break it character by character\n if (font.widthOfTextAtSize(word, fontSize) > maxWidth) {\n let remaining = word;\n while (remaining.length > 0) {\n let charCount = 1;\n // Find how many characters fit in maxWidth\n while (\n charCount < remaining.length &&\n font.widthOfTextAtSize(remaining.substring(0, charCount + 1), fontSize) <= maxWidth\n ) {\n charCount++;\n }\n const chunk = remaining.substring(0, charCount);\n remaining = remaining.substring(charCount);\n\n if (remaining.length > 0) {\n // More characters remaining, push this chunk as a complete line\n lines.push(chunk);\n } else {\n // Last chunk, keep it as current line (may combine with next word)\n currentLine = chunk;\n }\n }\n } else {\n currentLine = word;\n }\n }\n }\n if (currentLine) lines.push(currentLine);\n }\n\n return lines;\n}\n\n/**\n * Group highlights by page number.\n */\nfunction groupByPage(\n highlights: ExportableHighlight[]\n): Map<number, ExportableHighlight[]> {\n const map = new Map<number, ExportableHighlight[]>();\n for (const h of highlights) {\n const pageNum = h.position.boundingRect.pageNumber;\n if (!map.has(pageNum)) map.set(pageNum, []);\n map.get(pageNum)!.push(h);\n }\n return map;\n}\n\n/**\n * Render a text highlight (multiple rectangles for multi-line selections).\n * Supports highlight (background), underline, and strikethrough styles.\n */\nasync function renderTextHighlight(\n page: PDFPage,\n highlight: ExportableHighlight,\n options: ExportPdfOptions\n): Promise<void> {\n // Per-highlight color override or fallback to default\n const colorStr =\n highlight.highlightColor ||\n options.textHighlightColor ||\n \"rgba(255, 226, 143, 0.5)\";\n const color = parseColor(colorStr);\n const highlightStyle = highlight.highlightStyle || \"highlight\";\n\n // Text highlights use rects array for multi-line selections\n const rects =\n highlight.position.rects.length > 0\n ? highlight.position.rects\n : [highlight.position.boundingRect];\n\n for (const rect of rects) {\n const { x, y, width, height } = scaledToPdfPoints(rect, page);\n\n if (highlightStyle === \"highlight\") {\n // Draw filled rectangle for background highlight\n page.drawRectangle({\n x,\n y,\n width,\n height,\n color: rgb(color.r, color.g, color.b),\n opacity: color.a,\n });\n } else if (highlightStyle === \"underline\") {\n // Draw line at bottom of rectangle\n const lineThickness = Math.max(1, height * 0.1);\n page.drawRectangle({\n x,\n y,\n width,\n height: lineThickness,\n color: rgb(color.r, color.g, color.b),\n opacity: color.a,\n });\n } else if (highlightStyle === \"strikethrough\") {\n // Draw line through middle of rectangle\n const lineThickness = Math.max(1, height * 0.1);\n const lineY = y + height / 2 - lineThickness / 2;\n page.drawRectangle({\n x,\n y: lineY,\n width,\n height: lineThickness,\n color: rgb(color.r, color.g, color.b),\n opacity: color.a,\n });\n }\n }\n}\n\n/**\n * Render an area highlight (single rectangle).\n */\nasync function renderAreaHighlight(\n page: PDFPage,\n highlight: ExportableHighlight,\n options: ExportPdfOptions\n): Promise<void> {\n // Per-highlight color override or fallback to default\n const colorStr =\n highlight.highlightColor ||\n options.areaHighlightColor ||\n \"rgba(255, 226, 143, 0.5)\";\n const color = parseColor(colorStr);\n const { x, y, width, height } = scaledToPdfPoints(\n highlight.position.boundingRect,\n page\n );\n\n page.drawRectangle({\n x,\n y,\n width,\n height,\n color: rgb(color.r, color.g, color.b),\n opacity: color.a,\n });\n}\n\n/**\n * Render a freetext highlight (background rectangle + text).\n * Text is wrapped to fit within the box.\n */\nasync function renderFreetextHighlight(\n page: PDFPage,\n highlight: ExportableHighlight,\n options: ExportPdfOptions,\n font: PDFFont\n): Promise<void> {\n const text = highlight.content?.text || \"\";\n const textColor = parseColor(\n highlight.color || options.defaultFreetextColor || \"#333333\"\n );\n\n // Get box dimensions in PDF points\n const { x, y, width, height } = scaledToPdfPoints(\n highlight.position.boundingRect,\n page\n );\n\n // Scale font size by the same ratio used for the box coordinates\n // This ensures the font scales proportionally with the box\n const pdfHeight = page.getHeight();\n const yRatio = pdfHeight / highlight.position.boundingRect.height;\n const storedFontSize =\n parseInt(highlight.fontSize || \"\") || options.defaultFreetextFontSize || 14;\n const fontSize = storedFontSize * yRatio;\n\n console.log(\"Freetext export:\", {\n storedFontSize,\n yRatio,\n fontSize,\n boxDimensions: { x, y, width, height },\n text: text.substring(0, 50),\n });\n\n // Draw background (skip if transparent)\n const bgColorValue = highlight.backgroundColor || options.defaultFreetextBgColor || \"#ffffc8\";\n if (bgColorValue !== \"transparent\") {\n const bgColor = parseColor(bgColorValue);\n page.drawRectangle({\n x,\n y,\n width,\n height,\n color: rgb(bgColor.r, bgColor.g, bgColor.b),\n opacity: bgColor.a,\n });\n }\n\n // Draw wrapped text with scaled padding\n const padding = 4 * yRatio;\n const maxWidth = width - padding * 2;\n const lineHeight = fontSize * 1.3;\n\n if (maxWidth > 0 && text) {\n const lines = wrapText(text, font, fontSize, maxWidth);\n let currentY = y + height - fontSize - padding;\n\n for (const line of lines) {\n // Stop if we've run out of vertical space\n if (currentY < y + padding) break;\n\n // Skip empty lines but still move down\n if (line.trim()) {\n page.drawText(line, {\n x: x + padding,\n y: currentY,\n size: fontSize,\n font,\n color: rgb(textColor.r, textColor.g, textColor.b),\n });\n }\n\n currentY -= lineHeight;\n }\n }\n}\n\n/**\n * Transform visual coordinates to raw MediaBox coordinates.\n * pdf-lib's drawImage uses raw MediaBox space, but our coordinates are in visual space.\n */\nfunction transformToRawCoordinates(\n page: PDFPage,\n x: number,\n y: number,\n width: number,\n height: number\n): { x: number; y: number; width: number; height: number } {\n const rotation = page.getRotation().angle;\n const pageWidth = page.getWidth(); // Visual width\n const pageHeight = page.getHeight(); // Visual height\n\n if (rotation === 90) {\n // Visual (x, y) → Raw MediaBox coordinates\n // When rotated 90° CCW, visual top-left maps to raw bottom-left\n return {\n x: y,\n y: pageWidth - x - width,\n width: height,\n height: width,\n };\n } else if (rotation === 180) {\n // Rotated 180°, origin flips to opposite corner\n return {\n x: pageWidth - x - width,\n y: pageHeight - y - height,\n width,\n height,\n };\n } else if (rotation === 270) {\n // When rotated 90° CW (270° CCW)\n return {\n x: pageHeight - y - height,\n y: x,\n width: height,\n height: width,\n };\n }\n\n // No rotation - coordinates are already correct\n return { x, y, width, height };\n}\n\n/**\n * Render an image highlight (embedded image).\n * Handles page rotation by transforming visual coordinates to raw MediaBox space.\n * Image fills the entire bounding box to match the visual wrapper in preview.\n */\nasync function renderImageHighlight(\n pdfDoc: PDFDocument,\n page: PDFPage,\n highlight: ExportableHighlight\n): Promise<void> {\n const imageDataUrl = highlight.content?.image;\n if (!imageDataUrl) return;\n\n try {\n const { bytes, type } = dataUrlToBytes(imageDataUrl);\n const image =\n type === \"png\"\n ? await pdfDoc.embedPng(bytes)\n : await pdfDoc.embedJpg(bytes);\n\n // Calculate coordinates in visual space - use full bounding box dimensions\n const visualCoords = scaledToPdfPoints(\n highlight.position.boundingRect,\n page\n );\n\n // Transform to raw MediaBox coordinates based on page rotation\n const rawCoords = transformToRawCoordinates(\n page,\n visualCoords.x,\n visualCoords.y,\n visualCoords.width,\n visualCoords.height\n );\n\n console.log(\"Image export:\", {\n rotation: page.getRotation().angle,\n visualCoords,\n rawCoords,\n });\n\n // Draw image filling the entire bounding box\n page.drawImage(image, {\n x: rawCoords.x,\n y: rawCoords.y,\n width: rawCoords.width,\n height: rawCoords.height,\n });\n } catch (error) {\n console.error(\"Failed to embed image:\", error);\n }\n}\n\n/**\n * Render a shape highlight (rectangle, circle, or arrow).\n */\nasync function renderShapeHighlight(\n page: PDFPage,\n highlight: ExportableHighlight\n): Promise<void> {\n // Get shape data from content or top-level properties\n const shapeType = highlight.content?.shape?.shapeType || highlight.shapeType || \"rectangle\";\n const strokeColorStr = highlight.content?.shape?.strokeColor || highlight.strokeColor || \"#000000\";\n const strokeWidth = highlight.content?.shape?.strokeWidth || highlight.strokeWidth || 2;\n\n const color = parseColor(strokeColorStr);\n const { x, y, width, height } = scaledToPdfPoints(\n highlight.position.boundingRect,\n page\n );\n\n switch (shapeType) {\n case \"rectangle\":\n page.drawRectangle({\n x,\n y,\n width,\n height,\n borderColor: rgb(color.r, color.g, color.b),\n borderWidth: strokeWidth,\n opacity: color.a,\n });\n break;\n\n case \"circle\":\n page.drawEllipse({\n x: x + width / 2,\n y: y + height / 2,\n xScale: width / 2,\n yScale: height / 2,\n borderColor: rgb(color.r, color.g, color.b),\n borderWidth: strokeWidth,\n opacity: color.a,\n });\n break;\n\n case \"arrow\": {\n // Use stored start/end points if available, otherwise default to left-to-right\n const startPt = highlight.content?.shape?.startPoint;\n const endPt = highlight.content?.shape?.endPoint;\n\n // Calculate actual coordinates\n // Note: PDF coordinates have Y going up, so we need to flip the Y\n const startX = startPt ? x + startPt.x * width : x;\n const startY = startPt ? y + (1 - startPt.y) * height : y + height / 2;\n const endX = endPt ? x + endPt.x * width : x + width;\n const endY = endPt ? y + (1 - endPt.y) * height : y + height / 2;\n\n // Draw the main line\n page.drawLine({\n start: { x: startX, y: startY },\n end: { x: endX, y: endY },\n color: rgb(color.r, color.g, color.b),\n thickness: strokeWidth,\n opacity: color.a,\n });\n\n // Calculate arrowhead direction\n const angle = Math.atan2(endY - startY, endX - startX);\n const arrowSize = Math.min(15, width * 0.2, height * 0.4);\n const arrowAngle = Math.PI / 6; // 30 degrees\n\n // Draw arrowhead (two lines forming a V at the end)\n page.drawLine({\n start: {\n x: endX - arrowSize * Math.cos(angle - arrowAngle),\n y: endY - arrowSize * Math.sin(angle - arrowAngle),\n },\n end: { x: endX, y: endY },\n color: rgb(color.r, color.g, color.b),\n thickness: strokeWidth,\n opacity: color.a,\n });\n page.drawLine({\n start: {\n x: endX - arrowSize * Math.cos(angle + arrowAngle),\n y: endY - arrowSize * Math.sin(angle + arrowAngle),\n },\n end: { x: endX, y: endY },\n color: rgb(color.r, color.g, color.b),\n thickness: strokeWidth,\n opacity: color.a,\n });\n break;\n }\n }\n}\n\n/**\n * Export a PDF with annotations embedded.\n *\n * @param pdfSource - The source PDF as a URL string, Uint8Array, or ArrayBuffer\n * @param highlights - Array of highlights to embed in the PDF\n * @param options - Export options for customizing colors and behavior\n * @returns Promise<Uint8Array> - The modified PDF as bytes\n *\n * @example\n * ```typescript\n * const pdfBytes = await exportPdf(pdfUrl, highlights, {\n * textHighlightColor: \"rgba(255, 255, 0, 0.4)\",\n * onProgress: (current, total) => console.log(`${current}/${total} pages`)\n * });\n *\n * // Download the file\n * const blob = new Blob([pdfBytes], { type: \"application/pdf\" });\n * const url = URL.createObjectURL(blob);\n * const a = document.createElement(\"a\");\n * a.href = url;\n * a.download = \"annotated.pdf\";\n * a.click();\n * URL.revokeObjectURL(url);\n * ```\n *\n * @category Function\n */\nexport async function exportPdf(\n pdfSource: string | Uint8Array | ArrayBuffer,\n highlights: ExportableHighlight[],\n options: ExportPdfOptions = {}\n): Promise<Uint8Array> {\n // Load PDF\n let pdfBytes: ArrayBuffer;\n if (typeof pdfSource === \"string\") {\n const response = await fetch(pdfSource);\n pdfBytes = await response.arrayBuffer();\n } else {\n pdfBytes =\n pdfSource instanceof Uint8Array\n ? pdfSource.buffer.slice(\n pdfSource.byteOffset,\n pdfSource.byteOffset + pdfSource.byteLength\n )\n : pdfSource;\n }\n\n const pdfDoc = await PDFDocument.load(pdfBytes);\n const pages = pdfDoc.getPages();\n const font = await pdfDoc.embedFont(StandardFonts.Helvetica);\n\n // Group by page and render\n const byPage = groupByPage(highlights);\n const totalPages = byPage.size;\n let currentPage = 0;\n\n for (const [pageNum, pageHighlights] of byPage) {\n const page = pages[pageNum - 1]; // 1-indexed to 0-indexed\n if (!page) continue;\n\n for (const highlight of pageHighlights) {\n switch (highlight.type) {\n case \"text\":\n await renderTextHighlight(page, highlight, options);\n break;\n case \"area\":\n await renderAreaHighlight(page, highlight, options);\n break;\n case \"freetext\":\n await renderFreetextHighlight(page, highlight, options, font);\n break;\n case \"image\":\n await renderImageHighlight(pdfDoc, page, highlight);\n break;\n case \"drawing\":\n // Drawings are stored as PNG images, reuse image highlight rendering\n await renderImageHighlight(pdfDoc, page, highlight);\n break;\n case \"shape\":\n await renderShapeHighlight(page, highlight);\n break;\n default:\n // Default to area highlight for backwards compatibility\n await renderAreaHighlight(page, highlight, options);\n }\n }\n\n currentPage++;\n options.onProgress?.(currentPage, totalPages);\n }\n\n return pdfDoc.save();\n}\n"],"mappings":"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","names":["React","useLayoutEffect","useRef","useState","pageNumber","X0","X1","Y0","Y1","document","React","createContext","useContext","React","React","useEffect","useRef","useState","getBoundingRect","useState","useRef","useEffect","event","React","React","useRef","useEffect","useCallback","useState","useRef","useState","useCallback","useEffect","React","React","useRef","useState","useState","useRef","React","useState","useRef","useLayoutEffect","React","React","useState","useRef","useEffect","React","useRef","React","useEffect","useRef","useRef","React","React","useState","useRef","useEffect","DefaultStyleIcon","React","DefaultDeleteIcon","DEFAULT_COLOR_PRESETS","useState","useRef","useEffect","React","useState","useRef","useEffect","Rnd","React","DefaultStyleIcon","DefaultDeleteIcon","useState","useRef","useEffect","Rnd","React","Rnd","DefaultDragIcon","React","DefaultDeleteIcon","Rnd","React","useRef","useEffect","useCallback","React","useState","useCallback","useEffect","useRef","Rnd","DefaultDragIcon","React","DefaultDeleteIcon","useState","useRef","useEffect","useCallback","Rnd","React","useState","useRef","useEffect","Rnd","DefaultStyleIcon","React","DefaultDeleteIcon","DEFAULT_COLOR_PRESETS","STROKE_WIDTHS","useState","useRef","useEffect","Rnd","React","useEffect","useRef","useState","getDocument","document","error"]}
|