@embedpdf/plugin-annotation 1.1.1 → 1.2.1

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.
Files changed (107) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +1924 -396
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/actions.d.ts +21 -15
  6. package/dist/lib/annotation-plugin.d.ts +30 -7
  7. package/dist/lib/handlers/circle.handler.d.ts +3 -0
  8. package/dist/lib/handlers/click-detector.d.ts +27 -0
  9. package/dist/lib/handlers/free-text.handler.d.ts +3 -0
  10. package/dist/lib/handlers/index.d.ts +8 -0
  11. package/dist/lib/handlers/ink.handler.d.ts +3 -0
  12. package/dist/lib/handlers/line.handler.d.ts +3 -0
  13. package/dist/lib/handlers/polygon.handler.d.ts +3 -0
  14. package/dist/lib/handlers/polyline.handler.d.ts +3 -0
  15. package/dist/lib/handlers/square.handler.d.ts +3 -0
  16. package/dist/lib/handlers/stamp.handler.d.ts +3 -0
  17. package/dist/lib/handlers/types.d.ts +139 -0
  18. package/dist/lib/helpers.d.ts +1 -6
  19. package/dist/lib/index.d.ts +3 -1
  20. package/dist/lib/patching/index.d.ts +1 -1
  21. package/dist/lib/patching/patch-registry.d.ts +27 -0
  22. package/dist/lib/patching/patches/index.d.ts +4 -0
  23. package/dist/lib/patching/patches/ink.patch.d.ts +3 -0
  24. package/dist/lib/patching/patches/line.patch.d.ts +3 -0
  25. package/dist/lib/patching/patches/polygon.patch.d.ts +3 -0
  26. package/dist/lib/patching/patches/polyline.patch.d.ts +3 -0
  27. package/dist/lib/selectors.d.ts +8 -12
  28. package/dist/lib/tools/default-tools.d.ts +436 -0
  29. package/dist/lib/tools/tools-utils.d.ts +25 -0
  30. package/dist/lib/tools/types.d.ts +96 -0
  31. package/dist/lib/types.d.ts +78 -161
  32. package/dist/lib/utils/index.d.ts +1 -0
  33. package/dist/lib/utils/use-state.d.ts +12 -0
  34. package/dist/preact/adapter.d.ts +1 -5
  35. package/dist/preact/index.cjs +1 -1
  36. package/dist/preact/index.cjs.map +1 -1
  37. package/dist/preact/index.js +392 -1796
  38. package/dist/preact/index.js.map +1 -1
  39. package/dist/react/adapter.d.ts +2 -4
  40. package/dist/react/index.cjs +1 -1
  41. package/dist/react/index.cjs.map +1 -1
  42. package/dist/react/index.js +393 -1795
  43. package/dist/react/index.js.map +1 -1
  44. package/dist/shared-preact/components/annotation-container.d.ts +18 -16
  45. package/dist/shared-preact/components/annotation-layer.d.ts +9 -2
  46. package/dist/shared-preact/components/annotation-paint-layer.d.ts +6 -0
  47. package/dist/shared-preact/components/annotations/free-text.d.ts +1 -0
  48. package/dist/shared-preact/components/annotations/polygon.d.ts +4 -1
  49. package/dist/shared-preact/components/annotations.d.ts +4 -1
  50. package/dist/shared-preact/components/preview-renderer.d.ts +7 -0
  51. package/dist/shared-preact/components/text-markup/highlight.d.ts +2 -2
  52. package/dist/shared-preact/components/text-markup/squiggly.d.ts +2 -2
  53. package/dist/shared-preact/components/text-markup/strikeout.d.ts +2 -2
  54. package/dist/shared-preact/components/text-markup/underline.d.ts +2 -2
  55. package/dist/shared-preact/types.d.ts +32 -2
  56. package/dist/shared-react/components/annotation-container.d.ts +18 -16
  57. package/dist/shared-react/components/annotation-layer.d.ts +9 -2
  58. package/dist/shared-react/components/annotation-paint-layer.d.ts +6 -0
  59. package/dist/shared-react/components/annotations/free-text.d.ts +1 -0
  60. package/dist/shared-react/components/annotations/polygon.d.ts +4 -1
  61. package/dist/shared-react/components/annotations.d.ts +4 -1
  62. package/dist/shared-react/components/preview-renderer.d.ts +7 -0
  63. package/dist/shared-react/components/text-markup/highlight.d.ts +2 -2
  64. package/dist/shared-react/components/text-markup/squiggly.d.ts +2 -2
  65. package/dist/shared-react/components/text-markup/strikeout.d.ts +2 -2
  66. package/dist/shared-react/components/text-markup/underline.d.ts +2 -2
  67. package/dist/shared-react/types.d.ts +32 -2
  68. package/dist/vue/hooks/index.d.ts +1 -0
  69. package/dist/vue/hooks/use-annotation.d.ts +3 -0
  70. package/dist/vue/index.cjs +2 -0
  71. package/dist/vue/index.cjs.map +1 -0
  72. package/dist/vue/index.d.ts +2 -0
  73. package/dist/vue/index.js +10 -0
  74. package/dist/vue/index.js.map +1 -0
  75. package/package.json +19 -12
  76. package/dist/lib/patching/derived-rect.d.ts +0 -2
  77. package/dist/lib/variant-key.d.ts +0 -8
  78. package/dist/shared-preact/components/annotations/circle-paint.d.ts +0 -10
  79. package/dist/shared-preact/components/annotations/free-text-paint.d.ts +0 -10
  80. package/dist/shared-preact/components/annotations/ink-highlight-paint.d.ts +0 -0
  81. package/dist/shared-preact/components/annotations/ink-paint.d.ts +0 -18
  82. package/dist/shared-preact/components/annotations/line-paint.d.ts +0 -10
  83. package/dist/shared-preact/components/annotations/polygon-paint.d.ts +0 -9
  84. package/dist/shared-preact/components/annotations/polyline-paint.d.ts +0 -10
  85. package/dist/shared-preact/components/annotations/square-paint.d.ts +0 -10
  86. package/dist/shared-preact/components/annotations/stamp-paint.d.ts +0 -8
  87. package/dist/shared-preact/components/resize-handles.d.ts +0 -9
  88. package/dist/shared-preact/components/vertex-editor.d.ts +0 -19
  89. package/dist/shared-preact/hooks/use-drag-resize.d.ts +0 -38
  90. package/dist/shared-preact/patch-ink.d.ts +0 -16
  91. package/dist/shared-preact/patchers.d.ts +0 -9
  92. package/dist/shared-preact/vertex-patchers.d.ts +0 -10
  93. package/dist/shared-react/components/annotations/circle-paint.d.ts +0 -10
  94. package/dist/shared-react/components/annotations/free-text-paint.d.ts +0 -10
  95. package/dist/shared-react/components/annotations/ink-highlight-paint.d.ts +0 -0
  96. package/dist/shared-react/components/annotations/ink-paint.d.ts +0 -17
  97. package/dist/shared-react/components/annotations/line-paint.d.ts +0 -10
  98. package/dist/shared-react/components/annotations/polygon-paint.d.ts +0 -9
  99. package/dist/shared-react/components/annotations/polyline-paint.d.ts +0 -10
  100. package/dist/shared-react/components/annotations/square-paint.d.ts +0 -10
  101. package/dist/shared-react/components/annotations/stamp-paint.d.ts +0 -8
  102. package/dist/shared-react/components/resize-handles.d.ts +0 -9
  103. package/dist/shared-react/components/vertex-editor.d.ts +0 -19
  104. package/dist/shared-react/hooks/use-drag-resize.d.ts +0 -38
  105. package/dist/shared-react/patch-ink.d.ts +0 -16
  106. package/dist/shared-react/patchers.d.ts +0 -9
  107. package/dist/shared-react/vertex-patchers.d.ts +0 -10
@@ -1,324 +1,17 @@
1
1
  import { usePlugin, useCapability } from "@embedpdf/core/react";
2
2
  import { AnnotationPlugin, patching, getAnnotationsByPageIndex, getSelectedAnnotationByPageIndex, isInk, isSquare, isCircle, isUnderline, isStrikeout, isSquiggly, isHighlight, isLine, isPolyline, isPolygon, isFreeText, isStamp } from "@embedpdf/plugin-annotation";
3
3
  export * from "@embedpdf/plugin-annotation";
4
- import { jsx, jsxs, Fragment as Fragment$1 } from "react/jsx-runtime";
5
- import { restoreOffset, rectEquals, PdfAnnotationBorderStyle, PdfAnnotationSubtype, expandRect, rectFromPoints, textAlignmentToCss, standardFontCss, PdfVerticalAlignment, ignore, PdfErrorCode, blendModeToCss, PdfBlendMode, uuidV4 } from "@embedpdf/models";
4
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
5
+ import { PdfAnnotationBorderStyle, textAlignmentToCss, standardFontCss, PdfVerticalAlignment, ignore, PdfErrorCode, blendModeToCss, PdfBlendMode, PdfAnnotationSubtype } from "@embedpdf/models";
6
6
  import { usePointerHandlers } from "@embedpdf/plugin-interaction-manager/react";
7
7
  import { useSelectionCapability } from "@embedpdf/plugin-selection/react";
8
- import { useState, useRef, Fragment, useEffect, useLayoutEffect, useMemo, useCallback } from "react";
9
- import { CounterRotate } from "@embedpdf/utils/react";
10
- import { clamp } from "@embedpdf/core";
8
+ import { useState, useRef, useEffect, useMemo, useLayoutEffect, Fragment as Fragment$1, useCallback } from "react";
9
+ import { useInteractionHandles, useDoublePressProps, CounterRotate } from "@embedpdf/utils/react";
11
10
  const useAnnotationPlugin = () => usePlugin(AnnotationPlugin.id);
12
11
  const useAnnotationCapability = () => useCapability(AnnotationPlugin.id);
13
- const mapDoubleClick = (handler) => handler ? { onDoubleClick: handler } : {};
14
- function VertexEditor({
15
- rect,
16
- rotation,
17
- scale,
18
- vertices,
19
- onEdit,
20
- onCommit,
21
- handleSize = 12
22
- }) {
23
- const [dragIdx, setDragIdx] = useState(null);
24
- const startScreen = useRef(null);
25
- const startVerts = useRef([]);
26
- const applyDelta = (deltaScreen) => {
27
- const deltaPdf = restoreOffset(deltaScreen, rotation, scale);
28
- const next = [...startVerts.current];
29
- if (dragIdx !== null) {
30
- next[dragIdx] = {
31
- x: next[dragIdx].x + deltaPdf.x,
32
- y: next[dragIdx].y + deltaPdf.y
33
- };
34
- }
35
- return next;
36
- };
37
- const handleDown = (idx) => (e) => {
38
- e.stopPropagation();
39
- e.preventDefault();
40
- setDragIdx(idx);
41
- startScreen.current = { x: e.clientX, y: e.clientY };
42
- startVerts.current = vertices;
43
- e.target.setPointerCapture(e.pointerId);
44
- };
45
- const handleMove = (e) => {
46
- if (dragIdx === null || !startScreen.current) return;
47
- const deltaRaw = {
48
- x: e.clientX - startScreen.current.x,
49
- y: e.clientY - startScreen.current.y
50
- };
51
- onEdit(applyDelta(deltaRaw));
52
- };
53
- const handleUp = (e) => {
54
- if (dragIdx === null || !startScreen.current) return;
55
- e.target.releasePointerCapture(e.pointerId);
56
- const deltaRaw = {
57
- x: e.clientX - startScreen.current.x,
58
- y: e.clientY - startScreen.current.y
59
- };
60
- onCommit(applyDelta(deltaRaw));
61
- setDragIdx(null);
62
- };
63
- return /* @__PURE__ */ jsx(Fragment, { children: vertices.map((v, i) => {
64
- const left = (v.x - rect.origin.x) * scale - handleSize / 2;
65
- const top = (v.y - rect.origin.y) * scale - handleSize / 2;
66
- return /* @__PURE__ */ jsx(
67
- "div",
68
- {
69
- style: {
70
- position: "absolute",
71
- left,
72
- top,
73
- width: handleSize,
74
- height: handleSize,
75
- borderRadius: "50%",
76
- background: "#2196f3",
77
- cursor: "pointer",
78
- pointerEvents: "auto",
79
- zIndex: 4
80
- },
81
- onPointerDown: handleDown(i),
82
- onPointerMove: handleMove,
83
- onPointerUp: handleUp
84
- },
85
- i
86
- );
87
- }) });
88
- }
89
- function useDragResize({
90
- scale,
91
- pageWidth,
92
- pageHeight,
93
- rotation,
94
- tracked,
95
- isSelected,
96
- isDraggable,
97
- isResizable,
98
- computePatch,
99
- computeVertices,
100
- lockAspectRatio = false,
101
- currentRect,
102
- setCurrentRect,
103
- setCurrentVertices,
104
- setPreviewObject,
105
- commit
106
- }) {
107
- const drag = useRef("idle");
108
- const dir = useRef("none");
109
- const startPos = useRef(null);
110
- const startRect = useRef(null);
111
- const clamp2 = (v, min, max) => Math.max(min, Math.min(max, v));
112
- const pageW = pageWidth / scale;
113
- const pageH = pageHeight / scale;
114
- const applyDelta = (dx, dy) => {
115
- if (!startRect.current) return currentRect;
116
- let { origin, size } = startRect.current;
117
- let ox = origin.x;
118
- let oy = origin.y;
119
- let w = size.width;
120
- let h = size.height;
121
- if (drag.current === "dragging") {
122
- ox += dx;
123
- oy += dy;
124
- } else if (drag.current === "resizing") {
125
- if (dir.current.includes("right")) w += dx;
126
- else if (dir.current.includes("left")) {
127
- ox += dx;
128
- w -= dx;
129
- }
130
- if (dir.current.includes("bottom")) h += dy;
131
- else if (dir.current.includes("top")) {
132
- oy += dy;
133
- h -= dy;
134
- }
135
- if (lockAspectRatio && startRect.current) {
136
- const ratio = startRect.current.size.width / startRect.current.size.height;
137
- const anchorRight = ox + w;
138
- const anchorBottom = oy + h;
139
- const horizontalPrimary = dir.current.includes("left") || dir.current.includes("right");
140
- if (horizontalPrimary) {
141
- h = w / ratio;
142
- } else {
143
- w = h * ratio;
144
- }
145
- if (dir.current.includes("left")) {
146
- ox = anchorRight - w;
147
- }
148
- if (dir.current.includes("top")) {
149
- oy = anchorBottom - h;
150
- }
151
- }
152
- }
153
- if (w < 1 || h < 1) return currentRect;
154
- w = clamp2(w, 1, pageW);
155
- h = clamp2(h, 1, pageH);
156
- ox = clamp2(ox, 0, pageW - w);
157
- oy = clamp2(oy, 0, pageH - h);
158
- return { origin: { x: ox, y: oy }, size: { width: w, height: h } };
159
- };
160
- const beginDrag = (kind, clientX, clientY) => {
161
- drag.current = kind;
162
- startPos.current = { x: clientX, y: clientY };
163
- startRect.current = currentRect;
164
- };
165
- const handleMove = (clientX, clientY) => {
166
- if (drag.current === "idle" || !startPos.current) return;
167
- const disp = {
168
- x: clientX - startPos.current.x,
169
- y: clientY - startPos.current.y
170
- };
171
- const { x, y } = restoreOffset(disp, rotation, scale);
172
- const nextRect = applyDelta(x, y);
173
- let patch = { rect: nextRect };
174
- if (computePatch) {
175
- patch = computePatch(tracked.object, {
176
- rect: nextRect,
177
- direction: drag.current === "resizing" ? dir.current : "bottom-right"
178
- });
179
- if (computeVertices) setCurrentVertices(computeVertices({ ...tracked.object, ...patch }));
180
- }
181
- setCurrentRect(patch.rect ?? nextRect);
182
- setPreviewObject(patch);
183
- };
184
- const finishDragInternal = () => {
185
- if (drag.current === "idle") return;
186
- const usedDir = dir.current || "bottom-right";
187
- drag.current = "idle";
188
- let patch = { rect: currentRect };
189
- if (computePatch) {
190
- patch = computePatch(tracked.object, {
191
- rect: currentRect,
192
- direction: usedDir
193
- });
194
- }
195
- commit(patch);
196
- startPos.current = null;
197
- startRect.current = null;
198
- dir.current = "none";
199
- setPreviewObject(null);
200
- };
201
- const onPointerDown = (e) => {
202
- if (!isSelected || !isDraggable) return;
203
- e.stopPropagation();
204
- e.preventDefault();
205
- beginDrag("dragging", e.clientX, e.clientY);
206
- e.currentTarget.setPointerCapture(e.pointerId);
207
- };
208
- const onPointerMove = (e) => handleMove(e.clientX, e.clientY);
209
- const onPointerUp = (e) => {
210
- finishDragInternal();
211
- if ((e == null ? void 0 : e.currentTarget) && e.pointerId !== void 0) {
212
- try {
213
- e.currentTarget.releasePointerCapture(e.pointerId);
214
- } catch {
215
- }
216
- }
217
- };
218
- const startResize = (direction) => (e) => {
219
- if (!isSelected || !isResizable) return;
220
- e.stopPropagation();
221
- e.preventDefault();
222
- dir.current = direction;
223
- beginDrag("resizing", e.clientX, e.clientY);
224
- e.currentTarget.setPointerCapture(e.pointerId);
225
- };
226
- const onTouchStart = (e) => {
227
- if (!isSelected || !isDraggable) return;
228
- e.stopPropagation();
229
- e.preventDefault();
230
- const t = e.touches[0];
231
- if (!t) return;
232
- beginDrag("dragging", t.clientX, t.clientY);
233
- };
234
- const onTouchMove = (e) => {
235
- const t = e.touches[0];
236
- if (!t) return;
237
- handleMove(t.clientX, t.clientY);
238
- };
239
- const onTouchEnd = () => finishDragInternal();
240
- useEffect(() => {
241
- drag.current = "idle";
242
- dir.current = "none";
243
- startPos.current = null;
244
- startRect.current = null;
245
- }, [tracked]);
246
- return {
247
- rootHandlers: {
248
- onPointerDown,
249
- onPointerMove,
250
- onPointerUp,
251
- onPointerCancel: () => onPointerUp(),
252
- onLostPointerCapture: () => onPointerUp(),
253
- /* mobile touch fallback */
254
- onTouchStart,
255
- onTouchMove,
256
- onTouchEnd,
257
- onTouchCancel: onTouchEnd
258
- },
259
- startResize
260
- };
261
- }
262
- const commonStyle = (o) => ({
263
- position: "absolute",
264
- width: 13,
265
- height: 13,
266
- background: "blue",
267
- borderRadius: "50%"
268
- });
269
- function ResizeHandles({ rotation, outlineOffset = 1, startResize }) {
270
- const o = outlineOffset;
271
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [
272
- /* @__PURE__ */ jsx(
273
- "div",
274
- {
275
- style: {
276
- ...commonStyle(),
277
- top: -7 - o,
278
- left: -7 - o,
279
- cursor: rotation % 2 ? "nesw-resize" : "nwse-resize"
280
- },
281
- onPointerDown: startResize("top-left")
282
- }
283
- ),
284
- /* @__PURE__ */ jsx(
285
- "div",
286
- {
287
- style: {
288
- ...commonStyle(),
289
- top: -7 - o,
290
- right: -7 - o,
291
- cursor: rotation % 2 ? "nwse-resize" : "nesw-resize"
292
- },
293
- onPointerDown: startResize("top-right")
294
- }
295
- ),
296
- /* @__PURE__ */ jsx(
297
- "div",
298
- {
299
- style: {
300
- ...commonStyle(),
301
- bottom: -7 - o,
302
- left: -7 - o,
303
- cursor: rotation % 2 ? "nwse-resize" : "nesw-resize"
304
- },
305
- onPointerDown: startResize("bottom-left")
306
- }
307
- ),
308
- /* @__PURE__ */ jsx(
309
- "div",
310
- {
311
- style: {
312
- ...commonStyle(),
313
- bottom: -7 - o,
314
- right: -7 - o,
315
- cursor: rotation % 2 ? "nesw-resize" : "nwse-resize"
316
- },
317
- onPointerDown: startResize("bottom-right")
318
- }
319
- )
320
- ] });
321
- }
12
+ const suppressContentEditableWarningProps = {
13
+ suppressContentEditableWarning: true
14
+ };
322
15
  function AnnotationContainer({
323
16
  scale,
324
17
  pageIndex,
@@ -327,111 +20,135 @@ function AnnotationContainer({
327
20
  pageHeight,
328
21
  trackedAnnotation,
329
22
  children,
330
- style,
331
- outlineOffset = 1,
332
- isSelected = false,
333
- isDraggable = true,
334
- isResizable = true,
23
+ isSelected,
24
+ isDraggable,
25
+ isResizable,
335
26
  lockAspectRatio = false,
336
- computeVertices,
337
- computePatch,
27
+ style = {},
28
+ vertexConfig,
338
29
  selectionMenu,
30
+ outlineOffset = 1,
339
31
  onDoubleClick,
32
+ zIndex = 1,
33
+ resizeUI,
34
+ vertexUI,
35
+ selectionOutlineColor = "#007ACC",
340
36
  ...props
341
37
  }) {
38
+ const [preview, setPreview] = useState(trackedAnnotation.object);
342
39
  const { provides: annotationProvides } = useAnnotationCapability();
343
- const [currentRect, setCurrentRect] = useState(trackedAnnotation.object.rect);
344
- const [currentVertices, setCurrentVertices] = useState(
345
- (computeVertices == null ? void 0 : computeVertices(trackedAnnotation.object)) ?? []
346
- );
347
- const [previewObject, setPreviewObject] = useState(null);
348
- const { rootHandlers, startResize } = useDragResize({
349
- scale,
350
- pageWidth,
351
- pageHeight,
352
- rotation,
353
- tracked: trackedAnnotation,
354
- isSelected,
355
- isDraggable,
356
- isResizable,
357
- lockAspectRatio,
358
- computePatch,
359
- computeVertices,
360
- currentRect,
361
- setCurrentRect,
362
- setCurrentVertices,
363
- setPreviewObject,
364
- commit: (patch) => annotationProvides == null ? void 0 : annotationProvides.updateAnnotation(pageIndex, trackedAnnotation.object.id, patch)
40
+ const gestureBaseRef = useRef(null);
41
+ const currentObject = preview ? { ...trackedAnnotation.object, ...preview } : trackedAnnotation.object;
42
+ const HANDLE_COLOR = (resizeUI == null ? void 0 : resizeUI.color) ?? "#007ACC";
43
+ const VERTEX_COLOR = (vertexUI == null ? void 0 : vertexUI.color) ?? "#007ACC";
44
+ const HANDLE_SIZE = (resizeUI == null ? void 0 : resizeUI.size) ?? 12;
45
+ const VERTEX_SIZE = (vertexUI == null ? void 0 : vertexUI.size) ?? 12;
46
+ const { dragProps, vertices, resize } = useInteractionHandles({
47
+ controller: {
48
+ element: currentObject.rect,
49
+ vertices: vertexConfig == null ? void 0 : vertexConfig.extractVertices(currentObject),
50
+ constraints: {
51
+ minWidth: 10,
52
+ minHeight: 10,
53
+ boundingBox: { width: pageWidth / scale, height: pageHeight / scale }
54
+ },
55
+ maintainAspectRatio: lockAspectRatio,
56
+ pageRotation: rotation,
57
+ scale,
58
+ enabled: isSelected,
59
+ onUpdate: (event) => {
60
+ var _a;
61
+ if (!((_a = event.transformData) == null ? void 0 : _a.type)) return;
62
+ if (event.state === "start") {
63
+ gestureBaseRef.current = currentObject;
64
+ }
65
+ const transformType = event.transformData.type;
66
+ const base = gestureBaseRef.current ?? currentObject;
67
+ const changes = event.transformData.changes.vertices ? vertexConfig == null ? void 0 : vertexConfig.transformAnnotation(base, event.transformData.changes.vertices) : { rect: event.transformData.changes.rect };
68
+ const patched = annotationProvides == null ? void 0 : annotationProvides.transformAnnotation(base, {
69
+ type: transformType,
70
+ changes,
71
+ metadata: event.transformData.metadata
72
+ });
73
+ if (patched) {
74
+ setPreview((prev) => ({
75
+ ...prev,
76
+ ...patched
77
+ }));
78
+ }
79
+ if (event.state === "end" && patched) {
80
+ gestureBaseRef.current = null;
81
+ annotationProvides == null ? void 0 : annotationProvides.updateAnnotation(pageIndex, trackedAnnotation.object.id, patched);
82
+ }
83
+ }
84
+ },
85
+ resizeUI: {
86
+ handleSize: HANDLE_SIZE,
87
+ spacing: outlineOffset,
88
+ offsetMode: "outside",
89
+ includeSides: lockAspectRatio ? false : true,
90
+ zIndex: zIndex + 1
91
+ },
92
+ vertexUI: {
93
+ vertexSize: VERTEX_SIZE,
94
+ zIndex: zIndex + 2
95
+ },
96
+ includeVertices: vertexConfig ? true : false
365
97
  });
366
- useLayoutEffect(() => {
367
- if (!rectEquals(trackedAnnotation.object.rect, currentRect)) {
368
- setCurrentRect(trackedAnnotation.object.rect);
369
- setPreviewObject((prev) => prev ? { ...prev, rect: trackedAnnotation.object.rect } : null);
370
- setCurrentVertices((computeVertices == null ? void 0 : computeVertices(trackedAnnotation.object)) ?? []);
371
- }
372
- }, [trackedAnnotation]);
373
- const currentObject = previewObject ? { ...trackedAnnotation.object, ...previewObject } : trackedAnnotation.object;
374
- return /* @__PURE__ */ jsxs(Fragment, { children: [
98
+ const doubleProps = useDoublePressProps(onDoubleClick);
99
+ useEffect(() => {
100
+ setPreview(trackedAnnotation.object);
101
+ }, [trackedAnnotation.object]);
102
+ return /* @__PURE__ */ jsxs("div", { "data-no-interaction": true, children: [
375
103
  /* @__PURE__ */ jsxs(
376
104
  "div",
377
105
  {
378
- ...rootHandlers,
379
- ...mapDoubleClick(onDoubleClick),
106
+ ...isDraggable && isSelected ? dragProps : {},
107
+ ...doubleProps,
380
108
  style: {
381
109
  position: "absolute",
382
- outline: isSelected ? "1px solid #007ACC" : "none",
110
+ left: currentObject.rect.origin.x * scale,
111
+ top: currentObject.rect.origin.y * scale,
112
+ width: currentObject.rect.size.width * scale,
113
+ height: currentObject.rect.size.height * scale,
114
+ outline: isSelected ? `1px solid ${selectionOutlineColor}` : "none",
383
115
  outlineOffset: isSelected ? `${outlineOffset}px` : "0px",
384
- left: `${currentRect.origin.x * scale}px`,
385
- top: `${currentRect.origin.y * scale}px`,
386
- width: `${currentRect.size.width * scale}px`,
387
- height: `${currentRect.size.height * scale}px`,
388
116
  pointerEvents: isSelected ? "auto" : "none",
389
- touchAction: isSelected ? "auto" : "none",
117
+ touchAction: "none",
390
118
  cursor: isSelected && isDraggable ? "move" : "default",
391
- ...isSelected && {
392
- zIndex: 3
393
- },
119
+ zIndex,
394
120
  ...style
395
121
  },
396
122
  ...props,
397
123
  children: [
398
124
  typeof children === "function" ? children(currentObject) : children,
399
- isSelected && currentVertices.length > 0 && /* @__PURE__ */ jsx(
400
- VertexEditor,
401
- {
402
- rect: currentRect,
403
- rotation,
404
- scale,
405
- vertices: currentVertices,
406
- onEdit: (v) => {
407
- setCurrentVertices(v);
408
- if (computePatch) {
409
- const patch = computePatch(trackedAnnotation.object, {
410
- rect: currentRect,
411
- vertices: v
412
- });
413
- setPreviewObject(patch);
414
- setCurrentRect(patch.rect || currentRect);
415
- }
125
+ isSelected && isResizable && resize.map(
126
+ ({ key, ...hProps }) => (resizeUI == null ? void 0 : resizeUI.component) ? resizeUI.component({
127
+ key,
128
+ ...hProps,
129
+ backgroundColor: HANDLE_COLOR
130
+ }) : /* @__PURE__ */ jsx(
131
+ "div",
132
+ {
133
+ ...hProps,
134
+ style: { ...hProps.style, backgroundColor: HANDLE_COLOR }
416
135
  },
417
- onCommit: (v) => {
418
- if (annotationProvides && computePatch) {
419
- const patch = computePatch(trackedAnnotation.object, {
420
- rect: currentRect,
421
- vertices: v
422
- });
423
- annotationProvides.updateAnnotation(pageIndex, trackedAnnotation.object.id, patch);
424
- }
425
- }
426
- }
136
+ key
137
+ )
427
138
  ),
428
- isSelected && isResizable && /* @__PURE__ */ jsx(
429
- ResizeHandles,
430
- {
431
- rotation,
432
- outlineOffset,
433
- startResize
434
- }
139
+ isSelected && vertices.map(
140
+ ({ key, ...vProps }) => (vertexUI == null ? void 0 : vertexUI.component) ? vertexUI.component({
141
+ key,
142
+ ...vProps,
143
+ backgroundColor: VERTEX_COLOR
144
+ }) : /* @__PURE__ */ jsx(
145
+ "div",
146
+ {
147
+ ...vProps,
148
+ style: { ...vProps.style, backgroundColor: VERTEX_COLOR }
149
+ },
150
+ key
151
+ )
435
152
  )
436
153
  ]
437
154
  }
@@ -440,8 +157,14 @@ function AnnotationContainer({
440
157
  CounterRotate,
441
158
  {
442
159
  rect: {
443
- origin: { x: currentRect.origin.x * scale, y: currentRect.origin.y * scale },
444
- size: { width: currentRect.size.width * scale, height: currentRect.size.height * scale }
160
+ origin: {
161
+ x: currentObject.rect.origin.x * scale,
162
+ y: currentObject.rect.origin.y * scale
163
+ },
164
+ size: {
165
+ width: currentObject.rect.size.width * scale,
166
+ height: currentObject.rect.size.height * scale
167
+ }
445
168
  },
446
169
  rotation,
447
170
  children: ({ rect, menuWrapperProps }) => selectionMenu && selectionMenu({
@@ -457,14 +180,14 @@ function AnnotationContainer({
457
180
  function Highlight({
458
181
  color = "#FFFF00",
459
182
  opacity = 0.5,
460
- rects,
183
+ segmentRects,
461
184
  rect,
462
185
  scale,
463
186
  onClick,
464
187
  style,
465
188
  ...props
466
189
  }) {
467
- return /* @__PURE__ */ jsx(Fragment$1, { children: rects.map((b, i) => /* @__PURE__ */ jsx(
190
+ return /* @__PURE__ */ jsx(Fragment, { children: segmentRects.map((b, i) => /* @__PURE__ */ jsx(
468
191
  "div",
469
192
  {
470
193
  onPointerDown: onClick,
@@ -490,7 +213,7 @@ function Highlight({
490
213
  function Underline({
491
214
  color = "#FFFF00",
492
215
  opacity = 0.5,
493
- rects,
216
+ segmentRects,
494
217
  rect,
495
218
  scale,
496
219
  onClick,
@@ -498,7 +221,7 @@ function Underline({
498
221
  ...props
499
222
  }) {
500
223
  const thickness = 2 * scale;
501
- return /* @__PURE__ */ jsx(Fragment$1, { children: rects.map((r, i) => /* @__PURE__ */ jsx(
224
+ return /* @__PURE__ */ jsx(Fragment, { children: segmentRects.map((r, i) => /* @__PURE__ */ jsx(
502
225
  "div",
503
226
  {
504
227
  onPointerDown: onClick,
@@ -538,7 +261,7 @@ function Underline({
538
261
  function Strikeout({
539
262
  color = "#FFFF00",
540
263
  opacity = 0.5,
541
- rects,
264
+ segmentRects,
542
265
  rect,
543
266
  scale,
544
267
  onClick,
@@ -546,7 +269,7 @@ function Strikeout({
546
269
  ...props
547
270
  }) {
548
271
  const thickness = 2 * scale;
549
- return /* @__PURE__ */ jsx(Fragment$1, { children: rects.map((r, i) => /* @__PURE__ */ jsx(
272
+ return /* @__PURE__ */ jsx(Fragment, { children: segmentRects.map((r, i) => /* @__PURE__ */ jsx(
550
273
  "div",
551
274
  {
552
275
  onPointerDown: onClick,
@@ -587,7 +310,7 @@ function Strikeout({
587
310
  function Squiggly({
588
311
  color = "#FFFF00",
589
312
  opacity = 0.5,
590
- rects,
313
+ segmentRects,
591
314
  rect,
592
315
  scale,
593
316
  onClick,
@@ -601,7 +324,7 @@ function Squiggly({
601
324
  fill="none" stroke="${color}" stroke-width="${amplitude}" stroke-linecap="round"/>
602
325
  </svg>`;
603
326
  const svgDataUri = `url("data:image/svg+xml;utf8,${encodeURIComponent(svg)}")`;
604
- return /* @__PURE__ */ jsx(Fragment$1, { children: rects.map((r, i) => /* @__PURE__ */ jsx(
327
+ return /* @__PURE__ */ jsx(Fragment, { children: segmentRects.map((r, i) => /* @__PURE__ */ jsx(
605
328
  "div",
606
329
  {
607
330
  onPointerDown: onClick,
@@ -830,48 +553,6 @@ function Circle({
830
553
  }
831
554
  );
832
555
  }
833
- const patchInk = (original, ctx) => {
834
- if (original.type !== PdfAnnotationSubtype.INK) {
835
- throw new Error("resizeInkAnnotation: original is not an ink annotation");
836
- }
837
- const oldRect = original.rect;
838
- let scaleX = ctx.rect.size.width / oldRect.size.width;
839
- let scaleY = ctx.rect.size.height / oldRect.size.height;
840
- const minSize = 10;
841
- if (ctx.rect.size.width < minSize || ctx.rect.size.height < minSize) {
842
- scaleX = Math.max(scaleX, minSize / oldRect.size.width);
843
- scaleY = Math.max(scaleY, minSize / oldRect.size.height);
844
- ctx.rect = {
845
- origin: ctx.rect.origin,
846
- size: {
847
- width: oldRect.size.width * scaleX,
848
- height: oldRect.size.height * scaleY
849
- }
850
- };
851
- }
852
- if (ctx.uniform) {
853
- const minScale = Math.min(scaleX, scaleY);
854
- scaleX = minScale;
855
- scaleY = minScale;
856
- ctx.rect.size = {
857
- width: oldRect.size.width * minScale,
858
- height: oldRect.size.height * minScale
859
- };
860
- }
861
- const newInkList = original.inkList.map((stroke) => ({
862
- points: stroke.points.map((p) => ({
863
- x: ctx.rect.origin.x + (p.x - oldRect.origin.x) * scaleX,
864
- y: ctx.rect.origin.y + (p.y - oldRect.origin.y) * scaleY
865
- }))
866
- }));
867
- const avgScale = (scaleX + scaleY) / 2;
868
- const newStrokeWidth = Math.round(original.strokeWidth * avgScale);
869
- return {
870
- rect: ctx.rect,
871
- inkList: newInkList,
872
- strokeWidth: newStrokeWidth
873
- };
874
- };
875
556
  function Line({
876
557
  color = "transparent",
877
558
  opacity = 1,
@@ -1008,13 +689,13 @@ function Polyline({
1008
689
  const endings = useMemo(() => {
1009
690
  if (localPts.length < 2) return { start: null, end: null };
1010
691
  const toAngle = (a, b) => Math.atan2(b.y - a.y, b.x - a.x);
1011
- const startRad = toAngle(localPts[1], localPts[0]);
692
+ const startRad = toAngle(localPts[0], localPts[1]);
1012
693
  const endRad = toAngle(localPts[localPts.length - 2], localPts[localPts.length - 1]);
1013
694
  const start = patching.createEnding(
1014
695
  lineEndings == null ? void 0 : lineEndings.start,
1015
696
  strokeWidth,
1016
697
  startRad + Math.PI,
1017
- // tip points outward from first segment start
698
+ // tip points outward from line start
1018
699
  localPts[0].x,
1019
700
  localPts[0].y
1020
701
  );
@@ -1022,6 +703,7 @@ function Polyline({
1022
703
  lineEndings == null ? void 0 : lineEndings.end,
1023
704
  strokeWidth,
1024
705
  endRad,
706
+ // tip points in line direction
1025
707
  localPts[localPts.length - 1].x,
1026
708
  localPts[localPts.length - 1].y
1027
709
  );
@@ -1111,20 +793,27 @@ function Polygon({
1111
793
  strokeDashArray,
1112
794
  scale,
1113
795
  isSelected,
1114
- onClick
796
+ onClick,
797
+ currentVertex,
798
+ // A preview-only prop
799
+ handleSize = 14
800
+ // in CSS pixels
1115
801
  }) {
802
+ const allPoints = currentVertex ? [...vertices, currentVertex] : vertices;
1116
803
  const localPts = useMemo(
1117
- () => vertices.map(({ x, y }) => ({ x: x - rect.origin.x, y: y - rect.origin.y })),
1118
- [vertices, rect]
804
+ () => allPoints.map(({ x, y }) => ({ x: x - rect.origin.x, y: y - rect.origin.y })),
805
+ [allPoints, rect]
1119
806
  );
1120
807
  const pathData = useMemo(() => {
1121
808
  if (!localPts.length) return "";
1122
809
  const [first, ...rest] = localPts;
1123
- return (`M ${first.x} ${first.y} ` + rest.map((p) => `L ${p.x} ${p.y} `).join("") + "Z").trim();
1124
- }, [localPts]);
810
+ const isPreview = !!currentVertex;
811
+ return (`M ${first.x} ${first.y} ` + rest.map((p) => `L ${p.x} ${p.y}`).join(" ") + (isPreview ? "" : " Z")).trim();
812
+ }, [localPts, currentVertex]);
813
+ const isPreviewing = currentVertex && vertices.length > 0;
1125
814
  const width = rect.size.width * scale;
1126
815
  const height = rect.size.height * scale;
1127
- return /* @__PURE__ */ jsx(
816
+ return /* @__PURE__ */ jsxs(
1128
817
  "svg",
1129
818
  {
1130
819
  style: {
@@ -1138,79 +827,54 @@ function Polygon({
1138
827
  width,
1139
828
  height,
1140
829
  viewBox: `0 0 ${rect.size.width} ${rect.size.height}`,
1141
- children: /* @__PURE__ */ jsx(
1142
- "path",
1143
- {
1144
- d: pathData,
1145
- onPointerDown: onClick,
1146
- onTouchStart: onClick,
1147
- opacity,
1148
- style: {
1149
- fill: color,
1150
- stroke: strokeColor ?? color,
1151
- strokeWidth,
1152
- cursor: isSelected ? "move" : "pointer",
1153
- pointerEvents: isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible",
1154
- strokeLinecap: "butt",
1155
- strokeLinejoin: "miter",
1156
- ...strokeStyle === PdfAnnotationBorderStyle.DASHED && {
1157
- strokeDasharray: strokeDashArray == null ? void 0 : strokeDashArray.join(",")
830
+ children: [
831
+ /* @__PURE__ */ jsx(
832
+ "path",
833
+ {
834
+ d: pathData,
835
+ onPointerDown: onClick,
836
+ onTouchStart: onClick,
837
+ opacity,
838
+ style: {
839
+ fill: currentVertex ? "none" : color,
840
+ // No fill during preview
841
+ stroke: strokeColor ?? color,
842
+ strokeWidth,
843
+ cursor: isSelected ? "move" : "pointer",
844
+ pointerEvents: isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible",
845
+ strokeLinecap: "butt",
846
+ strokeLinejoin: "miter",
847
+ ...strokeStyle === PdfAnnotationBorderStyle.DASHED && {
848
+ strokeDasharray: strokeDashArray == null ? void 0 : strokeDashArray.join(",")
849
+ }
1158
850
  }
1159
851
  }
1160
- }
1161
- )
852
+ ),
853
+ isPreviewing && vertices.length > 1 && /* @__PURE__ */ jsx(
854
+ "path",
855
+ {
856
+ d: `M ${localPts[localPts.length - 1].x} ${localPts[localPts.length - 1].y} L ${localPts[0].x} ${localPts[0].y}`,
857
+ fill: "none",
858
+ style: { stroke: strokeColor, strokeWidth, strokeDasharray: "4,4", opacity: 0.7 }
859
+ }
860
+ ),
861
+ isPreviewing && vertices.length >= 2 && /* @__PURE__ */ jsx(
862
+ "rect",
863
+ {
864
+ x: localPts[0].x - handleSize / scale / 2,
865
+ y: localPts[0].y - handleSize / scale / 2,
866
+ width: handleSize / scale,
867
+ height: handleSize / scale,
868
+ fill: strokeColor,
869
+ opacity: 0.4,
870
+ stroke: strokeColor,
871
+ strokeWidth: strokeWidth / 2
872
+ }
873
+ )
874
+ ]
1162
875
  }
1163
876
  );
1164
877
  }
1165
- const patchLine = (orig, ctx) => {
1166
- if (ctx.vertices && ctx.vertices.length >= 2) {
1167
- const rect = patching.lineRectWithEndings(ctx.vertices, orig.strokeWidth, orig.lineEndings);
1168
- return {
1169
- rect,
1170
- linePoints: { start: ctx.vertices[0], end: ctx.vertices[1] }
1171
- };
1172
- }
1173
- const dx = ctx.rect.origin.x - orig.rect.origin.x;
1174
- const dy = ctx.rect.origin.y - orig.rect.origin.y;
1175
- return {
1176
- rect: ctx.rect,
1177
- linePoints: {
1178
- start: { x: orig.linePoints.start.x + dx, y: orig.linePoints.start.y + dy },
1179
- end: { x: orig.linePoints.end.x + dx, y: orig.linePoints.end.y + dy }
1180
- }
1181
- };
1182
- };
1183
- const patchPolyline = (orig, ctx) => {
1184
- if (ctx.vertices && ctx.vertices.length) {
1185
- return {
1186
- rect: patching.lineRectWithEndings(ctx.vertices, orig.strokeWidth, orig.lineEndings),
1187
- vertices: ctx.vertices
1188
- };
1189
- }
1190
- const dx = ctx.rect.origin.x - orig.rect.origin.x;
1191
- const dy = ctx.rect.origin.y - orig.rect.origin.y;
1192
- const moved = orig.vertices.map((p) => ({ x: p.x + dx, y: p.y + dy }));
1193
- return {
1194
- rect: ctx.rect,
1195
- vertices: moved
1196
- };
1197
- };
1198
- const patchPolygon = (orig, ctx) => {
1199
- if (ctx.vertices && ctx.vertices.length) {
1200
- const pad = orig.strokeWidth / 2;
1201
- return {
1202
- rect: expandRect(rectFromPoints(ctx.vertices), pad),
1203
- vertices: ctx.vertices
1204
- };
1205
- }
1206
- const dx = ctx.rect.origin.x - orig.rect.origin.x;
1207
- const dy = ctx.rect.origin.y - orig.rect.origin.y;
1208
- const moved = orig.vertices.map((p) => ({ x: p.x + dx, y: p.y + dy }));
1209
- return {
1210
- rect: ctx.rect,
1211
- vertices: moved
1212
- };
1213
- };
1214
878
  function FreeText({
1215
879
  isSelected,
1216
880
  isEditing,
@@ -1221,6 +885,7 @@ function FreeText({
1221
885
  }) {
1222
886
  const editorRef = useRef(null);
1223
887
  const { provides: annotationProvides } = useAnnotationCapability();
888
+ const [isIOS, setIsIOS] = useState(false);
1224
889
  useEffect(() => {
1225
890
  if (isEditing && editorRef.current) {
1226
891
  const editor = editorRef.current;
@@ -1235,6 +900,15 @@ function FreeText({
1235
900
  }
1236
901
  }
1237
902
  }, [isEditing]);
903
+ useLayoutEffect(() => {
904
+ try {
905
+ const nav = navigator;
906
+ const ios = /iPad|iPhone|iPod/.test(navigator.userAgent) || navigator.platform === "MacIntel" && (nav == null ? void 0 : nav.maxTouchPoints) > 1;
907
+ setIsIOS(ios);
908
+ } catch {
909
+ setIsIOS(false);
910
+ }
911
+ }, []);
1238
912
  const handleBlur = () => {
1239
913
  if (!annotationProvides) return;
1240
914
  if (!editorRef.current) return;
@@ -1242,6 +916,12 @@ function FreeText({
1242
916
  contents: editorRef.current.innerText
1243
917
  });
1244
918
  };
919
+ const computedFontPx = annotation.object.fontSize * scale;
920
+ const MIN_IOS_FOCUS_FONT_PX = 16;
921
+ const needsComp = isIOS && isEditing && computedFontPx > 0 && computedFontPx < MIN_IOS_FOCUS_FONT_PX;
922
+ const adjustedFontPx = needsComp ? MIN_IOS_FOCUS_FONT_PX : computedFontPx;
923
+ const scaleComp = needsComp ? computedFontPx / MIN_IOS_FOCUS_FONT_PX : 1;
924
+ const invScalePercent = needsComp ? 100 / scaleComp : 100;
1245
925
  return /* @__PURE__ */ jsx(
1246
926
  "div",
1247
927
  {
@@ -1260,9 +940,10 @@ function FreeText({
1260
940
  {
1261
941
  ref: editorRef,
1262
942
  onBlur: handleBlur,
943
+ tabIndex: 0,
1263
944
  style: {
1264
945
  color: annotation.object.fontColor,
1265
- fontSize: annotation.object.fontSize * scale,
946
+ fontSize: adjustedFontPx,
1266
947
  fontFamily: standardFontCss(annotation.object.fontFamily),
1267
948
  textAlign: textAlignmentToCss(annotation.object.textAlign),
1268
949
  flexDirection: "column",
@@ -1270,13 +951,17 @@ function FreeText({
1270
951
  display: "flex",
1271
952
  backgroundColor: annotation.object.backgroundColor,
1272
953
  opacity: annotation.object.opacity,
1273
- width: "100%",
1274
- height: "100%",
954
+ width: needsComp ? `${invScalePercent}%` : "100%",
955
+ height: needsComp ? `${invScalePercent}%` : "100%",
1275
956
  lineHeight: "1.18",
1276
957
  overflow: "hidden",
1277
- cursor: isEditing ? "text" : "pointer"
958
+ cursor: isEditing ? "text" : "pointer",
959
+ outline: "none",
960
+ transform: needsComp ? `scale(${scaleComp})` : void 0,
961
+ transformOrigin: "top left"
1278
962
  },
1279
963
  contentEditable: isEditing,
964
+ ...suppressContentEditableWarningProps,
1280
965
  children: annotation.object.contents
1281
966
  }
1282
967
  )
@@ -1328,7 +1013,7 @@ function RenderAnnotation({
1328
1013
  urlRef.current = null;
1329
1014
  }
1330
1015
  };
1331
- return /* @__PURE__ */ jsx(Fragment, { children: imageUrl && /* @__PURE__ */ jsx(
1016
+ return /* @__PURE__ */ jsx(Fragment$1, { children: imageUrl && /* @__PURE__ */ jsx(
1332
1017
  "img",
1333
1018
  {
1334
1019
  src: imageUrl,
@@ -1351,7 +1036,8 @@ function Stamp({ isSelected, annotation, pageIndex, scale, onClick }) {
1351
1036
  width: "100%",
1352
1037
  height: "100%",
1353
1038
  zIndex: 2,
1354
- pointerEvents: isSelected ? "none" : "auto"
1039
+ pointerEvents: isSelected ? "none" : "auto",
1040
+ cursor: "pointer"
1355
1041
  },
1356
1042
  onPointerDown: onClick,
1357
1043
  onTouchStart: onClick,
@@ -1399,15 +1085,17 @@ function Annotations(annotationsProps) {
1399
1085
  if (annotationProvides && selectionProvides) {
1400
1086
  annotationProvides.selectAnnotation(pageIndex, annotation.object.id);
1401
1087
  selectionProvides.clear();
1402
- setEditingId(null);
1088
+ if (annotation.object.id !== editingId) {
1089
+ setEditingId(null);
1090
+ }
1403
1091
  }
1404
1092
  },
1405
- [annotationProvides, selectionProvides, pageIndex]
1093
+ [annotationProvides, selectionProvides, editingId, pageIndex]
1406
1094
  );
1407
1095
  useEffect(() => {
1408
1096
  return register(handlers);
1409
1097
  }, [register, handlers]);
1410
- return /* @__PURE__ */ jsx(Fragment$1, { children: annotations.map((annotation) => {
1098
+ return /* @__PURE__ */ jsx(Fragment, { children: annotations.map((annotation) => {
1411
1099
  const isSelected = (selectionState == null ? void 0 : selectionState.object.id) === annotation.object.id;
1412
1100
  const isEditing = editingId === annotation.object.id;
1413
1101
  if (isInk(annotation)) {
@@ -1419,7 +1107,6 @@ function Annotations(annotationsProps) {
1419
1107
  isDraggable: true,
1420
1108
  isResizable: true,
1421
1109
  selectionMenu,
1422
- computePatch: patchInk,
1423
1110
  style: {
1424
1111
  mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1425
1112
  },
@@ -1427,12 +1114,8 @@ function Annotations(annotationsProps) {
1427
1114
  children: (obj) => /* @__PURE__ */ jsx(
1428
1115
  Ink,
1429
1116
  {
1117
+ ...obj,
1430
1118
  isSelected,
1431
- color: obj.color,
1432
- opacity: obj.opacity,
1433
- strokeWidth: obj.strokeWidth,
1434
- inkList: obj.inkList,
1435
- rect: obj.rect,
1436
1119
  scale,
1437
1120
  onClick: (e) => handleClick(e, annotation)
1438
1121
  }
@@ -1457,14 +1140,8 @@ function Annotations(annotationsProps) {
1457
1140
  children: (obj) => /* @__PURE__ */ jsx(
1458
1141
  Square,
1459
1142
  {
1143
+ ...obj,
1460
1144
  isSelected,
1461
- rect: obj.rect,
1462
- color: obj.color,
1463
- opacity: obj.opacity,
1464
- strokeWidth: obj.strokeWidth,
1465
- strokeColor: obj.strokeColor,
1466
- strokeStyle: obj.strokeStyle,
1467
- strokeDashArray: obj.strokeDashArray,
1468
1145
  scale,
1469
1146
  onClick: (e) => handleClick(e, annotation)
1470
1147
  }
@@ -1489,14 +1166,8 @@ function Annotations(annotationsProps) {
1489
1166
  children: (obj) => /* @__PURE__ */ jsx(
1490
1167
  Circle,
1491
1168
  {
1169
+ ...obj,
1492
1170
  isSelected,
1493
- rect: obj.rect,
1494
- color: obj.color,
1495
- opacity: obj.opacity,
1496
- strokeWidth: obj.strokeWidth,
1497
- strokeColor: obj.strokeColor,
1498
- strokeStyle: obj.strokeStyle,
1499
- strokeDashArray: obj.strokeDashArray,
1500
1171
  scale,
1501
1172
  onClick: (e) => handleClick(e, annotation)
1502
1173
  }
@@ -1514,21 +1185,12 @@ function Annotations(annotationsProps) {
1514
1185
  isDraggable: false,
1515
1186
  isResizable: false,
1516
1187
  selectionMenu,
1188
+ zIndex: 0,
1517
1189
  style: {
1518
1190
  mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1519
1191
  },
1520
1192
  ...annotationsProps,
1521
- children: (obj) => /* @__PURE__ */ jsx(
1522
- Underline,
1523
- {
1524
- rect: obj.rect,
1525
- color: obj.color,
1526
- opacity: obj.opacity,
1527
- rects: obj.segmentRects,
1528
- scale,
1529
- onClick: (e) => handleClick(e, annotation)
1530
- }
1531
- )
1193
+ children: (obj) => /* @__PURE__ */ jsx(Underline, { ...obj, scale, onClick: (e) => handleClick(e, annotation) })
1532
1194
  },
1533
1195
  annotation.object.id
1534
1196
  );
@@ -1542,21 +1204,12 @@ function Annotations(annotationsProps) {
1542
1204
  isDraggable: false,
1543
1205
  isResizable: false,
1544
1206
  selectionMenu,
1207
+ zIndex: 0,
1545
1208
  style: {
1546
1209
  mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1547
1210
  },
1548
1211
  ...annotationsProps,
1549
- children: (obj) => /* @__PURE__ */ jsx(
1550
- Strikeout,
1551
- {
1552
- rect: obj.rect,
1553
- color: obj.color,
1554
- opacity: obj.opacity,
1555
- rects: obj.segmentRects,
1556
- scale,
1557
- onClick: (e) => handleClick(e, annotation)
1558
- }
1559
- )
1212
+ children: (obj) => /* @__PURE__ */ jsx(Strikeout, { ...obj, scale, onClick: (e) => handleClick(e, annotation) })
1560
1213
  },
1561
1214
  annotation.object.id
1562
1215
  );
@@ -1570,21 +1223,12 @@ function Annotations(annotationsProps) {
1570
1223
  isDraggable: false,
1571
1224
  isResizable: false,
1572
1225
  selectionMenu,
1226
+ zIndex: 0,
1573
1227
  style: {
1574
1228
  mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1575
1229
  },
1576
1230
  ...annotationsProps,
1577
- children: (obj) => /* @__PURE__ */ jsx(
1578
- Squiggly,
1579
- {
1580
- color: obj.color,
1581
- opacity: obj.opacity,
1582
- rects: obj.segmentRects,
1583
- rect: obj.rect,
1584
- scale,
1585
- onClick: (e) => handleClick(e, annotation)
1586
- }
1587
- )
1231
+ children: (obj) => /* @__PURE__ */ jsx(Squiggly, { ...obj, scale, onClick: (e) => handleClick(e, annotation) })
1588
1232
  },
1589
1233
  annotation.object.id
1590
1234
  );
@@ -1598,21 +1242,12 @@ function Annotations(annotationsProps) {
1598
1242
  isDraggable: false,
1599
1243
  isResizable: false,
1600
1244
  selectionMenu,
1245
+ zIndex: 0,
1601
1246
  style: {
1602
1247
  mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Multiply)
1603
1248
  },
1604
1249
  ...annotationsProps,
1605
- children: (obj) => /* @__PURE__ */ jsx(
1606
- Highlight,
1607
- {
1608
- color: obj.color,
1609
- opacity: obj.opacity,
1610
- rects: obj.segmentRects,
1611
- scale,
1612
- rect: obj.rect,
1613
- onClick: (e) => handleClick(e, annotation)
1614
- }
1615
- )
1250
+ children: (obj) => /* @__PURE__ */ jsx(Highlight, { ...obj, scale, onClick: (e) => handleClick(e, annotation) })
1616
1251
  },
1617
1252
  annotation.object.id
1618
1253
  );
@@ -1626,28 +1261,30 @@ function Annotations(annotationsProps) {
1626
1261
  isDraggable: true,
1627
1262
  isResizable: false,
1628
1263
  selectionMenu,
1629
- computePatch: patchLine,
1630
- computeVertices: (annotation2) => [
1631
- annotation2.linePoints.start,
1632
- annotation2.linePoints.end
1633
- ],
1264
+ vertexConfig: {
1265
+ extractVertices: (annotation2) => [
1266
+ annotation2.linePoints.start,
1267
+ annotation2.linePoints.end
1268
+ ],
1269
+ transformAnnotation: (annotation2, vertices) => {
1270
+ return {
1271
+ ...annotation2,
1272
+ linePoints: {
1273
+ start: vertices[0],
1274
+ end: vertices[1]
1275
+ }
1276
+ };
1277
+ }
1278
+ },
1634
1279
  style: {
1635
1280
  mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1636
1281
  },
1637
1282
  ...annotationsProps,
1638
- children: (obj) => /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
1283
+ children: (obj) => /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(
1639
1284
  Line,
1640
1285
  {
1286
+ ...obj,
1641
1287
  isSelected,
1642
- rect: obj.rect,
1643
- color: obj.color,
1644
- opacity: obj.opacity,
1645
- linePoints: obj.linePoints,
1646
- lineEndings: obj.lineEndings,
1647
- strokeWidth: obj.strokeWidth,
1648
- strokeColor: obj.strokeColor,
1649
- strokeStyle: obj.strokeStyle,
1650
- strokeDashArray: obj.strokeDashArray,
1651
1288
  scale,
1652
1289
  onClick: (e) => handleClick(e, annotation)
1653
1290
  }
@@ -1665,23 +1302,24 @@ function Annotations(annotationsProps) {
1665
1302
  isDraggable: true,
1666
1303
  isResizable: false,
1667
1304
  selectionMenu,
1668
- computePatch: patchPolyline,
1669
- computeVertices: (annotation2) => annotation2.vertices,
1305
+ vertexConfig: {
1306
+ extractVertices: (annotation2) => annotation2.vertices,
1307
+ transformAnnotation: (annotation2, vertices) => {
1308
+ return {
1309
+ ...annotation2,
1310
+ vertices
1311
+ };
1312
+ }
1313
+ },
1670
1314
  style: {
1671
1315
  mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1672
1316
  },
1673
1317
  ...annotationsProps,
1674
- children: (obj) => /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
1318
+ children: (obj) => /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(
1675
1319
  Polyline,
1676
1320
  {
1321
+ ...obj,
1677
1322
  isSelected,
1678
- rect: obj.rect,
1679
- color: obj.color,
1680
- opacity: obj.opacity,
1681
- vertices: obj.vertices,
1682
- lineEndings: obj.lineEndings,
1683
- strokeWidth: obj.strokeWidth,
1684
- strokeColor: obj.strokeColor,
1685
1323
  scale,
1686
1324
  onClick: (e) => handleClick(e, annotation)
1687
1325
  }
@@ -1699,24 +1337,24 @@ function Annotations(annotationsProps) {
1699
1337
  isDraggable: true,
1700
1338
  isResizable: false,
1701
1339
  selectionMenu,
1702
- computeVertices: (annotation2) => annotation2.vertices,
1703
- computePatch: patchPolygon,
1340
+ vertexConfig: {
1341
+ extractVertices: (annotation2) => annotation2.vertices,
1342
+ transformAnnotation: (annotation2, vertices) => {
1343
+ return {
1344
+ ...annotation2,
1345
+ vertices
1346
+ };
1347
+ }
1348
+ },
1704
1349
  style: {
1705
1350
  mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1706
1351
  },
1707
1352
  ...annotationsProps,
1708
- children: (obj) => /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
1353
+ children: (obj) => /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(
1709
1354
  Polygon,
1710
1355
  {
1356
+ ...obj,
1711
1357
  isSelected,
1712
- rect: obj.rect,
1713
- color: obj.color,
1714
- opacity: obj.opacity,
1715
- vertices: obj.vertices,
1716
- strokeWidth: obj.strokeWidth,
1717
- strokeColor: obj.strokeColor,
1718
- strokeStyle: obj.strokeStyle,
1719
- strokeDashArray: obj.strokeDashArray,
1720
1358
  scale,
1721
1359
  onClick: (e) => handleClick(e, annotation)
1722
1360
  }
@@ -1731,17 +1369,16 @@ function Annotations(annotationsProps) {
1731
1369
  {
1732
1370
  trackedAnnotation: annotation,
1733
1371
  isSelected,
1734
- isDraggable: true,
1372
+ isDraggable: !isEditing,
1735
1373
  isResizable: true,
1736
1374
  selectionMenu,
1737
- outlineOffset: 6,
1375
+ style: {
1376
+ mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1377
+ },
1738
1378
  onDoubleClick: (e) => {
1739
1379
  e.stopPropagation();
1740
1380
  setEditingId(annotation.object.id);
1741
1381
  },
1742
- style: {
1743
- mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1744
- },
1745
1382
  ...annotationsProps,
1746
1383
  children: (object) => /* @__PURE__ */ jsx(
1747
1384
  FreeText,
@@ -1798,7 +1435,7 @@ function TextMarkup({ pageIndex, scale }) {
1798
1435
  const { provides: annotationProvides } = useAnnotationCapability();
1799
1436
  const [rects, setRects] = useState([]);
1800
1437
  const [boundingRect, setBoundingRect] = useState(null);
1801
- const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
1438
+ const [activeTool, setActiveTool] = useState(null);
1802
1439
  useEffect(() => {
1803
1440
  if (!selectionProvides) return;
1804
1441
  const off = selectionProvides.onSelectionChange(() => {
@@ -1813,8 +1450,8 @@ function TextMarkup({ pageIndex, scale }) {
1813
1450
  return off;
1814
1451
  }, [annotationProvides]);
1815
1452
  if (!boundingRect) return null;
1816
- if (!activeTool.defaults) return null;
1817
- switch (activeTool.defaults.subtype) {
1453
+ if (!activeTool || !activeTool.defaults) return null;
1454
+ switch (activeTool.defaults.type) {
1818
1455
  case PdfAnnotationSubtype.UNDERLINE:
1819
1456
  return /* @__PURE__ */ jsx(
1820
1457
  "div",
@@ -1830,7 +1467,7 @@ function TextMarkup({ pageIndex, scale }) {
1830
1467
  {
1831
1468
  color: (_b = activeTool.defaults) == null ? void 0 : _b.color,
1832
1469
  opacity: (_c = activeTool.defaults) == null ? void 0 : _c.opacity,
1833
- rects,
1470
+ segmentRects: rects,
1834
1471
  scale
1835
1472
  }
1836
1473
  )
@@ -1851,7 +1488,7 @@ function TextMarkup({ pageIndex, scale }) {
1851
1488
  {
1852
1489
  color: (_e = activeTool.defaults) == null ? void 0 : _e.color,
1853
1490
  opacity: (_f = activeTool.defaults) == null ? void 0 : _f.opacity,
1854
- rects,
1491
+ segmentRects: rects,
1855
1492
  scale
1856
1493
  }
1857
1494
  )
@@ -1872,7 +1509,7 @@ function TextMarkup({ pageIndex, scale }) {
1872
1509
  {
1873
1510
  color: (_h = activeTool.defaults) == null ? void 0 : _h.color,
1874
1511
  opacity: (_i = activeTool.defaults) == null ? void 0 : _i.opacity,
1875
- rects,
1512
+ segmentRects: rects,
1876
1513
  scale
1877
1514
  }
1878
1515
  )
@@ -1893,7 +1530,7 @@ function TextMarkup({ pageIndex, scale }) {
1893
1530
  {
1894
1531
  color: (_k = activeTool.defaults) == null ? void 0 : _k.color,
1895
1532
  opacity: (_l = activeTool.defaults) == null ? void 0 : _l.opacity,
1896
- rects,
1533
+ segmentRects: rects,
1897
1534
  scale
1898
1535
  }
1899
1536
  )
@@ -1903,1110 +1540,131 @@ function TextMarkup({ pageIndex, scale }) {
1903
1540
  return null;
1904
1541
  }
1905
1542
  }
1906
- const InkPaint = ({ pageIndex, scale, pageWidth, pageHeight }) => {
1907
- var _a, _b, _c, _d, _e;
1908
- const { provides: annotationProvides } = useAnnotationCapability();
1909
- const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
1910
- useEffect(() => {
1911
- if (!annotationProvides) return;
1912
- const off = annotationProvides.onActiveToolChange(setActiveTool);
1913
- return off;
1914
- }, [annotationProvides]);
1915
- if (!activeTool.defaults) return null;
1916
- if (activeTool.defaults.subtype !== PdfAnnotationSubtype.INK) return null;
1917
- const toolColor = ((_a = activeTool.defaults) == null ? void 0 : _a.color) ?? "#000000";
1918
- const toolOpacity = ((_b = activeTool.defaults) == null ? void 0 : _b.opacity) ?? 1;
1919
- const toolStrokeWidth = ((_c = activeTool.defaults) == null ? void 0 : _c.strokeWidth) ?? 2;
1920
- const toolBlendMode = ((_d = activeTool.defaults) == null ? void 0 : _d.blendMode) ?? PdfBlendMode.Normal;
1921
- const intent = (_e = activeTool.defaults) == null ? void 0 : _e.intent;
1922
- const { register } = usePointerHandlers({ modeId: "ink", pageIndex });
1923
- const [currentStrokes, setCurrentStrokes] = useState([]);
1924
- const [isDrawing, setIsDrawing] = useState(false);
1925
- const timerRef = useRef(null);
1926
- const pageWidthPDF = pageWidth / scale;
1927
- const pageHeightPDF = pageHeight / scale;
1928
- const handlers = useMemo(
1929
- () => ({
1930
- onPointerDown: (pos, evt) => {
1931
- var _a2;
1932
- const curX = clamp(pos.x, 0, pageWidthPDF);
1933
- const curY = clamp(pos.y, 0, pageHeightPDF);
1934
- setIsDrawing(true);
1935
- if (timerRef.current) {
1936
- clearTimeout(timerRef.current);
1937
- timerRef.current = null;
1938
- setCurrentStrokes((prev) => [...prev, { points: [{ x: curX, y: curY }] }]);
1939
- } else {
1940
- setCurrentStrokes([{ points: [{ x: curX, y: curY }] }]);
1941
- }
1942
- (_a2 = evt.setPointerCapture) == null ? void 0 : _a2.call(evt);
1943
- },
1944
- onPointerMove: (pos) => {
1945
- if (!isDrawing) return;
1946
- const curX = clamp(pos.x, 0, pageWidthPDF);
1947
- const curY = clamp(pos.y, 0, pageHeightPDF);
1948
- setCurrentStrokes((prev) => {
1949
- if (!prev.length) return prev;
1950
- const last = prev[prev.length - 1];
1951
- const newLast = { points: [...last.points, { x: curX, y: curY }] };
1952
- return [...prev.slice(0, -1), newLast];
1953
- });
1954
- },
1955
- onPointerUp: (_, evt) => {
1956
- var _a2;
1957
- setIsDrawing(false);
1958
- (_a2 = evt.releasePointerCapture) == null ? void 0 : _a2.call(evt);
1959
- if (timerRef.current) clearTimeout(timerRef.current);
1960
- timerRef.current = setTimeout(() => {
1961
- if (currentStrokes.length && annotationProvides) {
1962
- const allPoints2 = currentStrokes.flatMap((s) => s.points);
1963
- if (!allPoints2.length) return;
1964
- const rect2 = expandRect(rectFromPoints(allPoints2), toolStrokeWidth / 2);
1965
- if (rect2.size.width < 1 || rect2.size.height < 1) return;
1966
- const anno = {
1967
- type: PdfAnnotationSubtype.INK,
1968
- intent,
1969
- blendMode: toolBlendMode,
1970
- rect: rect2,
1971
- inkList: currentStrokes,
1972
- color: toolColor,
1973
- opacity: toolOpacity,
1974
- strokeWidth: toolStrokeWidth,
1975
- created: /* @__PURE__ */ new Date(),
1976
- pageIndex,
1977
- id: uuidV4()
1978
- };
1979
- annotationProvides.createAnnotation(pageIndex, anno);
1980
- annotationProvides.setActiveVariant(null);
1981
- annotationProvides.selectAnnotation(pageIndex, anno.id);
1982
- }
1983
- setCurrentStrokes([]);
1984
- timerRef.current = null;
1985
- }, 3e3);
1986
- },
1987
- onPointerCancel: (_, evt) => {
1988
- var _a2;
1989
- setIsDrawing(false);
1990
- (_a2 = evt.releasePointerCapture) == null ? void 0 : _a2.call(evt);
1991
- setCurrentStrokes([]);
1992
- if (timerRef.current) {
1993
- clearTimeout(timerRef.current);
1994
- timerRef.current = null;
1995
- }
1996
- }
1997
- }),
1998
- [
1999
- pageWidthPDF,
2000
- pageHeightPDF,
2001
- currentStrokes,
2002
- annotationProvides,
2003
- pageIndex,
2004
- toolColor,
2005
- toolOpacity,
2006
- toolStrokeWidth,
2007
- isDrawing
2008
- ]
2009
- );
2010
- useEffect(() => {
2011
- if (!register) return;
2012
- return register(handlers);
2013
- }, [register, handlers]);
2014
- useEffect(() => {
2015
- return () => {
2016
- if (timerRef.current) clearTimeout(timerRef.current);
2017
- };
2018
- }, []);
2019
- if (!currentStrokes.length) return null;
2020
- const allPoints = currentStrokes.flatMap((s) => s.points);
2021
- if (!allPoints.length) return null;
2022
- const rect = expandRect(rectFromPoints(allPoints), toolStrokeWidth / 2);
2023
- const paths = currentStrokes.map(({ points }) => {
2024
- let d = "";
2025
- points.forEach(({ x, y }, i) => {
2026
- const lx = x - rect.origin.x;
2027
- const ly = y - rect.origin.y;
2028
- d += (i === 0 ? "M" : "L") + lx + " " + ly + " ";
2029
- });
2030
- return d.trim();
2031
- });
2032
- return /* @__PURE__ */ jsx(
2033
- "svg",
2034
- {
2035
- style: {
2036
- position: "absolute",
2037
- left: rect.origin.x * scale,
2038
- top: rect.origin.y * scale,
2039
- width: rect.size.width * scale,
2040
- height: rect.size.height * scale,
2041
- pointerEvents: "none",
2042
- zIndex: 2
2043
- },
2044
- width: rect.size.width * scale,
2045
- height: rect.size.height * scale,
2046
- viewBox: `0 0 ${rect.size.width} ${rect.size.height}`,
2047
- children: paths.map((d, i) => /* @__PURE__ */ jsx(
2048
- "path",
2049
- {
2050
- d,
2051
- fill: "none",
2052
- opacity: toolOpacity,
2053
- style: {
2054
- stroke: toolColor,
2055
- strokeWidth: toolStrokeWidth,
2056
- strokeLinecap: "round",
2057
- strokeLinejoin: "round"
2058
- }
2059
- },
2060
- i
2061
- ))
2062
- }
2063
- );
2064
- };
2065
- const CirclePaint = ({
2066
- pageIndex,
2067
- scale,
2068
- pageWidth,
2069
- pageHeight,
2070
- cursor
2071
- }) => {
2072
- const { provides: annotationProvides } = useAnnotationCapability();
2073
- const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
2074
- useEffect(() => {
2075
- if (!annotationProvides) return;
2076
- return annotationProvides.onActiveToolChange(setActiveTool);
2077
- }, [annotationProvides]);
2078
- if (!activeTool.defaults) return null;
2079
- if (activeTool.defaults.subtype !== PdfAnnotationSubtype.CIRCLE) return null;
2080
- const toolColor = activeTool.defaults.color ?? "#000000";
2081
- const toolOpacity = activeTool.defaults.opacity ?? 1;
2082
- const toolStrokeWidth = activeTool.defaults.strokeWidth ?? 2;
2083
- const toolStrokeColor = activeTool.defaults.strokeColor ?? "#000000";
2084
- const toolStrokeStyle = activeTool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID;
2085
- const toolStrokeDashArray = activeTool.defaults.strokeDashArray ?? [];
2086
- const { register } = usePointerHandlers({ modeId: "circle", pageIndex });
2087
- const pageWidthPDF = pageWidth / scale;
2088
- const pageHeightPDF = pageHeight / scale;
2089
- const [start, setStart] = useState(null);
2090
- const [current, setCurrent] = useState(null);
2091
- const handlers = useMemo(
2092
- () => ({
2093
- onPointerDown: (pos, evt) => {
2094
- var _a;
2095
- const x = clamp(pos.x, 0, pageWidthPDF);
2096
- const y = clamp(pos.y, 0, pageHeightPDF);
2097
- setStart({ x, y });
2098
- setCurrent({ x, y });
2099
- (_a = evt.setPointerCapture) == null ? void 0 : _a.call(evt);
2100
- },
2101
- onPointerMove: (pos) => {
2102
- if (!start) return;
2103
- const x = clamp(pos.x, 0, pageWidthPDF);
2104
- const y = clamp(pos.y, 0, pageHeightPDF);
2105
- setCurrent({ x, y });
2106
- },
2107
- onPointerUp: (_, evt) => {
2108
- var _a;
2109
- if (start && current && annotationProvides) {
2110
- const minX2 = Math.min(start.x, current.x);
2111
- const minY2 = Math.min(start.y, current.y);
2112
- const maxX2 = Math.max(start.x, current.x);
2113
- const maxY2 = Math.max(start.y, current.y);
2114
- if (maxX2 - minX2 >= 1 && maxY2 - minY2 >= 1) {
2115
- const halfStroke2 = toolStrokeWidth / 2;
2116
- const rect = {
2117
- origin: { x: minX2 - halfStroke2, y: minY2 - halfStroke2 },
2118
- size: {
2119
- width: maxX2 - minX2 + toolStrokeWidth,
2120
- height: maxY2 - minY2 + toolStrokeWidth
2121
- }
2122
- };
2123
- const anno = {
2124
- type: PdfAnnotationSubtype.CIRCLE,
2125
- rect,
2126
- flags: ["print"],
2127
- color: toolColor,
2128
- opacity: toolOpacity,
2129
- strokeWidth: toolStrokeWidth,
2130
- strokeColor: toolStrokeColor,
2131
- strokeStyle: toolStrokeStyle,
2132
- strokeDashArray: toolStrokeDashArray,
2133
- created: /* @__PURE__ */ new Date(),
2134
- pageIndex,
2135
- id: uuidV4()
2136
- };
2137
- annotationProvides.createAnnotation(pageIndex, anno);
2138
- annotationProvides.setActiveVariant(null);
2139
- annotationProvides.selectAnnotation(pageIndex, anno.id);
2140
- }
2141
- }
2142
- (_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
2143
- setStart(null);
2144
- setCurrent(null);
2145
- },
2146
- onPointerCancel: (_, evt) => {
2147
- var _a;
2148
- (_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
2149
- setStart(null);
2150
- setCurrent(null);
2151
- }
2152
- }),
2153
- [
2154
- start,
2155
- current,
2156
- annotationProvides,
2157
- pageIndex,
2158
- pageWidthPDF,
2159
- pageHeightPDF,
2160
- toolColor,
2161
- toolOpacity,
2162
- toolStrokeWidth
2163
- ]
2164
- );
2165
- useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
2166
- if (!start || !current) return null;
2167
- const minX = Math.min(start.x, current.x);
2168
- const minY = Math.min(start.y, current.y);
2169
- const maxX = Math.max(start.x, current.x);
2170
- const maxY = Math.max(start.y, current.y);
2171
- const halfStroke = toolStrokeWidth / 2;
2172
- const svgMinX = minX - halfStroke;
2173
- const svgMinY = minY - halfStroke;
2174
- const width = maxX - minX;
2175
- const height = maxY - minY;
2176
- const dw = width + toolStrokeWidth;
2177
- const dh = height + toolStrokeWidth;
2178
- const cx = halfStroke + width / 2;
2179
- const cy = halfStroke + height / 2;
2180
- const rx = width / 2;
2181
- const ry = height / 2;
2182
- return /* @__PURE__ */ jsx(
2183
- "svg",
2184
- {
2185
- style: {
2186
- position: "absolute",
2187
- left: svgMinX * scale,
2188
- top: svgMinY * scale,
2189
- width: dw * scale,
2190
- height: dh * scale,
2191
- pointerEvents: "none",
2192
- zIndex: 2
2193
- },
2194
- width: dw * scale,
2195
- height: dh * scale,
2196
- viewBox: `0 0 ${dw} ${dh}`,
2197
- children: /* @__PURE__ */ jsx(
2198
- "ellipse",
2199
- {
2200
- cx,
2201
- cy,
2202
- rx,
2203
- ry,
2204
- fill: toolColor,
2205
- opacity: toolOpacity,
2206
- style: {
2207
- cursor,
2208
- stroke: toolStrokeColor,
2209
- strokeWidth: toolStrokeWidth,
2210
- ...toolStrokeStyle === PdfAnnotationBorderStyle.DASHED && {
2211
- strokeDasharray: toolStrokeDashArray.join(",")
2212
- }
2213
- }
2214
- }
2215
- )
2216
- }
2217
- );
2218
- };
2219
- const SquarePaint = ({
2220
- pageIndex,
2221
- scale,
2222
- pageWidth,
2223
- pageHeight,
2224
- cursor
2225
- }) => {
2226
- const { provides: annotationProvides } = useAnnotationCapability();
2227
- const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
2228
- useEffect(() => {
2229
- if (!annotationProvides) return;
2230
- return annotationProvides.onActiveToolChange(setActiveTool);
2231
- }, [annotationProvides]);
2232
- if (!activeTool.defaults) return null;
2233
- if (activeTool.defaults.subtype !== PdfAnnotationSubtype.SQUARE) return null;
2234
- const toolColor = activeTool.defaults.color ?? "#000000";
2235
- const toolOpacity = activeTool.defaults.opacity ?? 1;
2236
- const toolStrokeWidth = activeTool.defaults.strokeWidth ?? 2;
2237
- const toolStrokeColor = activeTool.defaults.strokeColor ?? "#000000";
2238
- const toolStrokeStyle = activeTool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID;
2239
- const toolStrokeDashArray = activeTool.defaults.strokeDashArray ?? [];
2240
- const { register } = usePointerHandlers({ modeId: "square", pageIndex });
2241
- const pageWidthPDF = pageWidth / scale;
2242
- const pageHeightPDF = pageHeight / scale;
2243
- const [start, setStart] = useState(null);
2244
- const [current, setCurrent] = useState(null);
2245
- const handlers = useMemo(
2246
- () => ({
2247
- onPointerDown: (pos, evt) => {
2248
- var _a, _b;
2249
- const x = clamp(pos.x, 0, pageWidthPDF);
2250
- const y = clamp(pos.y, 0, pageHeightPDF);
2251
- setStart({ x, y });
2252
- setCurrent({ x, y });
2253
- (_b = (_a = evt.target) == null ? void 0 : _a.setPointerCapture) == null ? void 0 : _b.call(_a, evt.pointerId);
2254
- },
2255
- onPointerMove: (pos) => {
2256
- if (!start) return;
2257
- const x = clamp(pos.x, 0, pageWidthPDF);
2258
- const y = clamp(pos.y, 0, pageHeightPDF);
2259
- setCurrent({ x, y });
2260
- },
2261
- onPointerUp: (_, evt) => {
2262
- var _a, _b;
2263
- if (start && current && annotationProvides) {
2264
- const minX2 = Math.min(start.x, current.x);
2265
- const minY2 = Math.min(start.y, current.y);
2266
- const maxX2 = Math.max(start.x, current.x);
2267
- const maxY2 = Math.max(start.y, current.y);
2268
- if (maxX2 - minX2 >= 1 && maxY2 - minY2 >= 1) {
2269
- const halfStroke2 = toolStrokeWidth / 2;
2270
- const rect = {
2271
- origin: { x: minX2 - halfStroke2, y: minY2 - halfStroke2 },
2272
- size: {
2273
- width: maxX2 - minX2 + toolStrokeWidth,
2274
- height: maxY2 - minY2 + toolStrokeWidth
2275
- }
2276
- };
2277
- const anno = {
2278
- type: PdfAnnotationSubtype.SQUARE,
2279
- rect,
2280
- flags: ["print"],
2281
- color: toolColor,
2282
- opacity: toolOpacity,
2283
- strokeWidth: toolStrokeWidth,
2284
- strokeColor: toolStrokeColor,
2285
- strokeStyle: toolStrokeStyle,
2286
- strokeDashArray: toolStrokeDashArray,
2287
- pageIndex,
2288
- id: uuidV4(),
2289
- created: /* @__PURE__ */ new Date()
2290
- };
2291
- annotationProvides.createAnnotation(pageIndex, anno);
2292
- annotationProvides.setActiveVariant(null);
2293
- annotationProvides.selectAnnotation(pageIndex, anno.id);
2294
- }
2295
- }
2296
- (_b = (_a = evt.target) == null ? void 0 : _a.releasePointerCapture) == null ? void 0 : _b.call(_a, evt.pointerId);
2297
- setStart(null);
2298
- setCurrent(null);
2299
- },
2300
- onPointerCancel: (_, evt) => {
2301
- var _a, _b;
2302
- (_b = (_a = evt.target) == null ? void 0 : _a.releasePointerCapture) == null ? void 0 : _b.call(_a, evt.pointerId);
2303
- setStart(null);
2304
- setCurrent(null);
2305
- }
2306
- }),
2307
- [
2308
- start,
2309
- current,
2310
- annotationProvides,
2311
- pageIndex,
2312
- pageWidthPDF,
2313
- pageHeightPDF,
2314
- toolColor,
2315
- toolOpacity,
2316
- toolStrokeWidth
2317
- ]
2318
- );
2319
- useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
2320
- if (!start || !current) return null;
2321
- const minX = Math.min(start.x, current.x);
2322
- const minY = Math.min(start.y, current.y);
2323
- const maxX = Math.max(start.x, current.x);
2324
- const maxY = Math.max(start.y, current.y);
2325
- const halfStroke = toolStrokeWidth / 2;
2326
- const svgMinX = minX - halfStroke;
2327
- const svgMinY = minY - halfStroke;
2328
- const width = maxX - minX;
2329
- const height = maxY - minY;
2330
- const dw = width + toolStrokeWidth;
2331
- const dh = height + toolStrokeWidth;
2332
- return /* @__PURE__ */ jsx(
2333
- "svg",
2334
- {
2335
- style: {
2336
- position: "absolute",
2337
- left: svgMinX * scale,
2338
- top: svgMinY * scale,
2339
- width: dw * scale,
2340
- height: dh * scale,
2341
- pointerEvents: "none",
2342
- zIndex: 2
2343
- },
2344
- width: dw * scale,
2345
- height: dh * scale,
2346
- viewBox: `0 0 ${dw} ${dh}`,
2347
- children: /* @__PURE__ */ jsx(
2348
- "rect",
2349
- {
2350
- x: halfStroke,
2351
- y: halfStroke,
2352
- width,
2353
- height,
2354
- fill: toolColor,
2355
- opacity: toolOpacity,
2356
- style: {
2357
- cursor,
2358
- stroke: toolStrokeColor,
2359
- strokeWidth: toolStrokeWidth,
2360
- ...toolStrokeStyle === PdfAnnotationBorderStyle.DASHED && {
2361
- strokeDasharray: toolStrokeDashArray.join(",")
2362
- }
2363
- }
2364
- }
2365
- )
2366
- }
2367
- );
2368
- };
2369
- const PolylinePaint = ({
2370
- pageIndex,
2371
- scale,
2372
- pageWidth,
2373
- pageHeight,
2374
- cursor
2375
- }) => {
2376
- const { provides: annotationProvides } = useAnnotationCapability();
2377
- const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
2378
- useEffect(() => {
2379
- if (!annotationProvides) return;
2380
- return annotationProvides.onActiveToolChange(setActiveTool);
2381
- }, [annotationProvides]);
2382
- if (!activeTool.defaults) return null;
2383
- if (activeTool.defaults.subtype !== PdfAnnotationSubtype.POLYLINE) return null;
2384
- const toolColor = activeTool.defaults.color ?? "#000000";
2385
- const toolOpacity = activeTool.defaults.opacity ?? 1;
2386
- const toolStrokeWidth = activeTool.defaults.strokeWidth ?? 2;
2387
- const toolStrokeColor = activeTool.defaults.strokeColor ?? "#000000";
2388
- const toolLineEndings = activeTool.defaults.lineEndings;
2389
- const toolStrokeStyle = activeTool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID;
2390
- const toolStrokeDashArray = activeTool.defaults.strokeDashArray;
2391
- const { register } = usePointerHandlers({ modeId: "polyline", pageIndex });
2392
- const pageWidthPDF = pageWidth / scale;
2393
- const pageHeightPDF = pageHeight / scale;
2394
- const [vertices, setVertices] = useState([]);
2395
- const [current, setCurrent] = useState(null);
2396
- const commitPolyline = (pts) => {
2397
- if (pts.length < 2) return;
2398
- const rect2 = patching.lineRectWithEndings(pts, toolStrokeWidth, toolLineEndings);
2399
- const anno = {
2400
- type: PdfAnnotationSubtype.POLYLINE,
2401
- rect: rect2,
2402
- vertices: pts,
2403
- color: toolColor,
2404
- opacity: toolOpacity,
2405
- strokeWidth: toolStrokeWidth,
2406
- strokeColor: toolStrokeColor,
2407
- strokeStyle: toolStrokeStyle,
2408
- strokeDashArray: toolStrokeDashArray,
2409
- lineEndings: toolLineEndings,
2410
- pageIndex,
2411
- id: uuidV4(),
2412
- created: /* @__PURE__ */ new Date()
2413
- };
2414
- annotationProvides.createAnnotation(pageIndex, anno);
2415
- annotationProvides.setActiveVariant(null);
2416
- annotationProvides.selectAnnotation(pageIndex, anno.id);
1543
+ function PreviewRenderer({ preview, scale }) {
1544
+ const { bounds } = preview;
1545
+ const style = {
1546
+ position: "absolute",
1547
+ left: bounds.origin.x * scale,
1548
+ top: bounds.origin.y * scale,
1549
+ width: bounds.size.width * scale,
1550
+ height: bounds.size.height * scale,
1551
+ pointerEvents: "none",
1552
+ zIndex: 10
2417
1553
  };
2418
- const handlers = useMemo(
2419
- () => ({
2420
- onClick: (pos) => {
2421
- const x = clamp(pos.x, 0, pageWidthPDF);
2422
- const y = clamp(pos.y, 0, pageHeightPDF);
2423
- setVertices((prev) => [...prev, { x, y }]);
2424
- setCurrent({ x, y });
2425
- },
2426
- onDoubleClick: () => {
2427
- if (vertices.length >= 1 && annotationProvides) {
2428
- commitPolyline(vertices);
1554
+ if (preview.type === PdfAnnotationSubtype.CIRCLE) {
1555
+ return /* @__PURE__ */ jsx("div", { style, children: /* @__PURE__ */ jsx(Circle, { isSelected: false, scale, ...preview.data }) });
1556
+ }
1557
+ if (preview.type === PdfAnnotationSubtype.SQUARE) {
1558
+ return /* @__PURE__ */ jsx("div", { style, children: /* @__PURE__ */ jsx(Square, { isSelected: false, scale, ...preview.data }) });
1559
+ }
1560
+ if (preview.type === PdfAnnotationSubtype.POLYGON) {
1561
+ return /* @__PURE__ */ jsx("div", { style, children: /* @__PURE__ */ jsx(Polygon, { isSelected: false, scale, ...preview.data }) });
1562
+ }
1563
+ if (preview.type === PdfAnnotationSubtype.POLYLINE) {
1564
+ return /* @__PURE__ */ jsx("div", { style, children: /* @__PURE__ */ jsx(Polyline, { isSelected: false, scale, ...preview.data }) });
1565
+ }
1566
+ if (preview.type === PdfAnnotationSubtype.LINE) {
1567
+ return /* @__PURE__ */ jsx("div", { style, children: /* @__PURE__ */ jsx(Line, { isSelected: false, scale, ...preview.data }) });
1568
+ }
1569
+ if (preview.type === PdfAnnotationSubtype.INK) {
1570
+ return /* @__PURE__ */ jsx("div", { style, children: /* @__PURE__ */ jsx(Ink, { isSelected: false, scale, ...preview.data }) });
1571
+ }
1572
+ if (preview.type === PdfAnnotationSubtype.FREETEXT) {
1573
+ return /* @__PURE__ */ jsx("div", { style, children: /* @__PURE__ */ jsx(
1574
+ "div",
1575
+ {
1576
+ style: {
1577
+ width: "100%",
1578
+ height: "100%",
1579
+ border: `1px dashed ${preview.data.fontColor || "#000000"}`,
1580
+ backgroundColor: "transparent"
2429
1581
  }
2430
- setVertices([]);
2431
- setCurrent(null);
2432
- },
2433
- onPointerMove: (pos) => {
2434
- if (!vertices.length) return;
2435
- const x = clamp(pos.x, 0, pageWidthPDF);
2436
- const y = clamp(pos.y, 0, pageHeightPDF);
2437
- setCurrent({ x, y });
2438
- },
2439
- onPointerCancel: () => {
2440
- setVertices([]);
2441
- setCurrent(null);
2442
1582
  }
2443
- }),
2444
- [vertices, annotationProvides, pageWidthPDF, pageHeightPDF]
2445
- );
2446
- useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
2447
- if (!vertices.length || !current) return null;
2448
- const allPts = [...vertices, current];
2449
- const rect = patching.lineRectWithEndings(allPts, toolStrokeWidth, toolLineEndings);
2450
- return /* @__PURE__ */ jsx(
2451
- "div",
2452
- {
2453
- style: {
2454
- position: "absolute",
2455
- left: rect.origin.x * scale,
2456
- top: rect.origin.y * scale,
2457
- width: rect.size.width * scale,
2458
- height: rect.size.height * scale,
2459
- pointerEvents: "none",
2460
- zIndex: 2,
2461
- overflow: "visible",
2462
- cursor
2463
- },
2464
- children: /* @__PURE__ */ jsx(
2465
- Polyline,
2466
- {
2467
- rect,
2468
- vertices: allPts,
2469
- strokeWidth: toolStrokeWidth,
2470
- scale,
2471
- isSelected: false,
2472
- color: toolColor,
2473
- strokeColor: toolStrokeColor,
2474
- opacity: toolOpacity,
2475
- lineEndings: toolLineEndings
2476
- }
2477
- )
2478
- }
2479
- );
2480
- };
2481
- const LinePaint = ({ pageIndex, scale, pageWidth, pageHeight, cursor }) => {
2482
- const { provides: annotationProvides } = useAnnotationCapability();
2483
- const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
2484
- useEffect(() => {
2485
- if (!annotationProvides) return;
2486
- return annotationProvides.onActiveToolChange(setActiveTool);
2487
- }, [annotationProvides]);
2488
- if (!activeTool.defaults) return null;
2489
- if (activeTool.defaults.subtype !== PdfAnnotationSubtype.LINE) return null;
2490
- const toolColor = activeTool.defaults.color ?? "#000000";
2491
- const toolOpacity = activeTool.defaults.opacity ?? 1;
2492
- const toolStrokeWidth = activeTool.defaults.strokeWidth ?? 2;
2493
- const toolStrokeColor = activeTool.defaults.strokeColor ?? "#000000";
2494
- const toolStrokeStyle = activeTool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID;
2495
- const toolStrokeDashArray = activeTool.defaults.strokeDashArray;
2496
- const toolLineEndings = activeTool.defaults.lineEndings;
2497
- const intent = activeTool.defaults.intent;
2498
- const { register } = usePointerHandlers({ modeId: ["line", "lineArrow"], pageIndex });
2499
- const pageWidthPDF = pageWidth / scale;
2500
- const pageHeightPDF = pageHeight / scale;
2501
- const [start, setStart] = useState(null);
2502
- const [current, setCurrent] = useState(null);
2503
- const commitLine = (p1, p2) => {
2504
- if (Math.abs(p2.x - p1.x) < 1 && Math.abs(p2.y - p1.y) < 1) return;
2505
- const rect2 = patching.lineRectWithEndings([p1, p2], toolStrokeWidth, toolLineEndings);
2506
- const anno = {
2507
- type: PdfAnnotationSubtype.LINE,
2508
- rect: rect2,
2509
- linePoints: { start: p1, end: p2 },
2510
- color: toolColor,
2511
- opacity: toolOpacity,
2512
- strokeWidth: toolStrokeWidth,
2513
- strokeColor: toolStrokeColor,
2514
- strokeStyle: toolStrokeStyle,
2515
- strokeDashArray: toolStrokeDashArray,
2516
- lineEndings: toolLineEndings,
2517
- intent,
2518
- pageIndex,
2519
- id: uuidV4(),
2520
- created: /* @__PURE__ */ new Date()
2521
- };
2522
- annotationProvides.createAnnotation(pageIndex, anno);
2523
- annotationProvides.setActiveVariant(null);
2524
- annotationProvides.selectAnnotation(pageIndex, anno.id);
2525
- };
2526
- const handlers = useMemo(
2527
- () => ({
2528
- onPointerDown: (pos, evt) => {
2529
- var _a;
2530
- const x = clamp(pos.x, 0, pageWidthPDF);
2531
- const y = clamp(pos.y, 0, pageHeightPDF);
2532
- setStart({ x, y });
2533
- setCurrent({ x, y });
2534
- (_a = evt.setPointerCapture) == null ? void 0 : _a.call(evt);
2535
- },
2536
- onPointerMove: (pos) => {
2537
- if (!start) return;
2538
- const x = clamp(pos.x, 0, pageWidthPDF);
2539
- const y = clamp(pos.y, 0, pageHeightPDF);
2540
- setCurrent({ x, y });
2541
- },
2542
- onPointerUp: (_, evt) => {
2543
- var _a;
2544
- if (start && current && annotationProvides) {
2545
- commitLine(start, current);
2546
- }
2547
- (_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
2548
- setStart(null);
2549
- setCurrent(null);
2550
- },
2551
- onPointerCancel: (_, evt) => {
2552
- var _a;
2553
- (_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
2554
- setStart(null);
2555
- setCurrent(null);
2556
- }
2557
- }),
2558
- [start, current, annotationProvides, pageWidthPDF, pageHeightPDF]
2559
- );
2560
- useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
2561
- if (!start || !current) return null;
2562
- const rect = patching.lineRectWithEndings([start, current], toolStrokeWidth, toolLineEndings);
2563
- return /* @__PURE__ */ jsx(
2564
- "div",
2565
- {
2566
- style: {
2567
- position: "absolute",
2568
- left: rect.origin.x * scale,
2569
- top: rect.origin.y * scale,
2570
- width: rect.size.width * scale,
2571
- height: rect.size.height * scale,
2572
- pointerEvents: "none",
2573
- zIndex: 2,
2574
- overflow: "visible",
2575
- cursor
2576
- },
2577
- children: /* @__PURE__ */ jsx(
2578
- Line,
2579
- {
2580
- rect,
2581
- linePoints: { start, end: current },
2582
- strokeWidth: toolStrokeWidth,
2583
- scale,
2584
- isSelected: false,
2585
- color: toolColor,
2586
- strokeColor: toolStrokeColor,
2587
- opacity: toolOpacity,
2588
- lineEndings: toolLineEndings,
2589
- strokeStyle: toolStrokeStyle,
2590
- strokeDashArray: toolStrokeDashArray
2591
- }
2592
- )
2593
- }
2594
- );
2595
- };
2596
- const HANDLE_SIZE_PX = 14;
2597
- const PolygonPaint = ({
2598
- pageIndex,
2599
- scale,
2600
- pageWidth,
2601
- pageHeight,
2602
- cursor
2603
- }) => {
2604
- const { provides: annotationProvides } = useAnnotationCapability();
2605
- const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
2606
- useEffect(() => annotationProvides == null ? void 0 : annotationProvides.onActiveToolChange(setActiveTool), [annotationProvides]);
2607
- if (!activeTool.defaults || activeTool.defaults.subtype !== PdfAnnotationSubtype.POLYGON)
2608
- return null;
2609
- const toolColor = activeTool.defaults.color ?? "#000000";
2610
- const toolOpacity = activeTool.defaults.opacity ?? 1;
2611
- const toolStrokeWidth = activeTool.defaults.strokeWidth ?? 2;
2612
- const toolStrokeColor = activeTool.defaults.strokeColor ?? "#000000";
2613
- const toolStrokeStyle = activeTool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID;
2614
- const toolStrokeDashArray = activeTool.defaults.strokeDashArray;
2615
- const { register } = usePointerHandlers({ modeId: "polygon", pageIndex });
2616
- const pageWidthPDF = pageWidth / scale;
2617
- const pageHeightPDF = pageHeight / scale;
2618
- const [vertices, setVertices] = useState([]);
2619
- const [current, setCurrent] = useState(null);
2620
- const commitPolygon = (pts) => {
2621
- const xs2 = pts.map((p) => p.x), ys2 = pts.map((p) => p.y);
2622
- const minX2 = Math.min(...xs2), minY2 = Math.min(...ys2);
2623
- const maxX2 = Math.max(...xs2), maxY2 = Math.max(...ys2);
2624
- if (maxX2 - minX2 < 1 || maxY2 - minY2 < 1) return;
2625
- const half2 = toolStrokeWidth / 2;
2626
- const rect = {
2627
- origin: { x: minX2 - half2, y: minY2 - half2 },
2628
- size: { width: maxX2 - minX2 + toolStrokeWidth, height: maxY2 - minY2 + toolStrokeWidth }
2629
- };
2630
- const anno = {
2631
- type: PdfAnnotationSubtype.POLYGON,
2632
- rect,
2633
- vertices: pts,
2634
- color: toolColor,
2635
- opacity: toolOpacity,
2636
- strokeWidth: toolStrokeWidth,
2637
- strokeColor: toolStrokeColor,
2638
- strokeStyle: toolStrokeStyle,
2639
- strokeDashArray: toolStrokeDashArray,
2640
- pageIndex,
2641
- id: uuidV4(),
2642
- created: /* @__PURE__ */ new Date()
2643
- };
2644
- annotationProvides.createAnnotation(pageIndex, anno);
2645
- annotationProvides.setActiveVariant(null);
2646
- annotationProvides.selectAnnotation(pageIndex, anno.id);
2647
- };
2648
- const isInsideStartHandle = (x, y) => {
2649
- if (vertices.length < 2) return false;
2650
- const sizePDF = HANDLE_SIZE_PX / scale;
2651
- const half2 = sizePDF / 2;
2652
- const v0 = vertices[0];
2653
- return x >= v0.x - half2 && x <= v0.x + half2 && y >= v0.y - half2 && y <= v0.y + half2;
2654
- };
2655
- const handlers = useMemo(
1583
+ ) });
1584
+ }
1585
+ return null;
1586
+ }
1587
+ function AnnotationPaintLayer({ pageIndex, scale }) {
1588
+ const { plugin: annotationPlugin } = useAnnotationPlugin();
1589
+ const [previews, setPreviews] = useState(/* @__PURE__ */ new Map());
1590
+ const fileInputRef = useRef(null);
1591
+ const canvasRef = useRef(null);
1592
+ const services = useMemo(
2656
1593
  () => ({
2657
- onClick: (pos) => {
2658
- const x = clamp(pos.x, 0, pageWidthPDF);
2659
- const y = clamp(pos.y, 0, pageHeightPDF);
2660
- if (isInsideStartHandle(x, y) && vertices.length >= 3 && annotationProvides) {
2661
- commitPolygon(vertices);
2662
- setVertices([]);
2663
- setCurrent(null);
2664
- return;
2665
- }
2666
- setVertices((prev) => [...prev, { x, y }]);
2667
- setCurrent({ x, y });
2668
- },
2669
- onDoubleClick: () => {
2670
- if (vertices.length >= 3 && annotationProvides) {
2671
- commitPolygon(vertices);
2672
- setVertices([]);
2673
- setCurrent(null);
2674
- } else {
2675
- setVertices([]);
2676
- setCurrent(null);
2677
- }
2678
- },
2679
- onPointerMove: (pos) => {
2680
- if (!vertices.length) return;
2681
- const x = clamp(pos.x, 0, pageWidthPDF);
2682
- const y = clamp(pos.y, 0, pageHeightPDF);
2683
- setCurrent({ x, y });
2684
- },
2685
- onPointerCancel: () => {
2686
- setVertices([]);
2687
- setCurrent(null);
2688
- }
2689
- }),
2690
- [vertices, current, annotationProvides, pageWidthPDF, pageHeightPDF]
2691
- );
2692
- useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
2693
- if (!vertices.length || !current) return null;
2694
- const allPts = [...vertices, current];
2695
- const xs = allPts.map((p) => p.x), ys = allPts.map((p) => p.y);
2696
- const minX = Math.min(...xs), minY = Math.min(...ys);
2697
- const maxX = Math.max(...xs), maxY = Math.max(...ys);
2698
- const half = toolStrokeWidth / 2;
2699
- const svgMinX = minX - half;
2700
- const svgMinY = minY - half;
2701
- const svgMaxX = maxX + half;
2702
- const svgMaxY = maxY + half;
2703
- const dw = svgMaxX - svgMinX;
2704
- const dh = svgMaxY - svgMinY;
2705
- const mainPath = useMemo(() => {
2706
- let d = "";
2707
- allPts.forEach(({ x, y }, i) => {
2708
- d += (i === 0 ? "M" : "L") + (x - svgMinX) + " " + (y - svgMinY) + " ";
2709
- });
2710
- return d.trim();
2711
- }, [allPts, svgMinX, svgMinY]);
2712
- const dottedPath = vertices.length >= 2 ? (() => {
2713
- const curLx = current.x - svgMinX;
2714
- const curLy = current.y - svgMinY;
2715
- const firstLx = vertices[0].x - svgMinX;
2716
- const firstLy = vertices[0].y - svgMinY;
2717
- return `M ${curLx} ${curLy} L ${firstLx} ${firstLy}`;
2718
- })() : null;
2719
- const handleSizePDF = HANDLE_SIZE_PX / scale;
2720
- const hHalf = handleSizePDF / 2;
2721
- const hx = vertices[0].x - hHalf - svgMinX;
2722
- const hy = vertices[0].y - hHalf - svgMinY;
2723
- return /* @__PURE__ */ jsxs(
2724
- "svg",
2725
- {
2726
- style: {
2727
- position: "absolute",
2728
- left: svgMinX * scale,
2729
- top: svgMinY * scale,
2730
- width: dw * scale,
2731
- height: dh * scale,
2732
- pointerEvents: "none",
2733
- // we handle clicks at the page layer
2734
- zIndex: 2,
2735
- overflow: "visible"
2736
- },
2737
- width: dw * scale,
2738
- height: dh * scale,
2739
- viewBox: `0 0 ${dw} ${dh}`,
2740
- children: [
2741
- /* @__PURE__ */ jsx(
2742
- "path",
2743
- {
2744
- d: mainPath,
2745
- fill: toolColor,
2746
- opacity: toolOpacity,
2747
- style: {
2748
- cursor,
2749
- stroke: toolStrokeColor,
2750
- strokeWidth: toolStrokeWidth,
2751
- ...toolStrokeStyle === PdfAnnotationBorderStyle.DASHED && {
2752
- strokeDasharray: toolStrokeDashArray == null ? void 0 : toolStrokeDashArray.join(",")
2753
- }
2754
- }
2755
- }
2756
- ),
2757
- dottedPath && /* @__PURE__ */ jsx(
2758
- "path",
2759
- {
2760
- d: dottedPath,
2761
- fill: "none",
2762
- style: { stroke: toolStrokeColor, strokeWidth: toolStrokeWidth, strokeDasharray: "4,4" }
2763
- }
2764
- ),
2765
- vertices.length >= 3 && /* @__PURE__ */ jsx(
2766
- "rect",
2767
- {
2768
- x: hx,
2769
- y: hy,
2770
- width: handleSizePDF,
2771
- height: handleSizePDF,
2772
- fill: toolStrokeColor,
2773
- opacity: 0.4,
2774
- stroke: toolStrokeColor,
2775
- strokeWidth: toolStrokeWidth / 2,
2776
- style: { pointerEvents: "none" }
1594
+ requestFile: ({ accept, onFile }) => {
1595
+ if (!fileInputRef.current) return;
1596
+ const input = fileInputRef.current;
1597
+ input.accept = accept;
1598
+ input.onchange = (e) => {
1599
+ var _a;
1600
+ const file = (_a = e.target.files) == null ? void 0 : _a[0];
1601
+ if (file) {
1602
+ onFile(file);
1603
+ input.value = "";
2777
1604
  }
2778
- )
2779
- ]
2780
- }
2781
- );
2782
- };
2783
- const FreeTextPaint = ({
2784
- pageIndex,
2785
- scale,
2786
- pageWidth,
2787
- pageHeight,
2788
- cursor = "text"
2789
- }) => {
2790
- const { provides: annotationProvides } = useAnnotationCapability();
2791
- const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
2792
- useEffect(() => annotationProvides == null ? void 0 : annotationProvides.onActiveToolChange(setActiveTool), [annotationProvides]);
2793
- if (!activeTool.defaults || activeTool.defaults.subtype !== PdfAnnotationSubtype.FREETEXT)
2794
- return null;
2795
- const toolFontColor = activeTool.defaults.fontColor ?? "#000000";
2796
- const toolOpacity = activeTool.defaults.opacity ?? 1;
2797
- const toolFontSize = activeTool.defaults.fontSize ?? 12;
2798
- const toolFontFamily = activeTool.defaults.fontFamily;
2799
- const toolBackgroundColor = activeTool.defaults.backgroundColor ?? "transparent";
2800
- const toolTextAlign = activeTool.defaults.textAlign;
2801
- const toolVerticalAlign = activeTool.defaults.verticalAlign;
2802
- const toolContent = activeTool.defaults.content ?? "Insert text here";
2803
- const { register } = usePointerHandlers({ modeId: "freeText", pageIndex });
2804
- const clamp2 = (v, min, max) => Math.max(min, Math.min(max, v));
2805
- const pageWidthPDF = pageWidth / scale;
2806
- const pageHeightPDF = pageHeight / scale;
2807
- const [start, setStart] = useState(null);
2808
- const [current, setCurrent] = useState(null);
2809
- const commitFreeText = (p1, p2) => {
2810
- const minX2 = Math.min(p1.x, p2.x);
2811
- const minY2 = Math.min(p1.y, p2.y);
2812
- const maxX2 = Math.max(p1.x, p2.x);
2813
- const maxY2 = Math.max(p1.y, p2.y);
2814
- const w = maxX2 - minX2;
2815
- const h = maxY2 - minY2;
2816
- if (w < 1 || h < 1) return;
2817
- const rect = {
2818
- origin: { x: minX2, y: minY2 },
2819
- size: { width: w, height: h }
2820
- };
2821
- const anno = {
2822
- type: PdfAnnotationSubtype.FREETEXT,
2823
- rect,
2824
- contents: toolContent,
2825
- fontColor: toolFontColor,
2826
- fontSize: toolFontSize,
2827
- fontFamily: toolFontFamily,
2828
- opacity: toolOpacity,
2829
- backgroundColor: toolBackgroundColor,
2830
- textAlign: toolTextAlign,
2831
- verticalAlign: toolVerticalAlign,
2832
- pageIndex,
2833
- id: uuidV4(),
2834
- created: /* @__PURE__ */ new Date()
2835
- };
2836
- annotationProvides.createAnnotation(pageIndex, anno);
2837
- annotationProvides.setActiveVariant(null);
2838
- annotationProvides.selectAnnotation(pageIndex, anno.id);
2839
- };
2840
- const handlers = useMemo(
2841
- () => ({
2842
- onPointerDown: (pos, evt) => {
2843
- var _a;
2844
- const x = clamp2(pos.x, 0, pageWidthPDF);
2845
- const y = clamp2(pos.y, 0, pageHeightPDF);
2846
- setStart({ x, y });
2847
- setCurrent({ x, y });
2848
- (_a = evt.setPointerCapture) == null ? void 0 : _a.call(evt);
1605
+ };
1606
+ input.click();
2849
1607
  },
2850
- onPointerMove: (pos) => {
2851
- if (!start) return;
2852
- const x = clamp2(pos.x, 0, pageWidthPDF);
2853
- const y = clamp2(pos.y, 0, pageHeightPDF);
2854
- setCurrent({ x, y });
2855
- },
2856
- onPointerUp: (_, evt) => {
2857
- var _a;
2858
- if (start && current && annotationProvides) {
2859
- commitFreeText(start, current);
2860
- }
2861
- (_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
2862
- setStart(null);
2863
- setCurrent(null);
2864
- },
2865
- onPointerCancel: (_, evt) => {
2866
- var _a;
2867
- (_a = evt.releasePointerCapture) == null ? void 0 : _a.call(evt);
2868
- setStart(null);
2869
- setCurrent(null);
1608
+ processImage: ({ source, maxWidth, maxHeight, onComplete }) => {
1609
+ const canvas = canvasRef.current;
1610
+ if (!canvas || !canvas.getContext) return;
1611
+ const ctx = canvas.getContext("2d");
1612
+ if (!ctx) return;
1613
+ const img = new Image();
1614
+ img.crossOrigin = "Anonymous";
1615
+ img.onload = () => {
1616
+ let { naturalWidth: width, naturalHeight: height } = img;
1617
+ const scaleX = maxWidth ? maxWidth / width : 1;
1618
+ const scaleY = maxHeight ? maxHeight / height : 1;
1619
+ const scaleFactor = Math.min(scaleX, scaleY, 1);
1620
+ const finalWidth = width * scaleFactor;
1621
+ const finalHeight = height * scaleFactor;
1622
+ canvas.width = finalWidth;
1623
+ canvas.height = finalHeight;
1624
+ ctx.drawImage(img, 0, 0, finalWidth, finalHeight);
1625
+ const imageData = ctx.getImageData(0, 0, finalWidth, finalHeight);
1626
+ if (typeof source !== "string") URL.revokeObjectURL(img.src);
1627
+ onComplete({ imageData, width: finalWidth, height: finalHeight });
1628
+ };
1629
+ img.src = typeof source === "string" ? source : URL.createObjectURL(source);
2870
1630
  }
2871
1631
  }),
2872
- [start, current, annotationProvides, pageWidthPDF, pageHeightPDF]
1632
+ []
2873
1633
  );
2874
- useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
2875
- if (!start || !current) return null;
2876
- const minX = Math.min(start.x, current.x);
2877
- const minY = Math.min(start.y, current.y);
2878
- const maxX = Math.max(start.x, current.x);
2879
- const maxY = Math.max(start.y, current.y);
2880
- const dw = maxX - minX;
2881
- const dh = maxY - minY;
2882
- return /* @__PURE__ */ jsx(
2883
- "svg",
2884
- {
2885
- style: {
2886
- position: "absolute",
2887
- left: minX * scale,
2888
- top: minY * scale,
2889
- width: dw * scale,
2890
- height: dh * scale,
2891
- pointerEvents: "none",
2892
- zIndex: 2
2893
- },
2894
- width: dw * scale,
2895
- height: dh * scale,
2896
- viewBox: `0 0 ${dw} ${dh}`,
2897
- children: /* @__PURE__ */ jsx(
2898
- "rect",
2899
- {
2900
- x: 0,
2901
- y: 0,
2902
- width: dw,
2903
- height: dh,
2904
- fill: "transparent",
2905
- style: {
2906
- stroke: toolFontColor,
2907
- strokeWidth: 1,
2908
- strokeDasharray: "4,4",
2909
- cursor
2910
- }
2911
- }
2912
- )
2913
- }
2914
- );
2915
- };
2916
- const StampPaint = ({ pageIndex, scale, pageWidth, pageHeight }) => {
2917
- const { provides: annotationProvides } = useAnnotationCapability();
2918
- const inputRef = useRef(null);
2919
- const canvasRef = useRef(null);
2920
- const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
2921
1634
  useEffect(() => {
2922
- if (!annotationProvides) return;
2923
- return annotationProvides.onActiveToolChange(setActiveTool);
2924
- }, [annotationProvides]);
2925
- if (!activeTool.defaults) return null;
2926
- if (activeTool.defaults.subtype !== PdfAnnotationSubtype.STAMP) return null;
2927
- const { register } = usePointerHandlers({ modeId: "stamp", pageIndex });
2928
- const pageWidthPDF = pageWidth / scale;
2929
- const pageHeightPDF = pageHeight / scale;
2930
- const [start, setStart] = useState(null);
2931
- const handlers = useMemo(
2932
- () => ({
2933
- onPointerDown: (pos, evt) => {
2934
- var _a;
2935
- const x = clamp(pos.x, 0, pageWidthPDF);
2936
- const y = clamp(pos.y, 0, pageHeightPDF);
2937
- setStart({ x, y });
2938
- (_a = inputRef.current) == null ? void 0 : _a.click();
1635
+ if (!annotationPlugin) return;
1636
+ return annotationPlugin.registerPageHandlers(pageIndex, scale, {
1637
+ services,
1638
+ onPreview: (toolId, state) => {
1639
+ setPreviews((prev) => {
1640
+ const next = new Map(prev);
1641
+ if (state) {
1642
+ next.set(toolId, state);
1643
+ } else {
1644
+ next.delete(toolId);
1645
+ }
1646
+ return next;
1647
+ });
2939
1648
  }
2940
- }),
2941
- [pageWidthPDF, pageHeightPDF]
2942
- );
2943
- useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
2944
- const onChange = async (e) => {
2945
- var _a;
2946
- if (!annotationProvides || !start) return;
2947
- const file = (_a = e.currentTarget.files) == null ? void 0 : _a[0];
2948
- if (!file) return;
2949
- const img = await new Promise((res, rej) => {
2950
- const i = new Image();
2951
- i.onload = () => res(i);
2952
- i.onerror = rej;
2953
- i.src = URL.createObjectURL(file);
2954
1649
  });
2955
- const imgW = img.naturalWidth;
2956
- const imgH = img.naturalHeight;
2957
- const maxW = pageWidthPDF;
2958
- const maxH = pageHeightPDF;
2959
- const scaleFactor = Math.min(1, maxW / imgW, maxH / imgH);
2960
- const pdfW = imgW * scaleFactor;
2961
- const pdfH = imgH * scaleFactor;
2962
- const posX = clamp(start.x, 0, maxW - pdfW);
2963
- const posY = clamp(start.y, 0, maxH - pdfH);
2964
- const rect = {
2965
- origin: { x: posX, y: posY },
2966
- size: { width: pdfW, height: pdfH }
2967
- };
2968
- const canvas = canvasRef.current;
2969
- if (!canvas) return;
2970
- canvas.width = pdfW;
2971
- canvas.height = pdfH;
2972
- const ctx = canvas.getContext("2d");
2973
- ctx.drawImage(img, 0, 0, pdfW, pdfH);
2974
- const imageData = ctx.getImageData(0, 0, pdfW, pdfH);
2975
- const anno = {
2976
- type: PdfAnnotationSubtype.STAMP,
2977
- flags: ["print"],
2978
- pageIndex,
2979
- id: uuidV4(),
2980
- created: /* @__PURE__ */ new Date(),
2981
- rect
2982
- };
2983
- annotationProvides.createAnnotation(pageIndex, anno, { imageData });
2984
- annotationProvides.setActiveVariant(null);
2985
- annotationProvides.selectAnnotation(pageIndex, anno.id);
2986
- setStart(null);
2987
- };
1650
+ }, [pageIndex, scale, annotationPlugin, services]);
2988
1651
  return /* @__PURE__ */ jsxs(Fragment, { children: [
2989
- /* @__PURE__ */ jsx("canvas", { style: { display: "none" }, ref: canvasRef }),
2990
- /* @__PURE__ */ jsx(
2991
- "input",
2992
- {
2993
- ref: inputRef,
2994
- type: "file",
2995
- accept: "image/png,image/jpeg",
2996
- style: { display: "none" },
2997
- onChange
2998
- }
2999
- )
1652
+ /* @__PURE__ */ jsx("input", { ref: fileInputRef, type: "file", style: { display: "none" } }),
1653
+ /* @__PURE__ */ jsx("canvas", { ref: canvasRef, style: { display: "none" } }),
1654
+ Array.from(previews.entries()).map(([toolId, preview]) => /* @__PURE__ */ jsx(PreviewRenderer, { preview, scale }, toolId))
3000
1655
  ] });
3001
- };
1656
+ }
3002
1657
  function AnnotationLayer({
1658
+ style,
3003
1659
  pageIndex,
3004
1660
  scale,
1661
+ selectionMenu,
1662
+ resizeUI,
1663
+ vertexUI,
3005
1664
  pageWidth,
3006
1665
  pageHeight,
3007
1666
  rotation,
3008
- selectionMenu,
3009
- style,
1667
+ selectionOutlineColor,
3010
1668
  ...props
3011
1669
  }) {
3012
1670
  return /* @__PURE__ */ jsxs(
@@ -3025,74 +1683,14 @@ function AnnotationLayer({
3025
1683
  scale,
3026
1684
  rotation,
3027
1685
  pageWidth,
3028
- pageHeight
1686
+ pageHeight,
1687
+ resizeUI,
1688
+ vertexUI,
1689
+ selectionOutlineColor
3029
1690
  }
3030
1691
  ),
3031
1692
  /* @__PURE__ */ jsx(TextMarkup, { pageIndex, scale }),
3032
- /* @__PURE__ */ jsx(InkPaint, { pageIndex, scale, pageWidth, pageHeight }),
3033
- /* @__PURE__ */ jsx(
3034
- CirclePaint,
3035
- {
3036
- pageIndex,
3037
- scale,
3038
- pageWidth,
3039
- pageHeight
3040
- }
3041
- ),
3042
- /* @__PURE__ */ jsx(
3043
- SquarePaint,
3044
- {
3045
- pageIndex,
3046
- scale,
3047
- pageWidth,
3048
- pageHeight
3049
- }
3050
- ),
3051
- /* @__PURE__ */ jsx(
3052
- PolygonPaint,
3053
- {
3054
- pageIndex,
3055
- scale,
3056
- pageWidth,
3057
- pageHeight
3058
- }
3059
- ),
3060
- /* @__PURE__ */ jsx(
3061
- PolylinePaint,
3062
- {
3063
- pageIndex,
3064
- scale,
3065
- pageWidth,
3066
- pageHeight
3067
- }
3068
- ),
3069
- /* @__PURE__ */ jsx(
3070
- LinePaint,
3071
- {
3072
- pageIndex,
3073
- scale,
3074
- pageWidth,
3075
- pageHeight
3076
- }
3077
- ),
3078
- /* @__PURE__ */ jsx(
3079
- FreeTextPaint,
3080
- {
3081
- pageIndex,
3082
- scale,
3083
- pageWidth,
3084
- pageHeight
3085
- }
3086
- ),
3087
- /* @__PURE__ */ jsx(
3088
- StampPaint,
3089
- {
3090
- pageIndex,
3091
- scale,
3092
- pageWidth,
3093
- pageHeight
3094
- }
3095
- )
1693
+ /* @__PURE__ */ jsx(AnnotationPaintLayer, { pageIndex, scale })
3096
1694
  ]
3097
1695
  }
3098
1696
  );