@embedpdf/plugin-redaction 2.3.0 → 2.4.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 (66) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +748 -105
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/actions.d.ts +25 -1
  6. package/dist/lib/index.d.ts +1 -0
  7. package/dist/lib/redaction-plugin.d.ts +98 -2
  8. package/dist/lib/tools.d.ts +28 -0
  9. package/dist/lib/types.d.ts +38 -11
  10. package/dist/preact/adapter.d.ts +4 -4
  11. package/dist/preact/annotation.d.ts +1 -0
  12. package/dist/preact/index.cjs +1 -1
  13. package/dist/preact/index.cjs.map +1 -1
  14. package/dist/preact/index.js +187 -11
  15. package/dist/preact/index.js.map +1 -1
  16. package/dist/react/annotation.d.ts +1 -0
  17. package/dist/react/index.cjs +1 -1
  18. package/dist/react/index.cjs.map +1 -1
  19. package/dist/react/index.js +187 -11
  20. package/dist/react/index.js.map +1 -1
  21. package/dist/shared/components/annotations/index.d.ts +2 -0
  22. package/dist/shared/components/annotations/redact-area.d.ts +18 -0
  23. package/dist/shared/components/annotations/redact-highlight.d.ts +18 -0
  24. package/dist/shared/components/index.d.ts +3 -0
  25. package/dist/shared/components/redact-renderer-registration.d.ts +5 -0
  26. package/dist/shared/components/redact-renderers.d.ts +7 -0
  27. package/dist/shared/index.d.ts +1 -0
  28. package/dist/shared-preact/components/annotations/index.d.ts +2 -0
  29. package/dist/shared-preact/components/annotations/redact-area.d.ts +18 -0
  30. package/dist/shared-preact/components/annotations/redact-highlight.d.ts +18 -0
  31. package/dist/shared-preact/components/index.d.ts +3 -0
  32. package/dist/shared-preact/components/redact-renderer-registration.d.ts +5 -0
  33. package/dist/shared-preact/components/redact-renderers.d.ts +7 -0
  34. package/dist/shared-preact/index.d.ts +1 -0
  35. package/dist/shared-react/components/annotations/index.d.ts +2 -0
  36. package/dist/shared-react/components/annotations/redact-area.d.ts +18 -0
  37. package/dist/shared-react/components/annotations/redact-highlight.d.ts +18 -0
  38. package/dist/shared-react/components/index.d.ts +3 -0
  39. package/dist/shared-react/components/redact-renderer-registration.d.ts +5 -0
  40. package/dist/shared-react/components/redact-renderers.d.ts +7 -0
  41. package/dist/shared-react/index.d.ts +1 -0
  42. package/dist/svelte/components/RedactRendererRegistration.svelte.d.ts +7 -0
  43. package/dist/svelte/components/annotations/RedactArea.svelte.d.ts +5 -0
  44. package/dist/svelte/components/annotations/RedactHighlight.svelte.d.ts +5 -0
  45. package/dist/svelte/components/annotations/index.d.ts +2 -0
  46. package/dist/svelte/components/index.d.ts +3 -0
  47. package/dist/svelte/components/redact-renderers.d.ts +7 -0
  48. package/dist/svelte/index.cjs +1 -1
  49. package/dist/svelte/index.cjs.map +1 -1
  50. package/dist/svelte/index.d.ts +1 -0
  51. package/dist/svelte/index.js +270 -22
  52. package/dist/svelte/index.js.map +1 -1
  53. package/dist/vue/components/annotations/index.d.ts +2 -0
  54. package/dist/vue/components/annotations/redact-area.vue.d.ts +6 -0
  55. package/dist/vue/components/annotations/redact-highlight.vue.d.ts +6 -0
  56. package/dist/vue/components/index.d.ts +3 -0
  57. package/dist/vue/components/redact-renderer-registration.vue.d.ts +13 -0
  58. package/dist/vue/components/redact-renderers.d.ts +7 -0
  59. package/dist/vue/components/types.d.ts +1 -1
  60. package/dist/vue/hooks/use-redaction.d.ts +2 -2
  61. package/dist/vue/index.cjs +1 -1
  62. package/dist/vue/index.cjs.map +1 -1
  63. package/dist/vue/index.d.ts +2 -1
  64. package/dist/vue/index.js +264 -59
  65. package/dist/vue/index.js.map +1 -1
  66. package/package.json +13 -9
@@ -1,11 +1,177 @@
1
- import { usePlugin, useCapability, useDocumentState } from "@embedpdf/core/preact";
2
- import { RedactionPlugin, initialDocumentState } from "@embedpdf/plugin-redaction";
1
+ import { createPluginPackage } from "@embedpdf/core";
2
+ import { RedactionPlugin, initialDocumentState, RedactionPluginPackage as RedactionPluginPackage$1 } from "@embedpdf/plugin-redaction";
3
3
  export * from "@embedpdf/plugin-redaction";
4
+ import { createRenderer, useRegisterRenderers } from "@embedpdf/plugin-annotation/preact";
5
+ import { jsx, Fragment, jsxs } from "preact/jsx-runtime";
6
+ import { PdfStandardFont, PdfTextAlignment, textAlignmentToCss, standardFontCss, PdfAnnotationSubtype, Rotation } from "@embedpdf/models";
4
7
  import { Fragment as Fragment$1 } from "preact";
5
8
  import { useState, useMemo, useEffect, useCallback } from "preact/hooks";
6
- import { jsx, Fragment, jsxs } from "preact/jsx-runtime";
9
+ import { usePlugin, useCapability, useDocumentState } from "@embedpdf/core/preact";
7
10
  import { CounterRotate } from "@embedpdf/utils/preact";
8
- import { Rotation } from "@embedpdf/models";
11
+ function RedactHighlight({
12
+ annotation,
13
+ isSelected,
14
+ scale,
15
+ onClick,
16
+ style
17
+ }) {
18
+ const [isHovered, setIsHovered] = useState(false);
19
+ const { object } = annotation;
20
+ const segmentRects = object.segmentRects ?? [];
21
+ const rect = object.rect;
22
+ const strokeColor = object.strokeColor ?? "#FF0000";
23
+ const color = object.color ?? "#000000";
24
+ const opacity = object.opacity ?? 1;
25
+ const textColor = object.fontColor ?? object.overlayColor ?? "#FFFFFF";
26
+ const overlayText = object.overlayText;
27
+ const overlayTextRepeat = object.overlayTextRepeat ?? false;
28
+ const fontSize = object.fontSize ?? 12;
29
+ const fontFamily = object.fontFamily ?? PdfStandardFont.Helvetica;
30
+ const textAlign = object.textAlign ?? PdfTextAlignment.Center;
31
+ const renderOverlayText = () => {
32
+ if (!overlayText) return null;
33
+ if (!overlayTextRepeat) return overlayText;
34
+ const reps = 10;
35
+ return Array(reps).fill(overlayText).join(" ");
36
+ };
37
+ return /* @__PURE__ */ jsx(
38
+ "div",
39
+ {
40
+ onMouseEnter: () => setIsHovered(true),
41
+ onMouseLeave: () => setIsHovered(false),
42
+ style: { position: "absolute", inset: 0 },
43
+ children: segmentRects.map((b, i) => /* @__PURE__ */ jsx(
44
+ "div",
45
+ {
46
+ onPointerDown: onClick,
47
+ onTouchStart: onClick,
48
+ style: {
49
+ position: "absolute",
50
+ left: (rect ? b.origin.x - rect.origin.x : b.origin.x) * scale,
51
+ top: (rect ? b.origin.y - rect.origin.y : b.origin.y) * scale,
52
+ width: b.size.width * scale,
53
+ height: b.size.height * scale,
54
+ // Default: transparent background with strokeColor (C) border
55
+ // Hovered: color (IC) background fill, no border
56
+ // Selected: no border (container handles it)
57
+ background: isHovered ? color : "transparent",
58
+ border: !isHovered ? `2px solid ${strokeColor}` : "none",
59
+ opacity: isHovered ? opacity : 1,
60
+ boxSizing: "border-box",
61
+ pointerEvents: "auto",
62
+ cursor: "pointer",
63
+ display: "flex",
64
+ alignItems: "center",
65
+ justifyContent: textAlign === PdfTextAlignment.Left ? "flex-start" : textAlign === PdfTextAlignment.Right ? "flex-end" : "center",
66
+ overflow: "hidden",
67
+ ...style
68
+ },
69
+ children: isHovered && overlayText && /* @__PURE__ */ jsx(
70
+ "span",
71
+ {
72
+ style: {
73
+ color: textColor,
74
+ fontSize: Math.min(fontSize * scale, b.size.height * scale * 0.8),
75
+ fontFamily: standardFontCss(fontFamily),
76
+ textAlign: textAlignmentToCss(textAlign),
77
+ whiteSpace: overlayTextRepeat ? "normal" : "nowrap",
78
+ overflow: "hidden",
79
+ textOverflow: "ellipsis",
80
+ lineHeight: 1
81
+ },
82
+ children: renderOverlayText()
83
+ }
84
+ )
85
+ },
86
+ i
87
+ ))
88
+ }
89
+ );
90
+ }
91
+ function RedactArea({ annotation, isSelected, scale, onClick, style }) {
92
+ const [isHovered, setIsHovered] = useState(false);
93
+ const { object } = annotation;
94
+ const strokeColor = object.strokeColor ?? "#FF0000";
95
+ const color = object.color ?? "#000000";
96
+ const opacity = object.opacity ?? 1;
97
+ const textColor = object.fontColor ?? object.overlayColor ?? "#FFFFFF";
98
+ const overlayText = object.overlayText;
99
+ const overlayTextRepeat = object.overlayTextRepeat ?? false;
100
+ const fontSize = object.fontSize ?? 12;
101
+ const fontFamily = object.fontFamily ?? PdfStandardFont.Helvetica;
102
+ const textAlign = object.textAlign ?? PdfTextAlignment.Center;
103
+ const renderOverlayText = () => {
104
+ if (!overlayText) return null;
105
+ if (!overlayTextRepeat) return overlayText;
106
+ const reps = 10;
107
+ return Array(reps).fill(overlayText).join(" ");
108
+ };
109
+ return /* @__PURE__ */ jsx(
110
+ "div",
111
+ {
112
+ onPointerDown: !isSelected ? onClick : void 0,
113
+ onTouchStart: !isSelected ? onClick : void 0,
114
+ onMouseEnter: () => setIsHovered(true),
115
+ onMouseLeave: () => setIsHovered(false),
116
+ style: {
117
+ position: "absolute",
118
+ inset: 0,
119
+ // Default: transparent background with strokeColor (C) border
120
+ // Hovered: color (IC) background fill, no border
121
+ // Selected: no border (container handles it)
122
+ background: isHovered ? color : "transparent",
123
+ border: !isHovered ? `2px solid ${strokeColor}` : "none",
124
+ opacity: isHovered ? opacity : 1,
125
+ boxSizing: "border-box",
126
+ pointerEvents: "auto",
127
+ cursor: isSelected ? "move" : "pointer",
128
+ display: "flex",
129
+ alignItems: "center",
130
+ justifyContent: textAlign === PdfTextAlignment.Left ? "flex-start" : textAlign === PdfTextAlignment.Right ? "flex-end" : "center",
131
+ overflow: "hidden",
132
+ ...style
133
+ },
134
+ children: isHovered && overlayText && /* @__PURE__ */ jsx(
135
+ "span",
136
+ {
137
+ style: {
138
+ color: textColor,
139
+ fontSize: fontSize * scale,
140
+ fontFamily: standardFontCss(fontFamily),
141
+ textAlign: textAlignmentToCss(textAlign),
142
+ whiteSpace: overlayTextRepeat ? "normal" : "nowrap",
143
+ overflow: "hidden",
144
+ textOverflow: "ellipsis",
145
+ padding: "4px"
146
+ },
147
+ children: renderOverlayText()
148
+ }
149
+ )
150
+ }
151
+ );
152
+ }
153
+ const redactRenderers = [
154
+ createRenderer({
155
+ id: "redactHighlight",
156
+ matches: (a) => {
157
+ var _a;
158
+ return a.type === PdfAnnotationSubtype.REDACT && "segmentRects" in a && (((_a = a.segmentRects) == null ? void 0 : _a.length) ?? 0) > 0;
159
+ },
160
+ render: (props) => /* @__PURE__ */ jsx(RedactHighlight, { ...props })
161
+ }),
162
+ createRenderer({
163
+ id: "redactArea",
164
+ matches: (a) => {
165
+ var _a;
166
+ return a.type === PdfAnnotationSubtype.REDACT && (!("segmentRects" in a) || !(((_a = a.segmentRects) == null ? void 0 : _a.length) ?? 0));
167
+ },
168
+ render: (props) => /* @__PURE__ */ jsx(RedactArea, { ...props })
169
+ })
170
+ ];
171
+ function RedactRendererRegistration() {
172
+ useRegisterRenderers(redactRenderers);
173
+ return null;
174
+ }
9
175
  const useRedactionPlugin = () => usePlugin(RedactionPlugin.id);
10
176
  const useRedactionCapability = () => useCapability(RedactionPlugin.id);
11
177
  const useRedaction = (documentId) => {
@@ -40,7 +206,7 @@ const MarqueeRedact = ({
40
206
  pageIndex,
41
207
  scale: scaleOverride,
42
208
  className,
43
- stroke = "red",
209
+ stroke,
44
210
  fill = "transparent"
45
211
  }) => {
46
212
  const { plugin: redactionPlugin } = useRedactionPlugin();
@@ -50,6 +216,7 @@ const MarqueeRedact = ({
50
216
  if (scaleOverride !== void 0) return scaleOverride;
51
217
  return (documentState == null ? void 0 : documentState.scale) ?? 1;
52
218
  }, [scaleOverride, documentState == null ? void 0 : documentState.scale]);
219
+ const strokeColor = stroke ?? (redactionPlugin == null ? void 0 : redactionPlugin.getPreviewStrokeColor()) ?? "red";
53
220
  useEffect(() => {
54
221
  if (!redactionPlugin || !documentId) return;
55
222
  return redactionPlugin.registerMarqueeOnPage({
@@ -72,7 +239,7 @@ const MarqueeRedact = ({
72
239
  top: rect.origin.y * scale,
73
240
  width: rect.size.width * scale,
74
241
  height: rect.size.height * scale,
75
- border: `1px solid ${stroke}`,
242
+ border: `1px solid ${strokeColor}`,
76
243
  background: fill,
77
244
  boxSizing: "border-box"
78
245
  },
@@ -119,6 +286,7 @@ function SelectionRedact({ documentId, pageIndex, scale }) {
119
286
  const { plugin: redactionPlugin } = useRedactionPlugin();
120
287
  const [rects, setRects] = useState([]);
121
288
  const [boundingRect, setBoundingRect] = useState(null);
289
+ const strokeColor = (redactionPlugin == null ? void 0 : redactionPlugin.getPreviewStrokeColor()) ?? "red";
122
290
  useEffect(() => {
123
291
  if (!redactionPlugin) return;
124
292
  return redactionPlugin.onRedactionSelectionChange(documentId, (formattedSelection) => {
@@ -144,7 +312,7 @@ function SelectionRedact({ documentId, pageIndex, scale }) {
144
312
  opacity: 1,
145
313
  rects,
146
314
  scale,
147
- border: "1px solid red"
315
+ border: `1px solid ${strokeColor}`
148
316
  }
149
317
  )
150
318
  }
@@ -165,11 +333,13 @@ function PendingRedactions({
165
333
  if (!redaction) return;
166
334
  const scoped = redaction.forDocument(documentId);
167
335
  const currentState = scoped.getState();
168
- setItems(currentState.pending[pageIndex] ?? []);
336
+ setItems((currentState.pending[pageIndex] ?? []).filter((it) => it.source === "legacy"));
169
337
  setSelectedId(
170
338
  currentState.selected && currentState.selected.page === pageIndex ? currentState.selected.id : null
171
339
  );
172
- const off1 = scoped.onPendingChange((map) => setItems(map[pageIndex] ?? []));
340
+ const off1 = scoped.onPendingChange((map) => {
341
+ setItems((map[pageIndex] ?? []).filter((it) => it.source === "legacy"));
342
+ });
173
343
  const off2 = scoped.onSelectedChange((sel) => {
174
344
  setSelectedId(sel && sel.page === pageIndex ? sel.id : null);
175
345
  });
@@ -203,7 +373,7 @@ function PendingRedactions({
203
373
  background: "transparent",
204
374
  outline: selectedId === it.id ? `1px solid ${bboxStroke}` : "none",
205
375
  outlineOffset: "2px",
206
- border: `1px solid red`,
376
+ border: `1px solid ${it.markColor}`,
207
377
  pointerEvents: "auto",
208
378
  cursor: "pointer"
209
379
  },
@@ -258,7 +428,7 @@ function PendingRedactions({
258
428
  rect: b,
259
429
  rects: it.rects,
260
430
  color: "transparent",
261
- border: "1px solid red",
431
+ border: `1px solid ${it.markColor}`,
262
432
  scale,
263
433
  onClick: (e) => select(e, it.id)
264
434
  }
@@ -321,8 +491,14 @@ const RedactionLayer = ({
321
491
  /* @__PURE__ */ jsx(SelectionRedact, { documentId, pageIndex, scale: actualScale })
322
492
  ] });
323
493
  };
494
+ const RedactionPluginPackage = createPluginPackage(RedactionPluginPackage$1).addUtility(RedactRendererRegistration).build();
324
495
  export {
496
+ RedactArea,
497
+ RedactHighlight,
498
+ RedactRendererRegistration,
325
499
  RedactionLayer,
500
+ RedactionPluginPackage,
501
+ redactRenderers,
326
502
  useRedaction,
327
503
  useRedactionCapability,
328
504
  useRedactionPlugin
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-redaction.ts","../../src/shared/components/marquee-redact.tsx","../../src/shared/components/highlight.tsx","../../src/shared/components/selection-redact.tsx","../../src/shared/components/pending-redactions.tsx","../../src/shared/components/redaction-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {\n initialDocumentState,\n RedactionPlugin,\n RedactionDocumentState,\n RedactionScope,\n} from '@embedpdf/plugin-redaction';\nimport { useState, useEffect, useMemo } from '@framework';\n\nexport const useRedactionPlugin = () => usePlugin<RedactionPlugin>(RedactionPlugin.id);\nexport const useRedactionCapability = () => useCapability<RedactionPlugin>(RedactionPlugin.id);\n\nexport const useRedaction = (\n documentId: string,\n): {\n state: RedactionDocumentState;\n provides: RedactionScope | null;\n} => {\n const { provides } = useRedactionCapability();\n const [state, setState] = useState<RedactionDocumentState>(initialDocumentState);\n\n const scope = useMemo(\n () => (provides ? provides.forDocument(documentId) : null),\n [provides, documentId],\n );\n\n useEffect(() => {\n if (!scope) {\n setState(initialDocumentState);\n return;\n }\n\n // Set initial state\n try {\n setState(scope.getState());\n } catch (e) {\n // Handle case where state might not be ready\n setState(initialDocumentState);\n }\n\n // Subscribe to changes\n const unsubscribe = scope.onStateChange((newState) => {\n setState(newState);\n });\n\n return unsubscribe;\n }, [scope]);\n\n return {\n state,\n provides: scope,\n };\n};\n","import { useEffect, useMemo, useState } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { Rect } from '@embedpdf/models';\n\nimport { useRedactionPlugin } from '../hooks/use-redaction';\n\ninterface MarqueeRedactProps {\n /** The ID of the document */\n documentId: string;\n /** Index of the page this layer lives on */\n pageIndex: number;\n /** Scale of the page */\n scale?: number;\n /** Optional CSS class applied to the marquee rectangle */\n className?: string;\n /** Stroke / fill colours (defaults below) */\n stroke?: string;\n fill?: string;\n}\n\nexport const MarqueeRedact = ({\n documentId,\n pageIndex,\n scale: scaleOverride,\n className,\n stroke = 'red',\n fill = 'transparent',\n}: MarqueeRedactProps) => {\n const { plugin: redactionPlugin } = useRedactionPlugin();\n const documentState = useDocumentState(documentId);\n\n const [rect, setRect] = useState<Rect | null>(null);\n\n const scale = useMemo(() => {\n if (scaleOverride !== undefined) return scaleOverride;\n return documentState?.scale ?? 1;\n }, [scaleOverride, documentState?.scale]);\n\n useEffect(() => {\n if (!redactionPlugin || !documentId) return;\n return redactionPlugin.registerMarqueeOnPage({\n documentId,\n pageIndex,\n scale,\n callback: {\n onPreview: setRect,\n },\n });\n }, [redactionPlugin, documentId, pageIndex, scale]);\n\n if (!rect) return null;\n\n return (\n <div\n style={{\n position: 'absolute',\n pointerEvents: 'none',\n left: rect.origin.x * scale,\n top: rect.origin.y * scale,\n width: rect.size.width * scale,\n height: rect.size.height * scale,\n border: `1px solid ${stroke}`,\n background: fill,\n boxSizing: 'border-box',\n }}\n className={className}\n />\n );\n};\n","import { HTMLAttributes, CSSProperties, MouseEvent, TouchEvent } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\ntype HighlightProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n color?: string;\n opacity?: number;\n border?: string;\n rects: Rect[];\n rect?: Rect;\n scale: number;\n onClick?: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n style?: CSSProperties;\n};\n\nexport function Highlight({\n color = '#FFFF00',\n opacity = 1,\n border = '1px solid red',\n rects,\n rect,\n scale,\n onClick,\n style,\n ...props\n}: HighlightProps) {\n return (\n <>\n {rects.map((b, i) => (\n <div\n key={i}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n position: 'absolute',\n border,\n left: (rect ? b.origin.x - rect.origin.x : b.origin.x) * scale,\n top: (rect ? b.origin.y - rect.origin.y : b.origin.y) * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background: color,\n opacity: opacity,\n pointerEvents: onClick ? 'auto' : 'none',\n cursor: onClick ? 'pointer' : 'default',\n zIndex: onClick ? 1 : undefined,\n ...style,\n }}\n {...props}\n />\n ))}\n </>\n );\n}\n","import { Rect } from '@embedpdf/models';\nimport { useEffect, useState } from '@framework';\nimport { useRedactionPlugin } from '../hooks';\nimport { Highlight } from './highlight';\n\ninterface SelectionRedactProps {\n documentId: string;\n pageIndex: number;\n scale: number;\n}\n\nexport function SelectionRedact({ documentId, pageIndex, scale }: SelectionRedactProps) {\n const { plugin: redactionPlugin } = useRedactionPlugin();\n const [rects, setRects] = useState<Array<Rect>>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n\n useEffect(() => {\n if (!redactionPlugin) return;\n return redactionPlugin.onRedactionSelectionChange(documentId, (formattedSelection) => {\n const selection = formattedSelection.find((s) => s.pageIndex === pageIndex);\n setRects(selection?.segmentRects ?? []);\n setBoundingRect(selection?.rect ?? null);\n });\n }, [redactionPlugin, documentId, pageIndex]);\n\n if (!boundingRect) return null;\n\n return (\n <div\n style={{\n mixBlendMode: 'normal',\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n }}\n >\n <Highlight\n color={'transparent'}\n opacity={1}\n rects={rects}\n scale={scale}\n border=\"1px solid red\"\n />\n </div>\n );\n}\n","import { Fragment, useEffect, useState, useCallback, MouseEvent, TouchEvent } from '@framework';\nimport { CounterRotate } from '@embedpdf/utils/@framework';\nimport { useRedactionCapability } from '../hooks';\nimport { RedactionItem } from '@embedpdf/plugin-redaction';\nimport { Highlight } from './highlight';\nimport { RedactionSelectionMenuRenderFn } from './types';\nimport { Rotation } from '@embedpdf/models';\n\ninterface PendingRedactionsProps {\n documentId: string;\n pageIndex: number;\n scale: number;\n rotation: Rotation;\n bboxStroke?: string;\n selectionMenu?: RedactionSelectionMenuRenderFn;\n}\n\nexport function PendingRedactions({\n documentId,\n pageIndex,\n scale,\n bboxStroke = 'rgba(0,0,0,0.8)',\n rotation = Rotation.Degree0,\n selectionMenu,\n}: PendingRedactionsProps) {\n const { provides: redaction } = useRedactionCapability();\n const [items, setItems] = useState<RedactionItem[]>([]);\n const [selectedId, setSelectedId] = useState<string | null>(null);\n\n useEffect(() => {\n if (!redaction) return;\n\n // Use document-scoped hooks so we only receive events for this document\n const scoped = redaction.forDocument(documentId);\n\n // Initialize with current state\n const currentState = scoped.getState();\n setItems(currentState.pending[pageIndex] ?? []);\n setSelectedId(\n currentState.selected && currentState.selected.page === pageIndex\n ? currentState.selected.id\n : null,\n );\n\n // Subscribe to future changes\n const off1 = scoped.onPendingChange((map) => setItems(map[pageIndex] ?? []));\n const off2 = scoped.onSelectedChange((sel) => {\n setSelectedId(sel && sel.page === pageIndex ? sel.id : null);\n });\n\n return () => {\n off1?.();\n off2?.();\n };\n }, [redaction, documentId, pageIndex]);\n\n const select = useCallback(\n (e: MouseEvent | TouchEvent, id: string) => {\n e.stopPropagation();\n if (!redaction) return;\n redaction.forDocument(documentId).selectPending(pageIndex, id);\n },\n [redaction, documentId, pageIndex],\n );\n\n if (!items.length) return null;\n\n return (\n <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>\n {items.map((it) => {\n if (it.kind === 'area') {\n const r = it.rect;\n return (\n <Fragment key={it.id}>\n <div\n style={{\n position: 'absolute',\n left: r.origin.x * scale,\n top: r.origin.y * scale,\n width: r.size.width * scale,\n height: r.size.height * scale,\n background: 'transparent',\n outline: selectedId === it.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n border: `1px solid red`,\n pointerEvents: 'auto',\n cursor: 'pointer',\n }}\n onPointerDown={(e) => select(e, it.id)}\n onTouchStart={(e) => select(e, it.id)}\n />\n {selectionMenu && (\n <CounterRotate\n rect={{\n origin: { x: r.origin.x * scale, y: r.origin.y * scale },\n size: { width: r.size.width * scale, height: r.size.height * scale },\n }}\n rotation={rotation}\n >\n {(props) =>\n selectionMenu({\n ...props,\n context: {\n type: 'redaction',\n item: it,\n pageIndex,\n },\n selected: selectedId === it.id,\n placement: {\n suggestTop: false,\n },\n })\n }\n </CounterRotate>\n )}\n </Fragment>\n );\n }\n\n const b = it.rect;\n return (\n <Fragment key={it.id}>\n <div\n style={{\n position: 'absolute',\n left: b.origin.x * scale,\n top: b.origin.y * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background: 'transparent',\n outline: selectedId === it.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n pointerEvents: 'auto',\n cursor: selectedId === it.id ? 'pointer' : 'default',\n }}\n >\n <Highlight\n rect={b}\n rects={it.rects}\n color=\"transparent\"\n border=\"1px solid red\"\n scale={scale}\n onClick={(e) => select(e, it.id)}\n />\n </div>\n {selectionMenu && (\n <CounterRotate\n rect={{\n origin: { x: b.origin.x * scale, y: b.origin.y * scale },\n size: { width: b.size.width * scale, height: b.size.height * scale },\n }}\n rotation={rotation}\n >\n {(props) =>\n selectionMenu({\n ...props,\n context: {\n type: 'redaction',\n item: it,\n pageIndex,\n },\n selected: selectedId === it.id,\n placement: {\n suggestTop: false,\n },\n })\n }\n </CounterRotate>\n )}\n </Fragment>\n );\n })}\n </div>\n );\n}\n","import { Fragment, useMemo } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { MarqueeRedact } from './marquee-redact';\nimport { SelectionRedact } from './selection-redact';\nimport { PendingRedactions } from './pending-redactions';\nimport { Rotation } from '@embedpdf/models';\nimport { RedactionSelectionMenuRenderFn } from './types';\n\ninterface RedactionLayerProps {\n /** The ID of the document this layer belongs to */\n documentId: string;\n /** Index of the page this layer lives on */\n pageIndex: number;\n /** Current render scale for this page */\n scale?: number;\n /** Page rotation (for counter-rotating menus, etc.) */\n rotation?: Rotation;\n /** Optional menu renderer for a selected redaction */\n selectionMenu?: RedactionSelectionMenuRenderFn;\n}\n\nexport const RedactionLayer = ({\n documentId,\n pageIndex,\n scale,\n rotation,\n selectionMenu,\n}: RedactionLayerProps) => {\n const documentState = useDocumentState(documentId);\n\n const actualScale = useMemo(() => {\n if (scale !== undefined) return scale;\n return documentState?.scale ?? 1;\n }, [scale, documentState?.scale]);\n\n const actualRotation = useMemo(() => {\n if (rotation !== undefined) return rotation;\n return documentState?.rotation ?? Rotation.Degree0;\n }, [rotation, documentState?.rotation]);\n\n return (\n <Fragment>\n <PendingRedactions\n documentId={documentId}\n pageIndex={pageIndex}\n scale={actualScale}\n rotation={actualRotation}\n selectionMenu={selectionMenu}\n />\n <MarqueeRedact documentId={documentId} pageIndex={pageIndex} scale={actualScale} />\n <SelectionRedact documentId={documentId} pageIndex={pageIndex} scale={actualScale} />\n </Fragment>\n );\n};\n"],"names":["Fragment"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/shared/components/annotations/redact-highlight.tsx","../../src/shared/components/annotations/redact-area.tsx","../../src/shared/components/redact-renderers.tsx","../../src/shared/components/redact-renderer-registration.tsx","../../src/shared/hooks/use-redaction.ts","../../src/shared/components/marquee-redact.tsx","../../src/shared/components/highlight.tsx","../../src/shared/components/selection-redact.tsx","../../src/shared/components/pending-redactions.tsx","../../src/shared/components/redaction-layer.tsx","../../src/shared/index.ts"],"sourcesContent":["import { CSSProperties, MouseEvent, TouchEvent, useState } from '@framework';\nimport {\n PdfRedactAnnoObject,\n PdfStandardFont,\n PdfTextAlignment,\n Rect,\n standardFontCss,\n textAlignmentToCss,\n} from '@embedpdf/models';\nimport { TrackedAnnotation } from '@embedpdf/plugin-annotation';\n\nexport interface RedactHighlightProps {\n annotation: TrackedAnnotation<PdfRedactAnnoObject>;\n isSelected: boolean;\n scale: number;\n pageIndex: number;\n onClick: (e: MouseEvent<Element> | TouchEvent<Element>) => void;\n style?: CSSProperties;\n}\n\n/**\n * Renders a text-based redact annotation using QuadPoints/segmentRects.\n * Default: shows strokeColor (C) border only, no fill.\n * Hovered: shows redaction preview with color (IC) as background fill + overlayText.\n * Selected: no border (AnnotationContainer handles selection styling).\n */\nexport function RedactHighlight({\n annotation,\n isSelected,\n scale,\n onClick,\n style,\n}: RedactHighlightProps) {\n const [isHovered, setIsHovered] = useState(false);\n const { object } = annotation;\n\n const segmentRects = object.segmentRects ?? [];\n const rect = object.rect;\n\n // C - Border/stroke color\n const strokeColor = object.strokeColor ?? '#FF0000';\n // IC - Interior color (background fill when redaction is applied)\n const color = object.color ?? '#000000';\n // CA - Opacity (0-1)\n const opacity = object.opacity ?? 1;\n // OC - Overlay text color (Adobe extension), fallback to fontColor\n const textColor = object.fontColor ?? object.overlayColor ?? '#FFFFFF';\n // Overlay text properties\n const overlayText = object.overlayText;\n const overlayTextRepeat = object.overlayTextRepeat ?? false;\n const fontSize = object.fontSize ?? 12;\n const fontFamily = object.fontFamily ?? PdfStandardFont.Helvetica;\n const textAlign = object.textAlign ?? PdfTextAlignment.Center;\n\n // Calculate how many times to repeat text (approximate)\n const renderOverlayText = () => {\n if (!overlayText) return null;\n if (!overlayTextRepeat) return overlayText;\n // Repeat text multiple times to fill the space\n const reps = 10; // Enough repetitions to fill most containers\n return Array(reps).fill(overlayText).join(' ');\n };\n\n return (\n <div\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n style={{ position: 'absolute', inset: 0 }}\n >\n {segmentRects.map((b: Rect, i: number) => (\n <div\n key={i}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n position: 'absolute',\n left: (rect ? b.origin.x - rect.origin.x : b.origin.x) * scale,\n top: (rect ? b.origin.y - rect.origin.y : b.origin.y) * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n // Default: transparent background with strokeColor (C) border\n // Hovered: color (IC) background fill, no border\n // Selected: no border (container handles it)\n background: isHovered ? color : 'transparent',\n border: !isHovered ? `2px solid ${strokeColor}` : 'none',\n opacity: isHovered ? opacity : 1,\n boxSizing: 'border-box',\n pointerEvents: 'auto',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent:\n textAlign === PdfTextAlignment.Left\n ? 'flex-start'\n : textAlign === PdfTextAlignment.Right\n ? 'flex-end'\n : 'center',\n overflow: 'hidden',\n ...style,\n }}\n >\n {isHovered && overlayText && (\n <span\n style={{\n color: textColor,\n fontSize: Math.min(fontSize * scale, b.size.height * scale * 0.8),\n fontFamily: standardFontCss(fontFamily),\n textAlign: textAlignmentToCss(textAlign),\n whiteSpace: overlayTextRepeat ? 'normal' : 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n lineHeight: 1,\n }}\n >\n {renderOverlayText()}\n </span>\n )}\n </div>\n ))}\n </div>\n );\n}\n","import { CSSProperties, MouseEvent, TouchEvent, useState } from '@framework';\nimport {\n PdfRedactAnnoObject,\n PdfStandardFont,\n PdfTextAlignment,\n standardFontCss,\n textAlignmentToCss,\n} from '@embedpdf/models';\nimport { TrackedAnnotation } from '@embedpdf/plugin-annotation';\n\nexport interface RedactAreaProps {\n annotation: TrackedAnnotation<PdfRedactAnnoObject>;\n isSelected: boolean;\n scale: number;\n pageIndex: number;\n onClick: (e: MouseEvent<Element> | TouchEvent<Element>) => void;\n style?: CSSProperties;\n}\n\n/**\n * Renders an area-based redact annotation (marquee redaction).\n * Default: shows strokeColor (C) border only, no fill.\n * Hovered: shows redaction preview with color (IC) as background fill + overlayText.\n * Selected: no border (AnnotationContainer handles selection styling).\n */\nexport function RedactArea({ annotation, isSelected, scale, onClick, style }: RedactAreaProps) {\n const [isHovered, setIsHovered] = useState(false);\n const { object } = annotation;\n\n // C - Border/stroke color\n const strokeColor = object.strokeColor ?? '#FF0000';\n // IC - Interior color (background fill when redaction is applied)\n const color = object.color ?? '#000000';\n // CA - Opacity (0-1)\n const opacity = object.opacity ?? 1;\n // OC - Overlay text color (Adobe extension), fallback to fontColor\n const textColor = object.fontColor ?? object.overlayColor ?? '#FFFFFF';\n // Overlay text properties\n const overlayText = object.overlayText;\n const overlayTextRepeat = object.overlayTextRepeat ?? false;\n const fontSize = object.fontSize ?? 12;\n const fontFamily = object.fontFamily ?? PdfStandardFont.Helvetica;\n const textAlign = object.textAlign ?? PdfTextAlignment.Center;\n\n // Calculate how many times to repeat text (approximate)\n const renderOverlayText = () => {\n if (!overlayText) return null;\n if (!overlayTextRepeat) return overlayText;\n // Repeat text multiple times to fill the space\n const reps = 10; // Enough repetitions to fill most containers\n return Array(reps).fill(overlayText).join(' ');\n };\n\n return (\n <div\n onPointerDown={!isSelected ? onClick : undefined}\n onTouchStart={!isSelected ? onClick : undefined}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n style={{\n position: 'absolute',\n inset: 0,\n // Default: transparent background with strokeColor (C) border\n // Hovered: color (IC) background fill, no border\n // Selected: no border (container handles it)\n background: isHovered ? color : 'transparent',\n border: !isHovered ? `2px solid ${strokeColor}` : 'none',\n opacity: isHovered ? opacity : 1,\n boxSizing: 'border-box',\n pointerEvents: 'auto',\n cursor: isSelected ? 'move' : 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent:\n textAlign === PdfTextAlignment.Left\n ? 'flex-start'\n : textAlign === PdfTextAlignment.Right\n ? 'flex-end'\n : 'center',\n overflow: 'hidden',\n ...style,\n }}\n >\n {isHovered && overlayText && (\n <span\n style={{\n color: textColor,\n fontSize: fontSize * scale,\n fontFamily: standardFontCss(fontFamily),\n textAlign: textAlignmentToCss(textAlign),\n whiteSpace: overlayTextRepeat ? 'normal' : 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n padding: '4px',\n }}\n >\n {renderOverlayText()}\n </span>\n )}\n </div>\n );\n}\n","import { PdfAnnotationSubtype, PdfRedactAnnoObject } from '@embedpdf/models';\nimport { createRenderer, BoxedAnnotationRenderer } from '@embedpdf/plugin-annotation/@framework';\nimport { RedactHighlight } from './annotations/redact-highlight';\nimport { RedactArea } from './annotations/redact-area';\n\n/**\n * Boxed annotation renderers for Redact annotations.\n * Type safety is enforced at definition time via createRenderer.\n * These are automatically registered with the annotation plugin via context.\n */\nexport const redactRenderers: BoxedAnnotationRenderer[] = [\n createRenderer<PdfRedactAnnoObject>({\n id: 'redactHighlight',\n matches: (a): a is PdfRedactAnnoObject =>\n a.type === PdfAnnotationSubtype.REDACT &&\n 'segmentRects' in a &&\n (a.segmentRects?.length ?? 0) > 0,\n render: (props) => <RedactHighlight {...props} />,\n }),\n createRenderer<PdfRedactAnnoObject>({\n id: 'redactArea',\n matches: (a): a is PdfRedactAnnoObject =>\n a.type === PdfAnnotationSubtype.REDACT &&\n (!('segmentRects' in a) || !(a.segmentRects?.length ?? 0)),\n render: (props) => <RedactArea {...props} />,\n }),\n];\n","import { useRegisterRenderers } from '@embedpdf/plugin-annotation/@framework';\nimport { redactRenderers } from '../components/redact-renderers';\n\n/**\n * Utility component that registers redact renderers once at app level.\n * Added via addUtility() so it mounts once, not per-page.\n */\nexport function RedactRendererRegistration() {\n useRegisterRenderers(redactRenderers);\n return null;\n}\n","import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {\n initialDocumentState,\n RedactionPlugin,\n RedactionDocumentState,\n RedactionScope,\n} from '@embedpdf/plugin-redaction';\nimport { useState, useEffect, useMemo } from '@framework';\n\nexport const useRedactionPlugin = () => usePlugin<RedactionPlugin>(RedactionPlugin.id);\nexport const useRedactionCapability = () => useCapability<RedactionPlugin>(RedactionPlugin.id);\n\nexport const useRedaction = (\n documentId: string,\n): {\n state: RedactionDocumentState;\n provides: RedactionScope | null;\n} => {\n const { provides } = useRedactionCapability();\n const [state, setState] = useState<RedactionDocumentState>(initialDocumentState);\n\n const scope = useMemo(\n () => (provides ? provides.forDocument(documentId) : null),\n [provides, documentId],\n );\n\n useEffect(() => {\n if (!scope) {\n setState(initialDocumentState);\n return;\n }\n\n // Set initial state\n try {\n setState(scope.getState());\n } catch (e) {\n // Handle case where state might not be ready\n setState(initialDocumentState);\n }\n\n // Subscribe to changes\n const unsubscribe = scope.onStateChange((newState) => {\n setState(newState);\n });\n\n return unsubscribe;\n }, [scope]);\n\n return {\n state,\n provides: scope,\n };\n};\n","import { useEffect, useMemo, useState } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { Rect } from '@embedpdf/models';\n\nimport { useRedactionPlugin } from '../hooks/use-redaction';\n\ninterface MarqueeRedactProps {\n /** The ID of the document */\n documentId: string;\n /** Index of the page this layer lives on */\n pageIndex: number;\n /** Scale of the page */\n scale?: number;\n /** Optional CSS class applied to the marquee rectangle */\n className?: string;\n /** Stroke / fill colours (defaults below) */\n stroke?: string;\n fill?: string;\n}\n\nexport const MarqueeRedact = ({\n documentId,\n pageIndex,\n scale: scaleOverride,\n className,\n stroke,\n fill = 'transparent',\n}: MarqueeRedactProps) => {\n const { plugin: redactionPlugin } = useRedactionPlugin();\n const documentState = useDocumentState(documentId);\n\n const [rect, setRect] = useState<Rect | null>(null);\n\n const scale = useMemo(() => {\n if (scaleOverride !== undefined) return scaleOverride;\n return documentState?.scale ?? 1;\n }, [scaleOverride, documentState?.scale]);\n\n // Get stroke color from plugin (annotation mode uses tool defaults, legacy uses red)\n // Allow prop override for backwards compatibility\n const strokeColor = stroke ?? redactionPlugin?.getPreviewStrokeColor() ?? 'red';\n\n useEffect(() => {\n if (!redactionPlugin || !documentId) return;\n return redactionPlugin.registerMarqueeOnPage({\n documentId,\n pageIndex,\n scale,\n callback: {\n onPreview: setRect,\n },\n });\n }, [redactionPlugin, documentId, pageIndex, scale]);\n\n if (!rect) return null;\n\n return (\n <div\n style={{\n position: 'absolute',\n pointerEvents: 'none',\n left: rect.origin.x * scale,\n top: rect.origin.y * scale,\n width: rect.size.width * scale,\n height: rect.size.height * scale,\n border: `1px solid ${strokeColor}`,\n background: fill,\n boxSizing: 'border-box',\n }}\n className={className}\n />\n );\n};\n","import { HTMLAttributes, CSSProperties, MouseEvent, TouchEvent } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\ntype HighlightProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n color?: string;\n opacity?: number;\n border?: string;\n rects: Rect[];\n rect?: Rect;\n scale: number;\n onClick?: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n style?: CSSProperties;\n};\n\nexport function Highlight({\n color = '#FFFF00',\n opacity = 1,\n border = '1px solid red',\n rects,\n rect,\n scale,\n onClick,\n style,\n ...props\n}: HighlightProps) {\n return (\n <>\n {rects.map((b, i) => (\n <div\n key={i}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n position: 'absolute',\n border,\n left: (rect ? b.origin.x - rect.origin.x : b.origin.x) * scale,\n top: (rect ? b.origin.y - rect.origin.y : b.origin.y) * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background: color,\n opacity: opacity,\n pointerEvents: onClick ? 'auto' : 'none',\n cursor: onClick ? 'pointer' : 'default',\n zIndex: onClick ? 1 : undefined,\n ...style,\n }}\n {...props}\n />\n ))}\n </>\n );\n}\n","import { Rect } from '@embedpdf/models';\nimport { useEffect, useState } from '@framework';\nimport { useRedactionPlugin } from '../hooks';\nimport { Highlight } from './highlight';\n\ninterface SelectionRedactProps {\n documentId: string;\n pageIndex: number;\n scale: number;\n}\n\nexport function SelectionRedact({ documentId, pageIndex, scale }: SelectionRedactProps) {\n const { plugin: redactionPlugin } = useRedactionPlugin();\n const [rects, setRects] = useState<Array<Rect>>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n\n // Get stroke color from plugin (annotation mode uses tool defaults, legacy uses red)\n const strokeColor = redactionPlugin?.getPreviewStrokeColor() ?? 'red';\n\n useEffect(() => {\n if (!redactionPlugin) return;\n return redactionPlugin.onRedactionSelectionChange(documentId, (formattedSelection) => {\n const selection = formattedSelection.find((s) => s.pageIndex === pageIndex);\n setRects(selection?.segmentRects ?? []);\n setBoundingRect(selection?.rect ?? null);\n });\n }, [redactionPlugin, documentId, pageIndex]);\n\n if (!boundingRect) return null;\n\n return (\n <div\n style={{\n mixBlendMode: 'normal',\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n }}\n >\n <Highlight\n color={'transparent'}\n opacity={1}\n rects={rects}\n scale={scale}\n border={`1px solid ${strokeColor}`}\n />\n </div>\n );\n}\n","import { Fragment, useEffect, useState, useCallback, MouseEvent, TouchEvent } from '@framework';\nimport { CounterRotate } from '@embedpdf/utils/@framework';\nimport { useRedactionCapability } from '../hooks';\nimport { RedactionItem } from '@embedpdf/plugin-redaction';\nimport { Highlight } from './highlight';\nimport { RedactionSelectionMenuRenderFn } from './types';\nimport { Rotation } from '@embedpdf/models';\n\ninterface PendingRedactionsProps {\n documentId: string;\n pageIndex: number;\n scale: number;\n rotation: Rotation;\n bboxStroke?: string;\n selectionMenu?: RedactionSelectionMenuRenderFn;\n}\n\nexport function PendingRedactions({\n documentId,\n pageIndex,\n scale,\n bboxStroke = 'rgba(0,0,0,0.8)',\n rotation = Rotation.Degree0,\n selectionMenu,\n}: PendingRedactionsProps) {\n const { provides: redaction } = useRedactionCapability();\n const [items, setItems] = useState<RedactionItem[]>([]);\n const [selectedId, setSelectedId] = useState<string | null>(null);\n\n useEffect(() => {\n if (!redaction) return;\n\n // Use document-scoped hooks so we only receive events for this document\n const scoped = redaction.forDocument(documentId);\n\n // Initialize with current state - only show legacy mode items\n const currentState = scoped.getState();\n setItems((currentState.pending[pageIndex] ?? []).filter((it) => it.source === 'legacy'));\n setSelectedId(\n currentState.selected && currentState.selected.page === pageIndex\n ? currentState.selected.id\n : null,\n );\n\n // Subscribe to future changes - only show legacy mode items\n const off1 = scoped.onPendingChange((map) => {\n setItems((map[pageIndex] ?? []).filter((it) => it.source === 'legacy'));\n });\n const off2 = scoped.onSelectedChange((sel) => {\n setSelectedId(sel && sel.page === pageIndex ? sel.id : null);\n });\n\n return () => {\n off1?.();\n off2?.();\n };\n }, [redaction, documentId, pageIndex]);\n\n const select = useCallback(\n (e: MouseEvent | TouchEvent, id: string) => {\n e.stopPropagation();\n if (!redaction) return;\n redaction.forDocument(documentId).selectPending(pageIndex, id);\n },\n [redaction, documentId, pageIndex],\n );\n\n if (!items.length) return null;\n\n return (\n <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>\n {items.map((it) => {\n if (it.kind === 'area') {\n const r = it.rect;\n return (\n <Fragment key={it.id}>\n <div\n style={{\n position: 'absolute',\n left: r.origin.x * scale,\n top: r.origin.y * scale,\n width: r.size.width * scale,\n height: r.size.height * scale,\n background: 'transparent',\n outline: selectedId === it.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n border: `1px solid ${it.markColor}`,\n pointerEvents: 'auto',\n cursor: 'pointer',\n }}\n onPointerDown={(e) => select(e, it.id)}\n onTouchStart={(e) => select(e, it.id)}\n />\n {selectionMenu && (\n <CounterRotate\n rect={{\n origin: { x: r.origin.x * scale, y: r.origin.y * scale },\n size: { width: r.size.width * scale, height: r.size.height * scale },\n }}\n rotation={rotation}\n >\n {(props) =>\n selectionMenu({\n ...props,\n context: {\n type: 'redaction',\n item: it,\n pageIndex,\n },\n selected: selectedId === it.id,\n placement: {\n suggestTop: false,\n },\n })\n }\n </CounterRotate>\n )}\n </Fragment>\n );\n }\n\n const b = it.rect;\n return (\n <Fragment key={it.id}>\n <div\n style={{\n position: 'absolute',\n left: b.origin.x * scale,\n top: b.origin.y * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background: 'transparent',\n outline: selectedId === it.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n pointerEvents: 'auto',\n cursor: selectedId === it.id ? 'pointer' : 'default',\n }}\n >\n <Highlight\n rect={b}\n rects={it.rects}\n color=\"transparent\"\n border={`1px solid ${it.markColor}`}\n scale={scale}\n onClick={(e) => select(e, it.id)}\n />\n </div>\n {selectionMenu && (\n <CounterRotate\n rect={{\n origin: { x: b.origin.x * scale, y: b.origin.y * scale },\n size: { width: b.size.width * scale, height: b.size.height * scale },\n }}\n rotation={rotation}\n >\n {(props) =>\n selectionMenu({\n ...props,\n context: {\n type: 'redaction',\n item: it,\n pageIndex,\n },\n selected: selectedId === it.id,\n placement: {\n suggestTop: false,\n },\n })\n }\n </CounterRotate>\n )}\n </Fragment>\n );\n })}\n </div>\n );\n}\n","import { Fragment, useMemo } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { MarqueeRedact } from './marquee-redact';\nimport { SelectionRedact } from './selection-redact';\nimport { PendingRedactions } from './pending-redactions';\nimport { Rotation } from '@embedpdf/models';\nimport { RedactionSelectionMenuRenderFn } from './types';\n\ninterface RedactionLayerProps {\n /** The ID of the document this layer belongs to */\n documentId: string;\n /** Index of the page this layer lives on */\n pageIndex: number;\n /** Current render scale for this page */\n scale?: number;\n /** Page rotation (for counter-rotating menus, etc.) */\n rotation?: Rotation;\n /** Optional menu renderer for a selected redaction */\n selectionMenu?: RedactionSelectionMenuRenderFn;\n}\n\nexport const RedactionLayer = ({\n documentId,\n pageIndex,\n scale,\n rotation,\n selectionMenu,\n}: RedactionLayerProps) => {\n const documentState = useDocumentState(documentId);\n\n const actualScale = useMemo(() => {\n if (scale !== undefined) return scale;\n return documentState?.scale ?? 1;\n }, [scale, documentState?.scale]);\n\n const actualRotation = useMemo(() => {\n if (rotation !== undefined) return rotation;\n return documentState?.rotation ?? Rotation.Degree0;\n }, [rotation, documentState?.rotation]);\n\n return (\n <Fragment>\n <PendingRedactions\n documentId={documentId}\n pageIndex={pageIndex}\n scale={actualScale}\n rotation={actualRotation}\n selectionMenu={selectionMenu}\n />\n <MarqueeRedact documentId={documentId} pageIndex={pageIndex} scale={actualScale} />\n <SelectionRedact documentId={documentId} pageIndex={pageIndex} scale={actualScale} />\n </Fragment>\n );\n};\n","import { createPluginPackage } from '@embedpdf/core';\nimport { RedactionPluginPackage as BaseRedactionPackage } from '@embedpdf/plugin-redaction';\nimport { RedactRendererRegistration } from './components/redact-renderer-registration';\n\nexport * from './hooks';\nexport * from './components';\nexport * from '@embedpdf/plugin-redaction';\n\n// Automatically register redact renderers when plugin is loaded\nexport const RedactionPluginPackage = createPluginPackage(BaseRedactionPackage)\n .addUtility(RedactRendererRegistration)\n .build();\n"],"names":["Fragment","BaseRedactionPackage"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export * from '@embedpdf/plugin-annotation/react';
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/react"),t=require("@embedpdf/plugin-redaction"),n=require("react"),i=require("react/jsx-runtime"),o=require("@embedpdf/utils/react"),r=require("@embedpdf/models"),s=()=>e.usePlugin(t.RedactionPlugin.id),d=()=>e.useCapability(t.RedactionPlugin.id),l=({documentId:t,pageIndex:o,scale:r,className:d,stroke:l="red",fill:a="transparent"})=>{const{plugin:c}=s(),u=e.useDocumentState(t),[p,g]=n.useState(null),x=n.useMemo(()=>void 0!==r?r:(null==u?void 0:u.scale)??1,[r,null==u?void 0:u.scale]);return n.useEffect(()=>{if(c&&t)return c.registerMarqueeOnPage({documentId:t,pageIndex:o,scale:x,callback:{onPreview:g}})},[c,t,o,x]),p?i.jsx("div",{style:{position:"absolute",pointerEvents:"none",left:p.origin.x*x,top:p.origin.y*x,width:p.size.width*x,height:p.size.height*x,border:`1px solid ${l}`,background:a,boxSizing:"border-box"},className:d}):null};function a({color:e="#FFFF00",opacity:t=1,border:n="1px solid red",rects:o,rect:r,scale:s,onClick:d,style:l,...a}){return i.jsx(i.Fragment,{children:o.map((o,c)=>i.jsx("div",{onPointerDown:d,onTouchStart:d,style:{position:"absolute",border:n,left:(r?o.origin.x-r.origin.x:o.origin.x)*s,top:(r?o.origin.y-r.origin.y:o.origin.y)*s,width:o.size.width*s,height:o.size.height*s,background:e,opacity:t,pointerEvents:d?"auto":"none",cursor:d?"pointer":"default",zIndex:d?1:void 0,...l},...a},c))})}function c({documentId:e,pageIndex:t,scale:o}){const{plugin:r}=s(),[d,l]=n.useState([]),[c,u]=n.useState(null);return n.useEffect(()=>{if(r)return r.onRedactionSelectionChange(e,e=>{const n=e.find(e=>e.pageIndex===t);l((null==n?void 0:n.segmentRects)??[]),u((null==n?void 0:n.rect)??null)})},[r,e,t]),c?i.jsx("div",{style:{mixBlendMode:"normal",pointerEvents:"none",position:"absolute",inset:0},children:i.jsx(a,{color:"transparent",opacity:1,rects:d,scale:o,border:"1px solid red"})}):null}function u({documentId:e,pageIndex:t,scale:s,bboxStroke:l="rgba(0,0,0,0.8)",rotation:c=r.Rotation.Degree0,selectionMenu:u}){const{provides:p}=d(),[g,x]=n.useState([]),[h,m]=n.useState(null);n.useEffect(()=>{if(!p)return;const n=p.forDocument(e),i=n.getState();x(i.pending[t]??[]),m(i.selected&&i.selected.page===t?i.selected.id:null);const o=n.onPendingChange(e=>x(e[t]??[])),r=n.onSelectedChange(e=>{m(e&&e.page===t?e.id:null)});return()=>{null==o||o(),null==r||r()}},[p,e,t]);const f=n.useCallback((n,i)=>{n.stopPropagation(),p&&p.forDocument(e).selectPending(t,i)},[p,e,t]);return g.length?i.jsx("div",{style:{position:"absolute",inset:0,pointerEvents:"none"},children:g.map(e=>{if("area"===e.kind){const r=e.rect;return i.jsxs(n.Fragment,{children:[i.jsx("div",{style:{position:"absolute",left:r.origin.x*s,top:r.origin.y*s,width:r.size.width*s,height:r.size.height*s,background:"transparent",outline:h===e.id?`1px solid ${l}`:"none",outlineOffset:"2px",border:"1px solid red",pointerEvents:"auto",cursor:"pointer"},onPointerDown:t=>f(t,e.id),onTouchStart:t=>f(t,e.id)}),u&&i.jsx(o.CounterRotate,{rect:{origin:{x:r.origin.x*s,y:r.origin.y*s},size:{width:r.size.width*s,height:r.size.height*s}},rotation:c,children:n=>u({...n,context:{type:"redaction",item:e,pageIndex:t},selected:h===e.id,placement:{suggestTop:!1}})})]},e.id)}const r=e.rect;return i.jsxs(n.Fragment,{children:[i.jsx("div",{style:{position:"absolute",left:r.origin.x*s,top:r.origin.y*s,width:r.size.width*s,height:r.size.height*s,background:"transparent",outline:h===e.id?`1px solid ${l}`:"none",outlineOffset:"2px",pointerEvents:"auto",cursor:h===e.id?"pointer":"default"},children:i.jsx(a,{rect:r,rects:e.rects,color:"transparent",border:"1px solid red",scale:s,onClick:t=>f(t,e.id)})}),u&&i.jsx(o.CounterRotate,{rect:{origin:{x:r.origin.x*s,y:r.origin.y*s},size:{width:r.size.width*s,height:r.size.height*s}},rotation:c,children:n=>u({...n,context:{type:"redaction",item:e,pageIndex:t},selected:h===e.id,placement:{suggestTop:!1}})})]},e.id)})}):null}exports.RedactionLayer=({documentId:t,pageIndex:o,scale:s,rotation:d,selectionMenu:a})=>{const p=e.useDocumentState(t),g=n.useMemo(()=>void 0!==s?s:(null==p?void 0:p.scale)??1,[s,null==p?void 0:p.scale]),x=n.useMemo(()=>void 0!==d?d:(null==p?void 0:p.rotation)??r.Rotation.Degree0,[d,null==p?void 0:p.rotation]);return i.jsxs(n.Fragment,{children:[i.jsx(u,{documentId:t,pageIndex:o,scale:g,rotation:x,selectionMenu:a}),i.jsx(l,{documentId:t,pageIndex:o,scale:g}),i.jsx(c,{documentId:t,pageIndex:o,scale:g})]})},exports.useRedaction=e=>{const{provides:i}=d(),[o,r]=n.useState(t.initialDocumentState),s=n.useMemo(()=>i?i.forDocument(e):null,[i,e]);return n.useEffect(()=>{if(!s)return void r(t.initialDocumentState);try{r(s.getState())}catch(e){r(t.initialDocumentState)}return s.onStateChange(e=>{r(e)})},[s]),{state:o,provides:s}},exports.useRedactionCapability=d,exports.useRedactionPlugin=s,Object.keys(t).forEach(e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})});
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core"),t=require("@embedpdf/plugin-redaction"),n=require("@embedpdf/plugin-annotation/react"),o=require("react/jsx-runtime"),i=require("@embedpdf/models"),r=require("react"),s=require("@embedpdf/core/react"),l=require("@embedpdf/utils/react");function a({annotation:e,isSelected:t,scale:n,onClick:s,style:l}){const[a,d]=r.useState(!1),{object:c}=e,u=c.segmentRects??[],g=c.rect,p=c.strokeColor??"#FF0000",x=c.color??"#000000",f=c.opacity??1,h=c.fontColor??c.overlayColor??"#FFFFFF",m=c.overlayText,y=c.overlayTextRepeat??!1,v=c.fontSize??12,b=c.fontFamily??i.PdfStandardFont.Helvetica,S=c.textAlign??i.PdfTextAlignment.Center,j=()=>{if(!m)return null;if(!y)return m;return Array(10).fill(m).join(" ")};return o.jsx("div",{onMouseEnter:()=>d(!0),onMouseLeave:()=>d(!1),style:{position:"absolute",inset:0},children:u.map((e,t)=>o.jsx("div",{onPointerDown:s,onTouchStart:s,style:{position:"absolute",left:(g?e.origin.x-g.origin.x:e.origin.x)*n,top:(g?e.origin.y-g.origin.y:e.origin.y)*n,width:e.size.width*n,height:e.size.height*n,background:a?x:"transparent",border:a?"none":`2px solid ${p}`,opacity:a?f:1,boxSizing:"border-box",pointerEvents:"auto",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:S===i.PdfTextAlignment.Left?"flex-start":S===i.PdfTextAlignment.Right?"flex-end":"center",overflow:"hidden",...l},children:a&&m&&o.jsx("span",{style:{color:h,fontSize:Math.min(v*n,e.size.height*n*.8),fontFamily:i.standardFontCss(b),textAlign:i.textAlignmentToCss(S),whiteSpace:y?"normal":"nowrap",overflow:"hidden",textOverflow:"ellipsis",lineHeight:1},children:j()})},t))})}function d({annotation:e,isSelected:t,scale:n,onClick:s,style:l}){const[a,d]=r.useState(!1),{object:c}=e,u=c.strokeColor??"#FF0000",g=c.color??"#000000",p=c.opacity??1,x=c.fontColor??c.overlayColor??"#FFFFFF",f=c.overlayText,h=c.overlayTextRepeat??!1,m=c.fontSize??12,y=c.fontFamily??i.PdfStandardFont.Helvetica,v=c.textAlign??i.PdfTextAlignment.Center;return o.jsx("div",{onPointerDown:t?void 0:s,onTouchStart:t?void 0:s,onMouseEnter:()=>d(!0),onMouseLeave:()=>d(!1),style:{position:"absolute",inset:0,background:a?g:"transparent",border:a?"none":`2px solid ${u}`,opacity:a?p:1,boxSizing:"border-box",pointerEvents:"auto",cursor:t?"move":"pointer",display:"flex",alignItems:"center",justifyContent:v===i.PdfTextAlignment.Left?"flex-start":v===i.PdfTextAlignment.Right?"flex-end":"center",overflow:"hidden",...l},children:a&&f&&o.jsx("span",{style:{color:x,fontSize:m*n,fontFamily:i.standardFontCss(y),textAlign:i.textAlignmentToCss(v),whiteSpace:h?"normal":"nowrap",overflow:"hidden",textOverflow:"ellipsis",padding:"4px"},children:(()=>{if(!f)return null;if(!h)return f;return Array(10).fill(f).join(" ")})()})})}const c=[n.createRenderer({id:"redactHighlight",matches:e=>{var t;return e.type===i.PdfAnnotationSubtype.REDACT&&"segmentRects"in e&&((null==(t=e.segmentRects)?void 0:t.length)??0)>0},render:e=>o.jsx(a,{...e})}),n.createRenderer({id:"redactArea",matches:e=>{var t;return!(e.type!==i.PdfAnnotationSubtype.REDACT||"segmentRects"in e&&(null==(t=e.segmentRects)?void 0:t.length))},render:e=>o.jsx(d,{...e})})];function u(){return n.useRegisterRenderers(c),null}const g=()=>s.usePlugin(t.RedactionPlugin.id),p=()=>s.useCapability(t.RedactionPlugin.id),x=({documentId:e,pageIndex:t,scale:n,className:i,stroke:l,fill:a="transparent"})=>{const{plugin:d}=g(),c=s.useDocumentState(e),[u,p]=r.useState(null),x=r.useMemo(()=>void 0!==n?n:(null==c?void 0:c.scale)??1,[n,null==c?void 0:c.scale]),f=l??(null==d?void 0:d.getPreviewStrokeColor())??"red";return r.useEffect(()=>{if(d&&e)return d.registerMarqueeOnPage({documentId:e,pageIndex:t,scale:x,callback:{onPreview:p}})},[d,e,t,x]),u?o.jsx("div",{style:{position:"absolute",pointerEvents:"none",left:u.origin.x*x,top:u.origin.y*x,width:u.size.width*x,height:u.size.height*x,border:`1px solid ${f}`,background:a,boxSizing:"border-box"},className:i}):null};function f({color:e="#FFFF00",opacity:t=1,border:n="1px solid red",rects:i,rect:r,scale:s,onClick:l,style:a,...d}){return o.jsx(o.Fragment,{children:i.map((i,c)=>o.jsx("div",{onPointerDown:l,onTouchStart:l,style:{position:"absolute",border:n,left:(r?i.origin.x-r.origin.x:i.origin.x)*s,top:(r?i.origin.y-r.origin.y:i.origin.y)*s,width:i.size.width*s,height:i.size.height*s,background:e,opacity:t,pointerEvents:l?"auto":"none",cursor:l?"pointer":"default",zIndex:l?1:void 0,...a},...d},c))})}function h({documentId:e,pageIndex:t,scale:n}){const{plugin:i}=g(),[s,l]=r.useState([]),[a,d]=r.useState(null),c=(null==i?void 0:i.getPreviewStrokeColor())??"red";return r.useEffect(()=>{if(i)return i.onRedactionSelectionChange(e,e=>{const n=e.find(e=>e.pageIndex===t);l((null==n?void 0:n.segmentRects)??[]),d((null==n?void 0:n.rect)??null)})},[i,e,t]),a?o.jsx("div",{style:{mixBlendMode:"normal",pointerEvents:"none",position:"absolute",inset:0},children:o.jsx(f,{color:"transparent",opacity:1,rects:s,scale:n,border:`1px solid ${c}`})}):null}function m({documentId:e,pageIndex:t,scale:n,bboxStroke:s="rgba(0,0,0,0.8)",rotation:a=i.Rotation.Degree0,selectionMenu:d}){const{provides:c}=p(),[u,g]=r.useState([]),[x,h]=r.useState(null);r.useEffect(()=>{if(!c)return;const n=c.forDocument(e),o=n.getState();g((o.pending[t]??[]).filter(e=>"legacy"===e.source)),h(o.selected&&o.selected.page===t?o.selected.id:null);const i=n.onPendingChange(e=>{g((e[t]??[]).filter(e=>"legacy"===e.source))}),r=n.onSelectedChange(e=>{h(e&&e.page===t?e.id:null)});return()=>{null==i||i(),null==r||r()}},[c,e,t]);const m=r.useCallback((n,o)=>{n.stopPropagation(),c&&c.forDocument(e).selectPending(t,o)},[c,e,t]);return u.length?o.jsx("div",{style:{position:"absolute",inset:0,pointerEvents:"none"},children:u.map(e=>{if("area"===e.kind){const i=e.rect;return o.jsxs(r.Fragment,{children:[o.jsx("div",{style:{position:"absolute",left:i.origin.x*n,top:i.origin.y*n,width:i.size.width*n,height:i.size.height*n,background:"transparent",outline:x===e.id?`1px solid ${s}`:"none",outlineOffset:"2px",border:`1px solid ${e.markColor}`,pointerEvents:"auto",cursor:"pointer"},onPointerDown:t=>m(t,e.id),onTouchStart:t=>m(t,e.id)}),d&&o.jsx(l.CounterRotate,{rect:{origin:{x:i.origin.x*n,y:i.origin.y*n},size:{width:i.size.width*n,height:i.size.height*n}},rotation:a,children:n=>d({...n,context:{type:"redaction",item:e,pageIndex:t},selected:x===e.id,placement:{suggestTop:!1}})})]},e.id)}const i=e.rect;return o.jsxs(r.Fragment,{children:[o.jsx("div",{style:{position:"absolute",left:i.origin.x*n,top:i.origin.y*n,width:i.size.width*n,height:i.size.height*n,background:"transparent",outline:x===e.id?`1px solid ${s}`:"none",outlineOffset:"2px",pointerEvents:"auto",cursor:x===e.id?"pointer":"default"},children:o.jsx(f,{rect:i,rects:e.rects,color:"transparent",border:`1px solid ${e.markColor}`,scale:n,onClick:t=>m(t,e.id)})}),d&&o.jsx(l.CounterRotate,{rect:{origin:{x:i.origin.x*n,y:i.origin.y*n},size:{width:i.size.width*n,height:i.size.height*n}},rotation:a,children:n=>d({...n,context:{type:"redaction",item:e,pageIndex:t},selected:x===e.id,placement:{suggestTop:!1}})})]},e.id)})}):null}const y=e.createPluginPackage(t.RedactionPluginPackage).addUtility(u).build();exports.RedactArea=d,exports.RedactHighlight=a,exports.RedactRendererRegistration=u,exports.RedactionLayer=({documentId:e,pageIndex:t,scale:n,rotation:l,selectionMenu:a})=>{const d=s.useDocumentState(e),c=r.useMemo(()=>void 0!==n?n:(null==d?void 0:d.scale)??1,[n,null==d?void 0:d.scale]),u=r.useMemo(()=>void 0!==l?l:(null==d?void 0:d.rotation)??i.Rotation.Degree0,[l,null==d?void 0:d.rotation]);return o.jsxs(r.Fragment,{children:[o.jsx(m,{documentId:e,pageIndex:t,scale:c,rotation:u,selectionMenu:a}),o.jsx(x,{documentId:e,pageIndex:t,scale:c}),o.jsx(h,{documentId:e,pageIndex:t,scale:c})]})},exports.RedactionPluginPackage=y,exports.redactRenderers=c,exports.useRedaction=e=>{const{provides:n}=p(),[o,i]=r.useState(t.initialDocumentState),s=r.useMemo(()=>n?n.forDocument(e):null,[n,e]);return r.useEffect(()=>{if(!s)return void i(t.initialDocumentState);try{i(s.getState())}catch(e){i(t.initialDocumentState)}return s.onStateChange(e=>{i(e)})},[s]),{state:o,provides:s}},exports.useRedactionCapability=p,exports.useRedactionPlugin=g,Object.keys(t).forEach(e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})});
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-redaction.ts","../../src/shared/components/marquee-redact.tsx","../../src/shared/components/highlight.tsx","../../src/shared/components/selection-redact.tsx","../../src/shared/components/pending-redactions.tsx","../../src/shared/components/redaction-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {\n initialDocumentState,\n RedactionPlugin,\n RedactionDocumentState,\n RedactionScope,\n} from '@embedpdf/plugin-redaction';\nimport { useState, useEffect, useMemo } from '@framework';\n\nexport const useRedactionPlugin = () => usePlugin<RedactionPlugin>(RedactionPlugin.id);\nexport const useRedactionCapability = () => useCapability<RedactionPlugin>(RedactionPlugin.id);\n\nexport const useRedaction = (\n documentId: string,\n): {\n state: RedactionDocumentState;\n provides: RedactionScope | null;\n} => {\n const { provides } = useRedactionCapability();\n const [state, setState] = useState<RedactionDocumentState>(initialDocumentState);\n\n const scope = useMemo(\n () => (provides ? provides.forDocument(documentId) : null),\n [provides, documentId],\n );\n\n useEffect(() => {\n if (!scope) {\n setState(initialDocumentState);\n return;\n }\n\n // Set initial state\n try {\n setState(scope.getState());\n } catch (e) {\n // Handle case where state might not be ready\n setState(initialDocumentState);\n }\n\n // Subscribe to changes\n const unsubscribe = scope.onStateChange((newState) => {\n setState(newState);\n });\n\n return unsubscribe;\n }, [scope]);\n\n return {\n state,\n provides: scope,\n };\n};\n","import { useEffect, useMemo, useState } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { Rect } from '@embedpdf/models';\n\nimport { useRedactionPlugin } from '../hooks/use-redaction';\n\ninterface MarqueeRedactProps {\n /** The ID of the document */\n documentId: string;\n /** Index of the page this layer lives on */\n pageIndex: number;\n /** Scale of the page */\n scale?: number;\n /** Optional CSS class applied to the marquee rectangle */\n className?: string;\n /** Stroke / fill colours (defaults below) */\n stroke?: string;\n fill?: string;\n}\n\nexport const MarqueeRedact = ({\n documentId,\n pageIndex,\n scale: scaleOverride,\n className,\n stroke = 'red',\n fill = 'transparent',\n}: MarqueeRedactProps) => {\n const { plugin: redactionPlugin } = useRedactionPlugin();\n const documentState = useDocumentState(documentId);\n\n const [rect, setRect] = useState<Rect | null>(null);\n\n const scale = useMemo(() => {\n if (scaleOverride !== undefined) return scaleOverride;\n return documentState?.scale ?? 1;\n }, [scaleOverride, documentState?.scale]);\n\n useEffect(() => {\n if (!redactionPlugin || !documentId) return;\n return redactionPlugin.registerMarqueeOnPage({\n documentId,\n pageIndex,\n scale,\n callback: {\n onPreview: setRect,\n },\n });\n }, [redactionPlugin, documentId, pageIndex, scale]);\n\n if (!rect) return null;\n\n return (\n <div\n style={{\n position: 'absolute',\n pointerEvents: 'none',\n left: rect.origin.x * scale,\n top: rect.origin.y * scale,\n width: rect.size.width * scale,\n height: rect.size.height * scale,\n border: `1px solid ${stroke}`,\n background: fill,\n boxSizing: 'border-box',\n }}\n className={className}\n />\n );\n};\n","import { HTMLAttributes, CSSProperties, MouseEvent, TouchEvent } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\ntype HighlightProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n color?: string;\n opacity?: number;\n border?: string;\n rects: Rect[];\n rect?: Rect;\n scale: number;\n onClick?: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n style?: CSSProperties;\n};\n\nexport function Highlight({\n color = '#FFFF00',\n opacity = 1,\n border = '1px solid red',\n rects,\n rect,\n scale,\n onClick,\n style,\n ...props\n}: HighlightProps) {\n return (\n <>\n {rects.map((b, i) => (\n <div\n key={i}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n position: 'absolute',\n border,\n left: (rect ? b.origin.x - rect.origin.x : b.origin.x) * scale,\n top: (rect ? b.origin.y - rect.origin.y : b.origin.y) * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background: color,\n opacity: opacity,\n pointerEvents: onClick ? 'auto' : 'none',\n cursor: onClick ? 'pointer' : 'default',\n zIndex: onClick ? 1 : undefined,\n ...style,\n }}\n {...props}\n />\n ))}\n </>\n );\n}\n","import { Rect } from '@embedpdf/models';\nimport { useEffect, useState } from '@framework';\nimport { useRedactionPlugin } from '../hooks';\nimport { Highlight } from './highlight';\n\ninterface SelectionRedactProps {\n documentId: string;\n pageIndex: number;\n scale: number;\n}\n\nexport function SelectionRedact({ documentId, pageIndex, scale }: SelectionRedactProps) {\n const { plugin: redactionPlugin } = useRedactionPlugin();\n const [rects, setRects] = useState<Array<Rect>>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n\n useEffect(() => {\n if (!redactionPlugin) return;\n return redactionPlugin.onRedactionSelectionChange(documentId, (formattedSelection) => {\n const selection = formattedSelection.find((s) => s.pageIndex === pageIndex);\n setRects(selection?.segmentRects ?? []);\n setBoundingRect(selection?.rect ?? null);\n });\n }, [redactionPlugin, documentId, pageIndex]);\n\n if (!boundingRect) return null;\n\n return (\n <div\n style={{\n mixBlendMode: 'normal',\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n }}\n >\n <Highlight\n color={'transparent'}\n opacity={1}\n rects={rects}\n scale={scale}\n border=\"1px solid red\"\n />\n </div>\n );\n}\n","import { Fragment, useEffect, useState, useCallback, MouseEvent, TouchEvent } from '@framework';\nimport { CounterRotate } from '@embedpdf/utils/@framework';\nimport { useRedactionCapability } from '../hooks';\nimport { RedactionItem } from '@embedpdf/plugin-redaction';\nimport { Highlight } from './highlight';\nimport { RedactionSelectionMenuRenderFn } from './types';\nimport { Rotation } from '@embedpdf/models';\n\ninterface PendingRedactionsProps {\n documentId: string;\n pageIndex: number;\n scale: number;\n rotation: Rotation;\n bboxStroke?: string;\n selectionMenu?: RedactionSelectionMenuRenderFn;\n}\n\nexport function PendingRedactions({\n documentId,\n pageIndex,\n scale,\n bboxStroke = 'rgba(0,0,0,0.8)',\n rotation = Rotation.Degree0,\n selectionMenu,\n}: PendingRedactionsProps) {\n const { provides: redaction } = useRedactionCapability();\n const [items, setItems] = useState<RedactionItem[]>([]);\n const [selectedId, setSelectedId] = useState<string | null>(null);\n\n useEffect(() => {\n if (!redaction) return;\n\n // Use document-scoped hooks so we only receive events for this document\n const scoped = redaction.forDocument(documentId);\n\n // Initialize with current state\n const currentState = scoped.getState();\n setItems(currentState.pending[pageIndex] ?? []);\n setSelectedId(\n currentState.selected && currentState.selected.page === pageIndex\n ? currentState.selected.id\n : null,\n );\n\n // Subscribe to future changes\n const off1 = scoped.onPendingChange((map) => setItems(map[pageIndex] ?? []));\n const off2 = scoped.onSelectedChange((sel) => {\n setSelectedId(sel && sel.page === pageIndex ? sel.id : null);\n });\n\n return () => {\n off1?.();\n off2?.();\n };\n }, [redaction, documentId, pageIndex]);\n\n const select = useCallback(\n (e: MouseEvent | TouchEvent, id: string) => {\n e.stopPropagation();\n if (!redaction) return;\n redaction.forDocument(documentId).selectPending(pageIndex, id);\n },\n [redaction, documentId, pageIndex],\n );\n\n if (!items.length) return null;\n\n return (\n <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>\n {items.map((it) => {\n if (it.kind === 'area') {\n const r = it.rect;\n return (\n <Fragment key={it.id}>\n <div\n style={{\n position: 'absolute',\n left: r.origin.x * scale,\n top: r.origin.y * scale,\n width: r.size.width * scale,\n height: r.size.height * scale,\n background: 'transparent',\n outline: selectedId === it.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n border: `1px solid red`,\n pointerEvents: 'auto',\n cursor: 'pointer',\n }}\n onPointerDown={(e) => select(e, it.id)}\n onTouchStart={(e) => select(e, it.id)}\n />\n {selectionMenu && (\n <CounterRotate\n rect={{\n origin: { x: r.origin.x * scale, y: r.origin.y * scale },\n size: { width: r.size.width * scale, height: r.size.height * scale },\n }}\n rotation={rotation}\n >\n {(props) =>\n selectionMenu({\n ...props,\n context: {\n type: 'redaction',\n item: it,\n pageIndex,\n },\n selected: selectedId === it.id,\n placement: {\n suggestTop: false,\n },\n })\n }\n </CounterRotate>\n )}\n </Fragment>\n );\n }\n\n const b = it.rect;\n return (\n <Fragment key={it.id}>\n <div\n style={{\n position: 'absolute',\n left: b.origin.x * scale,\n top: b.origin.y * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background: 'transparent',\n outline: selectedId === it.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n pointerEvents: 'auto',\n cursor: selectedId === it.id ? 'pointer' : 'default',\n }}\n >\n <Highlight\n rect={b}\n rects={it.rects}\n color=\"transparent\"\n border=\"1px solid red\"\n scale={scale}\n onClick={(e) => select(e, it.id)}\n />\n </div>\n {selectionMenu && (\n <CounterRotate\n rect={{\n origin: { x: b.origin.x * scale, y: b.origin.y * scale },\n size: { width: b.size.width * scale, height: b.size.height * scale },\n }}\n rotation={rotation}\n >\n {(props) =>\n selectionMenu({\n ...props,\n context: {\n type: 'redaction',\n item: it,\n pageIndex,\n },\n selected: selectedId === it.id,\n placement: {\n suggestTop: false,\n },\n })\n }\n </CounterRotate>\n )}\n </Fragment>\n );\n })}\n </div>\n );\n}\n","import { Fragment, useMemo } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { MarqueeRedact } from './marquee-redact';\nimport { SelectionRedact } from './selection-redact';\nimport { PendingRedactions } from './pending-redactions';\nimport { Rotation } from '@embedpdf/models';\nimport { RedactionSelectionMenuRenderFn } from './types';\n\ninterface RedactionLayerProps {\n /** The ID of the document this layer belongs to */\n documentId: string;\n /** Index of the page this layer lives on */\n pageIndex: number;\n /** Current render scale for this page */\n scale?: number;\n /** Page rotation (for counter-rotating menus, etc.) */\n rotation?: Rotation;\n /** Optional menu renderer for a selected redaction */\n selectionMenu?: RedactionSelectionMenuRenderFn;\n}\n\nexport const RedactionLayer = ({\n documentId,\n pageIndex,\n scale,\n rotation,\n selectionMenu,\n}: RedactionLayerProps) => {\n const documentState = useDocumentState(documentId);\n\n const actualScale = useMemo(() => {\n if (scale !== undefined) return scale;\n return documentState?.scale ?? 1;\n }, [scale, documentState?.scale]);\n\n const actualRotation = useMemo(() => {\n if (rotation !== undefined) return rotation;\n return documentState?.rotation ?? Rotation.Degree0;\n }, [rotation, documentState?.rotation]);\n\n return (\n <Fragment>\n <PendingRedactions\n documentId={documentId}\n pageIndex={pageIndex}\n scale={actualScale}\n rotation={actualRotation}\n selectionMenu={selectionMenu}\n />\n <MarqueeRedact documentId={documentId} pageIndex={pageIndex} scale={actualScale} />\n <SelectionRedact documentId={documentId} pageIndex={pageIndex} scale={actualScale} />\n </Fragment>\n );\n};\n"],"names":["useRedactionPlugin","usePlugin","RedactionPlugin","id","useRedactionCapability","useCapability","MarqueeRedact","documentId","pageIndex","scale","scaleOverride","className","stroke","fill","plugin","redactionPlugin","documentState","useDocumentState","rect","setRect","useState","useMemo","useEffect","registerMarqueeOnPage","callback","onPreview","jsx","style","position","pointerEvents","left","origin","x","top","y","width","size","height","border","background","boxSizing","Highlight","color","opacity","rects","onClick","props","Fragment","children","map","b","i","onPointerDown","onTouchStart","cursor","zIndex","SelectionRedact","setRects","boundingRect","setBoundingRect","onRedactionSelectionChange","formattedSelection","selection","find","s","segmentRects","mixBlendMode","inset","PendingRedactions","bboxStroke","rotation","Rotation","Degree0","selectionMenu","provides","redaction","items","setItems","selectedId","setSelectedId","scoped","forDocument","currentState","getState","pending","selected","page","off1","onPendingChange","off2","onSelectedChange","sel","select","useCallback","e","stopPropagation","selectPending","length","it","kind","r","outline","outlineOffset","CounterRotate","context","type","item","placement","suggestTop","actualScale","actualRotation","state","setState","initialDocumentState","scope","onStateChange","newState"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/shared/components/annotations/redact-highlight.tsx","../../src/shared/components/annotations/redact-area.tsx","../../src/shared/components/redact-renderers.tsx","../../src/shared/components/redact-renderer-registration.tsx","../../src/shared/hooks/use-redaction.ts","../../src/shared/components/marquee-redact.tsx","../../src/shared/components/highlight.tsx","../../src/shared/components/selection-redact.tsx","../../src/shared/components/pending-redactions.tsx","../../src/shared/components/redaction-layer.tsx","../../src/shared/index.ts"],"sourcesContent":["import { CSSProperties, MouseEvent, TouchEvent, useState } from '@framework';\nimport {\n PdfRedactAnnoObject,\n PdfStandardFont,\n PdfTextAlignment,\n Rect,\n standardFontCss,\n textAlignmentToCss,\n} from '@embedpdf/models';\nimport { TrackedAnnotation } from '@embedpdf/plugin-annotation';\n\nexport interface RedactHighlightProps {\n annotation: TrackedAnnotation<PdfRedactAnnoObject>;\n isSelected: boolean;\n scale: number;\n pageIndex: number;\n onClick: (e: MouseEvent<Element> | TouchEvent<Element>) => void;\n style?: CSSProperties;\n}\n\n/**\n * Renders a text-based redact annotation using QuadPoints/segmentRects.\n * Default: shows strokeColor (C) border only, no fill.\n * Hovered: shows redaction preview with color (IC) as background fill + overlayText.\n * Selected: no border (AnnotationContainer handles selection styling).\n */\nexport function RedactHighlight({\n annotation,\n isSelected,\n scale,\n onClick,\n style,\n}: RedactHighlightProps) {\n const [isHovered, setIsHovered] = useState(false);\n const { object } = annotation;\n\n const segmentRects = object.segmentRects ?? [];\n const rect = object.rect;\n\n // C - Border/stroke color\n const strokeColor = object.strokeColor ?? '#FF0000';\n // IC - Interior color (background fill when redaction is applied)\n const color = object.color ?? '#000000';\n // CA - Opacity (0-1)\n const opacity = object.opacity ?? 1;\n // OC - Overlay text color (Adobe extension), fallback to fontColor\n const textColor = object.fontColor ?? object.overlayColor ?? '#FFFFFF';\n // Overlay text properties\n const overlayText = object.overlayText;\n const overlayTextRepeat = object.overlayTextRepeat ?? false;\n const fontSize = object.fontSize ?? 12;\n const fontFamily = object.fontFamily ?? PdfStandardFont.Helvetica;\n const textAlign = object.textAlign ?? PdfTextAlignment.Center;\n\n // Calculate how many times to repeat text (approximate)\n const renderOverlayText = () => {\n if (!overlayText) return null;\n if (!overlayTextRepeat) return overlayText;\n // Repeat text multiple times to fill the space\n const reps = 10; // Enough repetitions to fill most containers\n return Array(reps).fill(overlayText).join(' ');\n };\n\n return (\n <div\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n style={{ position: 'absolute', inset: 0 }}\n >\n {segmentRects.map((b: Rect, i: number) => (\n <div\n key={i}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n position: 'absolute',\n left: (rect ? b.origin.x - rect.origin.x : b.origin.x) * scale,\n top: (rect ? b.origin.y - rect.origin.y : b.origin.y) * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n // Default: transparent background with strokeColor (C) border\n // Hovered: color (IC) background fill, no border\n // Selected: no border (container handles it)\n background: isHovered ? color : 'transparent',\n border: !isHovered ? `2px solid ${strokeColor}` : 'none',\n opacity: isHovered ? opacity : 1,\n boxSizing: 'border-box',\n pointerEvents: 'auto',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent:\n textAlign === PdfTextAlignment.Left\n ? 'flex-start'\n : textAlign === PdfTextAlignment.Right\n ? 'flex-end'\n : 'center',\n overflow: 'hidden',\n ...style,\n }}\n >\n {isHovered && overlayText && (\n <span\n style={{\n color: textColor,\n fontSize: Math.min(fontSize * scale, b.size.height * scale * 0.8),\n fontFamily: standardFontCss(fontFamily),\n textAlign: textAlignmentToCss(textAlign),\n whiteSpace: overlayTextRepeat ? 'normal' : 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n lineHeight: 1,\n }}\n >\n {renderOverlayText()}\n </span>\n )}\n </div>\n ))}\n </div>\n );\n}\n","import { CSSProperties, MouseEvent, TouchEvent, useState } from '@framework';\nimport {\n PdfRedactAnnoObject,\n PdfStandardFont,\n PdfTextAlignment,\n standardFontCss,\n textAlignmentToCss,\n} from '@embedpdf/models';\nimport { TrackedAnnotation } from '@embedpdf/plugin-annotation';\n\nexport interface RedactAreaProps {\n annotation: TrackedAnnotation<PdfRedactAnnoObject>;\n isSelected: boolean;\n scale: number;\n pageIndex: number;\n onClick: (e: MouseEvent<Element> | TouchEvent<Element>) => void;\n style?: CSSProperties;\n}\n\n/**\n * Renders an area-based redact annotation (marquee redaction).\n * Default: shows strokeColor (C) border only, no fill.\n * Hovered: shows redaction preview with color (IC) as background fill + overlayText.\n * Selected: no border (AnnotationContainer handles selection styling).\n */\nexport function RedactArea({ annotation, isSelected, scale, onClick, style }: RedactAreaProps) {\n const [isHovered, setIsHovered] = useState(false);\n const { object } = annotation;\n\n // C - Border/stroke color\n const strokeColor = object.strokeColor ?? '#FF0000';\n // IC - Interior color (background fill when redaction is applied)\n const color = object.color ?? '#000000';\n // CA - Opacity (0-1)\n const opacity = object.opacity ?? 1;\n // OC - Overlay text color (Adobe extension), fallback to fontColor\n const textColor = object.fontColor ?? object.overlayColor ?? '#FFFFFF';\n // Overlay text properties\n const overlayText = object.overlayText;\n const overlayTextRepeat = object.overlayTextRepeat ?? false;\n const fontSize = object.fontSize ?? 12;\n const fontFamily = object.fontFamily ?? PdfStandardFont.Helvetica;\n const textAlign = object.textAlign ?? PdfTextAlignment.Center;\n\n // Calculate how many times to repeat text (approximate)\n const renderOverlayText = () => {\n if (!overlayText) return null;\n if (!overlayTextRepeat) return overlayText;\n // Repeat text multiple times to fill the space\n const reps = 10; // Enough repetitions to fill most containers\n return Array(reps).fill(overlayText).join(' ');\n };\n\n return (\n <div\n onPointerDown={!isSelected ? onClick : undefined}\n onTouchStart={!isSelected ? onClick : undefined}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n style={{\n position: 'absolute',\n inset: 0,\n // Default: transparent background with strokeColor (C) border\n // Hovered: color (IC) background fill, no border\n // Selected: no border (container handles it)\n background: isHovered ? color : 'transparent',\n border: !isHovered ? `2px solid ${strokeColor}` : 'none',\n opacity: isHovered ? opacity : 1,\n boxSizing: 'border-box',\n pointerEvents: 'auto',\n cursor: isSelected ? 'move' : 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent:\n textAlign === PdfTextAlignment.Left\n ? 'flex-start'\n : textAlign === PdfTextAlignment.Right\n ? 'flex-end'\n : 'center',\n overflow: 'hidden',\n ...style,\n }}\n >\n {isHovered && overlayText && (\n <span\n style={{\n color: textColor,\n fontSize: fontSize * scale,\n fontFamily: standardFontCss(fontFamily),\n textAlign: textAlignmentToCss(textAlign),\n whiteSpace: overlayTextRepeat ? 'normal' : 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n padding: '4px',\n }}\n >\n {renderOverlayText()}\n </span>\n )}\n </div>\n );\n}\n","import { PdfAnnotationSubtype, PdfRedactAnnoObject } from '@embedpdf/models';\nimport { createRenderer, BoxedAnnotationRenderer } from '@embedpdf/plugin-annotation/@framework';\nimport { RedactHighlight } from './annotations/redact-highlight';\nimport { RedactArea } from './annotations/redact-area';\n\n/**\n * Boxed annotation renderers for Redact annotations.\n * Type safety is enforced at definition time via createRenderer.\n * These are automatically registered with the annotation plugin via context.\n */\nexport const redactRenderers: BoxedAnnotationRenderer[] = [\n createRenderer<PdfRedactAnnoObject>({\n id: 'redactHighlight',\n matches: (a): a is PdfRedactAnnoObject =>\n a.type === PdfAnnotationSubtype.REDACT &&\n 'segmentRects' in a &&\n (a.segmentRects?.length ?? 0) > 0,\n render: (props) => <RedactHighlight {...props} />,\n }),\n createRenderer<PdfRedactAnnoObject>({\n id: 'redactArea',\n matches: (a): a is PdfRedactAnnoObject =>\n a.type === PdfAnnotationSubtype.REDACT &&\n (!('segmentRects' in a) || !(a.segmentRects?.length ?? 0)),\n render: (props) => <RedactArea {...props} />,\n }),\n];\n","import { useRegisterRenderers } from '@embedpdf/plugin-annotation/@framework';\nimport { redactRenderers } from '../components/redact-renderers';\n\n/**\n * Utility component that registers redact renderers once at app level.\n * Added via addUtility() so it mounts once, not per-page.\n */\nexport function RedactRendererRegistration() {\n useRegisterRenderers(redactRenderers);\n return null;\n}\n","import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {\n initialDocumentState,\n RedactionPlugin,\n RedactionDocumentState,\n RedactionScope,\n} from '@embedpdf/plugin-redaction';\nimport { useState, useEffect, useMemo } from '@framework';\n\nexport const useRedactionPlugin = () => usePlugin<RedactionPlugin>(RedactionPlugin.id);\nexport const useRedactionCapability = () => useCapability<RedactionPlugin>(RedactionPlugin.id);\n\nexport const useRedaction = (\n documentId: string,\n): {\n state: RedactionDocumentState;\n provides: RedactionScope | null;\n} => {\n const { provides } = useRedactionCapability();\n const [state, setState] = useState<RedactionDocumentState>(initialDocumentState);\n\n const scope = useMemo(\n () => (provides ? provides.forDocument(documentId) : null),\n [provides, documentId],\n );\n\n useEffect(() => {\n if (!scope) {\n setState(initialDocumentState);\n return;\n }\n\n // Set initial state\n try {\n setState(scope.getState());\n } catch (e) {\n // Handle case where state might not be ready\n setState(initialDocumentState);\n }\n\n // Subscribe to changes\n const unsubscribe = scope.onStateChange((newState) => {\n setState(newState);\n });\n\n return unsubscribe;\n }, [scope]);\n\n return {\n state,\n provides: scope,\n };\n};\n","import { useEffect, useMemo, useState } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { Rect } from '@embedpdf/models';\n\nimport { useRedactionPlugin } from '../hooks/use-redaction';\n\ninterface MarqueeRedactProps {\n /** The ID of the document */\n documentId: string;\n /** Index of the page this layer lives on */\n pageIndex: number;\n /** Scale of the page */\n scale?: number;\n /** Optional CSS class applied to the marquee rectangle */\n className?: string;\n /** Stroke / fill colours (defaults below) */\n stroke?: string;\n fill?: string;\n}\n\nexport const MarqueeRedact = ({\n documentId,\n pageIndex,\n scale: scaleOverride,\n className,\n stroke,\n fill = 'transparent',\n}: MarqueeRedactProps) => {\n const { plugin: redactionPlugin } = useRedactionPlugin();\n const documentState = useDocumentState(documentId);\n\n const [rect, setRect] = useState<Rect | null>(null);\n\n const scale = useMemo(() => {\n if (scaleOverride !== undefined) return scaleOverride;\n return documentState?.scale ?? 1;\n }, [scaleOverride, documentState?.scale]);\n\n // Get stroke color from plugin (annotation mode uses tool defaults, legacy uses red)\n // Allow prop override for backwards compatibility\n const strokeColor = stroke ?? redactionPlugin?.getPreviewStrokeColor() ?? 'red';\n\n useEffect(() => {\n if (!redactionPlugin || !documentId) return;\n return redactionPlugin.registerMarqueeOnPage({\n documentId,\n pageIndex,\n scale,\n callback: {\n onPreview: setRect,\n },\n });\n }, [redactionPlugin, documentId, pageIndex, scale]);\n\n if (!rect) return null;\n\n return (\n <div\n style={{\n position: 'absolute',\n pointerEvents: 'none',\n left: rect.origin.x * scale,\n top: rect.origin.y * scale,\n width: rect.size.width * scale,\n height: rect.size.height * scale,\n border: `1px solid ${strokeColor}`,\n background: fill,\n boxSizing: 'border-box',\n }}\n className={className}\n />\n );\n};\n","import { HTMLAttributes, CSSProperties, MouseEvent, TouchEvent } from '@framework';\nimport { Rect } from '@embedpdf/models';\n\ntype HighlightProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n color?: string;\n opacity?: number;\n border?: string;\n rects: Rect[];\n rect?: Rect;\n scale: number;\n onClick?: (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => void;\n style?: CSSProperties;\n};\n\nexport function Highlight({\n color = '#FFFF00',\n opacity = 1,\n border = '1px solid red',\n rects,\n rect,\n scale,\n onClick,\n style,\n ...props\n}: HighlightProps) {\n return (\n <>\n {rects.map((b, i) => (\n <div\n key={i}\n onPointerDown={onClick}\n onTouchStart={onClick}\n style={{\n position: 'absolute',\n border,\n left: (rect ? b.origin.x - rect.origin.x : b.origin.x) * scale,\n top: (rect ? b.origin.y - rect.origin.y : b.origin.y) * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background: color,\n opacity: opacity,\n pointerEvents: onClick ? 'auto' : 'none',\n cursor: onClick ? 'pointer' : 'default',\n zIndex: onClick ? 1 : undefined,\n ...style,\n }}\n {...props}\n />\n ))}\n </>\n );\n}\n","import { Rect } from '@embedpdf/models';\nimport { useEffect, useState } from '@framework';\nimport { useRedactionPlugin } from '../hooks';\nimport { Highlight } from './highlight';\n\ninterface SelectionRedactProps {\n documentId: string;\n pageIndex: number;\n scale: number;\n}\n\nexport function SelectionRedact({ documentId, pageIndex, scale }: SelectionRedactProps) {\n const { plugin: redactionPlugin } = useRedactionPlugin();\n const [rects, setRects] = useState<Array<Rect>>([]);\n const [boundingRect, setBoundingRect] = useState<Rect | null>(null);\n\n // Get stroke color from plugin (annotation mode uses tool defaults, legacy uses red)\n const strokeColor = redactionPlugin?.getPreviewStrokeColor() ?? 'red';\n\n useEffect(() => {\n if (!redactionPlugin) return;\n return redactionPlugin.onRedactionSelectionChange(documentId, (formattedSelection) => {\n const selection = formattedSelection.find((s) => s.pageIndex === pageIndex);\n setRects(selection?.segmentRects ?? []);\n setBoundingRect(selection?.rect ?? null);\n });\n }, [redactionPlugin, documentId, pageIndex]);\n\n if (!boundingRect) return null;\n\n return (\n <div\n style={{\n mixBlendMode: 'normal',\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n }}\n >\n <Highlight\n color={'transparent'}\n opacity={1}\n rects={rects}\n scale={scale}\n border={`1px solid ${strokeColor}`}\n />\n </div>\n );\n}\n","import { Fragment, useEffect, useState, useCallback, MouseEvent, TouchEvent } from '@framework';\nimport { CounterRotate } from '@embedpdf/utils/@framework';\nimport { useRedactionCapability } from '../hooks';\nimport { RedactionItem } from '@embedpdf/plugin-redaction';\nimport { Highlight } from './highlight';\nimport { RedactionSelectionMenuRenderFn } from './types';\nimport { Rotation } from '@embedpdf/models';\n\ninterface PendingRedactionsProps {\n documentId: string;\n pageIndex: number;\n scale: number;\n rotation: Rotation;\n bboxStroke?: string;\n selectionMenu?: RedactionSelectionMenuRenderFn;\n}\n\nexport function PendingRedactions({\n documentId,\n pageIndex,\n scale,\n bboxStroke = 'rgba(0,0,0,0.8)',\n rotation = Rotation.Degree0,\n selectionMenu,\n}: PendingRedactionsProps) {\n const { provides: redaction } = useRedactionCapability();\n const [items, setItems] = useState<RedactionItem[]>([]);\n const [selectedId, setSelectedId] = useState<string | null>(null);\n\n useEffect(() => {\n if (!redaction) return;\n\n // Use document-scoped hooks so we only receive events for this document\n const scoped = redaction.forDocument(documentId);\n\n // Initialize with current state - only show legacy mode items\n const currentState = scoped.getState();\n setItems((currentState.pending[pageIndex] ?? []).filter((it) => it.source === 'legacy'));\n setSelectedId(\n currentState.selected && currentState.selected.page === pageIndex\n ? currentState.selected.id\n : null,\n );\n\n // Subscribe to future changes - only show legacy mode items\n const off1 = scoped.onPendingChange((map) => {\n setItems((map[pageIndex] ?? []).filter((it) => it.source === 'legacy'));\n });\n const off2 = scoped.onSelectedChange((sel) => {\n setSelectedId(sel && sel.page === pageIndex ? sel.id : null);\n });\n\n return () => {\n off1?.();\n off2?.();\n };\n }, [redaction, documentId, pageIndex]);\n\n const select = useCallback(\n (e: MouseEvent | TouchEvent, id: string) => {\n e.stopPropagation();\n if (!redaction) return;\n redaction.forDocument(documentId).selectPending(pageIndex, id);\n },\n [redaction, documentId, pageIndex],\n );\n\n if (!items.length) return null;\n\n return (\n <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>\n {items.map((it) => {\n if (it.kind === 'area') {\n const r = it.rect;\n return (\n <Fragment key={it.id}>\n <div\n style={{\n position: 'absolute',\n left: r.origin.x * scale,\n top: r.origin.y * scale,\n width: r.size.width * scale,\n height: r.size.height * scale,\n background: 'transparent',\n outline: selectedId === it.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n border: `1px solid ${it.markColor}`,\n pointerEvents: 'auto',\n cursor: 'pointer',\n }}\n onPointerDown={(e) => select(e, it.id)}\n onTouchStart={(e) => select(e, it.id)}\n />\n {selectionMenu && (\n <CounterRotate\n rect={{\n origin: { x: r.origin.x * scale, y: r.origin.y * scale },\n size: { width: r.size.width * scale, height: r.size.height * scale },\n }}\n rotation={rotation}\n >\n {(props) =>\n selectionMenu({\n ...props,\n context: {\n type: 'redaction',\n item: it,\n pageIndex,\n },\n selected: selectedId === it.id,\n placement: {\n suggestTop: false,\n },\n })\n }\n </CounterRotate>\n )}\n </Fragment>\n );\n }\n\n const b = it.rect;\n return (\n <Fragment key={it.id}>\n <div\n style={{\n position: 'absolute',\n left: b.origin.x * scale,\n top: b.origin.y * scale,\n width: b.size.width * scale,\n height: b.size.height * scale,\n background: 'transparent',\n outline: selectedId === it.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n pointerEvents: 'auto',\n cursor: selectedId === it.id ? 'pointer' : 'default',\n }}\n >\n <Highlight\n rect={b}\n rects={it.rects}\n color=\"transparent\"\n border={`1px solid ${it.markColor}`}\n scale={scale}\n onClick={(e) => select(e, it.id)}\n />\n </div>\n {selectionMenu && (\n <CounterRotate\n rect={{\n origin: { x: b.origin.x * scale, y: b.origin.y * scale },\n size: { width: b.size.width * scale, height: b.size.height * scale },\n }}\n rotation={rotation}\n >\n {(props) =>\n selectionMenu({\n ...props,\n context: {\n type: 'redaction',\n item: it,\n pageIndex,\n },\n selected: selectedId === it.id,\n placement: {\n suggestTop: false,\n },\n })\n }\n </CounterRotate>\n )}\n </Fragment>\n );\n })}\n </div>\n );\n}\n","import { Fragment, useMemo } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { MarqueeRedact } from './marquee-redact';\nimport { SelectionRedact } from './selection-redact';\nimport { PendingRedactions } from './pending-redactions';\nimport { Rotation } from '@embedpdf/models';\nimport { RedactionSelectionMenuRenderFn } from './types';\n\ninterface RedactionLayerProps {\n /** The ID of the document this layer belongs to */\n documentId: string;\n /** Index of the page this layer lives on */\n pageIndex: number;\n /** Current render scale for this page */\n scale?: number;\n /** Page rotation (for counter-rotating menus, etc.) */\n rotation?: Rotation;\n /** Optional menu renderer for a selected redaction */\n selectionMenu?: RedactionSelectionMenuRenderFn;\n}\n\nexport const RedactionLayer = ({\n documentId,\n pageIndex,\n scale,\n rotation,\n selectionMenu,\n}: RedactionLayerProps) => {\n const documentState = useDocumentState(documentId);\n\n const actualScale = useMemo(() => {\n if (scale !== undefined) return scale;\n return documentState?.scale ?? 1;\n }, [scale, documentState?.scale]);\n\n const actualRotation = useMemo(() => {\n if (rotation !== undefined) return rotation;\n return documentState?.rotation ?? Rotation.Degree0;\n }, [rotation, documentState?.rotation]);\n\n return (\n <Fragment>\n <PendingRedactions\n documentId={documentId}\n pageIndex={pageIndex}\n scale={actualScale}\n rotation={actualRotation}\n selectionMenu={selectionMenu}\n />\n <MarqueeRedact documentId={documentId} pageIndex={pageIndex} scale={actualScale} />\n <SelectionRedact documentId={documentId} pageIndex={pageIndex} scale={actualScale} />\n </Fragment>\n );\n};\n","import { createPluginPackage } from '@embedpdf/core';\nimport { RedactionPluginPackage as BaseRedactionPackage } from '@embedpdf/plugin-redaction';\nimport { RedactRendererRegistration } from './components/redact-renderer-registration';\n\nexport * from './hooks';\nexport * from './components';\nexport * from '@embedpdf/plugin-redaction';\n\n// Automatically register redact renderers when plugin is loaded\nexport const RedactionPluginPackage = createPluginPackage(BaseRedactionPackage)\n .addUtility(RedactRendererRegistration)\n .build();\n"],"names":["RedactHighlight","annotation","isSelected","scale","onClick","style","isHovered","setIsHovered","useState","object","segmentRects","rect","strokeColor","color","opacity","textColor","fontColor","overlayColor","overlayText","overlayTextRepeat","fontSize","fontFamily","PdfStandardFont","Helvetica","textAlign","PdfTextAlignment","Center","renderOverlayText","Array","fill","join","jsx","onMouseEnter","onMouseLeave","position","inset","children","map","b","i","onPointerDown","onTouchStart","left","origin","x","top","y","width","size","height","background","border","boxSizing","pointerEvents","cursor","display","alignItems","justifyContent","Left","Right","overflow","Math","min","standardFontCss","textAlignmentToCss","whiteSpace","textOverflow","lineHeight","RedactArea","padding","redactRenderers","createRenderer","id","matches","a","type","PdfAnnotationSubtype","REDACT","_a","length","render","props","RedactRendererRegistration","useRegisterRenderers","useRedactionPlugin","usePlugin","RedactionPlugin","useRedactionCapability","useCapability","MarqueeRedact","documentId","pageIndex","scaleOverride","className","stroke","plugin","redactionPlugin","documentState","useDocumentState","setRect","useMemo","getPreviewStrokeColor","useEffect","registerMarqueeOnPage","callback","onPreview","Highlight","rects","Fragment","zIndex","SelectionRedact","setRects","boundingRect","setBoundingRect","onRedactionSelectionChange","formattedSelection","selection","find","s","mixBlendMode","PendingRedactions","bboxStroke","rotation","Rotation","Degree0","selectionMenu","provides","redaction","items","setItems","selectedId","setSelectedId","scoped","forDocument","currentState","getState","pending","filter","it","source","selected","page","off1","onPendingChange","off2","onSelectedChange","sel","select","useCallback","e","stopPropagation","selectPending","kind","r","outline","outlineOffset","markColor","CounterRotate","context","item","placement","suggestTop","RedactionPluginPackage","createPluginPackage","BaseRedactionPackage","addUtility","build","actualScale","actualRotation","state","setState","initialDocumentState","scope","onStateChange","newState"],"mappings":"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"}