@embedpdf/plugin-annotation 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/preact/index.cjs +1 -1
- package/dist/preact/index.cjs.map +1 -1
- package/dist/preact/index.js +5 -3
- package/dist/preact/index.js.map +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +5 -3
- package/dist/react/index.js.map +1 -1
- package/dist/svelte/index.cjs +1 -1
- package/dist/svelte/index.cjs.map +1 -1
- package/dist/svelte/index.js +6 -3
- package/dist/svelte/index.js.map +1 -1
- package/dist/vue/index.cjs +1 -1
- package/dist/vue/index.cjs.map +1 -1
- package/dist/vue/index.js +5 -3
- package/dist/vue/index.js.map +1 -1
- package/package.json +10 -10
package/dist/react/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/react/adapter.ts","../../src/shared/context/renderer-registry.tsx","../../src/shared/hooks/use-annotation.ts","../../src/shared/components/annotation-container.tsx","../../src/shared/components/group-selection-box.tsx","../../src/shared/components/text-markup/highlight.tsx","../../src/shared/components/text-markup/underline.tsx","../../src/shared/components/text-markup/strikeout.tsx","../../src/shared/components/text-markup/squiggly.tsx","../../src/shared/components/annotations/ink.tsx","../../src/shared/components/annotations/square.tsx","../../src/shared/components/annotations/circle.tsx","../../src/shared/components/annotations/line.tsx","../../src/shared/components/annotations/polyline.tsx","../../src/shared/components/annotations/polygon.tsx","../../src/shared/components/annotations/free-text.tsx","../../src/shared/components/render-annotation.tsx","../../src/shared/components/annotations/stamp.tsx","../../src/shared/components/annotations/link.tsx","../../src/shared/components/annotations.tsx","../../src/shared/components/text-markup.tsx","../../src/shared/components/preview-renderer.tsx","../../src/shared/components/annotation-paint-layer.tsx","../../src/shared/index.ts","../../src/shared/components/annotation-layer.tsx","../../src/shared/components/types.ts"],"sourcesContent":["export {\n Fragment,\n useEffect,\n useRef,\n useState,\n useCallback,\n useMemo,\n useLayoutEffect,\n createContext,\n useContext,\n JSX,\n ChangeEvent,\n} from 'react';\nexport type {\n ReactNode,\n HTMLAttributes,\n CSSProperties,\n MouseEvent,\n PointerEvent,\n TouchEvent,\n} from 'react';\n\nexport const suppressContentEditableWarningProps = {\n suppressContentEditableWarning: true,\n};\n","import {\n createContext,\n useContext,\n useState,\n useCallback,\n useRef,\n useEffect,\n ReactNode,\n} from '@framework';\nimport { BoxedAnnotationRenderer } from '../components/types';\n\n// Separate contexts: register function is stable, renderers list changes\ntype RegisterFn = (entries: BoxedAnnotationRenderer[]) => () => void;\n\nconst RegisterContext = createContext<RegisterFn | null>(null);\nconst RenderersContext = createContext<BoxedAnnotationRenderer[]>([]);\n\nexport function AnnotationRendererProvider({ children }: { children: ReactNode }) {\n const [renderers, setRenderers] = useState<BoxedAnnotationRenderer[]>([]);\n\n // Stable reference - no dependencies\n const register = useCallback((entries: BoxedAnnotationRenderer[]) => {\n setRenderers((prev) => {\n const ids = new Set(entries.map((e) => e.id));\n return [...prev.filter((r) => !ids.has(r.id)), ...entries];\n });\n return () => setRenderers((prev) => prev.filter((r) => !entries.some((e) => e.id === r.id)));\n }, []);\n\n return (\n <RegisterContext.Provider value={register}>\n <RenderersContext.Provider value={renderers}>{children}</RenderersContext.Provider>\n </RegisterContext.Provider>\n );\n}\n\n/**\n * Hook to register annotation renderers. Handles all registration lifecycle internally.\n * Plugin authors just call this with their renderers array.\n */\nexport function useRegisterRenderers(renderers: BoxedAnnotationRenderer[]) {\n const register = useContext(RegisterContext);\n const renderersRef = useRef(renderers);\n\n useEffect(() => {\n if (!register) return;\n return register(renderersRef.current);\n }, [register]);\n}\n\n/**\n * Hook to get all registered renderers (for rendering components).\n */\nexport function useRegisteredRenderers(): BoxedAnnotationRenderer[] {\n return useContext(RenderersContext);\n}\n\n/**\n * Low-level hook if someone needs direct access to register function.\n * Most plugins should use useRegisterRenderers instead.\n */\nexport function useRendererRegistry() {\n return useContext(RegisterContext);\n}\n","import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {\n AnnotationPlugin,\n AnnotationDocumentState,\n initialDocumentState,\n} from '@embedpdf/plugin-annotation';\nimport { useState, useEffect } from '@framework';\n\nexport const useAnnotationPlugin = () => usePlugin<AnnotationPlugin>(AnnotationPlugin.id);\nexport const useAnnotationCapability = () => useCapability<AnnotationPlugin>(AnnotationPlugin.id);\n\n/**\n * Hook for annotation state for a specific document\n * @param documentId Document ID\n */\nexport const useAnnotation = (documentId: string) => {\n const { provides } = useAnnotationCapability();\n const [state, setState] = useState<AnnotationDocumentState>(\n provides?.forDocument(documentId)?.getState() ?? initialDocumentState(),\n );\n\n useEffect(() => {\n if (!provides) return;\n\n const scope = provides.forDocument(documentId);\n\n // Get initial state\n setState(scope.getState());\n\n // Subscribe to state changes\n return scope.onStateChange((newState) => {\n setState(newState);\n });\n }, [provides, documentId]);\n\n return {\n state,\n provides: provides?.forDocument(documentId) ?? null,\n };\n};\n","import { PdfAnnotationObject, Rect } from '@embedpdf/models';\nimport {\n CounterRotate,\n useDoublePressProps,\n useInteractionHandles,\n} from '@embedpdf/utils/@framework';\nimport { TrackedAnnotation } from '@embedpdf/plugin-annotation';\nimport { useState, JSX, CSSProperties, useRef, useEffect, useMemo, useCallback } from '@framework';\nimport { useDocumentPermissions } from '@embedpdf/core/@framework';\n\nimport { useAnnotationCapability, useAnnotationPlugin } from '../hooks';\nimport {\n CustomAnnotationRenderer,\n ResizeHandleUI,\n AnnotationSelectionMenuRenderFn,\n VertexHandleUI,\n GroupSelectionMenuRenderFn,\n BoxedAnnotationRenderer,\n} from './types';\nimport { VertexConfig } from '../types';\n\ninterface AnnotationContainerProps<T extends PdfAnnotationObject> {\n scale: number;\n documentId: string;\n pageIndex: number;\n rotation: number;\n pageWidth: number;\n pageHeight: number;\n trackedAnnotation: TrackedAnnotation<T>;\n children: JSX.Element | ((annotation: T) => JSX.Element);\n isSelected: boolean;\n /** Whether multiple annotations are selected (container becomes passive) */\n isMultiSelected?: boolean;\n isDraggable: boolean;\n isResizable: boolean;\n lockAspectRatio?: boolean;\n style?: CSSProperties;\n vertexConfig?: VertexConfig<T>;\n selectionMenu?: AnnotationSelectionMenuRenderFn;\n outlineOffset?: number;\n onDoubleClick?: (event: any) => void;\n onSelect: (event: any) => void;\n zIndex?: number;\n resizeUI?: ResizeHandleUI;\n vertexUI?: VertexHandleUI;\n selectionOutlineColor?: string;\n customAnnotationRenderer?: CustomAnnotationRenderer<T>;\n /** Passed from parent but not used - destructured to prevent DOM spread */\n groupSelectionMenu?: GroupSelectionMenuRenderFn;\n /** Passed from parent but not used - destructured to prevent DOM spread */\n annotationRenderers?: BoxedAnnotationRenderer[];\n}\n\n/**\n * AnnotationContainer wraps individual annotations with interaction handles.\n * When isMultiSelected is true, the container becomes passive - drag/resize\n * is handled by the GroupSelectionBox instead.\n */\nexport function AnnotationContainer<T extends PdfAnnotationObject>({\n scale,\n documentId,\n pageIndex,\n rotation,\n pageWidth,\n pageHeight,\n trackedAnnotation,\n children,\n isSelected,\n isMultiSelected = false,\n isDraggable,\n isResizable,\n lockAspectRatio = false,\n style = {},\n vertexConfig,\n selectionMenu,\n outlineOffset = 1,\n onDoubleClick,\n onSelect,\n zIndex = 1,\n resizeUI,\n vertexUI,\n selectionOutlineColor = '#007ACC',\n customAnnotationRenderer,\n // Destructure props that shouldn't be passed to DOM elements\n groupSelectionMenu: _groupSelectionMenu,\n annotationRenderers: _annotationRenderers,\n ...props\n}: AnnotationContainerProps<T>): JSX.Element {\n const [preview, setPreview] = useState<T>(trackedAnnotation.object);\n const { provides: annotationCapability } = useAnnotationCapability();\n const { plugin } = useAnnotationPlugin();\n const { canModifyAnnotations } = useDocumentPermissions(documentId);\n const gestureBaseRef = useRef<T | null>(null);\n\n // When multi-selected, disable individual drag/resize - GroupSelectionBox handles it\n const effectiveIsDraggable = canModifyAnnotations && isDraggable && !isMultiSelected;\n const effectiveIsResizable = canModifyAnnotations && isResizable && !isMultiSelected;\n // Get scoped API for this document\n const annotationProvides = useMemo(\n () => (annotationCapability ? annotationCapability.forDocument(documentId) : null),\n [annotationCapability, documentId],\n );\n\n const currentObject = preview\n ? { ...trackedAnnotation.object, ...preview }\n : trackedAnnotation.object;\n\n // UI constants\n const HANDLE_COLOR = resizeUI?.color ?? '#007ACC';\n const VERTEX_COLOR = vertexUI?.color ?? '#007ACC';\n const HANDLE_SIZE = resizeUI?.size ?? 12;\n const VERTEX_SIZE = vertexUI?.size ?? 12;\n\n // Store original rect at gesture start (only need rect for delta calculation)\n const gestureBaseRectRef = useRef<Rect | null>(null);\n\n // Handle single-annotation drag/resize (only when NOT multi-selected)\n // Uses the unified plugin API - all preview updates come from event subscriptions!\n const handleUpdate = useCallback(\n (\n event: Parameters<\n NonNullable<Parameters<typeof useInteractionHandles>[0]['controller']['onUpdate']>\n >[0],\n ) => {\n if (!event.transformData?.type || isMultiSelected || !plugin) return;\n\n const { type, changes, metadata } = event.transformData;\n const id = trackedAnnotation.object.id;\n const pageSize = { width: pageWidth, height: pageHeight };\n\n // Gesture start - initialize plugin drag/resize\n if (event.state === 'start') {\n gestureBaseRectRef.current = trackedAnnotation.object.rect;\n gestureBaseRef.current = trackedAnnotation.object; // For vertex edit\n if (type === 'move') {\n plugin.startDrag(documentId, { annotationIds: [id], pageSize });\n } else if (type === 'resize') {\n plugin.startResize(documentId, {\n annotationIds: [id],\n pageSize,\n resizeHandle: metadata?.handle ?? 'se',\n });\n }\n }\n\n // Gesture update - call plugin, preview comes from subscription\n if (changes.rect && gestureBaseRectRef.current) {\n if (type === 'move') {\n const delta = {\n x: changes.rect.origin.x - gestureBaseRectRef.current.origin.x,\n y: changes.rect.origin.y - gestureBaseRectRef.current.origin.y,\n };\n plugin.updateDrag(documentId, delta);\n } else if (type === 'resize') {\n plugin.updateResize(documentId, changes.rect);\n }\n }\n\n // Vertex edit - handle directly (no attached link handling needed)\n if (type === 'vertex-edit' && changes.vertices && vertexConfig) {\n const base = gestureBaseRef.current ?? trackedAnnotation.object;\n const vertexChanges = vertexConfig.transformAnnotation(base, changes.vertices);\n const patched = annotationCapability?.transformAnnotation<T>(base, {\n type,\n changes: vertexChanges as Partial<T>,\n metadata,\n });\n if (patched) {\n setPreview((prev) => ({ ...prev, ...patched }));\n if (event.state === 'end') {\n annotationProvides?.updateAnnotation(pageIndex, id, patched);\n }\n }\n }\n\n // Gesture end - commit\n if (event.state === 'end') {\n gestureBaseRectRef.current = null;\n gestureBaseRef.current = null;\n if (type === 'move') plugin.commitDrag(documentId);\n else if (type === 'resize') plugin.commitResize(documentId);\n }\n },\n [\n plugin,\n documentId,\n trackedAnnotation.object,\n pageWidth,\n pageHeight,\n pageIndex,\n isMultiSelected,\n vertexConfig,\n annotationCapability,\n annotationProvides,\n ],\n );\n\n const { dragProps, vertices, resize } = useInteractionHandles({\n controller: {\n element: currentObject.rect,\n vertices: vertexConfig?.extractVertices(currentObject),\n constraints: {\n minWidth: 10,\n minHeight: 10,\n boundingBox: { width: pageWidth, height: pageHeight },\n },\n maintainAspectRatio: lockAspectRatio,\n pageRotation: rotation,\n scale: scale,\n // Disable interaction handles when multi-selected\n enabled: isSelected && !isMultiSelected,\n onUpdate: handleUpdate,\n },\n resizeUI: {\n handleSize: HANDLE_SIZE,\n spacing: outlineOffset,\n offsetMode: 'outside',\n includeSides: lockAspectRatio ? false : true,\n zIndex: zIndex + 1,\n },\n vertexUI: {\n vertexSize: VERTEX_SIZE,\n zIndex: zIndex + 2,\n },\n includeVertices: vertexConfig ? true : false,\n });\n\n // Wrap onDoubleClick to respect permissions\n const guardedOnDoubleClick = useMemo(() => {\n if (!canModifyAnnotations || !onDoubleClick) return undefined;\n return onDoubleClick;\n }, [canModifyAnnotations, onDoubleClick]);\n\n const doubleProps = useDoublePressProps(guardedOnDoubleClick);\n\n // Sync preview with tracked annotation when it changes\n useEffect(() => {\n setPreview(trackedAnnotation.object);\n }, [trackedAnnotation.object]);\n\n // Subscribe to unified drag changes - plugin sends pre-computed patches!\n // ALL preview updates come through here (primary, attached links, multi-select)\n useEffect(() => {\n if (!plugin) return;\n const id = trackedAnnotation.object.id;\n\n const handleEvent = (event: {\n documentId: string;\n type: string;\n previewPatches?: Record<string, any>;\n }) => {\n if (event.documentId !== documentId) return;\n const patch = event.previewPatches?.[id];\n if (event.type === 'update' && patch) setPreview((prev) => ({ ...prev, ...patch }) as T);\n else if (event.type === 'cancel') setPreview(trackedAnnotation.object);\n };\n\n const unsubs = [plugin.onDragChange(handleEvent), plugin.onResizeChange(handleEvent)];\n\n return () => unsubs.forEach((u) => u());\n }, [plugin, documentId, trackedAnnotation.object]);\n\n // Determine if we should show the outline\n // When multi-selected, don't show individual outlines - GroupSelectionBox shows the group outline\n const showOutline = isSelected && !isMultiSelected;\n\n return (\n <div data-no-interaction>\n <div\n {...(effectiveIsDraggable && isSelected ? dragProps : {})}\n {...doubleProps}\n style={{\n position: 'absolute',\n left: currentObject.rect.origin.x * scale,\n top: currentObject.rect.origin.y * scale,\n width: currentObject.rect.size.width * scale,\n height: currentObject.rect.size.height * scale,\n outline: showOutline ? `1px solid ${selectionOutlineColor}` : 'none',\n outlineOffset: showOutline ? `${outlineOffset}px` : '0px',\n pointerEvents: isSelected && !isMultiSelected ? 'auto' : 'none',\n touchAction: 'none',\n cursor: isSelected && effectiveIsDraggable ? 'move' : 'default',\n zIndex,\n ...style,\n }}\n {...props}\n >\n {(() => {\n const childrenRender =\n typeof children === 'function' ? children(currentObject) : children;\n const customRender = customAnnotationRenderer?.({\n annotation: currentObject,\n children: childrenRender,\n isSelected,\n scale,\n rotation,\n pageWidth,\n pageHeight,\n pageIndex,\n onSelect,\n });\n if (customRender !== null && customRender !== undefined) {\n return customRender;\n }\n return childrenRender;\n })()}\n\n {/* Resize handles - only when single-selected */}\n {isSelected &&\n effectiveIsResizable &&\n resize.map(({ key, ...hProps }) =>\n resizeUI?.component ? (\n resizeUI.component({\n key,\n ...hProps,\n backgroundColor: HANDLE_COLOR,\n })\n ) : (\n <div\n key={key}\n {...hProps}\n style={{ ...hProps.style, backgroundColor: HANDLE_COLOR }}\n />\n ),\n )}\n\n {/* Vertex handles - only when single-selected */}\n {isSelected &&\n canModifyAnnotations &&\n !isMultiSelected &&\n vertices.map(({ key, ...vProps }) =>\n vertexUI?.component ? (\n vertexUI.component({\n key,\n ...vProps,\n backgroundColor: VERTEX_COLOR,\n })\n ) : (\n <div\n key={key}\n {...vProps}\n style={{ ...vProps.style, backgroundColor: VERTEX_COLOR }}\n />\n ),\n )}\n </div>\n\n {/* Selection menu - hide when multi-selected */}\n {selectionMenu && !isMultiSelected && (\n <CounterRotate\n rect={{\n origin: {\n x: currentObject.rect.origin.x * scale,\n y: currentObject.rect.origin.y * scale,\n },\n size: {\n width: currentObject.rect.size.width * scale,\n height: currentObject.rect.size.height * scale,\n },\n }}\n rotation={rotation}\n >\n {(counterRotateProps) =>\n selectionMenu({\n ...counterRotateProps,\n context: {\n type: 'annotation',\n annotation: trackedAnnotation,\n pageIndex,\n },\n selected: isSelected,\n placement: {\n suggestTop: false,\n },\n })\n }\n </CounterRotate>\n )}\n </div>\n );\n}\n","import { Rect, boundingRectOrEmpty } from '@embedpdf/models';\nimport { useInteractionHandles, CounterRotate } from '@embedpdf/utils/@framework';\nimport { TrackedAnnotation } from '@embedpdf/plugin-annotation';\nimport { useState, useMemo, useCallback, useRef, useEffect } from '@framework';\nimport { useDocumentPermissions } from '@embedpdf/core/@framework';\n\nimport { useAnnotationPlugin } from '../hooks';\nimport { ResizeHandleUI, GroupSelectionMenuRenderFn } from './types';\n\ninterface GroupSelectionBoxProps {\n documentId: string;\n pageIndex: number;\n scale: number;\n rotation: number;\n pageWidth: number;\n pageHeight: number;\n /** All selected annotations on this page */\n selectedAnnotations: TrackedAnnotation[];\n /** Whether the group is draggable (all annotations must be group-draggable) */\n isDraggable: boolean;\n /** Whether the group is resizable (all annotations must be group-resizable) */\n isResizable: boolean;\n /** Resize handle UI customization */\n resizeUI?: ResizeHandleUI;\n /** Selection outline color */\n selectionOutlineColor?: string;\n /** Outline offset */\n outlineOffset?: number;\n /** Z-index for the group box */\n zIndex?: number;\n /** Group selection menu render function */\n groupSelectionMenu?: GroupSelectionMenuRenderFn;\n}\n\n/**\n * GroupSelectionBox renders a bounding box around all selected annotations\n * with drag and resize handles for group manipulation.\n */\nexport function GroupSelectionBox({\n documentId,\n pageIndex,\n scale,\n rotation,\n pageWidth,\n pageHeight,\n selectedAnnotations,\n isDraggable,\n isResizable,\n resizeUI,\n selectionOutlineColor = '#007ACC',\n outlineOffset = 2,\n zIndex = 100,\n groupSelectionMenu,\n}: GroupSelectionBoxProps): JSX.Element | null {\n const { plugin } = useAnnotationPlugin();\n const { canModifyAnnotations } = useDocumentPermissions(documentId);\n const gestureBaseRef = useRef<Rect | null>(null);\n const isDraggingRef = useRef(false);\n const isResizingRef = useRef(false);\n\n // Check permissions before allowing drag/resize\n const effectiveIsDraggable = canModifyAnnotations && isDraggable;\n const effectiveIsResizable = canModifyAnnotations && isResizable;\n\n // Compute the group bounding box from all selected annotations\n const groupBox = useMemo(() => {\n const rects = selectedAnnotations.map((ta) => ta.object.rect);\n return boundingRectOrEmpty(rects);\n }, [selectedAnnotations]);\n\n // Preview state for the group box during drag/resize\n const [previewGroupBox, setPreviewGroupBox] = useState<Rect>(groupBox);\n\n // Sync preview with actual group box when not dragging/resizing\n useEffect(() => {\n if (!isDraggingRef.current && !isResizingRef.current) {\n setPreviewGroupBox(groupBox);\n }\n }, [groupBox]);\n\n // Handle both drag and resize updates using unified plugin API\n // The plugin handles attached links automatically and commits all patches\n const handleUpdate = useCallback(\n (\n event: Parameters<\n NonNullable<Parameters<typeof useInteractionHandles>[0]['controller']['onUpdate']>\n >[0],\n ) => {\n if (!event.transformData?.type) return;\n if (!plugin) return;\n\n const transformType = event.transformData.type;\n const isMove = transformType === 'move';\n const isResize = transformType === 'resize';\n\n // Skip drag operations if group is not draggable\n if (isMove && !effectiveIsDraggable) return;\n\n if (event.state === 'start') {\n gestureBaseRef.current = groupBox;\n\n if (isMove) {\n isDraggingRef.current = true;\n // Use unified drag API - plugin handles attached links automatically\n plugin.startDrag(documentId, {\n annotationIds: selectedAnnotations.map((ta) => ta.object.id),\n pageSize: { width: pageWidth, height: pageHeight },\n });\n } else if (isResize) {\n isResizingRef.current = true;\n // Use unified resize API - plugin handles attached links automatically\n plugin.startResize(documentId, {\n annotationIds: selectedAnnotations.map((ta) => ta.object.id),\n pageSize: { width: pageWidth, height: pageHeight },\n resizeHandle: event.transformData.metadata?.handle ?? 'se',\n });\n }\n }\n\n const base = gestureBaseRef.current ?? groupBox;\n\n if (isMove && event.transformData.changes.rect) {\n // Calculate delta from original position\n const newRect = event.transformData.changes.rect;\n const rawDelta = {\n x: newRect.origin.x - base.origin.x,\n y: newRect.origin.y - base.origin.y,\n };\n\n // Plugin clamps delta and emits events (attached links receive updates too)\n const clampedDelta = plugin.updateDrag(documentId, rawDelta);\n\n // Update preview group box with clamped delta\n setPreviewGroupBox({\n ...base,\n origin: {\n x: base.origin.x + clampedDelta.x,\n y: base.origin.y + clampedDelta.y,\n },\n });\n } else if (isResize && event.transformData.changes.rect) {\n const newGroupBox = event.transformData.changes.rect;\n\n // Plugin computes rects for all participants and emits events\n plugin.updateResize(documentId, newGroupBox);\n\n // Update preview\n setPreviewGroupBox(newGroupBox);\n }\n\n if (event.state === 'end') {\n gestureBaseRef.current = null;\n\n if (isMove && isDraggingRef.current) {\n isDraggingRef.current = false;\n // Plugin commits all patches (selected + attached links) - no patch building needed!\n plugin.commitDrag(documentId);\n } else if (isResize && isResizingRef.current) {\n isResizingRef.current = false;\n // Plugin commits all patches (selected + attached links) - no patch building needed!\n plugin.commitResize(documentId);\n }\n }\n },\n [\n plugin,\n documentId,\n pageWidth,\n pageHeight,\n groupBox,\n effectiveIsDraggable,\n selectedAnnotations,\n ],\n );\n\n // UI constants\n const HANDLE_COLOR = resizeUI?.color ?? '#007ACC';\n const HANDLE_SIZE = resizeUI?.size ?? 12;\n\n // Use interaction handles for both drag and resize\n const { dragProps, resize } = useInteractionHandles({\n controller: {\n element: previewGroupBox,\n constraints: {\n minWidth: 20,\n minHeight: 20,\n boundingBox: { width: pageWidth, height: pageHeight },\n },\n maintainAspectRatio: false,\n pageRotation: rotation,\n scale: scale,\n enabled: true,\n onUpdate: handleUpdate,\n },\n resizeUI: {\n handleSize: HANDLE_SIZE,\n spacing: outlineOffset,\n offsetMode: 'outside',\n includeSides: true,\n zIndex: zIndex + 1,\n },\n vertexUI: {\n vertexSize: 0,\n zIndex: zIndex,\n },\n includeVertices: false,\n });\n\n // Don't render if less than 2 annotations selected\n if (selectedAnnotations.length < 2) {\n return null;\n }\n\n return (\n <div data-group-selection-box data-no-interaction>\n {/* Group box - draggable only if effectiveIsDraggable is true */}\n <div\n {...(effectiveIsDraggable\n ? dragProps\n : {\n onPointerDown: (e) => e.stopPropagation(),\n })}\n style={{\n position: 'absolute',\n left: previewGroupBox.origin.x * scale,\n top: previewGroupBox.origin.y * scale,\n width: previewGroupBox.size.width * scale,\n height: previewGroupBox.size.height * scale,\n outline: `2px dashed ${selectionOutlineColor}`,\n outlineOffset: outlineOffset - 1,\n cursor: effectiveIsDraggable ? 'move' : 'default',\n touchAction: 'none',\n zIndex,\n }}\n >\n {/* Resize handles */}\n {effectiveIsResizable &&\n resize.map(({ key, ...hProps }) =>\n resizeUI?.component ? (\n resizeUI.component({\n key,\n ...hProps,\n backgroundColor: HANDLE_COLOR,\n })\n ) : (\n <div\n key={key}\n {...hProps}\n style={{ ...hProps.style, backgroundColor: HANDLE_COLOR }}\n />\n ),\n )}\n </div>\n\n {/* Group selection menu */}\n {groupSelectionMenu && (\n <CounterRotate\n rect={{\n origin: {\n x: previewGroupBox.origin.x * scale,\n y: previewGroupBox.origin.y * scale,\n },\n size: {\n width: previewGroupBox.size.width * scale,\n height: previewGroupBox.size.height * scale,\n },\n }}\n rotation={rotation}\n >\n {(counterRotateProps) =>\n groupSelectionMenu({\n ...counterRotateProps,\n context: {\n type: 'group',\n annotations: selectedAnnotations,\n pageIndex,\n },\n selected: true,\n placement: {\n suggestTop: false,\n },\n })\n }\n </CounterRotate>\n )}\n </div>\n );\n}\n","import { CSSProperties, MouseEvent, TouchEvent } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\ntype HighlightProps = {\n /** Stroke/markup color */\n strokeColor?: string;\n opacity?: number;\n segmentRects: Rect[];\n rect?: Rect;\n scale: number;\n onClick?: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n style?: CSSProperties;\n};\n\nexport function Highlight({\n strokeColor,\n opacity = 0.5,\n segmentRects,\n rect,\n scale,\n onClick,\n style,\n}: HighlightProps) {\n const resolvedColor = strokeColor ?? '#FFFF00';\n\n return (\n <>\n {segmentRects.map((b, i) => (\n <div\n key={i}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n position: 'absolute',\n left: (rect ? b.origin.x - rect.origin.x : b.origin.x) * scale,\n top: (rect ? b.origin.y - rect.origin.y : b.origin.y) * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background: resolvedColor,\n opacity: opacity,\n pointerEvents: onClick ? 'auto' : 'none',\n cursor: onClick ? 'pointer' : 'default',\n zIndex: onClick ? 1 : undefined,\n ...style,\n }}\n />\n ))}\n </>\n );\n}\n","import { CSSProperties, MouseEvent, TouchEvent } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\ntype UnderlineProps = {\n /** Stroke/markup color */\n strokeColor?: string;\n opacity?: number;\n segmentRects: Rect[];\n rect?: Rect;\n scale: number;\n onClick?: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n style?: CSSProperties;\n};\n\nexport function Underline({\n strokeColor,\n opacity = 0.5,\n segmentRects,\n rect,\n scale,\n onClick,\n style,\n}: UnderlineProps) {\n const resolvedColor = strokeColor ?? '#FFFF00';\n const thickness = 2 * scale; // 2 CSS px at 100 % zoom\n\n return (\n <>\n {segmentRects.map((r, i) => (\n <div\n key={i}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n position: 'absolute',\n left: (rect ? r.origin.x - rect.origin.x : r.origin.x) * scale,\n top: (rect ? r.origin.y - rect.origin.y : r.origin.y) * scale,\n width: r.size.width * scale,\n height: r.size.height * scale,\n background: 'transparent',\n pointerEvents: onClick ? 'auto' : 'none',\n cursor: onClick ? 'pointer' : 'default',\n zIndex: onClick ? 1 : 0,\n ...style,\n }}\n >\n {/* Visual underline */}\n <div\n style={{\n position: 'absolute',\n left: 0,\n bottom: 0,\n width: '100%',\n height: thickness,\n background: resolvedColor,\n opacity: opacity,\n pointerEvents: 'none',\n }}\n />\n </div>\n ))}\n </>\n );\n}\n","import { CSSProperties, MouseEvent, TouchEvent } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\ntype StrikeoutProps = {\n /** Stroke/markup color */\n strokeColor?: string;\n opacity?: number;\n segmentRects: Rect[];\n rect?: Rect;\n scale: number;\n onClick?: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n style?: CSSProperties;\n};\n\nexport function Strikeout({\n strokeColor,\n opacity = 0.5,\n segmentRects,\n rect,\n scale,\n onClick,\n style,\n}: StrikeoutProps) {\n const resolvedColor = strokeColor ?? '#FFFF00';\n const thickness = 2 * scale;\n\n return (\n <>\n {segmentRects.map((r, i) => (\n <div\n key={i}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n position: 'absolute',\n left: (rect ? r.origin.x - rect.origin.x : r.origin.x) * scale,\n top: (rect ? r.origin.y - rect.origin.y : r.origin.y) * scale,\n width: r.size.width * scale,\n height: r.size.height * scale,\n background: 'transparent',\n pointerEvents: onClick ? 'auto' : 'none',\n cursor: onClick ? 'pointer' : 'default',\n zIndex: onClick ? 1 : 0,\n ...style,\n }}\n >\n {/* Visual strikeout line */}\n <div\n style={{\n position: 'absolute',\n left: 0,\n top: '50%',\n width: '100%',\n height: thickness,\n background: resolvedColor,\n opacity: opacity,\n transform: 'translateY(-50%)',\n pointerEvents: 'none',\n }}\n />\n </div>\n ))}\n </>\n );\n}\n","import { CSSProperties, MouseEvent, TouchEvent } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\ntype SquigglyProps = {\n /** Stroke/markup color */\n strokeColor?: string;\n opacity?: number;\n segmentRects: Rect[];\n rect?: Rect;\n scale: number;\n onClick?: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n style?: CSSProperties;\n};\n\nexport function Squiggly({\n strokeColor,\n opacity = 0.5,\n segmentRects,\n rect,\n scale,\n onClick,\n style,\n}: SquigglyProps) {\n const resolvedColor = strokeColor ?? '#FFFF00';\n const amplitude = 2 * scale; // wave height\n const period = 6 * scale; // wave length\n\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${period}\" height=\"${amplitude * 2}\" viewBox=\"0 0 ${period} ${amplitude * 2}\">\n <path d=\"M0 ${amplitude} Q ${period / 4} 0 ${period / 2} ${amplitude} T ${period} ${amplitude}\"\n fill=\"none\" stroke=\"${resolvedColor}\" stroke-width=\"${amplitude}\" stroke-linecap=\"round\"/>\n </svg>`;\n\n // Completely escape the SVG markup\n const svgDataUri = `url(\"data:image/svg+xml;utf8,${encodeURIComponent(svg)}\")`;\n\n return (\n <>\n {segmentRects.map((r, i) => (\n <div\n key={i}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n position: 'absolute',\n left: (rect ? r.origin.x - rect.origin.x : r.origin.x) * scale,\n top: (rect ? r.origin.y - rect.origin.y : r.origin.y) * scale,\n width: r.size.width * scale,\n height: r.size.height * scale,\n background: 'transparent',\n pointerEvents: onClick ? 'auto' : 'none',\n cursor: onClick ? 'pointer' : 'default',\n zIndex: onClick ? 1 : 0,\n ...style,\n }}\n >\n {/* Visual squiggly line */}\n <div\n style={{\n position: 'absolute',\n left: 0,\n bottom: 0,\n width: '100%',\n height: amplitude * 2,\n backgroundImage: svgDataUri,\n backgroundRepeat: 'repeat-x',\n backgroundSize: `${period}px ${amplitude * 2}px`,\n opacity: opacity,\n pointerEvents: 'none',\n }}\n />\n </div>\n ))}\n </>\n );\n}\n","import { useMemo, MouseEvent, TouchEvent } from '@framework';\nimport { PdfInkListObject, Rect } from '@embedpdf/models';\n\n/* ---------------------------------------------------------------- *\\\n|* Types *|\n\\* ---------------------------------------------------------------- */\n\ninterface InkProps {\n /** Whether the annotation is selected */\n isSelected: boolean;\n /** Stroke color */\n strokeColor?: string;\n /** 0 – 1 */\n opacity?: number;\n /** Line width in PDF units */\n strokeWidth: number;\n /** Array of strokes — exactly as in your JSON */\n inkList: PdfInkListObject[];\n /** Bounding box of the whole annotation */\n rect: Rect;\n /** Page zoom factor */\n scale: number;\n /** Callback for when the annotation is clicked */\n onClick?: (e: MouseEvent<SVGPathElement> | TouchEvent<SVGPathElement>) => void;\n}\n\n/**\n * Renders a PDF Ink annotation (free-hand drawing) as SVG.\n */\nexport function Ink({\n isSelected,\n strokeColor,\n opacity = 1,\n strokeWidth,\n inkList,\n rect,\n scale,\n onClick,\n}: InkProps): JSX.Element {\n const resolvedColor = strokeColor ?? '#000000';\n /* convert each stroke to an SVG <path d=\"\"> string */\n const paths = useMemo(() => {\n return inkList.map(({ points }) => {\n let d = '';\n points.forEach(({ x, y }, i) => {\n // localise to the annotation’s own bbox so viewBox can stay tidy\n const lx = x - rect.origin.x;\n const ly = y - rect.origin.y;\n d += (i === 0 ? 'M' : 'L') + lx + ' ' + ly + ' ';\n });\n return d.trim();\n });\n }, [inkList, rect]);\n\n /* absolute placement + scaling just like your text-markup components */\n const width = rect.size.width * scale;\n const height = rect.size.height * scale;\n\n return (\n <svg\n style={{\n position: 'absolute',\n width,\n height,\n pointerEvents: 'none',\n zIndex: 2,\n overflow: 'visible',\n }}\n width={width}\n height={height}\n viewBox={`0 0 ${rect.size.width} ${rect.size.height}`}\n >\n {paths.map((d, i) => (\n <path\n key={i}\n d={d}\n fill=\"none\"\n opacity={opacity}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n cursor: isSelected ? 'move' : 'pointer',\n pointerEvents: isSelected ? 'none' : 'visibleStroke',\n stroke: resolvedColor,\n strokeWidth: strokeWidth,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n }}\n />\n ))}\n </svg>\n );\n}\n","import { useMemo, MouseEvent, TouchEvent } from '@framework';\nimport { PdfAnnotationBorderStyle, Rect } from '@embedpdf/models';\n\n/* ---------------------------------------------------------------- *\\\n|* Types *|\n\\* ---------------------------------------------------------------- */\n\ninterface SquareProps {\n /** Whether the annotation is selected */\n isSelected: boolean;\n /** Fill colour – defaults to PDFium’s black if omitted */\n color?: string;\n /** Stroke colour – defaults to same as fill when omitted */\n strokeColor?: string;\n /** 0 – 1 */\n opacity?: number;\n /** Stroke width in PDF units */\n strokeWidth: number;\n /** Stroke type – defaults to solid when omitted */\n strokeStyle?: PdfAnnotationBorderStyle;\n /** Stroke dash array – defaults to undefined when omitted */\n strokeDashArray?: number[];\n /** Bounding box of the annotation (PDF units) */\n rect: Rect;\n /** Current page zoom factor */\n scale: number;\n /** Click handler (used for selection) */\n onClick?: (e: MouseEvent<SVGElement> | TouchEvent<SVGElement>) => void;\n}\n\n/**\n * Renders a PDF Square annotation (rectangle) as SVG.\n */\nexport function Square({\n isSelected,\n color = '#000000',\n strokeColor,\n opacity = 1,\n strokeWidth,\n strokeStyle = PdfAnnotationBorderStyle.SOLID,\n strokeDashArray,\n rect,\n scale,\n onClick,\n}: SquareProps): JSX.Element {\n /* ------------------------------------------------------------------ */\n /* geometry helpers */\n /* ------------------------------------------------------------------ */\n const { width, height, x, y } = useMemo(() => {\n // Full bounding box *includes* stroke width.\n const outerW = rect.size.width;\n const outerH = rect.size.height;\n\n // Remove the stroke so the visible fill matches the preview.\n const innerW = Math.max(outerW - strokeWidth, 0);\n const innerH = Math.max(outerH - strokeWidth, 0);\n\n return {\n width: innerW,\n height: innerH,\n x: strokeWidth / 2,\n y: strokeWidth / 2,\n };\n }, [rect, strokeWidth]);\n\n const svgWidth = (width + strokeWidth) * scale;\n const svgHeight = (height + strokeWidth) * scale;\n\n return (\n <svg\n style={{\n position: 'absolute',\n width: svgWidth,\n height: svgHeight,\n pointerEvents: 'none',\n zIndex: 2,\n }}\n width={svgWidth}\n height={svgHeight}\n viewBox={`0 0 ${width + strokeWidth} ${height + strokeWidth}`}\n >\n <rect\n x={x}\n y={y}\n width={width}\n height={height}\n fill={color}\n opacity={opacity}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n cursor: isSelected ? 'move' : 'pointer',\n pointerEvents: isSelected\n ? 'none'\n : color === 'transparent'\n ? 'visibleStroke'\n : 'visible',\n stroke: strokeColor ?? color,\n strokeWidth,\n ...(strokeStyle === PdfAnnotationBorderStyle.DASHED && {\n strokeDasharray: strokeDashArray?.join(','),\n }),\n }}\n />\n </svg>\n );\n}\n","import { useMemo, MouseEvent, TouchEvent } from '@framework';\nimport { PdfAnnotationBorderStyle, Rect } from '@embedpdf/models';\n\n/* ---------------------------------------------------------------- *\\\n|* Types *|\n\\* ---------------------------------------------------------------- */\n\ninterface CircleProps {\n /** Whether the annotation is selected */\n isSelected: boolean;\n /** Fill colour – defaults to PDFium’s black if omitted */\n color?: string;\n /** Stroke colour – defaults to same as fill when omitted */\n strokeColor?: string;\n /** 0 – 1 */\n opacity?: number;\n /** Stroke width in PDF units */\n strokeWidth: number;\n /** Stroke type – defaults to solid when omitted */\n strokeStyle?: PdfAnnotationBorderStyle;\n /** Stroke dash array – defaults to undefined when omitted */\n strokeDashArray?: number[];\n /** Bounding box of the annotation */\n rect: Rect;\n /** Current page zoom factor */\n scale: number;\n /** Click handler (used for selection) */\n onClick?: (e: MouseEvent<SVGElement> | TouchEvent<SVGElement>) => void;\n}\n\n/**\n * Renders a PDF Circle annotation (ellipse) as SVG.\n */\nexport function Circle({\n color = '#000000',\n strokeColor,\n opacity = 1,\n strokeWidth,\n strokeStyle = PdfAnnotationBorderStyle.SOLID,\n strokeDashArray,\n rect,\n scale,\n onClick,\n isSelected,\n}: CircleProps): JSX.Element {\n /* ------------------------------------------------------------------ */\n /* geometry helpers */\n /* ------------------------------------------------------------------ */\n const { width, height, cx, cy, rx, ry } = useMemo(() => {\n // Full bounding box *includes* stroke width.\n const outerW = rect.size.width;\n const outerH = rect.size.height;\n\n // Remove the stroke so the visible fill matches the preview.\n const innerW = Math.max(outerW - strokeWidth, 0);\n const innerH = Math.max(outerH - strokeWidth, 0);\n\n return {\n width: outerW,\n height: outerH,\n // Centre of the fill sits strokeWidth/2 in from the edges\n cx: strokeWidth / 2 + innerW / 2,\n cy: strokeWidth / 2 + innerH / 2,\n rx: innerW / 2,\n ry: innerH / 2,\n };\n }, [rect, strokeWidth]);\n\n const svgWidth = width * scale;\n const svgHeight = height * scale;\n\n return (\n <svg\n style={{\n position: 'absolute',\n width: svgWidth,\n height: svgHeight,\n pointerEvents: 'none',\n zIndex: 2,\n }}\n width={svgWidth}\n height={svgHeight}\n viewBox={`0 0 ${width} ${height}`}\n >\n <ellipse\n cx={cx}\n cy={cy}\n rx={rx}\n ry={ry}\n fill={color}\n opacity={opacity}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n cursor: isSelected ? 'move' : 'pointer',\n pointerEvents: isSelected\n ? 'none'\n : color === 'transparent'\n ? 'visibleStroke'\n : 'visible',\n stroke: strokeColor ?? color,\n strokeWidth,\n ...(strokeStyle === PdfAnnotationBorderStyle.DASHED && {\n strokeDasharray: strokeDashArray?.join(','),\n }),\n }}\n />\n </svg>\n );\n}\n","import { useMemo, MouseEvent, TouchEvent } from '@framework';\nimport { Rect, LinePoints, LineEndings, PdfAnnotationBorderStyle } from '@embedpdf/models';\nimport { patching } from '@embedpdf/plugin-annotation';\n\n/* ---------------------------------------------------------------- *\\\n|* Types *|\n\\* ---------------------------------------------------------------- */\n\ninterface LineProps {\n /** interior colour */\n color?: string;\n /** 0 – 1 */\n opacity?: number;\n /** Stroke width in PDF units */\n strokeWidth: number;\n /** Stroke colour (falls back to PDFium default black) */\n strokeColor?: string;\n /** Stroke style */\n strokeStyle?: PdfAnnotationBorderStyle;\n /** Stroke dash array */\n strokeDashArray?: number[];\n /** Bounding box of the annotation */\n rect: Rect;\n /** Line start / end points (page units) */\n linePoints: LinePoints;\n /** Line endings (eg. OpenArrow / Butt) */\n lineEndings?: LineEndings;\n /** Current page zoom factor */\n scale: number;\n /** Click handler (used for selection) */\n onClick?: (e: MouseEvent<SVGElement> | TouchEvent<SVGElement>) => void;\n /** Whether the annotation is selected */\n isSelected: boolean;\n}\n\n/**\n * Renders a PDF Line annotation as SVG (with arrow/butt endings).\n */\nexport function Line({\n color = 'transparent',\n opacity = 1,\n strokeWidth,\n strokeColor = '#000000',\n strokeStyle = PdfAnnotationBorderStyle.SOLID,\n strokeDashArray,\n rect,\n linePoints,\n lineEndings,\n scale,\n onClick,\n isSelected,\n}: LineProps): JSX.Element {\n /* -------------------------------------------------------------- */\n /* Localise the line within its own bounding box */\n /* -------------------------------------------------------------- */\n const { x1, y1, x2, y2 } = useMemo(() => {\n return {\n x1: linePoints.start.x - rect.origin.x,\n y1: linePoints.start.y - rect.origin.y,\n x2: linePoints.end.x - rect.origin.x,\n y2: linePoints.end.y - rect.origin.y,\n };\n }, [linePoints, rect]);\n\n /* -------------------------------------------------------------- */\n /* Arrow-head path data via shared factory */\n /* -------------------------------------------------------------- */\n const endings = useMemo(() => {\n const angle = Math.atan2(y2 - y1, x2 - x1);\n return {\n start: patching.createEnding(lineEndings?.start, strokeWidth, angle + Math.PI, x1, y1),\n end: patching.createEnding(lineEndings?.end, strokeWidth, angle, x2, y2),\n };\n }, [lineEndings, strokeWidth, x1, y1, x2, y2]);\n\n /* -------------------------------------------------------------- */\n /* Absolute placement + scaling (same pattern as other shapes) */\n /* -------------------------------------------------------------- */\n const width = rect.size.width * scale;\n const height = rect.size.height * scale;\n\n return (\n <svg\n style={{\n position: 'absolute',\n width,\n height,\n pointerEvents: 'none',\n zIndex: 2,\n overflow: 'visible',\n }}\n width={width}\n height={height}\n viewBox={`0 0 ${rect.size.width} ${rect.size.height}`}\n >\n {/* Main line */}\n <line\n x1={x1}\n y1={y1}\n x2={x2}\n y2={y2}\n opacity={opacity}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n cursor: isSelected ? 'move' : 'pointer',\n pointerEvents: isSelected ? 'none' : 'visibleStroke',\n stroke: strokeColor,\n strokeWidth,\n strokeLinecap: 'butt',\n ...(strokeStyle === PdfAnnotationBorderStyle.DASHED && {\n strokeDasharray: strokeDashArray?.join(','),\n }),\n }}\n />\n\n {/* Optional arrowheads / butt caps */}\n {endings.start && (\n <path\n d={endings.start.d}\n transform={endings.start.transform}\n onPointerDown={onClick}\n onTouchStart={onClick}\n stroke={strokeColor}\n style={{\n cursor: isSelected ? 'move' : 'pointer',\n strokeWidth,\n strokeLinecap: 'butt',\n pointerEvents: isSelected ? 'none' : endings.start.filled ? 'visible' : 'visibleStroke',\n ...(strokeStyle === PdfAnnotationBorderStyle.DASHED && {\n strokeDasharray: strokeDashArray?.join(','),\n }),\n }}\n fill={endings.start.filled ? color : 'none'}\n />\n )}\n {endings.end && (\n <path\n d={endings.end.d}\n transform={endings.end.transform}\n stroke={strokeColor}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n cursor: isSelected ? 'move' : 'pointer',\n strokeWidth,\n strokeLinecap: 'butt',\n pointerEvents: isSelected ? 'none' : endings.end.filled ? 'visible' : 'visibleStroke',\n ...(strokeStyle === PdfAnnotationBorderStyle.DASHED && {\n strokeDasharray: strokeDashArray?.join(','),\n }),\n }}\n fill={endings.end.filled ? color : 'none'}\n />\n )}\n </svg>\n );\n}\n","import { MouseEvent, TouchEvent, useMemo } from '@framework';\nimport { Rect, Position, LineEndings } from '@embedpdf/models';\nimport { patching } from '@embedpdf/plugin-annotation';\n\ninterface PolylineProps {\n rect: Rect;\n vertices: Position[];\n color?: string;\n strokeColor?: string;\n opacity?: number;\n strokeWidth: number;\n scale: number;\n isSelected: boolean;\n onClick?: (e: MouseEvent<SVGElement> | TouchEvent<SVGElement>) => void;\n /** Optional start & end endings */\n lineEndings?: LineEndings;\n}\n\nexport function Polyline({\n rect,\n vertices,\n color = 'transparent',\n strokeColor = '#000000',\n opacity = 1,\n strokeWidth,\n scale,\n isSelected,\n onClick,\n lineEndings,\n}: PolylineProps): JSX.Element {\n // Localise vertices to annotation rect\n const localPts = useMemo(\n () => vertices.map(({ x, y }) => ({ x: x - rect.origin.x, y: y - rect.origin.y })),\n [vertices, rect],\n );\n\n // Build path data \"M x0 y0 L x1 y1 ...\"\n const pathData = useMemo(() => {\n if (!localPts.length) return '';\n const [first, ...rest] = localPts;\n return (\n `M ${first.x} ${first.y} ` +\n rest\n .map((p) => `L ${p.x} ${p.y} `)\n .join('')\n .trim()\n );\n }, [localPts]);\n\n // Compute endings (angles from first→second, last-1→last)\n const endings = useMemo(() => {\n if (localPts.length < 2) return { start: null, end: null };\n const toAngle = (a: Position, b: Position) => Math.atan2(b.y - a.y, b.x - a.x);\n\n // Calculate angles in the direction of the line segments\n const startRad = toAngle(localPts[0], localPts[1]); // direction FROM first TO second\n const endRad = toAngle(localPts[localPts.length - 2], localPts[localPts.length - 1]); // direction FROM second-to-last TO last\n\n const start = patching.createEnding(\n lineEndings?.start,\n strokeWidth,\n startRad + Math.PI, // tip points outward from line start\n localPts[0].x,\n localPts[0].y,\n );\n const end = patching.createEnding(\n lineEndings?.end,\n strokeWidth,\n endRad, // tip points in line direction\n localPts[localPts.length - 1].x,\n localPts[localPts.length - 1].y,\n );\n return { start, end };\n }, [localPts, lineEndings, strokeWidth]);\n\n const width = rect.size.width * scale;\n const height = rect.size.height * scale;\n\n return (\n <svg\n style={{\n position: 'absolute',\n width,\n height,\n pointerEvents: 'none',\n zIndex: 2,\n overflow: 'visible',\n }}\n width={width}\n height={height}\n viewBox={`0 0 ${rect.size.width} ${rect.size.height}`}\n >\n <path\n d={pathData}\n onPointerDown={onClick}\n onTouchStart={onClick}\n opacity={opacity}\n style={{\n fill: 'none',\n stroke: strokeColor ?? color,\n strokeWidth,\n cursor: isSelected ? 'move' : 'pointer',\n pointerEvents: isSelected ? 'none' : 'visibleStroke',\n strokeLinecap: 'butt',\n strokeLinejoin: 'miter',\n }}\n />\n {endings.start && (\n <path\n d={endings.start.d}\n transform={endings.start.transform}\n stroke={strokeColor}\n fill={endings.start.filled ? color : 'none'}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n cursor: isSelected ? 'move' : 'pointer',\n strokeWidth,\n pointerEvents: isSelected ? 'none' : endings.start.filled ? 'visible' : 'visibleStroke',\n strokeLinecap: 'butt',\n }}\n />\n )}\n {endings.end && (\n <path\n d={endings.end.d}\n transform={endings.end.transform}\n stroke={strokeColor}\n fill={endings.end.filled ? color : 'none'}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n cursor: isSelected ? 'move' : 'pointer',\n strokeWidth,\n pointerEvents: isSelected ? 'none' : endings.end.filled ? 'visible' : 'visibleStroke',\n strokeLinecap: 'butt',\n }}\n />\n )}\n </svg>\n );\n}\n","import { useMemo, MouseEvent, TouchEvent } from '@framework';\nimport { Rect, Position, PdfAnnotationBorderStyle } from '@embedpdf/models';\n\ninterface PolygonProps {\n rect: Rect;\n vertices: Position[];\n color?: string;\n strokeColor?: string;\n opacity?: number;\n strokeWidth: number;\n strokeStyle?: PdfAnnotationBorderStyle;\n strokeDashArray?: number[];\n scale: number;\n isSelected: boolean;\n onClick?: (e: MouseEvent<SVGElement> | TouchEvent<SVGElement>) => void;\n\n // New optional props for preview rendering\n currentVertex?: Position;\n handleSize?: number;\n}\n\nexport function Polygon({\n rect,\n vertices,\n color = 'transparent',\n strokeColor = '#000000',\n opacity = 1,\n strokeWidth,\n strokeStyle = PdfAnnotationBorderStyle.SOLID,\n strokeDashArray,\n scale,\n isSelected,\n onClick,\n currentVertex, // A preview-only prop\n handleSize = 14, // in CSS pixels\n}: PolygonProps): JSX.Element {\n const allPoints = currentVertex ? [...vertices, currentVertex] : vertices;\n\n const localPts = useMemo(\n () => allPoints.map(({ x, y }) => ({ x: x - rect.origin.x, y: y - rect.origin.y })),\n [allPoints, rect],\n );\n\n const pathData = useMemo(() => {\n if (!localPts.length) return '';\n const [first, ...rest] = localPts;\n const isPreview = !!currentVertex;\n // Don't close the path with 'Z' if it's a preview\n return (\n `M ${first.x} ${first.y} ` +\n rest.map((p) => `L ${p.x} ${p.y}`).join(' ') +\n (isPreview ? '' : ' Z')\n ).trim();\n }, [localPts, currentVertex]);\n\n const isPreviewing = currentVertex && vertices.length > 0;\n\n const width = rect.size.width * scale;\n const height = rect.size.height * scale;\n\n return (\n <svg\n style={{\n position: 'absolute',\n width,\n height,\n pointerEvents: 'none',\n zIndex: 2,\n overflow: 'visible',\n }}\n width={width}\n height={height}\n viewBox={`0 0 ${rect.size.width} ${rect.size.height}`}\n >\n <path\n d={pathData}\n onPointerDown={onClick}\n onTouchStart={onClick}\n opacity={opacity}\n style={{\n fill: currentVertex ? 'none' : color, // No fill during preview\n stroke: strokeColor ?? color,\n strokeWidth,\n cursor: isSelected ? 'move' : 'pointer',\n pointerEvents: isSelected\n ? 'none'\n : color === 'transparent'\n ? 'visibleStroke'\n : 'visible',\n strokeLinecap: 'butt',\n strokeLinejoin: 'miter',\n ...(strokeStyle === PdfAnnotationBorderStyle.DASHED && {\n strokeDasharray: strokeDashArray?.join(','),\n }),\n }}\n />\n {/* --- Preview-only elements --- */}\n {isPreviewing && vertices.length > 1 && (\n <path\n d={`M ${localPts[localPts.length - 1].x} ${localPts[localPts.length - 1].y} L ${localPts[0].x} ${localPts[0].y}`}\n fill=\"none\"\n style={{ stroke: strokeColor, strokeWidth, strokeDasharray: '4,4', opacity: 0.7 }}\n />\n )}\n {isPreviewing && vertices.length >= 2 && (\n <rect\n x={localPts[0].x - handleSize / scale / 2}\n y={localPts[0].y - handleSize / scale / 2}\n width={handleSize / scale}\n height={handleSize / scale}\n fill={strokeColor}\n opacity={0.4}\n stroke={strokeColor}\n strokeWidth={strokeWidth / 2}\n />\n )}\n </svg>\n );\n}\n","import {\n MouseEvent,\n TouchEvent,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n suppressContentEditableWarningProps,\n} from '@framework';\nimport {\n PdfFreeTextAnnoObject,\n PdfVerticalAlignment,\n standardFontCss,\n textAlignmentToCss,\n} from '@embedpdf/models';\nimport { useAnnotationCapability } from '../..';\nimport { TrackedAnnotation } from '@embedpdf/plugin-annotation';\n\ninterface FreeTextProps {\n isSelected: boolean;\n isEditing: boolean;\n annotation: TrackedAnnotation<PdfFreeTextAnnoObject>;\n pageIndex: number;\n scale: number;\n onClick?: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n onDoubleClick?: (event: MouseEvent<HTMLDivElement>) => void;\n}\n\nexport function FreeText({\n isSelected,\n isEditing,\n annotation,\n pageIndex,\n scale,\n onClick,\n}: FreeTextProps) {\n const editorRef = useRef<HTMLSpanElement>(null);\n const { provides: annotationProvides } = useAnnotationCapability();\n const [isIOS, setIsIOS] = useState(false);\n\n useEffect(() => {\n if (isEditing && editorRef.current) {\n const editor = editorRef.current;\n editor.focus();\n\n const selection = window.getSelection();\n if (selection) {\n const range = document.createRange();\n range.selectNodeContents(editor);\n range.collapse(false);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n }\n }, [isEditing]);\n\n useLayoutEffect(() => {\n try {\n const nav = navigator as any;\n const ios =\n /iPad|iPhone|iPod/.test(navigator.userAgent) ||\n (navigator.platform === 'MacIntel' && nav?.maxTouchPoints > 1);\n setIsIOS(ios);\n } catch {\n setIsIOS(false);\n }\n }, []);\n\n const handleBlur = () => {\n if (!annotationProvides) return;\n if (!editorRef.current) return;\n annotationProvides.updateAnnotation(pageIndex, annotation.object.id, {\n contents: editorRef.current.innerText,\n });\n };\n\n // iOS zoom prevention: keep focused font-size >= 16px, visually scale down if needed.\n const computedFontPx = annotation.object.fontSize * scale;\n const MIN_IOS_FOCUS_FONT_PX = 16;\n const needsComp =\n isIOS && isEditing && computedFontPx > 0 && computedFontPx < MIN_IOS_FOCUS_FONT_PX;\n const adjustedFontPx = needsComp ? MIN_IOS_FOCUS_FONT_PX : computedFontPx;\n const scaleComp = needsComp ? computedFontPx / MIN_IOS_FOCUS_FONT_PX : 1;\n const invScalePercent = needsComp ? 100 / scaleComp : 100;\n\n return (\n <div\n style={{\n position: 'absolute',\n width: annotation.object.rect.size.width * scale,\n height: annotation.object.rect.size.height * scale,\n cursor: isSelected && !isEditing ? 'move' : 'default',\n pointerEvents: isSelected && !isEditing ? 'none' : 'auto',\n zIndex: 2,\n }}\n onPointerDown={onClick}\n onTouchStart={onClick}\n >\n <span\n ref={editorRef}\n onBlur={handleBlur}\n tabIndex={0}\n style={{\n color: annotation.object.fontColor,\n fontSize: adjustedFontPx,\n fontFamily: standardFontCss(annotation.object.fontFamily),\n textAlign: textAlignmentToCss(annotation.object.textAlign),\n flexDirection: 'column',\n justifyContent:\n annotation.object.verticalAlign === PdfVerticalAlignment.Top\n ? 'flex-start'\n : annotation.object.verticalAlign === PdfVerticalAlignment.Middle\n ? 'center'\n : 'flex-end',\n display: 'flex',\n backgroundColor: annotation.object.color ?? annotation.object.backgroundColor,\n opacity: annotation.object.opacity,\n width: needsComp ? `${invScalePercent}%` : '100%',\n height: needsComp ? `${invScalePercent}%` : '100%',\n lineHeight: '1.18',\n overflow: 'hidden',\n cursor: isEditing ? 'text' : 'pointer',\n outline: 'none',\n transform: needsComp ? `scale(${scaleComp})` : undefined,\n transformOrigin: 'top left',\n }}\n contentEditable={isEditing}\n {...suppressContentEditableWarningProps}\n >\n {annotation.object.contents}\n </span>\n </div>\n );\n}\n","import { Fragment, HTMLAttributes, CSSProperties, useEffect, useRef, useState } from '@framework';\nimport { AppearanceMode, ignore, PdfAnnotationObject, PdfErrorCode } from '@embedpdf/models';\n\nimport { useAnnotationCapability } from '../hooks/use-annotation';\n\ntype RenderAnnotationProps = Omit<HTMLAttributes<HTMLImageElement>, 'style'> & {\n documentId: string;\n pageIndex: number;\n annotation: PdfAnnotationObject;\n scaleFactor?: number;\n dpr?: number;\n style?: CSSProperties;\n};\n\nexport function RenderAnnotation({\n documentId,\n pageIndex,\n annotation,\n scaleFactor = 1,\n style,\n ...props\n}: RenderAnnotationProps) {\n const { provides: annotationProvides } = useAnnotationCapability();\n const [imageUrl, setImageUrl] = useState<string | null>(null);\n const urlRef = useRef<string | null>(null);\n\n const { width, height } = annotation.rect.size;\n\n useEffect(() => {\n if (annotationProvides) {\n const task = annotationProvides.forDocument(documentId).renderAnnotation({\n pageIndex,\n annotation,\n options: {\n scaleFactor,\n dpr: window.devicePixelRatio,\n },\n });\n task.wait((blob) => {\n const url = URL.createObjectURL(blob);\n setImageUrl(url);\n urlRef.current = url;\n }, ignore);\n\n return () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n } else {\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n }\n }, [pageIndex, scaleFactor, annotationProvides, documentId, annotation.id, width, height]);\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n return (\n <Fragment>\n {imageUrl && (\n <img\n src={imageUrl}\n onLoad={handleImageLoad}\n {...props}\n style={{\n width: '100%',\n height: '100%',\n display: 'block',\n ...(style || {}),\n }}\n />\n )}\n </Fragment>\n );\n}\n","import { MouseEvent, TouchEvent } from '@framework';\nimport { PdfStampAnnoObject } from '@embedpdf/models';\nimport { TrackedAnnotation } from '@embedpdf/plugin-annotation';\nimport { RenderAnnotation } from '../render-annotation';\n\ninterface StampProps {\n isSelected: boolean;\n annotation: TrackedAnnotation<PdfStampAnnoObject>;\n documentId: string;\n pageIndex: number;\n scale: number;\n onClick: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n}\n\nexport function Stamp({\n isSelected,\n annotation,\n documentId,\n pageIndex,\n scale,\n onClick,\n}: StampProps) {\n return (\n <div\n style={{\n position: 'absolute',\n width: '100%',\n height: '100%',\n zIndex: 2,\n pointerEvents: isSelected ? 'none' : 'auto',\n cursor: 'pointer',\n }}\n onPointerDown={onClick}\n onTouchStart={onClick}\n >\n <RenderAnnotation\n documentId={documentId}\n pageIndex={pageIndex}\n annotation={{ ...annotation.object, id: annotation.object.id }}\n scaleFactor={scale}\n />\n </div>\n );\n}\n","import { useMemo, MouseEvent, TouchEvent } from '@framework';\nimport { PdfAnnotationBorderStyle, Rect } from '@embedpdf/models';\n\n/* ---------------------------------------------------------------- *\\\n|* Types *|\n\\* ---------------------------------------------------------------- */\n\ninterface LinkProps {\n /** Whether the annotation is selected */\n isSelected: boolean;\n /** Stroke colour – defaults to blue when omitted */\n strokeColor?: string;\n /** Stroke width in PDF units */\n strokeWidth?: number;\n /** Stroke type – defaults to underline when omitted */\n strokeStyle?: PdfAnnotationBorderStyle;\n /** Stroke dash array – for dashed style */\n strokeDashArray?: number[];\n /** Bounding box of the annotation (PDF units) */\n rect: Rect;\n /** Current page zoom factor */\n scale: number;\n /** Click handler (used for selection) */\n onClick?: (e: MouseEvent<SVGElement> | TouchEvent<SVGElement>) => void;\n /** Whether this link has an IRT (In Reply To) reference - disables direct interaction */\n hasIRT?: boolean;\n}\n\n/**\n * Renders a PDF Link annotation as SVG.\n * Supports underline (default), solid, and dashed border styles.\n */\nexport function Link({\n isSelected,\n strokeColor = '#0000FF',\n strokeWidth = 2,\n strokeStyle = PdfAnnotationBorderStyle.UNDERLINE,\n strokeDashArray,\n rect,\n scale,\n onClick,\n hasIRT = false,\n}: LinkProps): JSX.Element {\n const { width, height } = useMemo(() => {\n return {\n width: rect.size.width,\n height: rect.size.height,\n };\n }, [rect]);\n\n const svgWidth = width * scale;\n const svgHeight = height * scale;\n\n // Calculate dash array for SVG\n const dashArray = useMemo(() => {\n if (strokeStyle === PdfAnnotationBorderStyle.DASHED) {\n return strokeDashArray?.join(',') ?? `${strokeWidth * 3},${strokeWidth}`;\n }\n return undefined;\n }, [strokeStyle, strokeDashArray, strokeWidth]);\n\n // For underline style, render a line at the bottom\n // For solid/dashed, render a rectangle border\n const isUnderline = strokeStyle === PdfAnnotationBorderStyle.UNDERLINE;\n\n return (\n <svg\n style={{\n position: 'absolute',\n width: svgWidth,\n height: svgHeight,\n pointerEvents: 'none',\n zIndex: 2,\n }}\n width={svgWidth}\n height={svgHeight}\n viewBox={`0 0 ${width} ${height}`}\n >\n {/* Invisible hit area for the entire link region */}\n {/* IRT links are not directly clickable - interaction goes through parent */}\n <rect\n x={0}\n y={0}\n width={width}\n height={height}\n fill=\"transparent\"\n onPointerDown={hasIRT ? undefined : onClick}\n onTouchStart={hasIRT ? undefined : onClick}\n style={{\n cursor: hasIRT ? 'default' : isSelected ? 'move' : 'pointer',\n pointerEvents: hasIRT ? 'none' : isSelected ? 'none' : 'visible',\n }}\n />\n\n {isUnderline ? (\n // Underline style: line at bottom of rect\n <line\n x1={1}\n y1={height - 1}\n x2={width - 1}\n y2={height - 1}\n stroke={strokeColor}\n strokeWidth={strokeWidth}\n strokeDasharray={dashArray}\n style={{\n pointerEvents: 'none',\n }}\n />\n ) : (\n // Solid/Dashed style: rectangle border\n <rect\n x={strokeWidth / 2}\n y={strokeWidth / 2}\n width={Math.max(width - strokeWidth, 0)}\n height={Math.max(height - strokeWidth, 0)}\n fill=\"transparent\"\n stroke={strokeColor}\n strokeWidth={strokeWidth}\n strokeDasharray={dashArray}\n style={{\n pointerEvents: 'none',\n }}\n />\n )}\n </svg>\n );\n}\n","import { blendModeToCss, PdfAnnotationObject, PdfBlendMode } from '@embedpdf/models';\nimport {\n getAnnotationsByPageIndex,\n getSelectedAnnotationIds,\n isHighlight,\n isInk,\n isSquiggly,\n isCircle,\n isStrikeout,\n isUnderline,\n TrackedAnnotation,\n isSquare,\n isLine,\n isPolyline,\n isPolygon,\n isFreeText,\n isStamp,\n isLink,\n resolveInteractionProp,\n} from '@embedpdf/plugin-annotation';\nimport { PdfLinkAnnoObject } from '@embedpdf/models';\nimport { PointerEventHandlers, EmbedPdfPointerEvent } from '@embedpdf/plugin-interaction-manager';\nimport { usePointerHandlers } from '@embedpdf/plugin-interaction-manager/@framework';\nimport { useSelectionCapability } from '@embedpdf/plugin-selection/@framework';\nimport {\n useMemo,\n useState,\n useEffect,\n useCallback,\n MouseEvent,\n Fragment,\n TouchEvent,\n} from '@framework';\n\nimport { useAnnotationCapability } from '../hooks';\nimport { AnnotationContainer } from './annotation-container';\nimport { GroupSelectionBox } from './group-selection-box';\nimport { Highlight } from './text-markup/highlight';\nimport { Underline } from './text-markup/underline';\nimport { Strikeout } from './text-markup/strikeout';\nimport { Squiggly } from './text-markup/squiggly';\nimport { Ink } from './annotations/ink';\nimport { Square } from './annotations/square';\nimport {\n CustomAnnotationRenderer,\n ResizeHandleUI,\n AnnotationSelectionMenuRenderFn,\n GroupSelectionMenuRenderFn,\n VertexHandleUI,\n BoxedAnnotationRenderer,\n} from './types';\nimport { Circle } from './annotations/circle';\nimport { Line } from './annotations/line';\nimport { Polyline } from './annotations/polyline';\nimport { Polygon } from './annotations/polygon';\nimport { FreeText } from './annotations/free-text';\nimport { Stamp } from './annotations/stamp';\nimport { Link } from './annotations/link';\n\ninterface AnnotationsProps {\n documentId: string;\n pageIndex: number;\n scale: number;\n rotation: number;\n pageWidth: number;\n pageHeight: number;\n selectionMenu?: AnnotationSelectionMenuRenderFn;\n groupSelectionMenu?: GroupSelectionMenuRenderFn;\n resizeUI?: ResizeHandleUI;\n vertexUI?: VertexHandleUI;\n selectionOutlineColor?: string;\n customAnnotationRenderer?: CustomAnnotationRenderer<PdfAnnotationObject>;\n /** Custom renderers for specific annotation types (provided by external plugins) */\n annotationRenderers?: BoxedAnnotationRenderer[];\n}\n\nexport function Annotations(annotationsProps: AnnotationsProps) {\n const { documentId, pageIndex, scale, pageWidth, pageHeight, selectionMenu } = annotationsProps;\n const { provides: annotationCapability } = useAnnotationCapability();\n const { provides: selectionProvides } = useSelectionCapability();\n const [annotations, setAnnotations] = useState<TrackedAnnotation[]>([]);\n const { register } = usePointerHandlers({ documentId, pageIndex });\n const [allSelectedIds, setAllSelectedIds] = useState<string[]>([]);\n const [editingId, setEditingId] = useState<string | null>(null);\n\n // Get scoped API for this document (memoized to prevent infinite loops)\n const annotationProvides = useMemo(\n () => (annotationCapability ? annotationCapability.forDocument(documentId) : null),\n [annotationCapability, documentId],\n );\n\n // Check if multiple annotations are selected\n const isMultiSelected = allSelectedIds.length > 1;\n\n useEffect(() => {\n if (annotationProvides) {\n // Initialize with current state immediately\n const currentState = annotationProvides.getState();\n setAnnotations(getAnnotationsByPageIndex(currentState, pageIndex));\n setAllSelectedIds(getSelectedAnnotationIds(currentState));\n\n // Then subscribe to changes\n return annotationProvides.onStateChange((state) => {\n setAnnotations(getAnnotationsByPageIndex(state, pageIndex));\n setAllSelectedIds(getSelectedAnnotationIds(state));\n });\n }\n }, [annotationProvides, pageIndex]);\n\n const handlers = useMemo(\n (): PointerEventHandlers<EmbedPdfPointerEvent<MouseEvent>> => ({\n onPointerDown: (_, pe) => {\n // Only deselect if clicking directly on the layer (not on an annotation)\n if (pe.target === pe.currentTarget && annotationProvides) {\n annotationProvides.deselectAnnotation();\n setEditingId(null);\n }\n },\n }),\n [annotationProvides],\n );\n\n const handleClick = useCallback(\n (e: MouseEvent | TouchEvent, annotation: TrackedAnnotation) => {\n e.stopPropagation();\n if (annotationProvides && selectionProvides) {\n selectionProvides.clear();\n\n // Check for modifier key (Cmd on Mac, Ctrl on Windows/Linux)\n const isModifierPressed = 'metaKey' in e ? e.metaKey || e.ctrlKey : false;\n\n if (isModifierPressed) {\n // Toggle selection: add or remove from current selection\n annotationProvides.toggleSelection(pageIndex, annotation.object.id);\n } else {\n // Exclusive select: clear and select only this one\n annotationProvides.selectAnnotation(pageIndex, annotation.object.id);\n }\n\n if (annotation.object.id !== editingId) {\n setEditingId(null);\n }\n }\n },\n [annotationProvides, selectionProvides, editingId, pageIndex],\n );\n\n // Special handler for link annotations - if IRT exists, select the parent\n const handleLinkClick = useCallback(\n (e: MouseEvent | TouchEvent, annotation: TrackedAnnotation<PdfLinkAnnoObject>) => {\n e.stopPropagation();\n if (!annotationProvides || !selectionProvides) return;\n\n selectionProvides.clear();\n\n // If link has IRT, select the parent annotation instead\n if (annotation.object.inReplyToId) {\n const parentId = annotation.object.inReplyToId;\n const parent = annotations.find((a) => a.object.id === parentId);\n if (parent) {\n annotationProvides.selectAnnotation(parent.object.pageIndex, parentId);\n return;\n }\n }\n\n // Standalone link - select it directly\n annotationProvides.selectAnnotation(pageIndex, annotation.object.id);\n },\n [annotationProvides, selectionProvides, annotations, pageIndex],\n );\n\n useEffect(() => {\n return register(handlers, {\n documentId,\n });\n }, [register, handlers]);\n // Get selected annotations that are on THIS page (for group selection box)\n const selectedAnnotationsOnPage = useMemo(() => {\n return annotations.filter((anno) => allSelectedIds.includes(anno.object.id));\n }, [annotations, allSelectedIds]);\n\n // Check if all selected annotations on this page are draggable in group context\n const areAllSelectedDraggable = useMemo(() => {\n if (selectedAnnotationsOnPage.length < 2) return false;\n\n return selectedAnnotationsOnPage.every((ta) => {\n const tool = annotationProvides?.findToolForAnnotation(ta.object);\n // Use group-specific property, falling back to single-annotation property\n const groupDraggable = resolveInteractionProp(\n tool?.interaction.isGroupDraggable,\n ta.object,\n true,\n );\n const singleDraggable = resolveInteractionProp(\n tool?.interaction.isDraggable,\n ta.object,\n true,\n );\n return tool?.interaction.isGroupDraggable !== undefined ? groupDraggable : singleDraggable;\n });\n }, [selectedAnnotationsOnPage, annotationProvides]);\n\n // Check if all selected annotations on this page are resizable in group context\n const areAllSelectedResizable = useMemo(() => {\n if (selectedAnnotationsOnPage.length < 2) return false;\n\n return selectedAnnotationsOnPage.every((ta) => {\n const tool = annotationProvides?.findToolForAnnotation(ta.object);\n // Use group-specific property, falling back to single-annotation property\n const groupResizable = resolveInteractionProp(\n tool?.interaction.isGroupResizable,\n ta.object,\n true,\n );\n const singleResizable = resolveInteractionProp(\n tool?.interaction.isResizable,\n ta.object,\n true,\n );\n return tool?.interaction.isGroupResizable !== undefined ? groupResizable : singleResizable;\n });\n }, [selectedAnnotationsOnPage, annotationProvides]);\n\n // Check if all selected annotations are on the same page (this page)\n const allSelectedOnSamePage = useMemo(() => {\n if (!annotationProvides) return false;\n const allSelected = annotationProvides.getSelectedAnnotations();\n // All selected must be on this page\n return allSelected.length > 1 && allSelected.every((ta) => ta.object.pageIndex === pageIndex);\n }, [annotationProvides, pageIndex, allSelectedIds]);\n\n return (\n <>\n {annotations.map((annotation) => {\n const isSelected = allSelectedIds.includes(annotation.object.id);\n const isEditing = editingId === annotation.object.id;\n const tool = annotationProvides?.findToolForAnnotation(annotation.object);\n\n // Check for custom renderer first (from external plugins like redaction)\n for (const renderer of annotationsProps.annotationRenderers ?? []) {\n const element = renderer.tryRender(annotation, {\n isSelected,\n scale,\n pageIndex,\n onClick: (e) => handleClick(e, annotation),\n });\n if (element) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n false,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n false,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {() => element}\n </AnnotationContainer>\n );\n }\n }\n\n if (isInk(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n true,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n true,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Ink\n {...obj}\n isSelected={isSelected}\n scale={scale}\n onClick={(e) => handleClick(e, annotation)}\n />\n )}\n </AnnotationContainer>\n );\n }\n\n if (isSquare(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n true,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n true,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Square\n {...obj}\n isSelected={isSelected}\n scale={scale}\n onClick={(e) => handleClick(e, annotation)}\n />\n )}\n </AnnotationContainer>\n );\n }\n\n if (isCircle(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n true,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n true,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Circle\n {...obj}\n isSelected={isSelected}\n scale={scale}\n onClick={(e) => handleClick(e, annotation)}\n />\n )}\n </AnnotationContainer>\n );\n }\n\n if (isUnderline(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n false,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n false,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n zIndex={0}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Underline {...obj} scale={scale} onClick={(e) => handleClick(e, annotation)} />\n )}\n </AnnotationContainer>\n );\n }\n\n if (isStrikeout(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n false,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n false,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n zIndex={0}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Strikeout {...obj} scale={scale} onClick={(e) => handleClick(e, annotation)} />\n )}\n </AnnotationContainer>\n );\n }\n\n if (isSquiggly(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n false,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n false,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n zIndex={0}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Squiggly {...obj} scale={scale} onClick={(e) => handleClick(e, annotation)} />\n )}\n </AnnotationContainer>\n );\n }\n\n if (isHighlight(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n false,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n false,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n zIndex={0}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Multiply),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Highlight {...obj} scale={scale} onClick={(e) => handleClick(e, annotation)} />\n )}\n </AnnotationContainer>\n );\n }\n\n if (isLine(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n true,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n false,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n vertexConfig={{\n extractVertices: (annotation) => [\n annotation.linePoints.start,\n annotation.linePoints.end,\n ],\n transformAnnotation: (annotation, vertices) => {\n return {\n ...annotation,\n linePoints: {\n start: vertices[0],\n end: vertices[1],\n },\n };\n },\n }}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Fragment>\n <Line\n {...obj}\n isSelected={isSelected}\n scale={scale}\n onClick={(e) => handleClick(e, annotation)}\n />\n </Fragment>\n )}\n </AnnotationContainer>\n );\n }\n\n if (isPolyline(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n true,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n false,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n vertexConfig={{\n extractVertices: (annotation) => annotation.vertices,\n transformAnnotation: (annotation, vertices) => {\n return {\n ...annotation,\n vertices,\n };\n },\n }}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Fragment>\n <Polyline\n {...obj}\n isSelected={isSelected}\n scale={scale}\n onClick={(e) => handleClick(e, annotation)}\n />\n </Fragment>\n )}\n </AnnotationContainer>\n );\n }\n\n if (isPolygon(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n true,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n false,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n vertexConfig={{\n extractVertices: (annotation) => annotation.vertices,\n transformAnnotation: (annotation, vertices) => {\n return {\n ...annotation,\n vertices,\n };\n },\n }}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Fragment>\n <Polygon\n {...obj}\n isSelected={isSelected}\n scale={scale}\n onClick={(e) => handleClick(e, annotation)}\n />\n </Fragment>\n )}\n </AnnotationContainer>\n );\n }\n\n if (isFreeText(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={\n resolveInteractionProp(tool?.interaction.isDraggable, annotation.object, true) &&\n !isEditing\n }\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n true,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n onDoubleClick={(e) => {\n e.stopPropagation();\n setEditingId(annotation.object.id);\n }}\n {...annotationsProps}\n >\n {(object) => (\n <FreeText\n isSelected={isSelected}\n isEditing={isEditing}\n annotation={{\n ...annotation,\n object,\n }}\n pageIndex={pageIndex}\n scale={scale}\n onClick={(e) => handleClick(e, annotation)}\n />\n )}\n </AnnotationContainer>\n );\n }\n\n if (isStamp(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n true,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n true,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(_object) => (\n <Stamp\n isSelected={isSelected}\n annotation={annotation}\n documentId={documentId}\n pageIndex={pageIndex}\n scale={scale}\n onClick={(e) => handleClick(e, annotation)}\n />\n )}\n </AnnotationContainer>\n );\n }\n\n if (isLink(annotation)) {\n // IRT-linked links are not independently draggable/resizable\n const hasIRT = !!annotation.object.inReplyToId;\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={false}\n isResizable={false}\n lockAspectRatio={false}\n selectionMenu={hasIRT ? undefined : selectionMenu}\n onSelect={(e) => handleLinkClick(e, annotation)}\n {...annotationsProps}\n >\n {(obj) => (\n <Link\n {...obj}\n isSelected={isSelected}\n scale={scale}\n onClick={(e) => handleLinkClick(e, annotation)}\n hasIRT={hasIRT}\n />\n )}\n </AnnotationContainer>\n );\n }\n\n /* --------- fallback: an unsupported subtype --------------- */\n return null;\n })}\n\n {/* Group selection box for multi-select drag/resize */}\n {allSelectedOnSamePage && selectedAnnotationsOnPage.length >= 2 && (\n <GroupSelectionBox\n documentId={documentId}\n pageIndex={pageIndex}\n scale={scale}\n rotation={annotationsProps.rotation}\n pageWidth={pageWidth}\n pageHeight={pageHeight}\n selectedAnnotations={selectedAnnotationsOnPage}\n isDraggable={areAllSelectedDraggable}\n isResizable={areAllSelectedResizable}\n resizeUI={annotationsProps.resizeUI}\n selectionOutlineColor={annotationsProps.selectionOutlineColor}\n groupSelectionMenu={annotationsProps.groupSelectionMenu}\n />\n )}\n </>\n );\n}\n","import { blendModeToCss, PdfAnnotationSubtype, PdfBlendMode, Rect } from '@embedpdf/models';\nimport { AnnotationTool } from '@embedpdf/plugin-annotation';\nimport { useSelectionCapability } from '@embedpdf/plugin-selection/@framework';\n\nimport { useEffect, useState } from '@framework';\nimport { useAnnotationCapability } from '../hooks';\nimport { Highlight } from './text-markup/highlight';\nimport { Squiggly } from './text-markup/squiggly';\nimport { Underline } from './text-markup/underline';\nimport { Strikeout } from './text-markup/strikeout';\n\ninterface TextMarkupProps {\n documentId: string;\n pageIndex: number;\n scale: number;\n}\n\nexport function TextMarkup({ documentId, pageIndex, scale }: TextMarkupProps) {\n const { provides: selectionProvides } = useSelectionCapability();\n const { provides: annotationProvides } = useAnnotationCapability();\n const [rects, setRects] = useState<Array<Rect>>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n const [activeTool, setActiveTool] = useState<AnnotationTool | null>(null);\n\n useEffect(() => {\n if (!selectionProvides) return;\n\n return selectionProvides.forDocument(documentId).onSelectionChange(() => {\n setRects(selectionProvides.forDocument(documentId).getHighlightRectsForPage(pageIndex));\n setBoundingRect(selectionProvides.forDocument(documentId).getBoundingRectForPage(pageIndex));\n });\n }, [selectionProvides, documentId, pageIndex]);\n\n useEffect(() => {\n if (!annotationProvides) return;\n\n // Initialize with current active tool\n setActiveTool(annotationProvides.forDocument(documentId).getActiveTool());\n\n return annotationProvides\n .forDocument(documentId)\n .onActiveToolChange((event) => setActiveTool(event));\n }, [annotationProvides, documentId]);\n\n if (!boundingRect) return null;\n if (!activeTool || !activeTool.defaults) return null;\n\n switch (activeTool.defaults.type) {\n case PdfAnnotationSubtype.UNDERLINE:\n return (\n <div\n style={{\n mixBlendMode: blendModeToCss(activeTool.defaults?.blendMode ?? PdfBlendMode.Normal),\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n }}\n >\n <Underline\n strokeColor={activeTool.defaults?.strokeColor}\n opacity={activeTool.defaults?.opacity}\n segmentRects={rects}\n scale={scale}\n />\n </div>\n );\n case PdfAnnotationSubtype.HIGHLIGHT:\n return (\n <div\n style={{\n mixBlendMode: blendModeToCss(activeTool.defaults?.blendMode ?? PdfBlendMode.Multiply),\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n }}\n >\n <Highlight\n strokeColor={activeTool.defaults?.strokeColor}\n opacity={activeTool.defaults?.opacity}\n segmentRects={rects}\n scale={scale}\n />\n </div>\n );\n case PdfAnnotationSubtype.STRIKEOUT:\n return (\n <div\n style={{\n mixBlendMode: blendModeToCss(activeTool.defaults?.blendMode ?? PdfBlendMode.Normal),\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n }}\n >\n <Strikeout\n strokeColor={activeTool.defaults?.strokeColor}\n opacity={activeTool.defaults?.opacity}\n segmentRects={rects}\n scale={scale}\n />\n </div>\n );\n case PdfAnnotationSubtype.SQUIGGLY:\n return (\n <div\n style={{\n mixBlendMode: blendModeToCss(activeTool.defaults?.blendMode ?? PdfBlendMode.Normal),\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n }}\n >\n <Squiggly\n strokeColor={activeTool.defaults?.strokeColor}\n opacity={activeTool.defaults?.opacity}\n segmentRects={rects}\n scale={scale}\n />\n </div>\n );\n default:\n return null;\n }\n}\n","import { AnyPreviewState } from '@embedpdf/plugin-annotation';\nimport { Circle } from './annotations/circle';\nimport { Square } from './annotations/square';\nimport { Polygon } from './annotations/polygon';\nimport { PdfAnnotationSubtype } from '@embedpdf/models';\nimport { Polyline } from './annotations/polyline';\nimport { Line } from './annotations/line';\nimport { Ink } from './annotations/ink';\n\ninterface Props {\n preview: AnyPreviewState;\n scale: number;\n}\n\nexport function PreviewRenderer({ preview, scale }: Props) {\n const { bounds } = preview;\n\n const style = {\n position: 'absolute' as const,\n left: bounds.origin.x * scale,\n top: bounds.origin.y * scale,\n width: bounds.size.width * scale,\n height: bounds.size.height * scale,\n pointerEvents: 'none' as const,\n zIndex: 10,\n };\n\n // Use type guards for proper type narrowing\n if (preview.type === PdfAnnotationSubtype.CIRCLE) {\n return (\n <div style={style}>\n <Circle isSelected={false} scale={scale} {...preview.data} />\n </div>\n );\n }\n\n if (preview.type === PdfAnnotationSubtype.SQUARE) {\n return (\n <div style={style}>\n <Square isSelected={false} scale={scale} {...preview.data} />\n </div>\n );\n }\n\n if (preview.type === PdfAnnotationSubtype.POLYGON) {\n return (\n <div style={style}>\n <Polygon isSelected={false} scale={scale} {...preview.data} />\n </div>\n );\n }\n\n if (preview.type === PdfAnnotationSubtype.POLYLINE) {\n return (\n <div style={style}>\n <Polyline isSelected={false} scale={scale} {...preview.data} />\n </div>\n );\n }\n\n if (preview.type === PdfAnnotationSubtype.LINE) {\n return (\n <div style={style}>\n <Line isSelected={false} scale={scale} {...preview.data} />\n </div>\n );\n }\n\n if (preview.type === PdfAnnotationSubtype.INK) {\n return (\n <div style={style}>\n <Ink isSelected={false} scale={scale} {...preview.data} />\n </div>\n );\n }\n\n if (preview.type === PdfAnnotationSubtype.FREETEXT) {\n return (\n <div style={style}>\n {/* Render a simple dashed border preview */}\n <div\n style={{\n width: '100%',\n height: '100%',\n border: `1px dashed ${preview.data.fontColor || '#000000'}`,\n backgroundColor: 'transparent',\n }}\n />\n </div>\n );\n }\n\n return null;\n}\n","import { useEffect, useMemo, useRef, useState } from '@framework';\nimport { useAnnotationPlugin } from '../hooks';\nimport { AnyPreviewState, HandlerServices } from '@embedpdf/plugin-annotation';\nimport { PreviewRenderer } from './preview-renderer';\n\ninterface Props {\n documentId: string;\n pageIndex: number;\n scale: number;\n}\n\nexport function AnnotationPaintLayer({ documentId, pageIndex, scale }: Props) {\n const { plugin: annotationPlugin } = useAnnotationPlugin();\n const [previews, setPreviews] = useState<Map<string, AnyPreviewState>>(new Map());\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n const services = useMemo<HandlerServices>(\n () => ({\n requestFile: ({ accept, onFile }) => {\n if (!fileInputRef.current) return;\n const input = fileInputRef.current;\n input.accept = accept;\n input.onchange = (e) => {\n const file = (e.target as HTMLInputElement).files?.[0];\n if (file) {\n onFile(file);\n input.value = '';\n }\n };\n input.click();\n },\n processImage: ({ source, maxWidth, maxHeight, onComplete }) => {\n const canvas = canvasRef.current;\n if (!canvas || !canvas.getContext) return;\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n const img = new Image();\n img.crossOrigin = 'Anonymous';\n img.onload = () => {\n let { naturalWidth: width, naturalHeight: height } = img;\n\n // --- SCALING LOGIC ---\n // Calculate the scale factor to fit within maxWidth and maxHeight\n const scaleX = maxWidth ? maxWidth / width : 1;\n const scaleY = maxHeight ? maxHeight / height : 1;\n const scaleFactor = Math.min(scaleX, scaleY, 1); // Ensure we don't scale up\n\n const finalWidth = width * scaleFactor;\n const finalHeight = height * scaleFactor;\n\n canvas.width = finalWidth;\n canvas.height = finalHeight;\n ctx.drawImage(img, 0, 0, finalWidth, finalHeight);\n\n const imageData = ctx.getImageData(0, 0, finalWidth, finalHeight);\n if (typeof source !== 'string') URL.revokeObjectURL(img.src);\n\n onComplete({ imageData, width: finalWidth, height: finalHeight });\n };\n img.src = typeof source === 'string' ? source : URL.createObjectURL(source);\n },\n }),\n [],\n );\n\n useEffect(() => {\n if (!annotationPlugin) return;\n\n return annotationPlugin.registerPageHandlers(documentId, pageIndex, scale, {\n services,\n onPreview: (toolId, state) => {\n setPreviews((prev) => {\n const next = new Map(prev);\n if (state) {\n next.set(toolId, state);\n } else {\n next.delete(toolId);\n }\n return next;\n });\n },\n });\n }, [documentId, pageIndex, scale, annotationPlugin, services]);\n\n return (\n <>\n {/* Hidden DOM elements required by services */}\n <input ref={fileInputRef} type=\"file\" style={{ display: 'none' }} />\n <canvas ref={canvasRef} style={{ display: 'none' }} />\n\n {/* Render any active previews from any tool */}\n {Array.from(previews.entries()).map(([toolId, preview]) => (\n <PreviewRenderer key={toolId} preview={preview} scale={scale} />\n ))}\n </>\n );\n}\n","import { createPluginPackage } from '@embedpdf/core';\nimport { AnnotationPluginPackage as BaseAnnotationPackage } from '@embedpdf/plugin-annotation';\nimport { AnnotationRendererProvider } from './context/renderer-registry';\n\nexport * from './hooks';\nexport * from './components';\nexport * from './components/types';\nexport * from './context';\nexport * from '@embedpdf/plugin-annotation';\n\n// Automatically wrap with AnnotationRendererProvider\nexport const AnnotationPluginPackage = createPluginPackage(BaseAnnotationPackage)\n .addWrapper(AnnotationRendererProvider)\n .build();\n","import { HTMLAttributes, CSSProperties, useMemo } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { Annotations } from './annotations';\nimport { TextMarkup } from './text-markup';\nimport {\n ResizeHandleUI,\n VertexHandleUI,\n CustomAnnotationRenderer,\n AnnotationSelectionMenuRenderFn,\n GroupSelectionMenuRenderFn,\n BoxedAnnotationRenderer,\n} from './types';\nimport { AnnotationPaintLayer } from './annotation-paint-layer';\nimport { PdfAnnotationObject, Rotation } from '@embedpdf/models';\nimport { useRegisteredRenderers } from '../context/renderer-registry';\n\ntype AnnotationLayerProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n /** The ID of the document that this layer displays annotations for */\n documentId: string;\n pageIndex: number;\n scale?: number;\n rotation?: number;\n /** Customize selection menu across all annotations on this layer */\n selectionMenu?: AnnotationSelectionMenuRenderFn;\n /** Customize group selection menu across all annotations on this layer */\n groupSelectionMenu?: GroupSelectionMenuRenderFn;\n style?: CSSProperties;\n /** Customize resize handles */\n resizeUI?: ResizeHandleUI;\n /** Customize vertex handles */\n vertexUI?: VertexHandleUI;\n /** Customize selection outline color */\n selectionOutlineColor?: string;\n /** Customize annotation renderer */\n customAnnotationRenderer?: CustomAnnotationRenderer<PdfAnnotationObject>;\n /** Custom renderers for specific annotation types (provided by external plugins) */\n annotationRenderers?: BoxedAnnotationRenderer[];\n};\n\nexport function AnnotationLayer({\n style,\n documentId,\n pageIndex,\n scale: overrideScale,\n rotation: overrideRotation,\n selectionMenu,\n groupSelectionMenu,\n resizeUI,\n vertexUI,\n selectionOutlineColor,\n customAnnotationRenderer,\n annotationRenderers,\n ...props\n}: AnnotationLayerProps) {\n const documentState = useDocumentState(documentId);\n const page = documentState?.document?.pages?.[pageIndex];\n const width = page?.size?.width ?? 0;\n const height = page?.size?.height ?? 0;\n\n // Auto-load renderers from context\n const contextRenderers = useRegisteredRenderers();\n\n // Merge: context + explicit props (props take precedence by id)\n const allRenderers = useMemo(() => {\n const merged = [...contextRenderers];\n for (const renderer of annotationRenderers ?? []) {\n const idx = merged.findIndex((r) => r.id === renderer.id);\n if (idx >= 0) merged[idx] = renderer;\n else merged.push(renderer);\n }\n return merged;\n }, [contextRenderers, annotationRenderers]);\n\n const actualScale = useMemo(() => {\n if (overrideScale !== undefined) return overrideScale;\n return documentState?.scale ?? 1;\n }, [overrideScale, documentState?.scale]);\n\n const actualRotation = useMemo(() => {\n if (overrideRotation !== undefined) return overrideRotation;\n return documentState?.rotation ?? Rotation.Degree0;\n }, [overrideRotation, documentState?.rotation]);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n <Annotations\n documentId={documentId}\n selectionMenu={selectionMenu}\n groupSelectionMenu={groupSelectionMenu}\n pageIndex={pageIndex}\n scale={actualScale}\n rotation={actualRotation}\n pageWidth={width}\n pageHeight={height}\n resizeUI={resizeUI}\n vertexUI={vertexUI}\n selectionOutlineColor={selectionOutlineColor}\n customAnnotationRenderer={customAnnotationRenderer}\n annotationRenderers={allRenderers}\n />\n <TextMarkup documentId={documentId} pageIndex={pageIndex} scale={actualScale} />\n <AnnotationPaintLayer documentId={documentId} pageIndex={pageIndex} scale={actualScale} />\n </div>\n );\n}\n","import { PdfAnnotationObject } from '@embedpdf/models';\nimport { TrackedAnnotation } from '@embedpdf/plugin-annotation';\nimport {\n HandleElementProps,\n SelectionMenuPropsBase,\n SelectionMenuRenderFn,\n} from '@embedpdf/utils/@framework';\nimport { JSX, MouseEvent, TouchEvent } from '@framework';\n\nexport type ResizeDirection = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'none';\n\nexport interface AnnotationSelectionContext {\n type: 'annotation';\n annotation: TrackedAnnotation;\n pageIndex: number;\n}\n\nexport type AnnotationSelectionMenuProps = SelectionMenuPropsBase<AnnotationSelectionContext>;\nexport type AnnotationSelectionMenuRenderFn = SelectionMenuRenderFn<AnnotationSelectionContext>;\n\nexport interface GroupSelectionContext {\n type: 'group';\n annotations: TrackedAnnotation[];\n pageIndex: number;\n}\n\nexport type GroupSelectionMenuProps = SelectionMenuPropsBase<GroupSelectionContext>;\nexport type GroupSelectionMenuRenderFn = SelectionMenuRenderFn<GroupSelectionContext>;\n\nexport type HandleProps = HandleElementProps & {\n backgroundColor?: string;\n};\n\n/** UI customization for resize handles */\nexport interface ResizeHandleUI {\n /** Handle size in CSS px (default: 12) */\n size?: number;\n /** Default background color for the handle (used by default renderer) */\n color?: string;\n /** Custom renderer for each handle (overrides default) */\n component?: (p: HandleProps) => JSX.Element;\n}\n\n/** UI customization for vertex handles */\nexport interface VertexHandleUI {\n /** Handle size in CSS px (default: 12) */\n size?: number;\n /** Default background color for the handle (used by default renderer) */\n color?: string;\n /** Custom renderer for each vertex (overrides default) */\n component?: (p: HandleProps) => JSX.Element;\n}\n\n/**\n * Props for the custom annotation renderer\n */\nexport interface CustomAnnotationRendererProps<T extends PdfAnnotationObject> {\n annotation: T;\n children: JSX.Element;\n isSelected: boolean;\n scale: number;\n rotation: number;\n pageWidth: number;\n pageHeight: number;\n pageIndex: number;\n onSelect: (event: any) => void;\n}\n\n/**\n * Custom renderer for an annotation\n */\nexport type CustomAnnotationRenderer<T extends PdfAnnotationObject> = (\n props: CustomAnnotationRendererProps<T>,\n) => JSX.Element | null;\n\n/**\n * Props for an annotation renderer entry\n */\nexport interface AnnotationRendererProps<T extends PdfAnnotationObject> {\n annotation: TrackedAnnotation<T>;\n isSelected: boolean;\n scale: number;\n pageIndex: number;\n onClick: (e: MouseEvent<Element> | TouchEvent<Element>) => void;\n}\n\n/**\n * Entry for a custom annotation renderer that handles specific annotation types.\n * This allows external plugins to provide their own rendering for annotation subtypes.\n * Used at definition time for type safety.\n */\nexport interface AnnotationRendererEntry<T extends PdfAnnotationObject = PdfAnnotationObject> {\n /** Unique identifier for this renderer (usually matches tool id) */\n id: string;\n\n /** Returns true if this renderer should handle the annotation */\n matches: (annotation: PdfAnnotationObject) => annotation is T;\n\n /** The component to render the annotation */\n render: (props: AnnotationRendererProps<T>) => JSX.Element;\n}\n\n/**\n * Props passed to tryRender (everything except annotation which is passed separately)\n */\nexport type BoxedRendererProps = Omit<AnnotationRendererProps<PdfAnnotationObject>, 'annotation'>;\n\n/**\n * Boxed renderer that encapsulates type safety internally.\n * The generic is erased - this is what the registry actually stores.\n */\nexport interface BoxedAnnotationRenderer {\n /** Unique identifier for this renderer */\n id: string;\n\n /** Combined match + render: returns null if doesn't match, JSX.Element if it does */\n tryRender: (annotation: TrackedAnnotation, props: BoxedRendererProps) => JSX.Element | null;\n}\n\n/**\n * Creates a boxed renderer from a typed entry.\n * Type safety is enforced at definition time, then erased for storage.\n */\nexport function createRenderer<T extends PdfAnnotationObject>(\n entry: AnnotationRendererEntry<T>,\n): BoxedAnnotationRenderer {\n return {\n id: entry.id,\n tryRender: (annotation, props) => {\n if (entry.matches(annotation.object)) {\n return entry.render({\n ...props,\n annotation: annotation as TrackedAnnotation<T>,\n });\n }\n return null;\n },\n };\n}\n"],"names":["suppressContentEditableWarningProps","suppressContentEditableWarning","RegisterContext","createContext","RenderersContext","AnnotationRendererProvider","children","renderers","setRenderers","useState","register","useCallback","entries","prev","ids","Set","map","e","id","filter","r","has","some","jsx","Provider","value","useRegisteredRenderers","useContext","useAnnotationPlugin","usePlugin","AnnotationPlugin","useAnnotationCapability","useCapability","AnnotationContainer","scale","documentId","pageIndex","rotation","pageWidth","pageHeight","trackedAnnotation","isSelected","isMultiSelected","isDraggable","isResizable","lockAspectRatio","style","vertexConfig","selectionMenu","outlineOffset","onDoubleClick","onSelect","zIndex","resizeUI","vertexUI","selectionOutlineColor","customAnnotationRenderer","groupSelectionMenu","_groupSelectionMenu","annotationRenderers","_annotationRenderers","props","preview","setPreview","object","provides","annotationCapability","plugin","canModifyAnnotations","useDocumentPermissions","gestureBaseRef","useRef","effectiveIsDraggable","effectiveIsResizable","annotationProvides","useMemo","forDocument","currentObject","HANDLE_COLOR","color","VERTEX_COLOR","HANDLE_SIZE","size","VERTEX_SIZE","gestureBaseRectRef","handleUpdate","event","_a","transformData","type","changes","metadata","pageSize","width","height","state","current","rect","startDrag","annotationIds","startResize","resizeHandle","handle","delta","x","origin","y","updateDrag","updateResize","vertices","base","vertexChanges","transformAnnotation","patched","updateAnnotation","commitDrag","commitResize","dragProps","resize","useInteractionHandles","controller","element","extractVertices","constraints","minWidth","minHeight","boundingBox","maintainAspectRatio","pageRotation","enabled","onUpdate","handleSize","spacing","offsetMode","includeSides","vertexSize","includeVertices","guardedOnDoubleClick","doubleProps","useDoublePressProps","useEffect","handleEvent","patch","previewPatches","unsubs","onDragChange","onResizeChange","forEach","u","showOutline","jsxs","position","left","top","outline","pointerEvents","touchAction","cursor","childrenRender","customRender","annotation","key","hProps","component","backgroundColor","vProps","CounterRotate","counterRotateProps","context","selected","placement","suggestTop","GroupSelectionBox","selectedAnnotations","isDraggingRef","isResizingRef","groupBox","rects","ta","boundingRectOrEmpty","previewGroupBox","setPreviewGroupBox","transformType","isMove","isResize","_b","newRect","rawDelta","clampedDelta","newGroupBox","length","onPointerDown","stopPropagation","annotations","Highlight","strokeColor","opacity","segmentRects","onClick","resolvedColor","Fragment","b","i","onTouchStart","background","Underline","thickness","bottom","Strikeout","transform","Squiggly","amplitude","period","svgDataUri","encodeURIComponent","backgroundImage","backgroundRepeat","backgroundSize","Ink","strokeWidth","inkList","paths","points","d","lx","ly","trim","overflow","viewBox","fill","stroke","strokeLinecap","strokeLinejoin","Square","strokeStyle","PdfAnnotationBorderStyle","SOLID","strokeDashArray","outerW","outerH","Math","max","svgWidth","svgHeight","DASHED","strokeDasharray","join","Circle","cx","cy","rx","ry","innerW","innerH","Line","linePoints","lineEndings","x1","y1","x2","y2","start","end","endings","angle","atan2","patching","createEnding","PI","filled","Polyline","localPts","pathData","first","rest","p","toAngle","a","startRad","endRad","Polygon","currentVertex","allPoints","isPreview","isPreviewing","FreeText","isEditing","editorRef","isIOS","setIsIOS","editor","focus","selection","window","getSelection","range","document","createRange","selectNodeContents","collapse","removeAllRanges","addRange","useLayoutEffect","nav","navigator","ios","test","userAgent","platform","maxTouchPoints","computedFontPx","fontSize","needsComp","adjustedFontPx","scaleComp","invScalePercent","ref","onBlur","contents","innerText","tabIndex","fontColor","fontFamily","standardFontCss","textAlign","textAlignmentToCss","flexDirection","justifyContent","verticalAlign","PdfVerticalAlignment","Top","Middle","display","lineHeight","transformOrigin","contentEditable","RenderAnnotation","scaleFactor","imageUrl","setImageUrl","urlRef","task","renderAnnotation","options","dpr","devicePixelRatio","wait","blob","url","URL","createObjectURL","ignore","revokeObjectURL","abort","code","PdfErrorCode","Cancelled","message","src","onLoad","Stamp","Link","UNDERLINE","hasIRT","dashArray","isUnderline","Annotations","annotationsProps","selectionProvides","useSelectionCapability","setAnnotations","usePointerHandlers","allSelectedIds","setAllSelectedIds","editingId","setEditingId","currentState","getState","getAnnotationsByPageIndex","getSelectedAnnotationIds","onStateChange","handlers","_","pe","target","currentTarget","deselectAnnotation","handleClick","clear","metaKey","ctrlKey","toggleSelection","selectAnnotation","handleLinkClick","inReplyToId","parentId","parent","find","selectedAnnotationsOnPage","anno","includes","areAllSelectedDraggable","every","tool","findToolForAnnotation","groupDraggable","resolveInteractionProp","interaction","isGroupDraggable","singleDraggable","areAllSelectedResizable","groupResizable","isGroupResizable","singleResizable","allSelectedOnSamePage","allSelected","getSelectedAnnotations","renderer","tryRender","mixBlendMode","blendModeToCss","blendMode","PdfBlendMode","Normal","isInk","obj","isSquare","isCircle","isStrikeout","isSquiggly","isHighlight","Multiply","isLine","isPolyline","isPolygon","isFreeText","isStamp","_object","isLink","TextMarkup","setRects","boundingRect","setBoundingRect","activeTool","setActiveTool","onSelectionChange","getHighlightRectsForPage","getBoundingRectForPage","getActiveTool","onActiveToolChange","defaults","PdfAnnotationSubtype","inset","_c","HIGHLIGHT","_d","_e","_f","STRIKEOUT","_g","_h","_i","SQUIGGLY","_j","_k","_l","PreviewRenderer","bounds","CIRCLE","data","SQUARE","POLYGON","POLYLINE","LINE","INK","FREETEXT","border","AnnotationPaintLayer","annotationPlugin","previews","setPreviews","Map","fileInputRef","canvasRef","services","requestFile","accept","onFile","input","onchange","file","files","click","processImage","source","maxWidth","maxHeight","onComplete","canvas","getContext","ctx","img","Image","crossOrigin","onload","naturalWidth","naturalHeight","scaleX","scaleY","min","finalWidth","finalHeight","drawImage","imageData","getImageData","registerPageHandlers","onPreview","toolId","next","set","delete","Array","from","AnnotationPluginPackage","createPluginPackage","BaseAnnotationPackage","addWrapper","build","overrideScale","overrideRotation","documentState","useDocumentState","page","pages","contextRenderers","allRenderers","merged","idx","findIndex","push","actualScale","actualRotation","Rotation","Degree0","entry","matches","render","setState","initialDocumentState","scope","newState","renderersRef"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/react/adapter.ts","../../src/shared/context/renderer-registry.tsx","../../src/shared/hooks/use-annotation.ts","../../src/shared/components/annotation-container.tsx","../../src/shared/components/group-selection-box.tsx","../../src/shared/components/text-markup/highlight.tsx","../../src/shared/components/text-markup/underline.tsx","../../src/shared/components/text-markup/strikeout.tsx","../../src/shared/components/text-markup/squiggly.tsx","../../src/shared/components/annotations/ink.tsx","../../src/shared/components/annotations/square.tsx","../../src/shared/components/annotations/circle.tsx","../../src/shared/components/annotations/line.tsx","../../src/shared/components/annotations/polyline.tsx","../../src/shared/components/annotations/polygon.tsx","../../src/shared/components/annotations/free-text.tsx","../../src/shared/components/render-annotation.tsx","../../src/shared/components/annotations/stamp.tsx","../../src/shared/components/annotations/link.tsx","../../src/shared/components/annotations.tsx","../../src/shared/components/text-markup.tsx","../../src/shared/components/preview-renderer.tsx","../../src/shared/components/annotation-paint-layer.tsx","../../src/shared/index.ts","../../src/shared/components/annotation-layer.tsx","../../src/shared/components/types.ts"],"sourcesContent":["export {\n Fragment,\n useEffect,\n useRef,\n useState,\n useCallback,\n useMemo,\n useLayoutEffect,\n createContext,\n useContext,\n JSX,\n ChangeEvent,\n} from 'react';\nexport type {\n ReactNode,\n HTMLAttributes,\n CSSProperties,\n MouseEvent,\n PointerEvent,\n TouchEvent,\n} from 'react';\n\nexport const suppressContentEditableWarningProps = {\n suppressContentEditableWarning: true,\n};\n","import {\n createContext,\n useContext,\n useState,\n useCallback,\n useRef,\n useEffect,\n ReactNode,\n} from '@framework';\nimport { BoxedAnnotationRenderer } from '../components/types';\n\n// Separate contexts: register function is stable, renderers list changes\ntype RegisterFn = (entries: BoxedAnnotationRenderer[]) => () => void;\n\nconst RegisterContext = createContext<RegisterFn | null>(null);\nconst RenderersContext = createContext<BoxedAnnotationRenderer[]>([]);\n\nexport function AnnotationRendererProvider({ children }: { children: ReactNode }) {\n const [renderers, setRenderers] = useState<BoxedAnnotationRenderer[]>([]);\n\n // Stable reference - no dependencies\n const register = useCallback((entries: BoxedAnnotationRenderer[]) => {\n setRenderers((prev) => {\n const ids = new Set(entries.map((e) => e.id));\n return [...prev.filter((r) => !ids.has(r.id)), ...entries];\n });\n return () => setRenderers((prev) => prev.filter((r) => !entries.some((e) => e.id === r.id)));\n }, []);\n\n return (\n <RegisterContext.Provider value={register}>\n <RenderersContext.Provider value={renderers}>{children}</RenderersContext.Provider>\n </RegisterContext.Provider>\n );\n}\n\n/**\n * Hook to register annotation renderers. Handles all registration lifecycle internally.\n * Plugin authors just call this with their renderers array.\n */\nexport function useRegisterRenderers(renderers: BoxedAnnotationRenderer[]) {\n const register = useContext(RegisterContext);\n const renderersRef = useRef(renderers);\n\n useEffect(() => {\n if (!register) return;\n return register(renderersRef.current);\n }, [register]);\n}\n\n/**\n * Hook to get all registered renderers (for rendering components).\n */\nexport function useRegisteredRenderers(): BoxedAnnotationRenderer[] {\n return useContext(RenderersContext);\n}\n\n/**\n * Low-level hook if someone needs direct access to register function.\n * Most plugins should use useRegisterRenderers instead.\n */\nexport function useRendererRegistry() {\n return useContext(RegisterContext);\n}\n","import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {\n AnnotationPlugin,\n AnnotationDocumentState,\n initialDocumentState,\n} from '@embedpdf/plugin-annotation';\nimport { useState, useEffect } from '@framework';\n\nexport const useAnnotationPlugin = () => usePlugin<AnnotationPlugin>(AnnotationPlugin.id);\nexport const useAnnotationCapability = () => useCapability<AnnotationPlugin>(AnnotationPlugin.id);\n\n/**\n * Hook for annotation state for a specific document\n * @param documentId Document ID\n */\nexport const useAnnotation = (documentId: string) => {\n const { provides } = useAnnotationCapability();\n const [state, setState] = useState<AnnotationDocumentState>(\n provides?.forDocument(documentId)?.getState() ?? initialDocumentState(),\n );\n\n useEffect(() => {\n if (!provides) return;\n\n const scope = provides.forDocument(documentId);\n\n // Get initial state\n setState(scope.getState());\n\n // Subscribe to state changes\n return scope.onStateChange((newState) => {\n setState(newState);\n });\n }, [provides, documentId]);\n\n return {\n state,\n provides: provides?.forDocument(documentId) ?? null,\n };\n};\n","import { PdfAnnotationObject, Rect } from '@embedpdf/models';\nimport {\n CounterRotate,\n useDoublePressProps,\n useInteractionHandles,\n} from '@embedpdf/utils/@framework';\nimport { TrackedAnnotation } from '@embedpdf/plugin-annotation';\nimport { useState, JSX, CSSProperties, useRef, useEffect, useMemo, useCallback } from '@framework';\nimport { useDocumentPermissions } from '@embedpdf/core/@framework';\n\nimport { useAnnotationCapability, useAnnotationPlugin } from '../hooks';\nimport {\n CustomAnnotationRenderer,\n ResizeHandleUI,\n AnnotationSelectionMenuRenderFn,\n VertexHandleUI,\n GroupSelectionMenuRenderFn,\n BoxedAnnotationRenderer,\n} from './types';\nimport { VertexConfig } from '../types';\n\ninterface AnnotationContainerProps<T extends PdfAnnotationObject> {\n scale: number;\n documentId: string;\n pageIndex: number;\n rotation: number;\n pageWidth: number;\n pageHeight: number;\n trackedAnnotation: TrackedAnnotation<T>;\n children: JSX.Element | ((annotation: T) => JSX.Element);\n isSelected: boolean;\n /** Whether multiple annotations are selected (container becomes passive) */\n isMultiSelected?: boolean;\n isDraggable: boolean;\n isResizable: boolean;\n lockAspectRatio?: boolean;\n style?: CSSProperties;\n vertexConfig?: VertexConfig<T>;\n selectionMenu?: AnnotationSelectionMenuRenderFn;\n outlineOffset?: number;\n onDoubleClick?: (event: any) => void;\n onSelect: (event: any) => void;\n zIndex?: number;\n resizeUI?: ResizeHandleUI;\n vertexUI?: VertexHandleUI;\n selectionOutlineColor?: string;\n customAnnotationRenderer?: CustomAnnotationRenderer<T>;\n /** Passed from parent but not used - destructured to prevent DOM spread */\n groupSelectionMenu?: GroupSelectionMenuRenderFn;\n /** Passed from parent but not used - destructured to prevent DOM spread */\n annotationRenderers?: BoxedAnnotationRenderer[];\n}\n\n/**\n * AnnotationContainer wraps individual annotations with interaction handles.\n * When isMultiSelected is true, the container becomes passive - drag/resize\n * is handled by the GroupSelectionBox instead.\n */\nexport function AnnotationContainer<T extends PdfAnnotationObject>({\n scale,\n documentId,\n pageIndex,\n rotation,\n pageWidth,\n pageHeight,\n trackedAnnotation,\n children,\n isSelected,\n isMultiSelected = false,\n isDraggable,\n isResizable,\n lockAspectRatio = false,\n style = {},\n vertexConfig,\n selectionMenu,\n outlineOffset = 1,\n onDoubleClick,\n onSelect,\n zIndex = 1,\n resizeUI,\n vertexUI,\n selectionOutlineColor = '#007ACC',\n customAnnotationRenderer,\n // Destructure props that shouldn't be passed to DOM elements\n groupSelectionMenu: _groupSelectionMenu,\n annotationRenderers: _annotationRenderers,\n ...props\n}: AnnotationContainerProps<T>): JSX.Element {\n const [preview, setPreview] = useState<T>(trackedAnnotation.object);\n const { provides: annotationCapability } = useAnnotationCapability();\n const { plugin } = useAnnotationPlugin();\n const { canModifyAnnotations } = useDocumentPermissions(documentId);\n const gestureBaseRef = useRef<T | null>(null);\n\n // When multi-selected, disable individual drag/resize - GroupSelectionBox handles it\n const effectiveIsDraggable = canModifyAnnotations && isDraggable && !isMultiSelected;\n const effectiveIsResizable = canModifyAnnotations && isResizable && !isMultiSelected;\n // Get scoped API for this document\n const annotationProvides = useMemo(\n () => (annotationCapability ? annotationCapability.forDocument(documentId) : null),\n [annotationCapability, documentId],\n );\n\n const currentObject = preview\n ? { ...trackedAnnotation.object, ...preview }\n : trackedAnnotation.object;\n\n // UI constants\n const HANDLE_COLOR = resizeUI?.color ?? '#007ACC';\n const VERTEX_COLOR = vertexUI?.color ?? '#007ACC';\n const HANDLE_SIZE = resizeUI?.size ?? 12;\n const VERTEX_SIZE = vertexUI?.size ?? 12;\n\n // Store original rect at gesture start (only need rect for delta calculation)\n const gestureBaseRectRef = useRef<Rect | null>(null);\n\n // Handle single-annotation drag/resize (only when NOT multi-selected)\n // Uses the unified plugin API - all preview updates come from event subscriptions!\n const handleUpdate = useCallback(\n (\n event: Parameters<\n NonNullable<Parameters<typeof useInteractionHandles>[0]['controller']['onUpdate']>\n >[0],\n ) => {\n if (!event.transformData?.type || isMultiSelected || !plugin) return;\n\n const { type, changes, metadata } = event.transformData;\n const id = trackedAnnotation.object.id;\n const pageSize = { width: pageWidth, height: pageHeight };\n\n // Gesture start - initialize plugin drag/resize\n if (event.state === 'start') {\n gestureBaseRectRef.current = trackedAnnotation.object.rect;\n gestureBaseRef.current = trackedAnnotation.object; // For vertex edit\n if (type === 'move') {\n plugin.startDrag(documentId, { annotationIds: [id], pageSize });\n } else if (type === 'resize') {\n plugin.startResize(documentId, {\n annotationIds: [id],\n pageSize,\n resizeHandle: metadata?.handle ?? 'se',\n });\n }\n }\n\n // Gesture update - call plugin, preview comes from subscription\n if (changes.rect && gestureBaseRectRef.current) {\n if (type === 'move') {\n const delta = {\n x: changes.rect.origin.x - gestureBaseRectRef.current.origin.x,\n y: changes.rect.origin.y - gestureBaseRectRef.current.origin.y,\n };\n plugin.updateDrag(documentId, delta);\n } else if (type === 'resize') {\n plugin.updateResize(documentId, changes.rect);\n }\n }\n\n // Vertex edit - handle directly (no attached link handling needed)\n if (type === 'vertex-edit' && changes.vertices && vertexConfig) {\n const base = gestureBaseRef.current ?? trackedAnnotation.object;\n const vertexChanges = vertexConfig.transformAnnotation(base, changes.vertices);\n const patched = annotationCapability?.transformAnnotation<T>(base, {\n type,\n changes: vertexChanges as Partial<T>,\n metadata,\n });\n if (patched) {\n setPreview((prev) => ({ ...prev, ...patched }));\n if (event.state === 'end') {\n annotationProvides?.updateAnnotation(pageIndex, id, patched);\n }\n }\n }\n\n // Gesture end - commit\n if (event.state === 'end') {\n gestureBaseRectRef.current = null;\n gestureBaseRef.current = null;\n if (type === 'move') plugin.commitDrag(documentId);\n else if (type === 'resize') plugin.commitResize(documentId);\n }\n },\n [\n plugin,\n documentId,\n trackedAnnotation.object,\n pageWidth,\n pageHeight,\n pageIndex,\n isMultiSelected,\n vertexConfig,\n annotationCapability,\n annotationProvides,\n ],\n );\n\n const { dragProps, vertices, resize } = useInteractionHandles({\n controller: {\n element: currentObject.rect,\n vertices: vertexConfig?.extractVertices(currentObject),\n constraints: {\n minWidth: 10,\n minHeight: 10,\n boundingBox: { width: pageWidth, height: pageHeight },\n },\n maintainAspectRatio: lockAspectRatio,\n pageRotation: rotation,\n scale: scale,\n // Disable interaction handles when multi-selected\n enabled: isSelected && !isMultiSelected,\n onUpdate: handleUpdate,\n },\n resizeUI: {\n handleSize: HANDLE_SIZE,\n spacing: outlineOffset,\n offsetMode: 'outside',\n includeSides: lockAspectRatio ? false : true,\n zIndex: zIndex + 1,\n },\n vertexUI: {\n vertexSize: VERTEX_SIZE,\n zIndex: zIndex + 2,\n },\n includeVertices: vertexConfig ? true : false,\n });\n\n // Wrap onDoubleClick to respect permissions\n const guardedOnDoubleClick = useMemo(() => {\n if (!canModifyAnnotations || !onDoubleClick) return undefined;\n return onDoubleClick;\n }, [canModifyAnnotations, onDoubleClick]);\n\n const doubleProps = useDoublePressProps(guardedOnDoubleClick);\n\n // Sync preview with tracked annotation when it changes\n useEffect(() => {\n setPreview(trackedAnnotation.object);\n }, [trackedAnnotation.object]);\n\n // Subscribe to unified drag changes - plugin sends pre-computed patches!\n // ALL preview updates come through here (primary, attached links, multi-select)\n useEffect(() => {\n if (!plugin) return;\n const id = trackedAnnotation.object.id;\n\n const handleEvent = (event: {\n documentId: string;\n type: string;\n previewPatches?: Record<string, any>;\n }) => {\n if (event.documentId !== documentId) return;\n const patch = event.previewPatches?.[id];\n if (event.type === 'update' && patch) setPreview((prev) => ({ ...prev, ...patch }) as T);\n else if (event.type === 'cancel') setPreview(trackedAnnotation.object);\n };\n\n const unsubs = [plugin.onDragChange(handleEvent), plugin.onResizeChange(handleEvent)];\n\n return () => unsubs.forEach((u) => u());\n }, [plugin, documentId, trackedAnnotation.object]);\n\n // Determine if we should show the outline\n // When multi-selected, don't show individual outlines - GroupSelectionBox shows the group outline\n const showOutline = isSelected && !isMultiSelected;\n\n return (\n <div data-no-interaction>\n <div\n {...(effectiveIsDraggable && isSelected ? dragProps : {})}\n {...doubleProps}\n style={{\n position: 'absolute',\n left: currentObject.rect.origin.x * scale,\n top: currentObject.rect.origin.y * scale,\n width: currentObject.rect.size.width * scale,\n height: currentObject.rect.size.height * scale,\n outline: showOutline ? `1px solid ${selectionOutlineColor}` : 'none',\n outlineOffset: showOutline ? `${outlineOffset}px` : '0px',\n pointerEvents: isSelected && !isMultiSelected ? 'auto' : 'none',\n touchAction: 'none',\n cursor: isSelected && effectiveIsDraggable ? 'move' : 'default',\n zIndex,\n ...style,\n }}\n {...props}\n >\n {(() => {\n const childrenRender =\n typeof children === 'function' ? children(currentObject) : children;\n const customRender = customAnnotationRenderer?.({\n annotation: currentObject,\n children: childrenRender,\n isSelected,\n scale,\n rotation,\n pageWidth,\n pageHeight,\n pageIndex,\n onSelect,\n });\n if (customRender !== null && customRender !== undefined) {\n return customRender;\n }\n return childrenRender;\n })()}\n\n {/* Resize handles - only when single-selected */}\n {isSelected &&\n effectiveIsResizable &&\n resize.map(({ key, ...hProps }) =>\n resizeUI?.component ? (\n resizeUI.component({\n key,\n ...hProps,\n backgroundColor: HANDLE_COLOR,\n })\n ) : (\n <div\n key={key}\n {...hProps}\n style={{ ...hProps.style, backgroundColor: HANDLE_COLOR }}\n />\n ),\n )}\n\n {/* Vertex handles - only when single-selected */}\n {isSelected &&\n canModifyAnnotations &&\n !isMultiSelected &&\n vertices.map(({ key, ...vProps }) =>\n vertexUI?.component ? (\n vertexUI.component({\n key,\n ...vProps,\n backgroundColor: VERTEX_COLOR,\n })\n ) : (\n <div\n key={key}\n {...vProps}\n style={{ ...vProps.style, backgroundColor: VERTEX_COLOR }}\n />\n ),\n )}\n </div>\n\n {/* Selection menu - hide when multi-selected */}\n {selectionMenu && !isMultiSelected && (\n <CounterRotate\n rect={{\n origin: {\n x: currentObject.rect.origin.x * scale,\n y: currentObject.rect.origin.y * scale,\n },\n size: {\n width: currentObject.rect.size.width * scale,\n height: currentObject.rect.size.height * scale,\n },\n }}\n rotation={rotation}\n >\n {(counterRotateProps) =>\n selectionMenu({\n ...counterRotateProps,\n context: {\n type: 'annotation',\n annotation: trackedAnnotation,\n pageIndex,\n },\n selected: isSelected,\n placement: {\n suggestTop: false,\n },\n })\n }\n </CounterRotate>\n )}\n </div>\n );\n}\n","import { Rect, boundingRectOrEmpty } from '@embedpdf/models';\nimport { useInteractionHandles, CounterRotate } from '@embedpdf/utils/@framework';\nimport { TrackedAnnotation } from '@embedpdf/plugin-annotation';\nimport { useState, useMemo, useCallback, useRef, useEffect } from '@framework';\nimport { useDocumentPermissions } from '@embedpdf/core/@framework';\n\nimport { useAnnotationPlugin } from '../hooks';\nimport { ResizeHandleUI, GroupSelectionMenuRenderFn } from './types';\n\ninterface GroupSelectionBoxProps {\n documentId: string;\n pageIndex: number;\n scale: number;\n rotation: number;\n pageWidth: number;\n pageHeight: number;\n /** All selected annotations on this page */\n selectedAnnotations: TrackedAnnotation[];\n /** Whether the group is draggable (all annotations must be group-draggable) */\n isDraggable: boolean;\n /** Whether the group is resizable (all annotations must be group-resizable) */\n isResizable: boolean;\n /** Resize handle UI customization */\n resizeUI?: ResizeHandleUI;\n /** Selection outline color */\n selectionOutlineColor?: string;\n /** Outline offset */\n outlineOffset?: number;\n /** Z-index for the group box */\n zIndex?: number;\n /** Group selection menu render function */\n groupSelectionMenu?: GroupSelectionMenuRenderFn;\n}\n\n/**\n * GroupSelectionBox renders a bounding box around all selected annotations\n * with drag and resize handles for group manipulation.\n */\nexport function GroupSelectionBox({\n documentId,\n pageIndex,\n scale,\n rotation,\n pageWidth,\n pageHeight,\n selectedAnnotations,\n isDraggable,\n isResizable,\n resizeUI,\n selectionOutlineColor = '#007ACC',\n outlineOffset = 2,\n zIndex = 100,\n groupSelectionMenu,\n}: GroupSelectionBoxProps): JSX.Element | null {\n const { plugin } = useAnnotationPlugin();\n const { canModifyAnnotations } = useDocumentPermissions(documentId);\n const gestureBaseRef = useRef<Rect | null>(null);\n const isDraggingRef = useRef(false);\n const isResizingRef = useRef(false);\n\n // Check permissions before allowing drag/resize\n const effectiveIsDraggable = canModifyAnnotations && isDraggable;\n const effectiveIsResizable = canModifyAnnotations && isResizable;\n\n // Compute the group bounding box from all selected annotations\n const groupBox = useMemo(() => {\n const rects = selectedAnnotations.map((ta) => ta.object.rect);\n return boundingRectOrEmpty(rects);\n }, [selectedAnnotations]);\n\n // Preview state for the group box during drag/resize\n const [previewGroupBox, setPreviewGroupBox] = useState<Rect>(groupBox);\n\n // Sync preview with actual group box when not dragging/resizing\n useEffect(() => {\n if (!isDraggingRef.current && !isResizingRef.current) {\n setPreviewGroupBox(groupBox);\n }\n }, [groupBox]);\n\n // Handle both drag and resize updates using unified plugin API\n // The plugin handles attached links automatically and commits all patches\n const handleUpdate = useCallback(\n (\n event: Parameters<\n NonNullable<Parameters<typeof useInteractionHandles>[0]['controller']['onUpdate']>\n >[0],\n ) => {\n if (!event.transformData?.type) return;\n if (!plugin) return;\n\n const transformType = event.transformData.type;\n const isMove = transformType === 'move';\n const isResize = transformType === 'resize';\n\n // Skip drag operations if group is not draggable\n if (isMove && !effectiveIsDraggable) return;\n\n if (event.state === 'start') {\n gestureBaseRef.current = groupBox;\n\n if (isMove) {\n isDraggingRef.current = true;\n // Use unified drag API - plugin handles attached links automatically\n plugin.startDrag(documentId, {\n annotationIds: selectedAnnotations.map((ta) => ta.object.id),\n pageSize: { width: pageWidth, height: pageHeight },\n });\n } else if (isResize) {\n isResizingRef.current = true;\n // Use unified resize API - plugin handles attached links automatically\n plugin.startResize(documentId, {\n annotationIds: selectedAnnotations.map((ta) => ta.object.id),\n pageSize: { width: pageWidth, height: pageHeight },\n resizeHandle: event.transformData.metadata?.handle ?? 'se',\n });\n }\n }\n\n const base = gestureBaseRef.current ?? groupBox;\n\n if (isMove && event.transformData.changes.rect) {\n // Calculate delta from original position\n const newRect = event.transformData.changes.rect;\n const rawDelta = {\n x: newRect.origin.x - base.origin.x,\n y: newRect.origin.y - base.origin.y,\n };\n\n // Plugin clamps delta and emits events (attached links receive updates too)\n const clampedDelta = plugin.updateDrag(documentId, rawDelta);\n\n // Update preview group box with clamped delta\n setPreviewGroupBox({\n ...base,\n origin: {\n x: base.origin.x + clampedDelta.x,\n y: base.origin.y + clampedDelta.y,\n },\n });\n } else if (isResize && event.transformData.changes.rect) {\n const newGroupBox = event.transformData.changes.rect;\n\n // Plugin computes rects for all participants and emits events\n plugin.updateResize(documentId, newGroupBox);\n\n // Update preview\n setPreviewGroupBox(newGroupBox);\n }\n\n if (event.state === 'end') {\n gestureBaseRef.current = null;\n\n if (isMove && isDraggingRef.current) {\n isDraggingRef.current = false;\n // Plugin commits all patches (selected + attached links) - no patch building needed!\n plugin.commitDrag(documentId);\n } else if (isResize && isResizingRef.current) {\n isResizingRef.current = false;\n // Plugin commits all patches (selected + attached links) - no patch building needed!\n plugin.commitResize(documentId);\n }\n }\n },\n [\n plugin,\n documentId,\n pageWidth,\n pageHeight,\n groupBox,\n effectiveIsDraggable,\n selectedAnnotations,\n ],\n );\n\n // UI constants\n const HANDLE_COLOR = resizeUI?.color ?? '#007ACC';\n const HANDLE_SIZE = resizeUI?.size ?? 12;\n\n // Use interaction handles for both drag and resize\n const { dragProps, resize } = useInteractionHandles({\n controller: {\n element: previewGroupBox,\n constraints: {\n minWidth: 20,\n minHeight: 20,\n boundingBox: { width: pageWidth, height: pageHeight },\n },\n maintainAspectRatio: false,\n pageRotation: rotation,\n scale: scale,\n enabled: true,\n onUpdate: handleUpdate,\n },\n resizeUI: {\n handleSize: HANDLE_SIZE,\n spacing: outlineOffset,\n offsetMode: 'outside',\n includeSides: true,\n zIndex: zIndex + 1,\n },\n vertexUI: {\n vertexSize: 0,\n zIndex: zIndex,\n },\n includeVertices: false,\n });\n\n // Don't render if less than 2 annotations selected\n if (selectedAnnotations.length < 2) {\n return null;\n }\n\n return (\n <div data-group-selection-box data-no-interaction>\n {/* Group box - draggable only if effectiveIsDraggable is true */}\n <div\n {...(effectiveIsDraggable\n ? dragProps\n : {\n onPointerDown: (e) => e.stopPropagation(),\n })}\n style={{\n position: 'absolute',\n left: previewGroupBox.origin.x * scale,\n top: previewGroupBox.origin.y * scale,\n width: previewGroupBox.size.width * scale,\n height: previewGroupBox.size.height * scale,\n outline: `2px dashed ${selectionOutlineColor}`,\n outlineOffset: outlineOffset - 1,\n cursor: effectiveIsDraggable ? 'move' : 'default',\n touchAction: 'none',\n zIndex,\n }}\n >\n {/* Resize handles */}\n {effectiveIsResizable &&\n resize.map(({ key, ...hProps }) =>\n resizeUI?.component ? (\n resizeUI.component({\n key,\n ...hProps,\n backgroundColor: HANDLE_COLOR,\n })\n ) : (\n <div\n key={key}\n {...hProps}\n style={{ ...hProps.style, backgroundColor: HANDLE_COLOR }}\n />\n ),\n )}\n </div>\n\n {/* Group selection menu */}\n {groupSelectionMenu && (\n <CounterRotate\n rect={{\n origin: {\n x: previewGroupBox.origin.x * scale,\n y: previewGroupBox.origin.y * scale,\n },\n size: {\n width: previewGroupBox.size.width * scale,\n height: previewGroupBox.size.height * scale,\n },\n }}\n rotation={rotation}\n >\n {(counterRotateProps) =>\n groupSelectionMenu({\n ...counterRotateProps,\n context: {\n type: 'group',\n annotations: selectedAnnotations,\n pageIndex,\n },\n selected: true,\n placement: {\n suggestTop: false,\n },\n })\n }\n </CounterRotate>\n )}\n </div>\n );\n}\n","import { CSSProperties, MouseEvent, TouchEvent } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\ntype HighlightProps = {\n /** Stroke/markup color */\n strokeColor?: string;\n opacity?: number;\n segmentRects: Rect[];\n rect?: Rect;\n scale: number;\n onClick?: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n style?: CSSProperties;\n};\n\nexport function Highlight({\n strokeColor,\n opacity = 0.5,\n segmentRects,\n rect,\n scale,\n onClick,\n style,\n}: HighlightProps) {\n const resolvedColor = strokeColor ?? '#FFFF00';\n\n return (\n <>\n {segmentRects.map((b, i) => (\n <div\n key={i}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n position: 'absolute',\n left: (rect ? b.origin.x - rect.origin.x : b.origin.x) * scale,\n top: (rect ? b.origin.y - rect.origin.y : b.origin.y) * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background: resolvedColor,\n opacity: opacity,\n pointerEvents: onClick ? 'auto' : 'none',\n cursor: onClick ? 'pointer' : 'default',\n zIndex: onClick ? 1 : undefined,\n ...style,\n }}\n />\n ))}\n </>\n );\n}\n","import { CSSProperties, MouseEvent, TouchEvent } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\ntype UnderlineProps = {\n /** Stroke/markup color */\n strokeColor?: string;\n opacity?: number;\n segmentRects: Rect[];\n rect?: Rect;\n scale: number;\n onClick?: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n style?: CSSProperties;\n};\n\nexport function Underline({\n strokeColor,\n opacity = 0.5,\n segmentRects,\n rect,\n scale,\n onClick,\n style,\n}: UnderlineProps) {\n const resolvedColor = strokeColor ?? '#FFFF00';\n const thickness = 2 * scale; // 2 CSS px at 100 % zoom\n\n return (\n <>\n {segmentRects.map((r, i) => (\n <div\n key={i}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n position: 'absolute',\n left: (rect ? r.origin.x - rect.origin.x : r.origin.x) * scale,\n top: (rect ? r.origin.y - rect.origin.y : r.origin.y) * scale,\n width: r.size.width * scale,\n height: r.size.height * scale,\n background: 'transparent',\n pointerEvents: onClick ? 'auto' : 'none',\n cursor: onClick ? 'pointer' : 'default',\n zIndex: onClick ? 1 : 0,\n ...style,\n }}\n >\n {/* Visual underline */}\n <div\n style={{\n position: 'absolute',\n left: 0,\n bottom: 0,\n width: '100%',\n height: thickness,\n background: resolvedColor,\n opacity: opacity,\n pointerEvents: 'none',\n }}\n />\n </div>\n ))}\n </>\n );\n}\n","import { CSSProperties, MouseEvent, TouchEvent } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\ntype StrikeoutProps = {\n /** Stroke/markup color */\n strokeColor?: string;\n opacity?: number;\n segmentRects: Rect[];\n rect?: Rect;\n scale: number;\n onClick?: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n style?: CSSProperties;\n};\n\nexport function Strikeout({\n strokeColor,\n opacity = 0.5,\n segmentRects,\n rect,\n scale,\n onClick,\n style,\n}: StrikeoutProps) {\n const resolvedColor = strokeColor ?? '#FFFF00';\n const thickness = 2 * scale;\n\n return (\n <>\n {segmentRects.map((r, i) => (\n <div\n key={i}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n position: 'absolute',\n left: (rect ? r.origin.x - rect.origin.x : r.origin.x) * scale,\n top: (rect ? r.origin.y - rect.origin.y : r.origin.y) * scale,\n width: r.size.width * scale,\n height: r.size.height * scale,\n background: 'transparent',\n pointerEvents: onClick ? 'auto' : 'none',\n cursor: onClick ? 'pointer' : 'default',\n zIndex: onClick ? 1 : 0,\n ...style,\n }}\n >\n {/* Visual strikeout line */}\n <div\n style={{\n position: 'absolute',\n left: 0,\n top: '50%',\n width: '100%',\n height: thickness,\n background: resolvedColor,\n opacity: opacity,\n transform: 'translateY(-50%)',\n pointerEvents: 'none',\n }}\n />\n </div>\n ))}\n </>\n );\n}\n","import { CSSProperties, MouseEvent, TouchEvent } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\ntype SquigglyProps = {\n /** Stroke/markup color */\n strokeColor?: string;\n opacity?: number;\n segmentRects: Rect[];\n rect?: Rect;\n scale: number;\n onClick?: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n style?: CSSProperties;\n};\n\nexport function Squiggly({\n strokeColor,\n opacity = 0.5,\n segmentRects,\n rect,\n scale,\n onClick,\n style,\n}: SquigglyProps) {\n const resolvedColor = strokeColor ?? '#FFFF00';\n const amplitude = 2 * scale; // wave height\n const period = 6 * scale; // wave length\n\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${period}\" height=\"${amplitude * 2}\" viewBox=\"0 0 ${period} ${amplitude * 2}\">\n <path d=\"M0 ${amplitude} Q ${period / 4} 0 ${period / 2} ${amplitude} T ${period} ${amplitude}\"\n fill=\"none\" stroke=\"${resolvedColor}\" stroke-width=\"${amplitude}\" stroke-linecap=\"round\"/>\n </svg>`;\n\n // Completely escape the SVG markup\n const svgDataUri = `url(\"data:image/svg+xml;utf8,${encodeURIComponent(svg)}\")`;\n\n return (\n <>\n {segmentRects.map((r, i) => (\n <div\n key={i}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n position: 'absolute',\n left: (rect ? r.origin.x - rect.origin.x : r.origin.x) * scale,\n top: (rect ? r.origin.y - rect.origin.y : r.origin.y) * scale,\n width: r.size.width * scale,\n height: r.size.height * scale,\n background: 'transparent',\n pointerEvents: onClick ? 'auto' : 'none',\n cursor: onClick ? 'pointer' : 'default',\n zIndex: onClick ? 1 : 0,\n ...style,\n }}\n >\n {/* Visual squiggly line */}\n <div\n style={{\n position: 'absolute',\n left: 0,\n bottom: 0,\n width: '100%',\n height: amplitude * 2,\n backgroundImage: svgDataUri,\n backgroundRepeat: 'repeat-x',\n backgroundSize: `${period}px ${amplitude * 2}px`,\n opacity: opacity,\n pointerEvents: 'none',\n }}\n />\n </div>\n ))}\n </>\n );\n}\n","import { useMemo, MouseEvent, TouchEvent } from '@framework';\nimport { PdfInkListObject, Rect } from '@embedpdf/models';\n\n/* ---------------------------------------------------------------- *\\\n|* Types *|\n\\* ---------------------------------------------------------------- */\n\ninterface InkProps {\n /** Whether the annotation is selected */\n isSelected: boolean;\n /** Stroke color */\n strokeColor?: string;\n /** 0 – 1 */\n opacity?: number;\n /** Line width in PDF units */\n strokeWidth: number;\n /** Array of strokes — exactly as in your JSON */\n inkList: PdfInkListObject[];\n /** Bounding box of the whole annotation */\n rect: Rect;\n /** Page zoom factor */\n scale: number;\n /** Callback for when the annotation is clicked */\n onClick?: (e: MouseEvent<SVGPathElement> | TouchEvent<SVGPathElement>) => void;\n}\n\n/**\n * Renders a PDF Ink annotation (free-hand drawing) as SVG.\n */\nexport function Ink({\n isSelected,\n strokeColor,\n opacity = 1,\n strokeWidth,\n inkList,\n rect,\n scale,\n onClick,\n}: InkProps): JSX.Element {\n const resolvedColor = strokeColor ?? '#000000';\n /* convert each stroke to an SVG <path d=\"\"> string */\n const paths = useMemo(() => {\n return inkList.map(({ points }) => {\n let d = '';\n points.forEach(({ x, y }, i) => {\n // localise to the annotation’s own bbox so viewBox can stay tidy\n const lx = x - rect.origin.x;\n const ly = y - rect.origin.y;\n d += (i === 0 ? 'M' : 'L') + lx + ' ' + ly + ' ';\n });\n return d.trim();\n });\n }, [inkList, rect]);\n\n /* absolute placement + scaling just like your text-markup components */\n const width = rect.size.width * scale;\n const height = rect.size.height * scale;\n\n return (\n <svg\n style={{\n position: 'absolute',\n width,\n height,\n pointerEvents: 'none',\n zIndex: 2,\n overflow: 'visible',\n }}\n width={width}\n height={height}\n viewBox={`0 0 ${rect.size.width} ${rect.size.height}`}\n >\n {paths.map((d, i) => (\n <path\n key={i}\n d={d}\n fill=\"none\"\n opacity={opacity}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n cursor: isSelected ? 'move' : 'pointer',\n pointerEvents: isSelected ? 'none' : 'visibleStroke',\n stroke: resolvedColor,\n strokeWidth: strokeWidth,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n }}\n />\n ))}\n </svg>\n );\n}\n","import { useMemo, MouseEvent, TouchEvent } from '@framework';\nimport { PdfAnnotationBorderStyle, Rect } from '@embedpdf/models';\n\n/* ---------------------------------------------------------------- *\\\n|* Types *|\n\\* ---------------------------------------------------------------- */\n\ninterface SquareProps {\n /** Whether the annotation is selected */\n isSelected: boolean;\n /** Fill colour – defaults to PDFium’s black if omitted */\n color?: string;\n /** Stroke colour – defaults to same as fill when omitted */\n strokeColor?: string;\n /** 0 – 1 */\n opacity?: number;\n /** Stroke width in PDF units */\n strokeWidth: number;\n /** Stroke type – defaults to solid when omitted */\n strokeStyle?: PdfAnnotationBorderStyle;\n /** Stroke dash array – defaults to undefined when omitted */\n strokeDashArray?: number[];\n /** Bounding box of the annotation (PDF units) */\n rect: Rect;\n /** Current page zoom factor */\n scale: number;\n /** Click handler (used for selection) */\n onClick?: (e: MouseEvent<SVGElement> | TouchEvent<SVGElement>) => void;\n}\n\n/**\n * Renders a PDF Square annotation (rectangle) as SVG.\n */\nexport function Square({\n isSelected,\n color = '#000000',\n strokeColor,\n opacity = 1,\n strokeWidth,\n strokeStyle = PdfAnnotationBorderStyle.SOLID,\n strokeDashArray,\n rect,\n scale,\n onClick,\n}: SquareProps): JSX.Element {\n /* ------------------------------------------------------------------ */\n /* geometry helpers */\n /* ------------------------------------------------------------------ */\n const { width, height, x, y } = useMemo(() => {\n // Full bounding box *includes* stroke width.\n const outerW = rect.size.width;\n const outerH = rect.size.height;\n\n // Remove the stroke so the visible fill matches the preview.\n const innerW = Math.max(outerW - strokeWidth, 0);\n const innerH = Math.max(outerH - strokeWidth, 0);\n\n return {\n width: innerW,\n height: innerH,\n x: strokeWidth / 2,\n y: strokeWidth / 2,\n };\n }, [rect, strokeWidth]);\n\n const svgWidth = (width + strokeWidth) * scale;\n const svgHeight = (height + strokeWidth) * scale;\n\n return (\n <svg\n style={{\n position: 'absolute',\n width: svgWidth,\n height: svgHeight,\n pointerEvents: 'none',\n zIndex: 2,\n }}\n width={svgWidth}\n height={svgHeight}\n viewBox={`0 0 ${width + strokeWidth} ${height + strokeWidth}`}\n >\n <rect\n x={x}\n y={y}\n width={width}\n height={height}\n fill={color}\n opacity={opacity}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n cursor: isSelected ? 'move' : 'pointer',\n pointerEvents: isSelected\n ? 'none'\n : color === 'transparent'\n ? 'visibleStroke'\n : 'visible',\n stroke: strokeColor ?? color,\n strokeWidth,\n ...(strokeStyle === PdfAnnotationBorderStyle.DASHED && {\n strokeDasharray: strokeDashArray?.join(','),\n }),\n }}\n />\n </svg>\n );\n}\n","import { useMemo, MouseEvent, TouchEvent } from '@framework';\nimport { PdfAnnotationBorderStyle, Rect } from '@embedpdf/models';\n\n/* ---------------------------------------------------------------- *\\\n|* Types *|\n\\* ---------------------------------------------------------------- */\n\ninterface CircleProps {\n /** Whether the annotation is selected */\n isSelected: boolean;\n /** Fill colour – defaults to PDFium’s black if omitted */\n color?: string;\n /** Stroke colour – defaults to same as fill when omitted */\n strokeColor?: string;\n /** 0 – 1 */\n opacity?: number;\n /** Stroke width in PDF units */\n strokeWidth: number;\n /** Stroke type – defaults to solid when omitted */\n strokeStyle?: PdfAnnotationBorderStyle;\n /** Stroke dash array – defaults to undefined when omitted */\n strokeDashArray?: number[];\n /** Bounding box of the annotation */\n rect: Rect;\n /** Current page zoom factor */\n scale: number;\n /** Click handler (used for selection) */\n onClick?: (e: MouseEvent<SVGElement> | TouchEvent<SVGElement>) => void;\n}\n\n/**\n * Renders a PDF Circle annotation (ellipse) as SVG.\n */\nexport function Circle({\n color = '#000000',\n strokeColor,\n opacity = 1,\n strokeWidth,\n strokeStyle = PdfAnnotationBorderStyle.SOLID,\n strokeDashArray,\n rect,\n scale,\n onClick,\n isSelected,\n}: CircleProps): JSX.Element {\n /* ------------------------------------------------------------------ */\n /* geometry helpers */\n /* ------------------------------------------------------------------ */\n const { width, height, cx, cy, rx, ry } = useMemo(() => {\n // Full bounding box *includes* stroke width.\n const outerW = rect.size.width;\n const outerH = rect.size.height;\n\n // Remove the stroke so the visible fill matches the preview.\n const innerW = Math.max(outerW - strokeWidth, 0);\n const innerH = Math.max(outerH - strokeWidth, 0);\n\n return {\n width: outerW,\n height: outerH,\n // Centre of the fill sits strokeWidth/2 in from the edges\n cx: strokeWidth / 2 + innerW / 2,\n cy: strokeWidth / 2 + innerH / 2,\n rx: innerW / 2,\n ry: innerH / 2,\n };\n }, [rect, strokeWidth]);\n\n const svgWidth = width * scale;\n const svgHeight = height * scale;\n\n return (\n <svg\n style={{\n position: 'absolute',\n width: svgWidth,\n height: svgHeight,\n pointerEvents: 'none',\n zIndex: 2,\n }}\n width={svgWidth}\n height={svgHeight}\n viewBox={`0 0 ${width} ${height}`}\n >\n <ellipse\n cx={cx}\n cy={cy}\n rx={rx}\n ry={ry}\n fill={color}\n opacity={opacity}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n cursor: isSelected ? 'move' : 'pointer',\n pointerEvents: isSelected\n ? 'none'\n : color === 'transparent'\n ? 'visibleStroke'\n : 'visible',\n stroke: strokeColor ?? color,\n strokeWidth,\n ...(strokeStyle === PdfAnnotationBorderStyle.DASHED && {\n strokeDasharray: strokeDashArray?.join(','),\n }),\n }}\n />\n </svg>\n );\n}\n","import { useMemo, MouseEvent, TouchEvent } from '@framework';\nimport { Rect, LinePoints, LineEndings, PdfAnnotationBorderStyle } from '@embedpdf/models';\nimport { patching } from '@embedpdf/plugin-annotation';\n\n/* ---------------------------------------------------------------- *\\\n|* Types *|\n\\* ---------------------------------------------------------------- */\n\ninterface LineProps {\n /** interior colour */\n color?: string;\n /** 0 – 1 */\n opacity?: number;\n /** Stroke width in PDF units */\n strokeWidth: number;\n /** Stroke colour (falls back to PDFium default black) */\n strokeColor?: string;\n /** Stroke style */\n strokeStyle?: PdfAnnotationBorderStyle;\n /** Stroke dash array */\n strokeDashArray?: number[];\n /** Bounding box of the annotation */\n rect: Rect;\n /** Line start / end points (page units) */\n linePoints: LinePoints;\n /** Line endings (eg. OpenArrow / Butt) */\n lineEndings?: LineEndings;\n /** Current page zoom factor */\n scale: number;\n /** Click handler (used for selection) */\n onClick?: (e: MouseEvent<SVGElement> | TouchEvent<SVGElement>) => void;\n /** Whether the annotation is selected */\n isSelected: boolean;\n}\n\n/**\n * Renders a PDF Line annotation as SVG (with arrow/butt endings).\n */\nexport function Line({\n color = 'transparent',\n opacity = 1,\n strokeWidth,\n strokeColor = '#000000',\n strokeStyle = PdfAnnotationBorderStyle.SOLID,\n strokeDashArray,\n rect,\n linePoints,\n lineEndings,\n scale,\n onClick,\n isSelected,\n}: LineProps): JSX.Element {\n /* -------------------------------------------------------------- */\n /* Localise the line within its own bounding box */\n /* -------------------------------------------------------------- */\n const { x1, y1, x2, y2 } = useMemo(() => {\n return {\n x1: linePoints.start.x - rect.origin.x,\n y1: linePoints.start.y - rect.origin.y,\n x2: linePoints.end.x - rect.origin.x,\n y2: linePoints.end.y - rect.origin.y,\n };\n }, [linePoints, rect]);\n\n /* -------------------------------------------------------------- */\n /* Arrow-head path data via shared factory */\n /* -------------------------------------------------------------- */\n const endings = useMemo(() => {\n const angle = Math.atan2(y2 - y1, x2 - x1);\n return {\n start: patching.createEnding(lineEndings?.start, strokeWidth, angle + Math.PI, x1, y1),\n end: patching.createEnding(lineEndings?.end, strokeWidth, angle, x2, y2),\n };\n }, [lineEndings, strokeWidth, x1, y1, x2, y2]);\n\n /* -------------------------------------------------------------- */\n /* Absolute placement + scaling (same pattern as other shapes) */\n /* -------------------------------------------------------------- */\n const width = rect.size.width * scale;\n const height = rect.size.height * scale;\n\n return (\n <svg\n style={{\n position: 'absolute',\n width,\n height,\n pointerEvents: 'none',\n zIndex: 2,\n overflow: 'visible',\n }}\n width={width}\n height={height}\n viewBox={`0 0 ${rect.size.width} ${rect.size.height}`}\n >\n {/* Main line */}\n <line\n x1={x1}\n y1={y1}\n x2={x2}\n y2={y2}\n opacity={opacity}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n cursor: isSelected ? 'move' : 'pointer',\n pointerEvents: isSelected ? 'none' : 'visibleStroke',\n stroke: strokeColor,\n strokeWidth,\n strokeLinecap: 'butt',\n ...(strokeStyle === PdfAnnotationBorderStyle.DASHED && {\n strokeDasharray: strokeDashArray?.join(','),\n }),\n }}\n />\n\n {/* Optional arrowheads / butt caps */}\n {endings.start && (\n <path\n d={endings.start.d}\n transform={endings.start.transform}\n onPointerDown={onClick}\n onTouchStart={onClick}\n stroke={strokeColor}\n style={{\n cursor: isSelected ? 'move' : 'pointer',\n strokeWidth,\n strokeLinecap: 'butt',\n pointerEvents: isSelected ? 'none' : endings.start.filled ? 'visible' : 'visibleStroke',\n ...(strokeStyle === PdfAnnotationBorderStyle.DASHED && {\n strokeDasharray: strokeDashArray?.join(','),\n }),\n }}\n fill={endings.start.filled ? color : 'none'}\n />\n )}\n {endings.end && (\n <path\n d={endings.end.d}\n transform={endings.end.transform}\n stroke={strokeColor}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n cursor: isSelected ? 'move' : 'pointer',\n strokeWidth,\n strokeLinecap: 'butt',\n pointerEvents: isSelected ? 'none' : endings.end.filled ? 'visible' : 'visibleStroke',\n ...(strokeStyle === PdfAnnotationBorderStyle.DASHED && {\n strokeDasharray: strokeDashArray?.join(','),\n }),\n }}\n fill={endings.end.filled ? color : 'none'}\n />\n )}\n </svg>\n );\n}\n","import { MouseEvent, TouchEvent, useMemo } from '@framework';\nimport { Rect, Position, LineEndings } from '@embedpdf/models';\nimport { patching } from '@embedpdf/plugin-annotation';\n\ninterface PolylineProps {\n rect: Rect;\n vertices: Position[];\n color?: string;\n strokeColor?: string;\n opacity?: number;\n strokeWidth: number;\n scale: number;\n isSelected: boolean;\n onClick?: (e: MouseEvent<SVGElement> | TouchEvent<SVGElement>) => void;\n /** Optional start & end endings */\n lineEndings?: LineEndings;\n}\n\nexport function Polyline({\n rect,\n vertices,\n color = 'transparent',\n strokeColor = '#000000',\n opacity = 1,\n strokeWidth,\n scale,\n isSelected,\n onClick,\n lineEndings,\n}: PolylineProps): JSX.Element {\n // Localise vertices to annotation rect\n const localPts = useMemo(\n () => vertices.map(({ x, y }) => ({ x: x - rect.origin.x, y: y - rect.origin.y })),\n [vertices, rect],\n );\n\n // Build path data \"M x0 y0 L x1 y1 ...\"\n const pathData = useMemo(() => {\n if (!localPts.length) return '';\n const [first, ...rest] = localPts;\n return (\n `M ${first.x} ${first.y} ` +\n rest\n .map((p) => `L ${p.x} ${p.y} `)\n .join('')\n .trim()\n );\n }, [localPts]);\n\n // Compute endings (angles from first→second, last-1→last)\n const endings = useMemo(() => {\n if (localPts.length < 2) return { start: null, end: null };\n const toAngle = (a: Position, b: Position) => Math.atan2(b.y - a.y, b.x - a.x);\n\n // Calculate angles in the direction of the line segments\n const startRad = toAngle(localPts[0], localPts[1]); // direction FROM first TO second\n const endRad = toAngle(localPts[localPts.length - 2], localPts[localPts.length - 1]); // direction FROM second-to-last TO last\n\n const start = patching.createEnding(\n lineEndings?.start,\n strokeWidth,\n startRad + Math.PI, // tip points outward from line start\n localPts[0].x,\n localPts[0].y,\n );\n const end = patching.createEnding(\n lineEndings?.end,\n strokeWidth,\n endRad, // tip points in line direction\n localPts[localPts.length - 1].x,\n localPts[localPts.length - 1].y,\n );\n return { start, end };\n }, [localPts, lineEndings, strokeWidth]);\n\n const width = rect.size.width * scale;\n const height = rect.size.height * scale;\n\n return (\n <svg\n style={{\n position: 'absolute',\n width,\n height,\n pointerEvents: 'none',\n zIndex: 2,\n overflow: 'visible',\n }}\n width={width}\n height={height}\n viewBox={`0 0 ${rect.size.width} ${rect.size.height}`}\n >\n <path\n d={pathData}\n onPointerDown={onClick}\n onTouchStart={onClick}\n opacity={opacity}\n style={{\n fill: 'none',\n stroke: strokeColor ?? color,\n strokeWidth,\n cursor: isSelected ? 'move' : 'pointer',\n pointerEvents: isSelected ? 'none' : 'visibleStroke',\n strokeLinecap: 'butt',\n strokeLinejoin: 'miter',\n }}\n />\n {endings.start && (\n <path\n d={endings.start.d}\n transform={endings.start.transform}\n stroke={strokeColor}\n fill={endings.start.filled ? color : 'none'}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n cursor: isSelected ? 'move' : 'pointer',\n strokeWidth,\n pointerEvents: isSelected ? 'none' : endings.start.filled ? 'visible' : 'visibleStroke',\n strokeLinecap: 'butt',\n }}\n />\n )}\n {endings.end && (\n <path\n d={endings.end.d}\n transform={endings.end.transform}\n stroke={strokeColor}\n fill={endings.end.filled ? color : 'none'}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n cursor: isSelected ? 'move' : 'pointer',\n strokeWidth,\n pointerEvents: isSelected ? 'none' : endings.end.filled ? 'visible' : 'visibleStroke',\n strokeLinecap: 'butt',\n }}\n />\n )}\n </svg>\n );\n}\n","import { useMemo, MouseEvent, TouchEvent } from '@framework';\nimport { Rect, Position, PdfAnnotationBorderStyle } from '@embedpdf/models';\n\ninterface PolygonProps {\n rect: Rect;\n vertices: Position[];\n color?: string;\n strokeColor?: string;\n opacity?: number;\n strokeWidth: number;\n strokeStyle?: PdfAnnotationBorderStyle;\n strokeDashArray?: number[];\n scale: number;\n isSelected: boolean;\n onClick?: (e: MouseEvent<SVGElement> | TouchEvent<SVGElement>) => void;\n\n // New optional props for preview rendering\n currentVertex?: Position;\n handleSize?: number;\n}\n\nexport function Polygon({\n rect,\n vertices,\n color = 'transparent',\n strokeColor = '#000000',\n opacity = 1,\n strokeWidth,\n strokeStyle = PdfAnnotationBorderStyle.SOLID,\n strokeDashArray,\n scale,\n isSelected,\n onClick,\n currentVertex, // A preview-only prop\n handleSize = 14, // in CSS pixels\n}: PolygonProps): JSX.Element {\n const allPoints = currentVertex ? [...vertices, currentVertex] : vertices;\n\n const localPts = useMemo(\n () => allPoints.map(({ x, y }) => ({ x: x - rect.origin.x, y: y - rect.origin.y })),\n [allPoints, rect],\n );\n\n const pathData = useMemo(() => {\n if (!localPts.length) return '';\n const [first, ...rest] = localPts;\n const isPreview = !!currentVertex;\n // Don't close the path with 'Z' if it's a preview\n return (\n `M ${first.x} ${first.y} ` +\n rest.map((p) => `L ${p.x} ${p.y}`).join(' ') +\n (isPreview ? '' : ' Z')\n ).trim();\n }, [localPts, currentVertex]);\n\n const isPreviewing = currentVertex && vertices.length > 0;\n\n const width = rect.size.width * scale;\n const height = rect.size.height * scale;\n\n return (\n <svg\n style={{\n position: 'absolute',\n width,\n height,\n pointerEvents: 'none',\n zIndex: 2,\n overflow: 'visible',\n }}\n width={width}\n height={height}\n viewBox={`0 0 ${rect.size.width} ${rect.size.height}`}\n >\n <path\n d={pathData}\n onPointerDown={onClick}\n onTouchStart={onClick}\n opacity={opacity}\n style={{\n fill: currentVertex ? 'none' : color, // No fill during preview\n stroke: strokeColor ?? color,\n strokeWidth,\n cursor: isSelected ? 'move' : 'pointer',\n pointerEvents: isSelected\n ? 'none'\n : color === 'transparent'\n ? 'visibleStroke'\n : 'visible',\n strokeLinecap: 'butt',\n strokeLinejoin: 'miter',\n ...(strokeStyle === PdfAnnotationBorderStyle.DASHED && {\n strokeDasharray: strokeDashArray?.join(','),\n }),\n }}\n />\n {/* --- Preview-only elements --- */}\n {isPreviewing && vertices.length > 1 && (\n <path\n d={`M ${localPts[localPts.length - 1].x} ${localPts[localPts.length - 1].y} L ${localPts[0].x} ${localPts[0].y}`}\n fill=\"none\"\n style={{ stroke: strokeColor, strokeWidth, strokeDasharray: '4,4', opacity: 0.7 }}\n />\n )}\n {isPreviewing && vertices.length >= 2 && (\n <rect\n x={localPts[0].x - handleSize / scale / 2}\n y={localPts[0].y - handleSize / scale / 2}\n width={handleSize / scale}\n height={handleSize / scale}\n fill={strokeColor}\n opacity={0.4}\n stroke={strokeColor}\n strokeWidth={strokeWidth / 2}\n />\n )}\n </svg>\n );\n}\n","import {\n MouseEvent,\n TouchEvent,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n suppressContentEditableWarningProps,\n} from '@framework';\nimport {\n PdfFreeTextAnnoObject,\n PdfVerticalAlignment,\n standardFontCss,\n textAlignmentToCss,\n} from '@embedpdf/models';\nimport { useAnnotationCapability } from '../..';\nimport { TrackedAnnotation } from '@embedpdf/plugin-annotation';\n\ninterface FreeTextProps {\n isSelected: boolean;\n isEditing: boolean;\n annotation: TrackedAnnotation<PdfFreeTextAnnoObject>;\n pageIndex: number;\n scale: number;\n onClick?: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n onDoubleClick?: (event: MouseEvent<HTMLDivElement>) => void;\n}\n\nexport function FreeText({\n isSelected,\n isEditing,\n annotation,\n pageIndex,\n scale,\n onClick,\n}: FreeTextProps) {\n const editorRef = useRef<HTMLSpanElement>(null);\n const { provides: annotationProvides } = useAnnotationCapability();\n const [isIOS, setIsIOS] = useState(false);\n\n useEffect(() => {\n if (isEditing && editorRef.current) {\n const editor = editorRef.current;\n editor.focus();\n\n const selection = window.getSelection();\n if (selection) {\n const range = document.createRange();\n range.selectNodeContents(editor);\n range.collapse(false);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n }\n }, [isEditing]);\n\n useLayoutEffect(() => {\n try {\n const nav = navigator as any;\n const ios =\n /iPad|iPhone|iPod/.test(navigator.userAgent) ||\n (navigator.platform === 'MacIntel' && nav?.maxTouchPoints > 1);\n setIsIOS(ios);\n } catch {\n setIsIOS(false);\n }\n }, []);\n\n const handleBlur = () => {\n if (!annotationProvides) return;\n if (!editorRef.current) return;\n annotationProvides.updateAnnotation(pageIndex, annotation.object.id, {\n contents: editorRef.current.innerText,\n });\n };\n\n // iOS zoom prevention: keep focused font-size >= 16px, visually scale down if needed.\n const computedFontPx = annotation.object.fontSize * scale;\n const MIN_IOS_FOCUS_FONT_PX = 16;\n const needsComp =\n isIOS && isEditing && computedFontPx > 0 && computedFontPx < MIN_IOS_FOCUS_FONT_PX;\n const adjustedFontPx = needsComp ? MIN_IOS_FOCUS_FONT_PX : computedFontPx;\n const scaleComp = needsComp ? computedFontPx / MIN_IOS_FOCUS_FONT_PX : 1;\n const invScalePercent = needsComp ? 100 / scaleComp : 100;\n\n return (\n <div\n style={{\n position: 'absolute',\n width: annotation.object.rect.size.width * scale,\n height: annotation.object.rect.size.height * scale,\n cursor: isSelected && !isEditing ? 'move' : 'default',\n pointerEvents: isSelected && !isEditing ? 'none' : 'auto',\n zIndex: 2,\n }}\n onPointerDown={onClick}\n onTouchStart={onClick}\n >\n <span\n ref={editorRef}\n onBlur={handleBlur}\n tabIndex={0}\n style={{\n color: annotation.object.fontColor,\n fontSize: adjustedFontPx,\n fontFamily: standardFontCss(annotation.object.fontFamily),\n textAlign: textAlignmentToCss(annotation.object.textAlign),\n flexDirection: 'column',\n justifyContent:\n annotation.object.verticalAlign === PdfVerticalAlignment.Top\n ? 'flex-start'\n : annotation.object.verticalAlign === PdfVerticalAlignment.Middle\n ? 'center'\n : 'flex-end',\n display: 'flex',\n backgroundColor: annotation.object.color ?? annotation.object.backgroundColor,\n opacity: annotation.object.opacity,\n width: needsComp ? `${invScalePercent}%` : '100%',\n height: needsComp ? `${invScalePercent}%` : '100%',\n lineHeight: '1.18',\n overflow: 'hidden',\n cursor: isEditing ? 'text' : 'pointer',\n outline: 'none',\n transform: needsComp ? `scale(${scaleComp})` : undefined,\n transformOrigin: 'top left',\n }}\n contentEditable={isEditing}\n {...suppressContentEditableWarningProps}\n >\n {annotation.object.contents}\n </span>\n </div>\n );\n}\n","import { Fragment, HTMLAttributes, CSSProperties, useEffect, useRef, useState } from '@framework';\nimport { AppearanceMode, ignore, PdfAnnotationObject, PdfErrorCode } from '@embedpdf/models';\n\nimport { useAnnotationCapability } from '../hooks/use-annotation';\n\ntype RenderAnnotationProps = Omit<HTMLAttributes<HTMLImageElement>, 'style'> & {\n documentId: string;\n pageIndex: number;\n annotation: PdfAnnotationObject;\n scaleFactor?: number;\n dpr?: number;\n style?: CSSProperties;\n};\n\nexport function RenderAnnotation({\n documentId,\n pageIndex,\n annotation,\n scaleFactor = 1,\n style,\n ...props\n}: RenderAnnotationProps) {\n const { provides: annotationProvides } = useAnnotationCapability();\n const [imageUrl, setImageUrl] = useState<string | null>(null);\n const urlRef = useRef<string | null>(null);\n\n const { width, height } = annotation.rect.size;\n\n useEffect(() => {\n if (annotationProvides) {\n const task = annotationProvides.forDocument(documentId).renderAnnotation({\n pageIndex,\n annotation,\n options: {\n scaleFactor,\n dpr: window.devicePixelRatio,\n },\n });\n task.wait((blob) => {\n const url = URL.createObjectURL(blob);\n setImageUrl(url);\n urlRef.current = url;\n }, ignore);\n\n return () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n } else {\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n }\n }, [pageIndex, scaleFactor, annotationProvides, documentId, annotation.id, width, height]);\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n return (\n <Fragment>\n {imageUrl && (\n <img\n src={imageUrl}\n onLoad={handleImageLoad}\n {...props}\n style={{\n width: '100%',\n height: '100%',\n display: 'block',\n ...(style || {}),\n }}\n />\n )}\n </Fragment>\n );\n}\n","import { MouseEvent, TouchEvent } from '@framework';\nimport { PdfStampAnnoObject } from '@embedpdf/models';\nimport { TrackedAnnotation } from '@embedpdf/plugin-annotation';\nimport { RenderAnnotation } from '../render-annotation';\n\ninterface StampProps {\n isSelected: boolean;\n annotation: TrackedAnnotation<PdfStampAnnoObject>;\n documentId: string;\n pageIndex: number;\n scale: number;\n onClick: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n}\n\nexport function Stamp({\n isSelected,\n annotation,\n documentId,\n pageIndex,\n scale,\n onClick,\n}: StampProps) {\n return (\n <div\n style={{\n position: 'absolute',\n width: '100%',\n height: '100%',\n zIndex: 2,\n pointerEvents: isSelected ? 'none' : 'auto',\n cursor: 'pointer',\n }}\n onPointerDown={onClick}\n onTouchStart={onClick}\n >\n <RenderAnnotation\n documentId={documentId}\n pageIndex={pageIndex}\n annotation={{ ...annotation.object, id: annotation.object.id }}\n scaleFactor={scale}\n />\n </div>\n );\n}\n","import { useMemo, MouseEvent, TouchEvent } from '@framework';\nimport { PdfAnnotationBorderStyle, Rect } from '@embedpdf/models';\n\n/* ---------------------------------------------------------------- *\\\n|* Types *|\n\\* ---------------------------------------------------------------- */\n\ninterface LinkProps {\n /** Whether the annotation is selected */\n isSelected: boolean;\n /** Stroke colour – defaults to blue when omitted */\n strokeColor?: string;\n /** Stroke width in PDF units */\n strokeWidth?: number;\n /** Stroke type – defaults to underline when omitted */\n strokeStyle?: PdfAnnotationBorderStyle;\n /** Stroke dash array – for dashed style */\n strokeDashArray?: number[];\n /** Bounding box of the annotation (PDF units) */\n rect: Rect;\n /** Current page zoom factor */\n scale: number;\n /** Click handler (used for selection) */\n onClick?: (e: MouseEvent<SVGElement> | TouchEvent<SVGElement>) => void;\n /** Whether this link has an IRT (In Reply To) reference - disables direct interaction */\n hasIRT?: boolean;\n}\n\n/**\n * Renders a PDF Link annotation as SVG.\n * Supports underline (default), solid, and dashed border styles.\n */\nexport function Link({\n isSelected,\n strokeColor = '#0000FF',\n strokeWidth = 2,\n strokeStyle = PdfAnnotationBorderStyle.UNDERLINE,\n strokeDashArray,\n rect,\n scale,\n onClick,\n hasIRT = false,\n}: LinkProps): JSX.Element {\n const { width, height } = useMemo(() => {\n return {\n width: rect.size.width,\n height: rect.size.height,\n };\n }, [rect]);\n\n const svgWidth = width * scale;\n const svgHeight = height * scale;\n\n // Calculate dash array for SVG\n const dashArray = useMemo(() => {\n if (strokeStyle === PdfAnnotationBorderStyle.DASHED) {\n return strokeDashArray?.join(',') ?? `${strokeWidth * 3},${strokeWidth}`;\n }\n return undefined;\n }, [strokeStyle, strokeDashArray, strokeWidth]);\n\n // For underline style, render a line at the bottom\n // For solid/dashed, render a rectangle border\n const isUnderline = strokeStyle === PdfAnnotationBorderStyle.UNDERLINE;\n\n return (\n <svg\n style={{\n position: 'absolute',\n width: svgWidth,\n height: svgHeight,\n pointerEvents: 'none',\n zIndex: 2,\n }}\n width={svgWidth}\n height={svgHeight}\n viewBox={`0 0 ${width} ${height}`}\n >\n {/* Invisible hit area for the entire link region */}\n {/* IRT links are not directly clickable - interaction goes through parent */}\n <rect\n x={0}\n y={0}\n width={width}\n height={height}\n fill=\"transparent\"\n onPointerDown={hasIRT ? undefined : onClick}\n onTouchStart={hasIRT ? undefined : onClick}\n style={{\n cursor: hasIRT ? 'default' : isSelected ? 'move' : 'pointer',\n pointerEvents: hasIRT ? 'none' : isSelected ? 'none' : 'visible',\n }}\n />\n\n {isUnderline ? (\n // Underline style: line at bottom of rect\n <line\n x1={1}\n y1={height - 1}\n x2={width - 1}\n y2={height - 1}\n stroke={strokeColor}\n strokeWidth={strokeWidth}\n strokeDasharray={dashArray}\n style={{\n pointerEvents: 'none',\n }}\n />\n ) : (\n // Solid/Dashed style: rectangle border\n <rect\n x={strokeWidth / 2}\n y={strokeWidth / 2}\n width={Math.max(width - strokeWidth, 0)}\n height={Math.max(height - strokeWidth, 0)}\n fill=\"transparent\"\n stroke={strokeColor}\n strokeWidth={strokeWidth}\n strokeDasharray={dashArray}\n style={{\n pointerEvents: 'none',\n }}\n />\n )}\n </svg>\n );\n}\n","import { blendModeToCss, PdfAnnotationObject, PdfBlendMode } from '@embedpdf/models';\nimport {\n getAnnotationsByPageIndex,\n getSelectedAnnotationIds,\n isHighlight,\n isInk,\n isSquiggly,\n isCircle,\n isStrikeout,\n isUnderline,\n TrackedAnnotation,\n isSquare,\n isLine,\n isPolyline,\n isPolygon,\n isFreeText,\n isStamp,\n isLink,\n resolveInteractionProp,\n} from '@embedpdf/plugin-annotation';\nimport { PdfLinkAnnoObject } from '@embedpdf/models';\nimport { PointerEventHandlers, EmbedPdfPointerEvent } from '@embedpdf/plugin-interaction-manager';\nimport { usePointerHandlers } from '@embedpdf/plugin-interaction-manager/@framework';\nimport { useSelectionCapability } from '@embedpdf/plugin-selection/@framework';\nimport {\n useMemo,\n useState,\n useEffect,\n useCallback,\n MouseEvent,\n Fragment,\n TouchEvent,\n} from '@framework';\n\nimport { useAnnotationCapability } from '../hooks';\nimport { AnnotationContainer } from './annotation-container';\nimport { GroupSelectionBox } from './group-selection-box';\nimport { Highlight } from './text-markup/highlight';\nimport { Underline } from './text-markup/underline';\nimport { Strikeout } from './text-markup/strikeout';\nimport { Squiggly } from './text-markup/squiggly';\nimport { Ink } from './annotations/ink';\nimport { Square } from './annotations/square';\nimport {\n CustomAnnotationRenderer,\n ResizeHandleUI,\n AnnotationSelectionMenuRenderFn,\n GroupSelectionMenuRenderFn,\n VertexHandleUI,\n BoxedAnnotationRenderer,\n} from './types';\nimport { Circle } from './annotations/circle';\nimport { Line } from './annotations/line';\nimport { Polyline } from './annotations/polyline';\nimport { Polygon } from './annotations/polygon';\nimport { FreeText } from './annotations/free-text';\nimport { Stamp } from './annotations/stamp';\nimport { Link } from './annotations/link';\n\ninterface AnnotationsProps {\n documentId: string;\n pageIndex: number;\n scale: number;\n rotation: number;\n pageWidth: number;\n pageHeight: number;\n selectionMenu?: AnnotationSelectionMenuRenderFn;\n groupSelectionMenu?: GroupSelectionMenuRenderFn;\n resizeUI?: ResizeHandleUI;\n vertexUI?: VertexHandleUI;\n selectionOutlineColor?: string;\n customAnnotationRenderer?: CustomAnnotationRenderer<PdfAnnotationObject>;\n /** Custom renderers for specific annotation types (provided by external plugins) */\n annotationRenderers?: BoxedAnnotationRenderer[];\n}\n\nexport function Annotations(annotationsProps: AnnotationsProps) {\n const { documentId, pageIndex, scale, pageWidth, pageHeight, selectionMenu } = annotationsProps;\n const { provides: annotationCapability } = useAnnotationCapability();\n const { provides: selectionProvides } = useSelectionCapability();\n const [annotations, setAnnotations] = useState<TrackedAnnotation[]>([]);\n const { register } = usePointerHandlers({ documentId, pageIndex });\n const [allSelectedIds, setAllSelectedIds] = useState<string[]>([]);\n const [editingId, setEditingId] = useState<string | null>(null);\n\n // Get scoped API for this document (memoized to prevent infinite loops)\n const annotationProvides = useMemo(\n () => (annotationCapability ? annotationCapability.forDocument(documentId) : null),\n [annotationCapability, documentId],\n );\n\n // Check if multiple annotations are selected\n const isMultiSelected = allSelectedIds.length > 1;\n\n useEffect(() => {\n if (annotationProvides) {\n // Initialize with current state immediately\n const currentState = annotationProvides.getState();\n setAnnotations(getAnnotationsByPageIndex(currentState, pageIndex));\n setAllSelectedIds(getSelectedAnnotationIds(currentState));\n\n // Then subscribe to changes\n return annotationProvides.onStateChange((state) => {\n setAnnotations(getAnnotationsByPageIndex(state, pageIndex));\n setAllSelectedIds(getSelectedAnnotationIds(state));\n });\n }\n }, [annotationProvides, pageIndex]);\n\n const handlers = useMemo(\n (): PointerEventHandlers<EmbedPdfPointerEvent<MouseEvent>> => ({\n onPointerDown: (_, pe) => {\n // Only deselect if clicking directly on the layer (not on an annotation)\n if (pe.target === pe.currentTarget && annotationProvides) {\n annotationProvides.deselectAnnotation();\n setEditingId(null);\n }\n },\n }),\n [annotationProvides],\n );\n\n const handleClick = useCallback(\n (e: MouseEvent | TouchEvent, annotation: TrackedAnnotation) => {\n e.stopPropagation();\n if (annotationProvides && selectionProvides) {\n selectionProvides.clear();\n\n // Check for modifier key (Cmd on Mac, Ctrl on Windows/Linux)\n const isModifierPressed = 'metaKey' in e ? e.metaKey || e.ctrlKey : false;\n\n if (isModifierPressed) {\n // Toggle selection: add or remove from current selection\n annotationProvides.toggleSelection(pageIndex, annotation.object.id);\n } else {\n // Exclusive select: clear and select only this one\n annotationProvides.selectAnnotation(pageIndex, annotation.object.id);\n }\n\n if (annotation.object.id !== editingId) {\n setEditingId(null);\n }\n }\n },\n [annotationProvides, selectionProvides, editingId, pageIndex],\n );\n\n // Special handler for link annotations - if IRT exists, select the parent\n const handleLinkClick = useCallback(\n (e: MouseEvent | TouchEvent, annotation: TrackedAnnotation<PdfLinkAnnoObject>) => {\n e.stopPropagation();\n if (!annotationProvides || !selectionProvides) return;\n\n selectionProvides.clear();\n\n // If link has IRT, select the parent annotation instead\n if (annotation.object.inReplyToId) {\n const parentId = annotation.object.inReplyToId;\n const parent = annotations.find((a) => a.object.id === parentId);\n if (parent) {\n annotationProvides.selectAnnotation(parent.object.pageIndex, parentId);\n return;\n }\n }\n\n // Standalone link - select it directly\n annotationProvides.selectAnnotation(pageIndex, annotation.object.id);\n },\n [annotationProvides, selectionProvides, annotations, pageIndex],\n );\n\n useEffect(() => {\n return register(handlers, {\n documentId,\n });\n }, [register, handlers]);\n // Get selected annotations that are on THIS page (for group selection box)\n const selectedAnnotationsOnPage = useMemo(() => {\n return annotations.filter((anno) => allSelectedIds.includes(anno.object.id));\n }, [annotations, allSelectedIds]);\n\n // Check if all selected annotations on this page are draggable in group context\n const areAllSelectedDraggable = useMemo(() => {\n if (selectedAnnotationsOnPage.length < 2) return false;\n\n return selectedAnnotationsOnPage.every((ta) => {\n const tool = annotationProvides?.findToolForAnnotation(ta.object);\n // Use group-specific property, falling back to single-annotation property\n const groupDraggable = resolveInteractionProp(\n tool?.interaction.isGroupDraggable,\n ta.object,\n true,\n );\n const singleDraggable = resolveInteractionProp(\n tool?.interaction.isDraggable,\n ta.object,\n true,\n );\n return tool?.interaction.isGroupDraggable !== undefined ? groupDraggable : singleDraggable;\n });\n }, [selectedAnnotationsOnPage, annotationProvides]);\n\n // Check if all selected annotations on this page are resizable in group context\n const areAllSelectedResizable = useMemo(() => {\n if (selectedAnnotationsOnPage.length < 2) return false;\n\n return selectedAnnotationsOnPage.every((ta) => {\n const tool = annotationProvides?.findToolForAnnotation(ta.object);\n // Use group-specific property, falling back to single-annotation property\n const groupResizable = resolveInteractionProp(\n tool?.interaction.isGroupResizable,\n ta.object,\n true,\n );\n const singleResizable = resolveInteractionProp(\n tool?.interaction.isResizable,\n ta.object,\n true,\n );\n return tool?.interaction.isGroupResizable !== undefined ? groupResizable : singleResizable;\n });\n }, [selectedAnnotationsOnPage, annotationProvides]);\n\n // Check if all selected annotations are on the same page (this page)\n const allSelectedOnSamePage = useMemo(() => {\n if (!annotationProvides) return false;\n const allSelected = annotationProvides.getSelectedAnnotations();\n // All selected must be on this page\n return allSelected.length > 1 && allSelected.every((ta) => ta.object.pageIndex === pageIndex);\n }, [annotationProvides, pageIndex, allSelectedIds]);\n\n return (\n <>\n {annotations.map((annotation) => {\n const isSelected = allSelectedIds.includes(annotation.object.id);\n const isEditing = editingId === annotation.object.id;\n const tool = annotationProvides?.findToolForAnnotation(annotation.object);\n\n // Check for custom renderer first (from external plugins like redaction)\n for (const renderer of annotationsProps.annotationRenderers ?? []) {\n const element = renderer.tryRender(annotation, {\n isSelected,\n scale,\n pageIndex,\n onClick: (e) => handleClick(e, annotation),\n });\n if (element) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n false,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n false,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {() => element}\n </AnnotationContainer>\n );\n }\n }\n\n if (isInk(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n true,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n true,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Ink\n {...obj}\n isSelected={isSelected}\n scale={scale}\n onClick={(e) => handleClick(e, annotation)}\n />\n )}\n </AnnotationContainer>\n );\n }\n\n if (isSquare(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n true,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n true,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Square\n {...obj}\n isSelected={isSelected}\n scale={scale}\n onClick={(e) => handleClick(e, annotation)}\n />\n )}\n </AnnotationContainer>\n );\n }\n\n if (isCircle(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n true,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n true,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Circle\n {...obj}\n isSelected={isSelected}\n scale={scale}\n onClick={(e) => handleClick(e, annotation)}\n />\n )}\n </AnnotationContainer>\n );\n }\n\n if (isUnderline(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n false,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n false,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n zIndex={0}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Underline {...obj} scale={scale} onClick={(e) => handleClick(e, annotation)} />\n )}\n </AnnotationContainer>\n );\n }\n\n if (isStrikeout(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n false,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n false,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n zIndex={0}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Strikeout {...obj} scale={scale} onClick={(e) => handleClick(e, annotation)} />\n )}\n </AnnotationContainer>\n );\n }\n\n if (isSquiggly(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n false,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n false,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n zIndex={0}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Squiggly {...obj} scale={scale} onClick={(e) => handleClick(e, annotation)} />\n )}\n </AnnotationContainer>\n );\n }\n\n if (isHighlight(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n false,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n false,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n zIndex={0}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Multiply),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Highlight {...obj} scale={scale} onClick={(e) => handleClick(e, annotation)} />\n )}\n </AnnotationContainer>\n );\n }\n\n if (isLine(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n true,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n false,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n vertexConfig={{\n extractVertices: (annotation) => [\n annotation.linePoints.start,\n annotation.linePoints.end,\n ],\n transformAnnotation: (annotation, vertices) => {\n return {\n ...annotation,\n linePoints: {\n start: vertices[0],\n end: vertices[1],\n },\n };\n },\n }}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Fragment>\n <Line\n {...obj}\n isSelected={isSelected}\n scale={scale}\n onClick={(e) => handleClick(e, annotation)}\n />\n </Fragment>\n )}\n </AnnotationContainer>\n );\n }\n\n if (isPolyline(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n true,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n false,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n vertexConfig={{\n extractVertices: (annotation) => annotation.vertices,\n transformAnnotation: (annotation, vertices) => {\n return {\n ...annotation,\n vertices,\n };\n },\n }}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Fragment>\n <Polyline\n {...obj}\n isSelected={isSelected}\n scale={scale}\n onClick={(e) => handleClick(e, annotation)}\n />\n </Fragment>\n )}\n </AnnotationContainer>\n );\n }\n\n if (isPolygon(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n true,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n false,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n vertexConfig={{\n extractVertices: (annotation) => annotation.vertices,\n transformAnnotation: (annotation, vertices) => {\n return {\n ...annotation,\n vertices,\n };\n },\n }}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(obj) => (\n <Fragment>\n <Polygon\n {...obj}\n isSelected={isSelected}\n scale={scale}\n onClick={(e) => handleClick(e, annotation)}\n />\n </Fragment>\n )}\n </AnnotationContainer>\n );\n }\n\n if (isFreeText(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={\n resolveInteractionProp(tool?.interaction.isDraggable, annotation.object, true) &&\n !isEditing\n }\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n true,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n onDoubleClick={(e) => {\n e.stopPropagation();\n setEditingId(annotation.object.id);\n }}\n {...annotationsProps}\n >\n {(object) => (\n <FreeText\n isSelected={isSelected}\n isEditing={isEditing}\n annotation={{\n ...annotation,\n object,\n }}\n pageIndex={pageIndex}\n scale={scale}\n onClick={(e) => handleClick(e, annotation)}\n />\n )}\n </AnnotationContainer>\n );\n }\n\n if (isStamp(annotation)) {\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={resolveInteractionProp(\n tool?.interaction.isDraggable,\n annotation.object,\n true,\n )}\n isResizable={resolveInteractionProp(\n tool?.interaction.isResizable,\n annotation.object,\n true,\n )}\n lockAspectRatio={resolveInteractionProp(\n tool?.interaction.lockAspectRatio,\n annotation.object,\n false,\n )}\n selectionMenu={selectionMenu}\n onSelect={(e) => handleClick(e, annotation)}\n style={{\n mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal),\n }}\n {...annotationsProps}\n >\n {(_object) => (\n <Stamp\n isSelected={isSelected}\n annotation={annotation}\n documentId={documentId}\n pageIndex={pageIndex}\n scale={scale}\n onClick={(e) => handleClick(e, annotation)}\n />\n )}\n </AnnotationContainer>\n );\n }\n\n if (isLink(annotation)) {\n // IRT-linked links are not independently draggable/resizable\n const hasIRT = !!annotation.object.inReplyToId;\n return (\n <AnnotationContainer\n key={annotation.object.id}\n trackedAnnotation={annotation}\n isSelected={isSelected}\n isMultiSelected={isMultiSelected}\n isDraggable={false}\n isResizable={false}\n lockAspectRatio={false}\n selectionMenu={hasIRT ? undefined : selectionMenu}\n onSelect={(e) => handleLinkClick(e, annotation)}\n {...annotationsProps}\n >\n {(obj) => (\n <Link\n {...obj}\n isSelected={isSelected}\n scale={scale}\n onClick={(e) => handleLinkClick(e, annotation)}\n hasIRT={hasIRT}\n />\n )}\n </AnnotationContainer>\n );\n }\n\n /* --------- fallback: an unsupported subtype --------------- */\n return null;\n })}\n\n {/* Group selection box for multi-select drag/resize */}\n {allSelectedOnSamePage && selectedAnnotationsOnPage.length >= 2 && (\n <GroupSelectionBox\n documentId={documentId}\n pageIndex={pageIndex}\n scale={scale}\n rotation={annotationsProps.rotation}\n pageWidth={pageWidth}\n pageHeight={pageHeight}\n selectedAnnotations={selectedAnnotationsOnPage}\n isDraggable={areAllSelectedDraggable}\n isResizable={areAllSelectedResizable}\n resizeUI={annotationsProps.resizeUI}\n selectionOutlineColor={annotationsProps.selectionOutlineColor}\n groupSelectionMenu={annotationsProps.groupSelectionMenu}\n />\n )}\n </>\n );\n}\n","import { blendModeToCss, PdfAnnotationSubtype, PdfBlendMode, Rect } from '@embedpdf/models';\nimport { AnnotationTool } from '@embedpdf/plugin-annotation';\nimport { useSelectionCapability } from '@embedpdf/plugin-selection/@framework';\n\nimport { useEffect, useState } from '@framework';\nimport { useAnnotationCapability } from '../hooks';\nimport { Highlight } from './text-markup/highlight';\nimport { Squiggly } from './text-markup/squiggly';\nimport { Underline } from './text-markup/underline';\nimport { Strikeout } from './text-markup/strikeout';\n\ninterface TextMarkupProps {\n documentId: string;\n pageIndex: number;\n scale: number;\n}\n\nexport function TextMarkup({ documentId, pageIndex, scale }: TextMarkupProps) {\n const { provides: selectionProvides } = useSelectionCapability();\n const { provides: annotationProvides } = useAnnotationCapability();\n const [rects, setRects] = useState<Array<Rect>>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n const [activeTool, setActiveTool] = useState<AnnotationTool | null>(null);\n\n useEffect(() => {\n if (!selectionProvides) return;\n\n return selectionProvides.forDocument(documentId).onSelectionChange(() => {\n setRects(selectionProvides.forDocument(documentId).getHighlightRectsForPage(pageIndex));\n setBoundingRect(selectionProvides.forDocument(documentId).getBoundingRectForPage(pageIndex));\n });\n }, [selectionProvides, documentId, pageIndex]);\n\n useEffect(() => {\n if (!annotationProvides) return;\n\n // Initialize with current active tool\n setActiveTool(annotationProvides.forDocument(documentId).getActiveTool());\n\n return annotationProvides\n .forDocument(documentId)\n .onActiveToolChange((event) => setActiveTool(event));\n }, [annotationProvides, documentId]);\n\n if (!boundingRect) return null;\n if (!activeTool || !activeTool.defaults) return null;\n\n switch (activeTool.defaults.type) {\n case PdfAnnotationSubtype.UNDERLINE:\n return (\n <div\n style={{\n mixBlendMode: blendModeToCss(activeTool.defaults?.blendMode ?? PdfBlendMode.Normal),\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n }}\n >\n <Underline\n strokeColor={activeTool.defaults?.strokeColor}\n opacity={activeTool.defaults?.opacity}\n segmentRects={rects}\n scale={scale}\n />\n </div>\n );\n case PdfAnnotationSubtype.HIGHLIGHT:\n return (\n <div\n style={{\n mixBlendMode: blendModeToCss(activeTool.defaults?.blendMode ?? PdfBlendMode.Multiply),\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n }}\n >\n <Highlight\n strokeColor={activeTool.defaults?.strokeColor}\n opacity={activeTool.defaults?.opacity}\n segmentRects={rects}\n scale={scale}\n />\n </div>\n );\n case PdfAnnotationSubtype.STRIKEOUT:\n return (\n <div\n style={{\n mixBlendMode: blendModeToCss(activeTool.defaults?.blendMode ?? PdfBlendMode.Normal),\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n }}\n >\n <Strikeout\n strokeColor={activeTool.defaults?.strokeColor}\n opacity={activeTool.defaults?.opacity}\n segmentRects={rects}\n scale={scale}\n />\n </div>\n );\n case PdfAnnotationSubtype.SQUIGGLY:\n return (\n <div\n style={{\n mixBlendMode: blendModeToCss(activeTool.defaults?.blendMode ?? PdfBlendMode.Normal),\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n }}\n >\n <Squiggly\n strokeColor={activeTool.defaults?.strokeColor}\n opacity={activeTool.defaults?.opacity}\n segmentRects={rects}\n scale={scale}\n />\n </div>\n );\n default:\n return null;\n }\n}\n","import { AnyPreviewState } from '@embedpdf/plugin-annotation';\nimport { Circle } from './annotations/circle';\nimport { Square } from './annotations/square';\nimport { Polygon } from './annotations/polygon';\nimport { PdfAnnotationSubtype } from '@embedpdf/models';\nimport { Polyline } from './annotations/polyline';\nimport { Line } from './annotations/line';\nimport { Ink } from './annotations/ink';\n\ninterface Props {\n preview: AnyPreviewState;\n scale: number;\n}\n\nexport function PreviewRenderer({ preview, scale }: Props) {\n const { bounds } = preview;\n\n const style = {\n position: 'absolute' as const,\n left: bounds.origin.x * scale,\n top: bounds.origin.y * scale,\n width: bounds.size.width * scale,\n height: bounds.size.height * scale,\n pointerEvents: 'none' as const,\n zIndex: 10,\n };\n\n // Use type guards for proper type narrowing\n if (preview.type === PdfAnnotationSubtype.CIRCLE) {\n return (\n <div style={style}>\n <Circle isSelected={false} scale={scale} {...preview.data} />\n </div>\n );\n }\n\n if (preview.type === PdfAnnotationSubtype.SQUARE) {\n return (\n <div style={style}>\n <Square isSelected={false} scale={scale} {...preview.data} />\n </div>\n );\n }\n\n if (preview.type === PdfAnnotationSubtype.POLYGON) {\n return (\n <div style={style}>\n <Polygon isSelected={false} scale={scale} {...preview.data} />\n </div>\n );\n }\n\n if (preview.type === PdfAnnotationSubtype.POLYLINE) {\n return (\n <div style={style}>\n <Polyline isSelected={false} scale={scale} {...preview.data} />\n </div>\n );\n }\n\n if (preview.type === PdfAnnotationSubtype.LINE) {\n return (\n <div style={style}>\n <Line isSelected={false} scale={scale} {...preview.data} />\n </div>\n );\n }\n\n if (preview.type === PdfAnnotationSubtype.INK) {\n return (\n <div style={style}>\n <Ink isSelected={false} scale={scale} {...preview.data} />\n </div>\n );\n }\n\n if (preview.type === PdfAnnotationSubtype.FREETEXT) {\n return (\n <div style={style}>\n {/* Render a simple dashed border preview */}\n <div\n style={{\n width: '100%',\n height: '100%',\n border: `1px dashed ${preview.data.fontColor || '#000000'}`,\n backgroundColor: 'transparent',\n }}\n />\n </div>\n );\n }\n\n return null;\n}\n","import { useEffect, useMemo, useRef, useState } from '@framework';\nimport { useAnnotationPlugin } from '../hooks';\nimport { AnyPreviewState, HandlerServices } from '@embedpdf/plugin-annotation';\nimport { PreviewRenderer } from './preview-renderer';\n\ninterface Props {\n documentId: string;\n pageIndex: number;\n scale: number;\n}\n\nexport function AnnotationPaintLayer({ documentId, pageIndex, scale }: Props) {\n const { plugin: annotationPlugin } = useAnnotationPlugin();\n const [previews, setPreviews] = useState<Map<string, AnyPreviewState>>(new Map());\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n const services = useMemo<HandlerServices>(\n () => ({\n requestFile: ({ accept, onFile }) => {\n if (!fileInputRef.current) return;\n const input = fileInputRef.current;\n input.accept = accept;\n input.onchange = (e) => {\n const file = (e.target as HTMLInputElement).files?.[0];\n if (file) {\n onFile(file);\n input.value = '';\n }\n };\n input.click();\n },\n processImage: ({ source, maxWidth, maxHeight, onComplete }) => {\n const canvas = canvasRef.current;\n if (!canvas || !canvas.getContext) return;\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n const img = new Image();\n img.crossOrigin = 'Anonymous';\n img.onload = () => {\n let { naturalWidth: width, naturalHeight: height } = img;\n\n // --- SCALING LOGIC ---\n // Calculate the scale factor to fit within maxWidth and maxHeight\n const scaleX = maxWidth ? maxWidth / width : 1;\n const scaleY = maxHeight ? maxHeight / height : 1;\n const scaleFactor = Math.min(scaleX, scaleY, 1); // Ensure we don't scale up\n\n const finalWidth = width * scaleFactor;\n const finalHeight = height * scaleFactor;\n\n canvas.width = finalWidth;\n canvas.height = finalHeight;\n ctx.drawImage(img, 0, 0, finalWidth, finalHeight);\n\n const imageData = ctx.getImageData(0, 0, finalWidth, finalHeight);\n if (typeof source !== 'string') URL.revokeObjectURL(img.src);\n\n onComplete({ imageData, width: finalWidth, height: finalHeight });\n };\n img.src = typeof source === 'string' ? source : URL.createObjectURL(source);\n },\n }),\n [],\n );\n\n useEffect(() => {\n if (!annotationPlugin) return;\n\n return annotationPlugin.registerPageHandlers(documentId, pageIndex, scale, {\n services,\n onPreview: (toolId, state) => {\n setPreviews((prev) => {\n const next = new Map(prev);\n if (state) {\n next.set(toolId, state);\n } else {\n next.delete(toolId);\n }\n return next;\n });\n },\n });\n }, [documentId, pageIndex, scale, annotationPlugin, services]);\n\n return (\n <>\n {/* Hidden DOM elements required by services */}\n <input ref={fileInputRef} type=\"file\" style={{ display: 'none' }} />\n <canvas ref={canvasRef} style={{ display: 'none' }} />\n\n {/* Render any active previews from any tool */}\n {Array.from(previews.entries()).map(([toolId, preview]) => (\n <PreviewRenderer key={toolId} preview={preview} scale={scale} />\n ))}\n </>\n );\n}\n","import { createPluginPackage } from '@embedpdf/core';\nimport { AnnotationPluginPackage as BaseAnnotationPackage } from '@embedpdf/plugin-annotation';\nimport { AnnotationRendererProvider } from './context/renderer-registry';\n\nexport * from './hooks';\nexport * from './components';\nexport * from './components/types';\nexport * from './context';\nexport * from '@embedpdf/plugin-annotation';\n\n// Automatically wrap with AnnotationRendererProvider\nexport const AnnotationPluginPackage = createPluginPackage(BaseAnnotationPackage)\n .addWrapper(AnnotationRendererProvider)\n .build();\n","import { HTMLAttributes, CSSProperties, useMemo } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { Annotations } from './annotations';\nimport { TextMarkup } from './text-markup';\nimport {\n ResizeHandleUI,\n VertexHandleUI,\n CustomAnnotationRenderer,\n AnnotationSelectionMenuRenderFn,\n GroupSelectionMenuRenderFn,\n BoxedAnnotationRenderer,\n} from './types';\nimport { AnnotationPaintLayer } from './annotation-paint-layer';\nimport { PdfAnnotationObject, Rotation } from '@embedpdf/models';\nimport { useRegisteredRenderers } from '../context/renderer-registry';\n\ntype AnnotationLayerProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n /** The ID of the document that this layer displays annotations for */\n documentId: string;\n pageIndex: number;\n scale?: number;\n rotation?: number;\n /** Customize selection menu across all annotations on this layer */\n selectionMenu?: AnnotationSelectionMenuRenderFn;\n /** Customize group selection menu across all annotations on this layer */\n groupSelectionMenu?: GroupSelectionMenuRenderFn;\n style?: CSSProperties;\n /** Customize resize handles */\n resizeUI?: ResizeHandleUI;\n /** Customize vertex handles */\n vertexUI?: VertexHandleUI;\n /** Customize selection outline color */\n selectionOutlineColor?: string;\n /** Customize annotation renderer */\n customAnnotationRenderer?: CustomAnnotationRenderer<PdfAnnotationObject>;\n /** Custom renderers for specific annotation types (provided by external plugins) */\n annotationRenderers?: BoxedAnnotationRenderer[];\n};\n\nexport function AnnotationLayer({\n style,\n documentId,\n pageIndex,\n scale: overrideScale,\n rotation: overrideRotation,\n selectionMenu,\n groupSelectionMenu,\n resizeUI,\n vertexUI,\n selectionOutlineColor,\n customAnnotationRenderer,\n annotationRenderers,\n ...props\n}: AnnotationLayerProps) {\n const documentState = useDocumentState(documentId);\n const page = documentState?.document?.pages?.[pageIndex];\n const width = page?.size?.width ?? 0;\n const height = page?.size?.height ?? 0;\n\n // Auto-load renderers from context\n const contextRenderers = useRegisteredRenderers();\n\n // Merge: context + explicit props (props take precedence by id)\n const allRenderers = useMemo(() => {\n const merged = [...contextRenderers];\n for (const renderer of annotationRenderers ?? []) {\n const idx = merged.findIndex((r) => r.id === renderer.id);\n if (idx >= 0) merged[idx] = renderer;\n else merged.push(renderer);\n }\n return merged;\n }, [contextRenderers, annotationRenderers]);\n\n const actualScale = useMemo(() => {\n if (overrideScale !== undefined) return overrideScale;\n return documentState?.scale ?? 1;\n }, [overrideScale, documentState?.scale]);\n\n const actualRotation = useMemo(() => {\n if (overrideRotation !== undefined) return overrideRotation;\n // Combine page intrinsic rotation with document rotation\n const pageRotation = page?.rotation ?? 0;\n const docRotation = documentState?.rotation ?? 0;\n return ((pageRotation + docRotation) % 4) as Rotation;\n }, [overrideRotation, page?.rotation, documentState?.rotation]);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n <Annotations\n documentId={documentId}\n selectionMenu={selectionMenu}\n groupSelectionMenu={groupSelectionMenu}\n pageIndex={pageIndex}\n scale={actualScale}\n rotation={actualRotation}\n pageWidth={width}\n pageHeight={height}\n resizeUI={resizeUI}\n vertexUI={vertexUI}\n selectionOutlineColor={selectionOutlineColor}\n customAnnotationRenderer={customAnnotationRenderer}\n annotationRenderers={allRenderers}\n />\n <TextMarkup documentId={documentId} pageIndex={pageIndex} scale={actualScale} />\n <AnnotationPaintLayer documentId={documentId} pageIndex={pageIndex} scale={actualScale} />\n </div>\n );\n}\n","import { PdfAnnotationObject } from '@embedpdf/models';\nimport { TrackedAnnotation } from '@embedpdf/plugin-annotation';\nimport {\n HandleElementProps,\n SelectionMenuPropsBase,\n SelectionMenuRenderFn,\n} from '@embedpdf/utils/@framework';\nimport { JSX, MouseEvent, TouchEvent } from '@framework';\n\nexport type ResizeDirection = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'none';\n\nexport interface AnnotationSelectionContext {\n type: 'annotation';\n annotation: TrackedAnnotation;\n pageIndex: number;\n}\n\nexport type AnnotationSelectionMenuProps = SelectionMenuPropsBase<AnnotationSelectionContext>;\nexport type AnnotationSelectionMenuRenderFn = SelectionMenuRenderFn<AnnotationSelectionContext>;\n\nexport interface GroupSelectionContext {\n type: 'group';\n annotations: TrackedAnnotation[];\n pageIndex: number;\n}\n\nexport type GroupSelectionMenuProps = SelectionMenuPropsBase<GroupSelectionContext>;\nexport type GroupSelectionMenuRenderFn = SelectionMenuRenderFn<GroupSelectionContext>;\n\nexport type HandleProps = HandleElementProps & {\n backgroundColor?: string;\n};\n\n/** UI customization for resize handles */\nexport interface ResizeHandleUI {\n /** Handle size in CSS px (default: 12) */\n size?: number;\n /** Default background color for the handle (used by default renderer) */\n color?: string;\n /** Custom renderer for each handle (overrides default) */\n component?: (p: HandleProps) => JSX.Element;\n}\n\n/** UI customization for vertex handles */\nexport interface VertexHandleUI {\n /** Handle size in CSS px (default: 12) */\n size?: number;\n /** Default background color for the handle (used by default renderer) */\n color?: string;\n /** Custom renderer for each vertex (overrides default) */\n component?: (p: HandleProps) => JSX.Element;\n}\n\n/**\n * Props for the custom annotation renderer\n */\nexport interface CustomAnnotationRendererProps<T extends PdfAnnotationObject> {\n annotation: T;\n children: JSX.Element;\n isSelected: boolean;\n scale: number;\n rotation: number;\n pageWidth: number;\n pageHeight: number;\n pageIndex: number;\n onSelect: (event: any) => void;\n}\n\n/**\n * Custom renderer for an annotation\n */\nexport type CustomAnnotationRenderer<T extends PdfAnnotationObject> = (\n props: CustomAnnotationRendererProps<T>,\n) => JSX.Element | null;\n\n/**\n * Props for an annotation renderer entry\n */\nexport interface AnnotationRendererProps<T extends PdfAnnotationObject> {\n annotation: TrackedAnnotation<T>;\n isSelected: boolean;\n scale: number;\n pageIndex: number;\n onClick: (e: MouseEvent<Element> | TouchEvent<Element>) => void;\n}\n\n/**\n * Entry for a custom annotation renderer that handles specific annotation types.\n * This allows external plugins to provide their own rendering for annotation subtypes.\n * Used at definition time for type safety.\n */\nexport interface AnnotationRendererEntry<T extends PdfAnnotationObject = PdfAnnotationObject> {\n /** Unique identifier for this renderer (usually matches tool id) */\n id: string;\n\n /** Returns true if this renderer should handle the annotation */\n matches: (annotation: PdfAnnotationObject) => annotation is T;\n\n /** The component to render the annotation */\n render: (props: AnnotationRendererProps<T>) => JSX.Element;\n}\n\n/**\n * Props passed to tryRender (everything except annotation which is passed separately)\n */\nexport type BoxedRendererProps = Omit<AnnotationRendererProps<PdfAnnotationObject>, 'annotation'>;\n\n/**\n * Boxed renderer that encapsulates type safety internally.\n * The generic is erased - this is what the registry actually stores.\n */\nexport interface BoxedAnnotationRenderer {\n /** Unique identifier for this renderer */\n id: string;\n\n /** Combined match + render: returns null if doesn't match, JSX.Element if it does */\n tryRender: (annotation: TrackedAnnotation, props: BoxedRendererProps) => JSX.Element | null;\n}\n\n/**\n * Creates a boxed renderer from a typed entry.\n * Type safety is enforced at definition time, then erased for storage.\n */\nexport function createRenderer<T extends PdfAnnotationObject>(\n entry: AnnotationRendererEntry<T>,\n): BoxedAnnotationRenderer {\n return {\n id: entry.id,\n tryRender: (annotation, props) => {\n if (entry.matches(annotation.object)) {\n return entry.render({\n ...props,\n annotation: annotation as TrackedAnnotation<T>,\n });\n }\n return null;\n },\n };\n}\n"],"names":["suppressContentEditableWarningProps","suppressContentEditableWarning","RegisterContext","createContext","RenderersContext","AnnotationRendererProvider","children","renderers","setRenderers","useState","register","useCallback","entries","prev","ids","Set","map","e","id","filter","r","has","some","jsx","Provider","value","useRegisteredRenderers","useContext","useAnnotationPlugin","usePlugin","AnnotationPlugin","useAnnotationCapability","useCapability","AnnotationContainer","scale","documentId","pageIndex","rotation","pageWidth","pageHeight","trackedAnnotation","isSelected","isMultiSelected","isDraggable","isResizable","lockAspectRatio","style","vertexConfig","selectionMenu","outlineOffset","onDoubleClick","onSelect","zIndex","resizeUI","vertexUI","selectionOutlineColor","customAnnotationRenderer","groupSelectionMenu","_groupSelectionMenu","annotationRenderers","_annotationRenderers","props","preview","setPreview","object","provides","annotationCapability","plugin","canModifyAnnotations","useDocumentPermissions","gestureBaseRef","useRef","effectiveIsDraggable","effectiveIsResizable","annotationProvides","useMemo","forDocument","currentObject","HANDLE_COLOR","color","VERTEX_COLOR","HANDLE_SIZE","size","VERTEX_SIZE","gestureBaseRectRef","handleUpdate","event","_a","transformData","type","changes","metadata","pageSize","width","height","state","current","rect","startDrag","annotationIds","startResize","resizeHandle","handle","delta","x","origin","y","updateDrag","updateResize","vertices","base","vertexChanges","transformAnnotation","patched","updateAnnotation","commitDrag","commitResize","dragProps","resize","useInteractionHandles","controller","element","extractVertices","constraints","minWidth","minHeight","boundingBox","maintainAspectRatio","pageRotation","enabled","onUpdate","handleSize","spacing","offsetMode","includeSides","vertexSize","includeVertices","guardedOnDoubleClick","doubleProps","useDoublePressProps","useEffect","handleEvent","patch","previewPatches","unsubs","onDragChange","onResizeChange","forEach","u","showOutline","jsxs","position","left","top","outline","pointerEvents","touchAction","cursor","childrenRender","customRender","annotation","key","hProps","component","backgroundColor","vProps","CounterRotate","counterRotateProps","context","selected","placement","suggestTop","GroupSelectionBox","selectedAnnotations","isDraggingRef","isResizingRef","groupBox","rects","ta","boundingRectOrEmpty","previewGroupBox","setPreviewGroupBox","transformType","isMove","isResize","_b","newRect","rawDelta","clampedDelta","newGroupBox","length","onPointerDown","stopPropagation","annotations","Highlight","strokeColor","opacity","segmentRects","onClick","resolvedColor","Fragment","b","i","onTouchStart","background","Underline","thickness","bottom","Strikeout","transform","Squiggly","amplitude","period","svgDataUri","encodeURIComponent","backgroundImage","backgroundRepeat","backgroundSize","Ink","strokeWidth","inkList","paths","points","d","lx","ly","trim","overflow","viewBox","fill","stroke","strokeLinecap","strokeLinejoin","Square","strokeStyle","PdfAnnotationBorderStyle","SOLID","strokeDashArray","outerW","outerH","Math","max","svgWidth","svgHeight","DASHED","strokeDasharray","join","Circle","cx","cy","rx","ry","innerW","innerH","Line","linePoints","lineEndings","x1","y1","x2","y2","start","end","endings","angle","atan2","patching","createEnding","PI","filled","Polyline","localPts","pathData","first","rest","p","toAngle","a","startRad","endRad","Polygon","currentVertex","allPoints","isPreview","isPreviewing","FreeText","isEditing","editorRef","isIOS","setIsIOS","editor","focus","selection","window","getSelection","range","document","createRange","selectNodeContents","collapse","removeAllRanges","addRange","useLayoutEffect","nav","navigator","ios","test","userAgent","platform","maxTouchPoints","computedFontPx","fontSize","needsComp","adjustedFontPx","scaleComp","invScalePercent","ref","onBlur","contents","innerText","tabIndex","fontColor","fontFamily","standardFontCss","textAlign","textAlignmentToCss","flexDirection","justifyContent","verticalAlign","PdfVerticalAlignment","Top","Middle","display","lineHeight","transformOrigin","contentEditable","RenderAnnotation","scaleFactor","imageUrl","setImageUrl","urlRef","task","renderAnnotation","options","dpr","devicePixelRatio","wait","blob","url","URL","createObjectURL","ignore","revokeObjectURL","abort","code","PdfErrorCode","Cancelled","message","src","onLoad","Stamp","Link","UNDERLINE","hasIRT","dashArray","isUnderline","Annotations","annotationsProps","selectionProvides","useSelectionCapability","setAnnotations","usePointerHandlers","allSelectedIds","setAllSelectedIds","editingId","setEditingId","currentState","getState","getAnnotationsByPageIndex","getSelectedAnnotationIds","onStateChange","handlers","_","pe","target","currentTarget","deselectAnnotation","handleClick","clear","metaKey","ctrlKey","toggleSelection","selectAnnotation","handleLinkClick","inReplyToId","parentId","parent","find","selectedAnnotationsOnPage","anno","includes","areAllSelectedDraggable","every","tool","findToolForAnnotation","groupDraggable","resolveInteractionProp","interaction","isGroupDraggable","singleDraggable","areAllSelectedResizable","groupResizable","isGroupResizable","singleResizable","allSelectedOnSamePage","allSelected","getSelectedAnnotations","renderer","tryRender","mixBlendMode","blendModeToCss","blendMode","PdfBlendMode","Normal","isInk","obj","isSquare","isCircle","isStrikeout","isSquiggly","isHighlight","Multiply","isLine","isPolyline","isPolygon","isFreeText","isStamp","_object","isLink","TextMarkup","setRects","boundingRect","setBoundingRect","activeTool","setActiveTool","onSelectionChange","getHighlightRectsForPage","getBoundingRectForPage","getActiveTool","onActiveToolChange","defaults","PdfAnnotationSubtype","inset","_c","HIGHLIGHT","_d","_e","_f","STRIKEOUT","_g","_h","_i","SQUIGGLY","_j","_k","_l","PreviewRenderer","bounds","CIRCLE","data","SQUARE","POLYGON","POLYLINE","LINE","INK","FREETEXT","border","AnnotationPaintLayer","annotationPlugin","previews","setPreviews","Map","fileInputRef","canvasRef","services","requestFile","accept","onFile","input","onchange","file","files","click","processImage","source","maxWidth","maxHeight","onComplete","canvas","getContext","ctx","img","Image","crossOrigin","onload","naturalWidth","naturalHeight","scaleX","scaleY","min","finalWidth","finalHeight","drawImage","imageData","getImageData","registerPageHandlers","onPreview","toolId","next","set","delete","Array","from","AnnotationPluginPackage","createPluginPackage","BaseAnnotationPackage","addWrapper","build","overrideScale","overrideRotation","documentState","useDocumentState","page","pages","contextRenderers","allRenderers","merged","idx","findIndex","push","actualScale","actualRotation","entry","matches","render","setState","initialDocumentState","scope","newState","renderersRef"],"mappings":"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"}
|