@embedpdf/plugin-annotation 1.0.5 → 1.0.7

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.
@@ -4,118 +4,169 @@ import { AnnotationPlugin } from "@embedpdf/plugin-annotation";
4
4
  var useAnnotationPlugin = () => usePlugin(AnnotationPlugin.id);
5
5
  var useAnnotationCapability = () => useCapability(AnnotationPlugin.id);
6
6
 
7
- // src/preact/components/annotation-layer.tsx
8
- import { useEffect, useMemo, useState } from "preact/hooks";
9
-
10
- // ../models/dist/index.js
11
- var PdfAnnotationSubtype = /* @__PURE__ */ ((PdfAnnotationSubtype2) => {
12
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["UNKNOWN"] = 0] = "UNKNOWN";
13
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["TEXT"] = 1] = "TEXT";
14
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["LINK"] = 2] = "LINK";
15
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["FREETEXT"] = 3] = "FREETEXT";
16
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["LINE"] = 4] = "LINE";
17
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["SQUARE"] = 5] = "SQUARE";
18
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["CIRCLE"] = 6] = "CIRCLE";
19
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["POLYGON"] = 7] = "POLYGON";
20
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["POLYLINE"] = 8] = "POLYLINE";
21
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["HIGHLIGHT"] = 9] = "HIGHLIGHT";
22
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["UNDERLINE"] = 10] = "UNDERLINE";
23
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["SQUIGGLY"] = 11] = "SQUIGGLY";
24
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["STRIKEOUT"] = 12] = "STRIKEOUT";
25
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["STAMP"] = 13] = "STAMP";
26
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["CARET"] = 14] = "CARET";
27
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["INK"] = 15] = "INK";
28
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["POPUP"] = 16] = "POPUP";
29
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["FILEATTACHMENT"] = 17] = "FILEATTACHMENT";
30
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["SOUND"] = 18] = "SOUND";
31
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["MOVIE"] = 19] = "MOVIE";
32
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["WIDGET"] = 20] = "WIDGET";
33
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["SCREEN"] = 21] = "SCREEN";
34
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["PRINTERMARK"] = 22] = "PRINTERMARK";
35
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["TRAPNET"] = 23] = "TRAPNET";
36
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["WATERMARK"] = 24] = "WATERMARK";
37
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["THREED"] = 25] = "THREED";
38
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["RICHMEDIA"] = 26] = "RICHMEDIA";
39
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["XFAWIDGET"] = 27] = "XFAWIDGET";
40
- PdfAnnotationSubtype2[PdfAnnotationSubtype2["REDACT"] = 28] = "REDACT";
41
- return PdfAnnotationSubtype2;
42
- })(PdfAnnotationSubtype || {});
43
-
44
- // src/lib/selectors.ts
45
- var getAnnotationsByPageIndex = (state, pageIndex) => {
46
- return state.annotations[pageIndex] || [];
47
- };
7
+ // src/preact/components/annotations.tsx
8
+ import { PdfAnnotationSubtype } from "@embedpdf/models";
9
+ import { usePointerHandlers } from "@embedpdf/plugin-interaction-manager/preact";
10
+ import {
11
+ getAnnotationsByPageIndex,
12
+ getSelectedAnnotationByPageIndex
13
+ } from "@embedpdf/plugin-annotation";
14
+ import { useMemo, useState, useEffect } from "preact/hooks";
48
15
 
49
- // src/preact/components/annotations/highlight.tsx
16
+ // src/preact/components/selectable-container.tsx
50
17
  import { useCallback } from "preact/hooks";
51
- import { Fragment, jsx } from "preact/jsx-runtime";
52
- function HighlightAnnotation({
53
- annotation,
18
+ import { useSelectionCapability } from "@embedpdf/plugin-selection/preact";
19
+ import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
20
+ function SelectableAnnotationContainer({
21
+ trackedAnnotation,
54
22
  scale,
55
23
  isSelected = false,
56
- pageIndex
24
+ pageIndex,
25
+ children
57
26
  }) {
58
27
  const { provides: annotationProvides } = useAnnotationCapability();
59
- const highlightColor = annotation.color || { red: 255, green: 255, blue: 0, alpha: 76 };
60
- const rgbaColor = `rgba(${highlightColor.red}, ${highlightColor.green}, ${highlightColor.blue}, ${highlightColor.alpha / 255})`;
28
+ const { provides: selectionProvides } = useSelectionCapability();
61
29
  const handleClick = useCallback(
62
30
  (e) => {
63
31
  e.stopPropagation();
64
- if (annotationProvides) {
65
- annotationProvides.selectAnnotation(pageIndex, annotation.id);
32
+ if (annotationProvides && selectionProvides) {
33
+ annotationProvides.selectAnnotation(pageIndex, trackedAnnotation.localId);
34
+ selectionProvides.clear();
66
35
  }
67
36
  },
68
- [annotationProvides, isSelected, pageIndex, annotation.id]
37
+ [annotationProvides, selectionProvides, isSelected, pageIndex, trackedAnnotation.localId]
69
38
  );
70
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
39
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
40
+ children,
41
+ /* @__PURE__ */ jsx(
42
+ "div",
43
+ {
44
+ className: "markup-annotation",
45
+ style: {
46
+ position: "absolute",
47
+ mixBlendMode: "multiply",
48
+ cursor: "pointer",
49
+ outline: isSelected ? "2px solid #007ACC" : "none",
50
+ outlineOffset: isSelected ? "1px" : "0px",
51
+ left: `${trackedAnnotation.object.rect.origin.x * scale}px`,
52
+ top: `${trackedAnnotation.object.rect.origin.y * scale}px`,
53
+ width: `${trackedAnnotation.object.rect.size.width * scale}px`,
54
+ height: `${trackedAnnotation.object.rect.size.height * scale}px`,
55
+ zIndex: 1
56
+ },
57
+ onMouseDown: handleClick
58
+ }
59
+ )
60
+ ] });
61
+ }
62
+
63
+ // src/preact/components/text-markup/highlight.tsx
64
+ import { Fragment as Fragment2, jsx as jsx2 } from "preact/jsx-runtime";
65
+ function Highlight({ color = "#FFFF00", opacity = 0.5, rects, scale }) {
66
+ return /* @__PURE__ */ jsx2(Fragment2, { children: rects.map((b, i) => /* @__PURE__ */ jsx2(
71
67
  "div",
72
68
  {
73
- className: "highlight-annotation",
74
69
  style: {
75
70
  position: "absolute",
76
- mixBlendMode: "multiply",
77
- cursor: "pointer",
78
- outline: isSelected ? "2px solid #007ACC" : "none",
79
- left: `${annotation.rect.origin.x * scale}px`,
80
- top: `${annotation.rect.origin.y * scale}px`,
81
- width: `${annotation.rect.size.width * scale}px`,
82
- height: `${annotation.rect.size.height * scale}px`
83
- },
84
- onMouseDown: handleClick,
85
- children: annotation.segmentRects.map((rect, index) => /* @__PURE__ */ jsx(
86
- "div",
87
- {
88
- style: {
89
- position: "absolute",
90
- left: `${(rect.origin.x - annotation.rect.origin.x) * scale}px`,
91
- top: `${(rect.origin.y - annotation.rect.origin.y) * scale}px`,
92
- width: `${rect.size.width * scale}px`,
93
- height: `${rect.size.height * scale}px`,
94
- backgroundColor: rgbaColor
95
- }
96
- },
97
- index
98
- ))
99
- }
100
- ) });
71
+ left: b.origin.x * scale,
72
+ top: b.origin.y * scale,
73
+ width: b.size.width * scale,
74
+ height: b.size.height * scale,
75
+ background: color,
76
+ opacity,
77
+ pointerEvents: "none"
78
+ }
79
+ },
80
+ i
81
+ )) });
101
82
  }
102
83
 
103
- // src/preact/components/annotation-layer.tsx
104
- import { usePointerHandlers } from "@embedpdf/plugin-interaction-manager/preact";
105
- import { jsx as jsx2 } from "preact/jsx-runtime";
106
- function AnnotationLayer({ pageIndex, scale, style, ...props }) {
84
+ // src/preact/components/text-markup/underline.tsx
85
+ import { Fragment as Fragment3, jsx as jsx3 } from "preact/jsx-runtime";
86
+ function Underline({ color = "#FFFF00", opacity = 0.5, rects, scale }) {
87
+ const thickness = 2 * scale;
88
+ return /* @__PURE__ */ jsx3(Fragment3, { children: rects.map((r, i) => /* @__PURE__ */ jsx3(
89
+ "div",
90
+ {
91
+ style: {
92
+ position: "absolute",
93
+ left: r.origin.x * scale,
94
+ top: (r.origin.y + r.size.height) * scale - thickness,
95
+ width: r.size.width * scale,
96
+ height: thickness,
97
+ background: color,
98
+ opacity,
99
+ pointerEvents: "none"
100
+ }
101
+ },
102
+ i
103
+ )) });
104
+ }
105
+
106
+ // src/preact/components/text-markup/strikeout.tsx
107
+ import { Fragment as Fragment4, jsx as jsx4 } from "preact/jsx-runtime";
108
+ function Strikeout({ color = "#FFFF00", opacity = 0.5, rects, scale }) {
109
+ const thickness = 2 * scale;
110
+ return /* @__PURE__ */ jsx4(Fragment4, { children: rects.map((r, i) => /* @__PURE__ */ jsx4(
111
+ "div",
112
+ {
113
+ style: {
114
+ position: "absolute",
115
+ left: r.origin.x * scale,
116
+ top: (r.origin.y + r.size.height / 2) * scale - thickness / 2,
117
+ width: r.size.width * scale,
118
+ height: thickness,
119
+ background: color,
120
+ opacity,
121
+ pointerEvents: "none"
122
+ }
123
+ },
124
+ i
125
+ )) });
126
+ }
127
+
128
+ // src/preact/components/text-markup/squiggly.tsx
129
+ import { Fragment as Fragment5, jsx as jsx5 } from "preact/jsx-runtime";
130
+ function Squiggly({ color = "#FFFF00", opacity = 0.5, rects, scale }) {
131
+ const amplitude = 2 * scale;
132
+ const period = 6 * scale;
133
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${period}" height="${amplitude * 2}" viewBox="0 0 ${period} ${amplitude * 2}">
134
+ <path d="M0 ${amplitude} Q ${period / 4} 0 ${period / 2} ${amplitude} T ${period} ${amplitude}"
135
+ fill="none" stroke="${color}" stroke-width="${amplitude}" stroke-linecap="round"/>
136
+ </svg>`;
137
+ const svgDataUri = `url("data:image/svg+xml;utf8,${encodeURIComponent(svg)}")`;
138
+ return /* @__PURE__ */ jsx5(Fragment5, { children: rects.map((r, i) => /* @__PURE__ */ jsx5(
139
+ "div",
140
+ {
141
+ style: {
142
+ position: "absolute",
143
+ left: r.origin.x * scale,
144
+ top: (r.origin.y + r.size.height) * scale - amplitude,
145
+ width: r.size.width * scale,
146
+ height: amplitude * 2,
147
+ backgroundImage: svgDataUri,
148
+ backgroundRepeat: "repeat-x",
149
+ backgroundSize: `${period}px ${amplitude * 2}px`,
150
+ opacity,
151
+ pointerEvents: "none"
152
+ }
153
+ },
154
+ i
155
+ )) });
156
+ }
157
+
158
+ // src/preact/components/annotations.tsx
159
+ import { Fragment as Fragment6, jsx as jsx6 } from "preact/jsx-runtime";
160
+ function Annotations({ pageIndex, scale }) {
107
161
  const { provides: annotationProvides } = useAnnotationCapability();
108
162
  const [annotations, setAnnotations] = useState([]);
109
163
  const { register } = usePointerHandlers({ pageIndex });
110
- const [selectionState, setSelectionState] = useState({ selectedPageIndex: void 0, selectedAnnotationId: void 0 });
164
+ const [selectionState, setSelectionState] = useState(null);
111
165
  useEffect(() => {
112
166
  if (annotationProvides) {
113
167
  annotationProvides.onStateChange((state) => {
114
168
  setAnnotations(getAnnotationsByPageIndex(state, pageIndex));
115
- setSelectionState({
116
- selectedPageIndex: state.selectedAnnotation?.pageIndex,
117
- selectedAnnotationId: state.selectedAnnotation?.annotationId
118
- });
169
+ setSelectionState(getSelectedAnnotationByPageIndex(state, pageIndex));
119
170
  });
120
171
  }
121
172
  }, [annotationProvides]);
@@ -132,31 +183,177 @@ function AnnotationLayer({ pageIndex, scale, style, ...props }) {
132
183
  useEffect(() => {
133
184
  return register(handlers);
134
185
  }, [register, handlers]);
135
- return /* @__PURE__ */ jsx2(
186
+ return /* @__PURE__ */ jsx6(Fragment6, { children: annotations.map((annotation) => {
187
+ const isSelected = selectionState?.localId === annotation.localId;
188
+ switch (annotation.object.type) {
189
+ case PdfAnnotationSubtype.UNDERLINE:
190
+ return /* @__PURE__ */ jsx6(
191
+ SelectableAnnotationContainer,
192
+ {
193
+ trackedAnnotation: annotation,
194
+ scale,
195
+ isSelected,
196
+ pageIndex,
197
+ children: /* @__PURE__ */ jsx6(
198
+ Underline,
199
+ {
200
+ color: annotation.object.color,
201
+ opacity: annotation.object.opacity,
202
+ rects: annotation.object.segmentRects,
203
+ scale
204
+ }
205
+ )
206
+ },
207
+ annotation.localId
208
+ );
209
+ case PdfAnnotationSubtype.STRIKEOUT:
210
+ return /* @__PURE__ */ jsx6(
211
+ SelectableAnnotationContainer,
212
+ {
213
+ trackedAnnotation: annotation,
214
+ scale,
215
+ isSelected,
216
+ pageIndex,
217
+ children: /* @__PURE__ */ jsx6(
218
+ Strikeout,
219
+ {
220
+ color: annotation.object.color,
221
+ opacity: annotation.object.opacity,
222
+ rects: annotation.object.segmentRects,
223
+ scale
224
+ }
225
+ )
226
+ },
227
+ annotation.localId
228
+ );
229
+ case PdfAnnotationSubtype.SQUIGGLY:
230
+ return /* @__PURE__ */ jsx6(
231
+ SelectableAnnotationContainer,
232
+ {
233
+ trackedAnnotation: annotation,
234
+ scale,
235
+ isSelected,
236
+ pageIndex,
237
+ children: /* @__PURE__ */ jsx6(
238
+ Squiggly,
239
+ {
240
+ color: annotation.object.color,
241
+ opacity: annotation.object.opacity,
242
+ rects: annotation.object.segmentRects,
243
+ scale
244
+ }
245
+ )
246
+ },
247
+ annotation.localId
248
+ );
249
+ case PdfAnnotationSubtype.HIGHLIGHT:
250
+ return /* @__PURE__ */ jsx6(
251
+ SelectableAnnotationContainer,
252
+ {
253
+ trackedAnnotation: annotation,
254
+ scale,
255
+ isSelected,
256
+ pageIndex,
257
+ children: /* @__PURE__ */ jsx6(
258
+ Highlight,
259
+ {
260
+ color: annotation.object.color,
261
+ opacity: annotation.object.opacity,
262
+ rects: annotation.object.segmentRects,
263
+ scale
264
+ }
265
+ )
266
+ },
267
+ annotation.localId
268
+ );
269
+ default:
270
+ return null;
271
+ }
272
+ }) });
273
+ }
274
+
275
+ // src/preact/components/text-markup.tsx
276
+ import { PdfAnnotationSubtype as PdfAnnotationSubtype2 } from "@embedpdf/models";
277
+ import { useSelectionCapability as useSelectionCapability2 } from "@embedpdf/plugin-selection/preact";
278
+ import { useEffect as useEffect2, useState as useState2 } from "preact/hooks";
279
+ import { jsx as jsx7 } from "preact/jsx-runtime";
280
+ function TextMarkup({ pageIndex, scale }) {
281
+ const { provides: selectionProvides } = useSelectionCapability2();
282
+ const { provides: annotationProvides } = useAnnotationCapability();
283
+ const [rects, setRects] = useState2([]);
284
+ const [activeTool, setActiveTool] = useState2({ mode: null, defaults: null });
285
+ useEffect2(() => {
286
+ if (!selectionProvides) return;
287
+ const off = selectionProvides.onSelectionChange(() => {
288
+ setRects(selectionProvides.getHighlightRectsForPage(pageIndex));
289
+ });
290
+ return off;
291
+ }, [selectionProvides, pageIndex]);
292
+ useEffect2(() => {
293
+ if (!annotationProvides) return;
294
+ const off = annotationProvides.onActiveToolChange(setActiveTool);
295
+ return off;
296
+ }, [annotationProvides]);
297
+ switch (activeTool.mode) {
298
+ case PdfAnnotationSubtype2.UNDERLINE:
299
+ return /* @__PURE__ */ jsx7(
300
+ Underline,
301
+ {
302
+ color: activeTool.defaults?.color,
303
+ opacity: activeTool.defaults?.opacity,
304
+ rects,
305
+ scale
306
+ }
307
+ );
308
+ case PdfAnnotationSubtype2.HIGHLIGHT:
309
+ return /* @__PURE__ */ jsx7(
310
+ Highlight,
311
+ {
312
+ color: activeTool.defaults?.color,
313
+ opacity: activeTool.defaults?.opacity,
314
+ rects,
315
+ scale
316
+ }
317
+ );
318
+ case PdfAnnotationSubtype2.STRIKEOUT:
319
+ return /* @__PURE__ */ jsx7(
320
+ Strikeout,
321
+ {
322
+ color: activeTool.defaults?.color,
323
+ opacity: activeTool.defaults?.opacity,
324
+ rects,
325
+ scale
326
+ }
327
+ );
328
+ case PdfAnnotationSubtype2.SQUIGGLY:
329
+ return /* @__PURE__ */ jsx7(
330
+ Squiggly,
331
+ {
332
+ color: activeTool.defaults?.color,
333
+ opacity: activeTool.defaults?.opacity,
334
+ rects,
335
+ scale
336
+ }
337
+ );
338
+ default:
339
+ return null;
340
+ }
341
+ }
342
+
343
+ // src/preact/components/annotation-layer.tsx
344
+ import { jsx as jsx8, jsxs as jsxs2 } from "preact/jsx-runtime";
345
+ function AnnotationLayer({ pageIndex, scale, style, ...props }) {
346
+ return /* @__PURE__ */ jsxs2(
136
347
  "div",
137
348
  {
138
349
  style: {
139
350
  ...style
140
351
  },
141
352
  ...props,
142
- children: annotations.map((annotation) => {
143
- const isSelected = selectionState.selectedPageIndex === pageIndex && selectionState.selectedAnnotationId === annotation.id;
144
- switch (annotation.type) {
145
- case PdfAnnotationSubtype.HIGHLIGHT:
146
- return /* @__PURE__ */ jsx2(
147
- HighlightAnnotation,
148
- {
149
- annotation,
150
- scale,
151
- isSelected,
152
- pageIndex
153
- },
154
- annotation.id
155
- );
156
- default:
157
- return null;
158
- }
159
- })
353
+ children: [
354
+ /* @__PURE__ */ jsx8(Annotations, { pageIndex, scale }),
355
+ /* @__PURE__ */ jsx8(TextMarkup, { pageIndex, scale })
356
+ ]
160
357
  }
161
358
  );
162
359
  }