@embedpdf/react 3.0.0-next.14 → 3.0.0-next.15

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 (232) hide show
  1. package/dist/AnnotationList-CkijRHet-HEFNUIZe.d.cts +877 -0
  2. package/dist/AnnotationList-CkijRHet-HEFNUIZe.d.ts +877 -0
  3. package/dist/actions.cjs +25 -5
  4. package/dist/actions.cjs.map +1 -1
  5. package/dist/actions.d.cts +18 -5
  6. package/dist/actions.d.ts +18 -5
  7. package/dist/actions.js +22 -6
  8. package/dist/actions.js.map +1 -1
  9. package/dist/anchored-DeX95xSd.d.ts +85 -0
  10. package/dist/anchored-DzN3JywS.d.cts +85 -0
  11. package/dist/anchored.cjs +71 -28
  12. package/dist/anchored.cjs.map +1 -1
  13. package/dist/anchored.d.cts +2 -45
  14. package/dist/anchored.d.ts +2 -45
  15. package/dist/anchored.js +56 -19
  16. package/dist/anchored.js.map +1 -1
  17. package/dist/annotation-B48UT2ln.d.ts +302 -0
  18. package/dist/annotation-C1ttM8Wj.js +708 -0
  19. package/dist/annotation-C1ttM8Wj.js.map +1 -0
  20. package/dist/annotation-C9dVwo9b.d.cts +302 -0
  21. package/dist/annotation-Dex5EBda.cjs +830 -0
  22. package/dist/annotation-Dex5EBda.cjs.map +1 -0
  23. package/dist/annotation.cjs +20 -784
  24. package/dist/annotation.d.cts +2 -2
  25. package/dist/annotation.d.ts +2 -2
  26. package/dist/annotation.js +2 -769
  27. package/dist/commands.cjs +68 -28
  28. package/dist/commands.cjs.map +1 -1
  29. package/dist/commands.d.cts +37 -10
  30. package/dist/commands.d.ts +37 -10
  31. package/dist/commands.js +68 -31
  32. package/dist/commands.js.map +1 -1
  33. package/dist/form-55izw0jS.js +511 -0
  34. package/dist/form-55izw0jS.js.map +1 -0
  35. package/dist/form-BNqQfGGH.cjs +548 -0
  36. package/dist/form-BNqQfGGH.cjs.map +1 -0
  37. package/dist/form.cjs +5 -5
  38. package/dist/form.d.cts +41 -2
  39. package/dist/form.d.ts +41 -2
  40. package/dist/form.js +2 -3
  41. package/dist/history.cjs +38 -0
  42. package/dist/history.cjs.map +1 -0
  43. package/dist/history.d.cts +27 -0
  44. package/dist/history.d.ts +27 -0
  45. package/dist/history.js +27 -0
  46. package/dist/history.js.map +1 -0
  47. package/dist/i18n.cjs +26 -30
  48. package/dist/i18n.cjs.map +1 -1
  49. package/dist/i18n.d.cts +24 -21
  50. package/dist/i18n.d.ts +24 -21
  51. package/dist/i18n.js +24 -31
  52. package/dist/i18n.js.map +1 -1
  53. package/dist/index.cjs +200 -57
  54. package/dist/index.d.cts +31 -32
  55. package/dist/index.d.ts +31 -32
  56. package/dist/index.js +32 -30
  57. package/dist/inert-CmBEbKCn.cjs +19 -0
  58. package/dist/inert-CmBEbKCn.cjs.map +1 -0
  59. package/dist/inert-D8fkennb.js +14 -0
  60. package/dist/inert-D8fkennb.js.map +1 -0
  61. package/dist/interaction.cjs +48 -102
  62. package/dist/interaction.cjs.map +1 -1
  63. package/dist/interaction.d.cts +23 -32
  64. package/dist/interaction.d.ts +23 -32
  65. package/dist/interaction.js +33 -102
  66. package/dist/interaction.js.map +1 -1
  67. package/dist/link.cjs +65 -104
  68. package/dist/link.cjs.map +1 -1
  69. package/dist/link.d.cts +21 -16
  70. package/dist/link.d.ts +22 -17
  71. package/dist/link.js +67 -107
  72. package/dist/link.js.map +1 -1
  73. package/dist/measurement.cjs +36 -11
  74. package/dist/measurement.cjs.map +1 -1
  75. package/dist/measurement.d.cts +33 -7
  76. package/dist/measurement.d.ts +33 -7
  77. package/dist/measurement.js +35 -14
  78. package/dist/measurement.js.map +1 -1
  79. package/dist/metadata.cjs +20 -7
  80. package/dist/metadata.cjs.map +1 -1
  81. package/dist/metadata.d.cts +22 -7
  82. package/dist/metadata.d.ts +22 -7
  83. package/dist/metadata.js +20 -10
  84. package/dist/metadata.js.map +1 -1
  85. package/dist/page-edit.cjs +7 -3
  86. package/dist/page-edit.cjs.map +1 -1
  87. package/dist/page-edit.d.cts +6 -2
  88. package/dist/page-edit.d.ts +6 -2
  89. package/dist/page-edit.js +7 -4
  90. package/dist/page-edit.js.map +1 -1
  91. package/dist/page-layers-Bkaaz8Zf.js +26 -0
  92. package/dist/page-layers-Bkaaz8Zf.js.map +1 -0
  93. package/dist/page-layers-BloZDoOV.cjs +37 -0
  94. package/dist/page-layers-BloZDoOV.cjs.map +1 -0
  95. package/dist/page-view.cjs +89 -82
  96. package/dist/page-view.cjs.map +1 -1
  97. package/dist/page-view.d.cts +14 -7
  98. package/dist/page-view.d.ts +18 -11
  99. package/dist/page-view.js +86 -81
  100. package/dist/page-view.js.map +1 -1
  101. package/dist/redaction.cjs +30 -15
  102. package/dist/redaction.cjs.map +1 -1
  103. package/dist/redaction.d.cts +27 -9
  104. package/dist/redaction.d.ts +27 -9
  105. package/dist/redaction.js +29 -18
  106. package/dist/redaction.js.map +1 -1
  107. package/dist/render.cjs +71 -46
  108. package/dist/render.cjs.map +1 -1
  109. package/dist/render.d.cts +17 -5
  110. package/dist/render.d.ts +17 -5
  111. package/dist/render.js +70 -49
  112. package/dist/render.js.map +1 -1
  113. package/dist/runtime-B6xcPsEb.js +398 -0
  114. package/dist/runtime-B6xcPsEb.js.map +1 -0
  115. package/dist/runtime-DBEBlpQV.d.cts +237 -0
  116. package/dist/runtime-V3MVMb91.d.ts +237 -0
  117. package/dist/runtime-fzpGv78v.cjs +555 -0
  118. package/dist/runtime-fzpGv78v.cjs.map +1 -0
  119. package/dist/runtime.cjs +45 -324
  120. package/dist/runtime.d.cts +2 -2
  121. package/dist/runtime.d.ts +2 -2
  122. package/dist/runtime.js +2 -306
  123. package/dist/search.cjs +81 -50
  124. package/dist/search.cjs.map +1 -1
  125. package/dist/search.d.cts +37 -24
  126. package/dist/search.d.ts +37 -24
  127. package/dist/search.js +81 -53
  128. package/dist/search.js.map +1 -1
  129. package/dist/selection.cjs +105 -108
  130. package/dist/selection.cjs.map +1 -1
  131. package/dist/selection.d.cts +54 -26
  132. package/dist/selection.d.ts +56 -28
  133. package/dist/selection.js +103 -110
  134. package/dist/selection.js.map +1 -1
  135. package/dist/shell.cjs +36 -21
  136. package/dist/shell.cjs.map +1 -1
  137. package/dist/shell.d.cts +32 -17
  138. package/dist/shell.d.ts +32 -17
  139. package/dist/shell.js +36 -24
  140. package/dist/shell.js.map +1 -1
  141. package/dist/signature.cjs +29 -48
  142. package/dist/signature.cjs.map +1 -1
  143. package/dist/signature.d.cts +26 -26
  144. package/dist/signature.d.ts +26 -26
  145. package/dist/signature.js +30 -48
  146. package/dist/signature.js.map +1 -1
  147. package/dist/stage-BIG6aeVd.cjs +369 -0
  148. package/dist/stage-BIG6aeVd.cjs.map +1 -0
  149. package/dist/stage-ByFPD-Fv.d.cts +117 -0
  150. package/dist/stage-DaboaheR.d.ts +117 -0
  151. package/dist/stage-DoVekb83.js +302 -0
  152. package/dist/stage-DoVekb83.js.map +1 -0
  153. package/dist/stage-scope-CQgCuf1w.cjs +46 -0
  154. package/dist/stage-scope-CQgCuf1w.cjs.map +1 -0
  155. package/dist/stage-scope-D7ZeNduT.js +23 -0
  156. package/dist/stage-scope-D7ZeNduT.js.map +1 -0
  157. package/dist/stage.cjs +12 -235
  158. package/dist/stage.d.cts +2 -116
  159. package/dist/stage.d.ts +2 -116
  160. package/dist/stage.js +3 -228
  161. package/dist/stamp.cjs +41 -35
  162. package/dist/stamp.cjs.map +1 -1
  163. package/dist/stamp.d.cts +25 -18
  164. package/dist/stamp.d.ts +25 -18
  165. package/dist/stamp.js +40 -37
  166. package/dist/stamp.js.map +1 -1
  167. package/dist/state-0K1I5cM4.d.cts +29 -0
  168. package/dist/state-0K1I5cM4.d.ts +29 -0
  169. package/dist/state-CbgxhwLA.js +62 -0
  170. package/dist/state-CbgxhwLA.js.map +1 -0
  171. package/dist/state-CsfZy_Eq.cjs +73 -0
  172. package/dist/state-CsfZy_Eq.cjs.map +1 -0
  173. package/dist/svg-shapes-Dm1yTR1b.js +40 -0
  174. package/dist/svg-shapes-Dm1yTR1b.js.map +1 -0
  175. package/dist/svg-shapes-zo0GNkc9.cjs +53 -0
  176. package/dist/svg-shapes-zo0GNkc9.cjs.map +1 -0
  177. package/dist/toolbar.cjs +297 -295
  178. package/dist/toolbar.cjs.map +1 -1
  179. package/dist/toolbar.d.cts +58 -68
  180. package/dist/toolbar.d.ts +67 -77
  181. package/dist/toolbar.js +271 -293
  182. package/dist/toolbar.js.map +1 -1
  183. package/dist/view-manager.cjs +34 -0
  184. package/dist/view-manager.cjs.map +1 -0
  185. package/dist/view-manager.d.cts +21 -0
  186. package/dist/view-manager.d.ts +21 -0
  187. package/dist/view-manager.js +23 -0
  188. package/dist/view-manager.js.map +1 -0
  189. package/package.json +37 -39
  190. package/dist/annotation-BCED_p9H.d.cts +0 -160
  191. package/dist/annotation-anchors-CetwM1g7.js +0 -15
  192. package/dist/annotation-anchors-CetwM1g7.js.map +0 -1
  193. package/dist/annotation-anchors-DuYRBJLl.cjs +0 -26
  194. package/dist/annotation-anchors-DuYRBJLl.cjs.map +0 -1
  195. package/dist/annotation-hooks-BB5ZhPpf.cjs +0 -16
  196. package/dist/annotation-hooks-BB5ZhPpf.cjs.map +0 -1
  197. package/dist/annotation-hooks-Df8EmzDO.js +0 -11
  198. package/dist/annotation-hooks-Df8EmzDO.js.map +0 -1
  199. package/dist/annotation-k38KDlIZ.d.ts +0 -160
  200. package/dist/annotation-menu.cjs +0 -64
  201. package/dist/annotation-menu.cjs.map +0 -1
  202. package/dist/annotation-menu.d.cts +0 -33
  203. package/dist/annotation-menu.d.ts +0 -33
  204. package/dist/annotation-menu.js +0 -48
  205. package/dist/annotation-menu.js.map +0 -1
  206. package/dist/annotation.cjs.map +0 -1
  207. package/dist/annotation.js.map +0 -1
  208. package/dist/form-BVumS7up.cjs +0 -926
  209. package/dist/form-BVumS7up.cjs.map +0 -1
  210. package/dist/form-Bdjk0Z3T.d.cts +0 -537
  211. package/dist/form-CK3mp99m.js +0 -895
  212. package/dist/form-CK3mp99m.js.map +0 -1
  213. package/dist/form-CYRYgthn.d.ts +0 -537
  214. package/dist/rolldown-runtime-BBjsoOtd.js +0 -27
  215. package/dist/runtime-DE76hlnl.d.ts +0 -216
  216. package/dist/runtime-umHA_xHt.d.cts +0 -216
  217. package/dist/runtime.cjs.map +0 -1
  218. package/dist/runtime.js.map +0 -1
  219. package/dist/scrollbar.cjs +0 -241
  220. package/dist/scrollbar.cjs.map +0 -1
  221. package/dist/scrollbar.d.cts +0 -42
  222. package/dist/scrollbar.d.ts +0 -42
  223. package/dist/scrollbar.js +0 -213
  224. package/dist/scrollbar.js.map +0 -1
  225. package/dist/stage.cjs.map +0 -1
  226. package/dist/stage.js.map +0 -1
  227. package/dist/views.cjs +0 -35
  228. package/dist/views.cjs.map +0 -1
  229. package/dist/views.d.cts +0 -21
  230. package/dist/views.d.ts +0 -21
  231. package/dist/views.js +0 -27
  232. package/dist/views.js.map +0 -1
@@ -1,23 +1,30 @@
1
+ import { PageRef } from "@embedpdf/core";
1
2
  import * as React from "react";
2
3
  import { PageFrame } from "@embedpdf/core-geometry";
3
4
  //#region src/page-view.d.ts
4
5
  interface PageViewProps {
5
- page: number;
6
- /** Which document to show. Defaults to the active document. */
6
+ /** The page: its `ref`, which follows it when pages move, or its index, from 0. */
7
+ page: PageRef | number;
8
+ /** Which document to show. Defaults to the one a `<DocumentScope>` names, else the active one. */
7
9
  documentId?: string;
8
- /** Target width for the page CONTENT; the display box is the rotated footprint. */
10
+ /** Shown while the document or the page is not available yet (default: nothing). */
11
+ fallback?: React.ReactNode;
12
+ /** The width of the page, in pixels; the display box is the rotated footprint. Default 240. */
9
13
  width?: number;
10
- /** Reserved chrome bands around the page (screen px) — same model as `<Stage>`. */
11
- pageFrame?: PageFrame;
14
+ /** Space reserved around the page for your own labels, in pixels per side; the sides left out are 0. */
15
+ pageFrame?: Partial<PageFrame>;
12
16
  /** Page-space content (rotates with the page). */
13
17
  children: React.ReactNode;
14
18
  /** Box-space chrome (label, border, …) — never rotated. Mirrors `<Stage pageChrome>`. */
15
19
  pageChrome?: React.ReactNode;
20
+ /** On the outer box. */
21
+ className?: string;
22
+ /** On the outer box. */
16
23
  style?: React.CSSProperties;
17
24
  }
18
- /** A single page surface with NO Stage — same layers + rotation + chrome frame,
25
+ /** A single page surface with no Stage — same layers + rotation + chrome frame,
19
26
  * no camera/scroll/zoom. */
20
- declare function PageView({ page, documentId, width, pageFrame, children, pageChrome, style }: PageViewProps): import("react/jsx-runtime").JSX.Element | null;
27
+ declare function PageView({ page: wanted, documentId, fallback, width, pageFrame: framePatch, children, pageChrome, className, style }: PageViewProps): import("react/jsx-runtime").JSX.Element;
21
28
  //#endregion
22
29
  export { PageView, PageViewProps };
23
30
  //# sourceMappingURL=page-view.d.cts.map
@@ -1,23 +1,30 @@
1
- import * as React from "react";
1
+ import { PageRef } from "@embedpdf/core";
2
+ import * as React$1 from "react";
2
3
  import { PageFrame } from "@embedpdf/core-geometry";
3
4
  //#region src/page-view.d.ts
4
5
  interface PageViewProps {
5
- page: number;
6
- /** Which document to show. Defaults to the active document. */
6
+ /** The page: its `ref`, which follows it when pages move, or its index, from 0. */
7
+ page: PageRef | number;
8
+ /** Which document to show. Defaults to the one a `<DocumentScope>` names, else the active one. */
7
9
  documentId?: string;
8
- /** Target width for the page CONTENT; the display box is the rotated footprint. */
10
+ /** Shown while the document or the page is not available yet (default: nothing). */
11
+ fallback?: React$1.ReactNode;
12
+ /** The width of the page, in pixels; the display box is the rotated footprint. Default 240. */
9
13
  width?: number;
10
- /** Reserved chrome bands around the page (screen px) — same model as `<Stage>`. */
11
- pageFrame?: PageFrame;
14
+ /** Space reserved around the page for your own labels, in pixels per side; the sides left out are 0. */
15
+ pageFrame?: Partial<PageFrame>;
12
16
  /** Page-space content (rotates with the page). */
13
- children: React.ReactNode;
17
+ children: React$1.ReactNode;
14
18
  /** Box-space chrome (label, border, …) — never rotated. Mirrors `<Stage pageChrome>`. */
15
- pageChrome?: React.ReactNode;
16
- style?: React.CSSProperties;
19
+ pageChrome?: React$1.ReactNode;
20
+ /** On the outer box. */
21
+ className?: string;
22
+ /** On the outer box. */
23
+ style?: React$1.CSSProperties;
17
24
  }
18
- /** A single page surface with NO Stage — same layers + rotation + chrome frame,
25
+ /** A single page surface with no Stage — same layers + rotation + chrome frame,
19
26
  * no camera/scroll/zoom. */
20
- declare function PageView({ page, documentId, width, pageFrame, children, pageChrome, style }: PageViewProps): import("react/jsx-runtime").JSX.Element | null;
27
+ declare function PageView({ page: wanted, documentId, fallback, width, pageFrame: framePatch, children, pageChrome, className, style }: PageViewProps): import("react/jsx-runtime").JSX.Element;
21
28
  //#endregion
22
29
  export { PageView, PageViewProps };
23
30
  //# sourceMappingURL=page-view.d.ts.map
package/dist/page-view.js CHANGED
@@ -1,111 +1,116 @@
1
- import { DocumentScope, PageProvider, makePageContext, useActiveDocumentId, useKernel } from "./runtime.js";
2
- import { ProjectorProvider } from "./anchored.js";
3
- import { jsx, jsxs } from "react/jsx-runtime";
1
+ import { D as useViewerSettings, S as useOptionalCapability, a as PageProvider, h as useDocumentId, n as DocumentScope, x as useKernelValue } from "./runtime-B6xcPsEb.js";
2
+ import { ProjectorProvider, ShownPagesProvider } from "./anchored.js";
3
+ import { PagePointerSource } from "./interaction.js";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ import { toPageRef } from "@embedpdf/core";
6
+ import { clientPageProjector, makePageContext, observeClientGeometry, pageSurfaceLayout, pageViewTransformInput, paint } from "@embedpdf/web";
4
7
  import { useId, useMemo, useRef } from "react";
5
- import { observeClientGeometry } from "@embedpdf/web";
8
+ import { InteractionToken } from "@embedpdf/plugin-interaction/contract/host";
6
9
  import { NO_FRAME, pageTransform } from "@embedpdf/core-geometry";
7
10
  //#region src/page-view.tsx
8
- /** A single page surface with NO Stage — same layers + rotation + chrome frame,
11
+ /**
12
+ * The page's pointer surface, when the interaction plugin is registered. It sits
13
+ * below the layers, like the Stage's own listener: a press on a layer that lets
14
+ * the pointer through (the picture, the selection highlight) reaches the tools,
15
+ * and a control that takes its own presses (a link, a form field) keeps them.
16
+ */
17
+ function PointerSurface() {
18
+ return useOptionalCapability(InteractionToken) ? /* @__PURE__ */ jsx(PagePointerSource, {}) : null;
19
+ }
20
+ /** A single page surface with no Stage — same layers + rotation + chrome frame,
9
21
  * no camera/scroll/zoom. */
10
- function PageView({ page, documentId, width = 240, pageFrame = NO_FRAME, children, pageChrome, style }) {
11
- const kernel = useKernel();
12
- const active = useActiveDocumentId();
22
+ function PageView({ page: wanted, documentId, fallback = null, width = 240, pageFrame: framePatch, children, pageChrome, className, style }) {
23
+ const wantedRef = typeof wanted === "number" ? null : wanted;
24
+ const wantedIndex = typeof wanted === "number" ? wanted : null;
25
+ const { top = 0, right = 0, bottom = 0, left = 0 } = framePatch ?? NO_FRAME;
26
+ const pageFrame = useMemo(() => ({
27
+ top,
28
+ right,
29
+ bottom,
30
+ left
31
+ }), [
32
+ top,
33
+ right,
34
+ bottom,
35
+ left
36
+ ]);
37
+ const inScope = useDocumentId();
13
38
  const ref = useRef(null);
14
- const docId = documentId ?? active;
15
- const meta = docId ? kernel.getState().core.documents[docId] : void 0;
16
- const base = meta?.pages[page];
17
- const pon = base?.pageObjectNumber ?? page + 1;
18
- const rotation = base?.rotation ?? 0;
39
+ const docId = documentId ?? inScope;
40
+ const wantedPageObjectNumber = wantedRef?.objectNumber ?? null;
41
+ const base = useKernelValue((kernel) => {
42
+ if (!docId) return null;
43
+ const pages = kernel.documents.listPages(docId);
44
+ return (wantedPageObjectNumber !== null ? pages.find((pageInfo) => pageInfo.ref.objectNumber === wantedPageObjectNumber) : pages[wantedIndex ?? 0]) ?? null;
45
+ });
46
+ const page = base?.index ?? wantedIndex ?? 0;
47
+ const pageObjectNumber = base?.ref.objectNumber ?? wantedPageObjectNumber ?? page + 1;
48
+ const pageRef = useMemo(() => toPageRef(pageObjectNumber), [pageObjectNumber]);
19
49
  const dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
20
- const transform = useMemo(() => pageTransform({
21
- pageSize: base ? {
22
- width: base.size.width,
23
- height: base.size.height
24
- } : {
25
- width: 1,
26
- height: 1
27
- },
28
- rotation,
29
- scale: base ? width / base.size.width : 1,
30
- baseScale: 96 / 72 * (base?.userUnit ?? 1),
31
- dpr
32
- }), [
50
+ const transform = useMemo(() => pageTransform(pageViewTransformInput(base, width, dpr)), [
33
51
  base?.size.width,
34
52
  base?.size.height,
35
53
  base?.userUnit,
36
- rotation,
54
+ base?.rotation,
37
55
  width,
38
56
  dpr
39
57
  ]);
40
58
  const viewId = useId();
41
- const ctx = useMemo(() => makePageContext(docId ?? "", `page-view:${viewId}`, pon, page, pageFrame, transform, () => ref.current.getBoundingClientRect()), [
59
+ const ctx = useMemo(() => makePageContext(docId ?? "", `page-view:${viewId}`, pageRef, page, pageFrame, transform, () => ref.current.getBoundingClientRect()), [
42
60
  docId,
43
- pon,
61
+ pageRef,
44
62
  page,
45
63
  pageFrame,
46
64
  transform,
47
65
  viewId
48
66
  ]);
49
- const projector = useMemo(() => ({
50
- space: "client",
51
- toScreen: (p, rect) => p === ctx.pon && ref.current ? ctx.toClientRect(rect) : null,
52
- toScreenPoint: (p, at) => p === ctx.pon && ref.current ? ctx.toClientPoint(at) : null,
53
- viewEnv: (p) => p === ctx.pon ? {
54
- scale: ctx.transform.viewScale,
55
- rotation: ctx.transform.rotation,
56
- zoom: ctx.transform.zoom
57
- } : null
58
- }), [ctx]);
67
+ const projector = useMemo(() => clientPageProjector(ctx, () => ref.current !== null), [ctx]);
59
68
  const projectorBinding = useMemo(() => ({
60
69
  projector,
61
70
  revision: ctx,
62
71
  subscribe: observeClientGeometry
63
72
  }), [projector, ctx]);
64
- if (!docId || !meta || !base) return null;
65
- const t = transform;
66
- const outerW = t.viewWidth + pageFrame.left + pageFrame.right;
67
- const outerH = t.viewHeight + pageFrame.top + pageFrame.bottom;
68
- const contentLeft = pageFrame.left + (t.viewWidth - t.contentWidth) / 2;
69
- const contentTop = pageFrame.top + (t.viewHeight - t.contentHeight) / 2;
73
+ const shownPages = useMemo(() => /* @__PURE__ */ new Set([ctx.ref.objectNumber]), [ctx.ref.objectNumber]);
74
+ const look = useViewerSettings((settings) => settings.page);
75
+ if (!docId || !base) return /* @__PURE__ */ jsx(Fragment, { children: fallback });
76
+ const layout = pageSurfaceLayout(transform, pageFrame);
70
77
  return /* @__PURE__ */ jsx(DocumentScope, {
71
78
  id: docId,
72
- children: /* @__PURE__ */ jsx(ProjectorProvider, {
73
- value: projectorBinding,
74
- children: /* @__PURE__ */ jsx("div", {
75
- style: {
76
- position: "relative",
77
- width: outerW,
78
- height: outerH,
79
- ...style
80
- },
81
- children: /* @__PURE__ */ jsxs(PageProvider, {
82
- value: ctx,
83
- children: [
84
- /* @__PURE__ */ jsx("div", { style: {
85
- position: "absolute",
86
- left: pageFrame.left,
87
- top: pageFrame.top,
88
- width: t.viewWidth,
89
- height: t.viewHeight,
90
- boxShadow: "var(--epdf-page-shadow, 0 6px 18px rgba(0,0,0,.18))"
91
- } }),
92
- /* @__PURE__ */ jsx("div", {
93
- ref,
94
- style: {
79
+ children: /* @__PURE__ */ jsx(ShownPagesProvider, {
80
+ value: shownPages,
81
+ children: /* @__PURE__ */ jsx(ProjectorProvider, {
82
+ value: projectorBinding,
83
+ children: /* @__PURE__ */ jsx("div", {
84
+ className,
85
+ style: {
86
+ position: "relative",
87
+ width: layout.outer.width,
88
+ height: layout.outer.height,
89
+ ...style
90
+ },
91
+ children: /* @__PURE__ */ jsxs(PageProvider, {
92
+ value: ctx,
93
+ children: [
94
+ /* @__PURE__ */ jsx("div", { style: {
95
95
  position: "absolute",
96
- left: contentLeft,
97
- top: contentTop,
98
- width: t.contentWidth,
99
- height: t.contentHeight,
100
- background: "#fff",
101
- transform: rotation ? `rotate(${rotation}deg)` : void 0,
102
- userSelect: "none",
103
- WebkitUserSelect: "none"
104
- },
105
- children
106
- }),
107
- pageChrome
108
- ]
96
+ ...layout.shadow,
97
+ boxShadow: paint("page-shadow", look.shadow)
98
+ } }),
99
+ /* @__PURE__ */ jsxs("div", {
100
+ ref,
101
+ style: {
102
+ position: "absolute",
103
+ ...layout.content,
104
+ background: paint("page-background", look.background),
105
+ transform: layout.turn ?? void 0,
106
+ userSelect: "none",
107
+ WebkitUserSelect: "none"
108
+ },
109
+ children: [/* @__PURE__ */ jsx(PointerSurface, {}), children]
110
+ }),
111
+ pageChrome
112
+ ]
113
+ })
109
114
  })
110
115
  })
111
116
  })
@@ -1 +1 @@
1
- {"version":3,"file":"page-view.js","names":[],"sources":["../src/page-view.tsx"],"sourcesContent":["/**\n * <PageView> — a single page surface with NO Stage.\n *\n * Same layers + rotation + chrome frame as a `<Stage>` page, but no\n * camera/scroll/zoom and, crucially, NO dependency on `@embedpdf/plugin-stage`.\n * It builds its own `PageTransform` from a target content width and shares the\n * exact `PageContext` seam, so every layer (RenderLayer, AnnotationLayer, …)\n * works here identically — and it provides the measured `ViewProjector`, so\n * anchored UI (`<AnnotationMenu>`, `<SelectionMenu>`) works here too, portalled\n * and clipping-immune.\n */\nimport * as React from 'react';\nimport { useId, useMemo, useRef } from 'react';\nimport { NO_FRAME, pageTransform, type PageFrame } from '@embedpdf/core-geometry';\nimport { observeClientGeometry } from '@embedpdf/web';\nimport { ProjectorProvider, type ProjectorBinding, type ViewProjector } from './anchored';\nimport {\n DocumentScope,\n makePageContext,\n PageProvider,\n useActiveDocumentId,\n useKernel,\n} from './runtime';\n\nexport interface PageViewProps {\n page: number;\n /** Which document to show. Defaults to the active document. */\n documentId?: string;\n /** Target width for the page CONTENT; the display box is the rotated footprint. */\n width?: number;\n /** Reserved chrome bands around the page (screen px) — same model as `<Stage>`. */\n pageFrame?: PageFrame;\n /** Page-space content (rotates with the page). */\n children: React.ReactNode;\n /** Box-space chrome (label, border, …) — never rotated. Mirrors `<Stage pageChrome>`. */\n pageChrome?: React.ReactNode;\n style?: React.CSSProperties;\n}\n\n/** A single page surface with NO Stage — same layers + rotation + chrome frame,\n * no camera/scroll/zoom. */\nexport function PageView({\n page,\n documentId,\n width = 240,\n pageFrame = NO_FRAME,\n children,\n pageChrome,\n style,\n}: PageViewProps) {\n const kernel = useKernel();\n const active = useActiveDocumentId();\n const ref = useRef<HTMLDivElement>(null);\n const docId = documentId ?? active;\n const meta = docId ? kernel.getState().core.documents[docId] : undefined;\n const base = meta?.pages[page];\n const pon = base?.pageObjectNumber ?? page + 1;\n const rotation = base?.rotation ?? 0;\n const dpr = typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;\n // Standalone (no Stage/camera): build the page's transform from the target\n // content `width` directly. `scale` is view px per point = width / pageWidthPts.\n const transform = useMemo(\n () =>\n pageTransform({\n pageSize: base\n ? { width: base.size.width, height: base.size.height }\n : { width: 1, height: 1 },\n rotation,\n scale: base ? width / base.size.width : 1,\n // Physical 100% on the web: 1pt = 96/72 CSS px, times the page's\n // /UserUnit — so `transform.zoom` is meaningful even without a Stage\n // (a thumbnail-sized PageView reads as zoomed out, as it should).\n baseScale: (96 / 72) * (base?.userUnit ?? 1),\n dpr,\n }),\n [base?.size.width, base?.size.height, base?.userUnit, rotation, width, dpr],\n );\n // This instance's VIEW identity: two PageViews of the same page (a compare\n // strip) must plan rasters independently, like two stage lenses do.\n const viewId = useId();\n const ctx = useMemo(\n () =>\n makePageContext(\n docId ?? '',\n `page-view:${viewId}`,\n pon,\n page,\n pageFrame,\n transform,\n () => ref.current!.getBoundingClientRect(),\n ),\n [docId, pon, page, pageFrame, transform, viewId],\n );\n // The PageView's ViewProjector: no camera, so anchored UI positions by\n // MEASURING the DOM (client space → portal + position:fixed, immune to\n // ancestor overflow clipping). `toScreen` answers null until the page\n // element has committed — <Anchored> forces one post-commit pass to pick\n // it up. The binding's revision covers state-driven changes (a new\n // transform/page); `observeClientGeometry` covers the genuinely\n // browser-driven ones (document scroll, window resize) that no state\n // change announces.\n const projector = useMemo<ViewProjector>(\n () => ({\n space: 'client',\n toScreen: (p, rect) => (p === ctx.pon && ref.current ? ctx.toClientRect(rect) : null),\n toScreenPoint: (p, at) => (p === ctx.pon && ref.current ? ctx.toClientPoint(at) : null),\n viewEnv: (p) =>\n p === ctx.pon\n ? {\n scale: ctx.transform.viewScale,\n rotation: ctx.transform.rotation,\n zoom: ctx.transform.zoom,\n }\n : null,\n }),\n [ctx],\n );\n const projectorBinding = useMemo<ProjectorBinding>(\n () => ({ projector, revision: ctx, subscribe: observeClientGeometry }),\n [projector, ctx],\n );\n if (!docId || !meta || !base) return null;\n const t = transform;\n const outerW = t.viewWidth + pageFrame.left + pageFrame.right;\n const outerH = t.viewHeight + pageFrame.top + pageFrame.bottom;\n const contentLeft = pageFrame.left + (t.viewWidth - t.contentWidth) / 2;\n const contentTop = pageFrame.top + (t.viewHeight - t.contentHeight) / 2;\n return (\n <DocumentScope id={docId}>\n <ProjectorProvider value={projectorBinding}>\n <div style={{ position: 'relative', width: outerW, height: outerH, ...style }}>\n <PageProvider value={ctx}>\n {/* drop shadow ONLY — transparent, axis-aligned, can't leak behind the bitmap */}\n <div\n style={{\n position: 'absolute',\n left: pageFrame.left,\n top: pageFrame.top,\n width: t.viewWidth,\n height: t.viewHeight,\n boxShadow: 'var(--epdf-page-shadow, 0 6px 18px rgba(0,0,0,.18))',\n }}\n />\n {/* white backing + content as ONE box; rotation 0 carries no transform */}\n <div\n ref={ref}\n style={{\n position: 'absolute',\n left: contentLeft,\n top: contentTop,\n width: t.contentWidth,\n height: t.contentHeight,\n background: '#fff',\n transform: rotation ? `rotate(${rotation}deg)` : undefined,\n userSelect: 'none',\n WebkitUserSelect: 'none',\n }}\n >\n {children}\n </div>\n {pageChrome}\n </PageProvider>\n </div>\n </ProjectorProvider>\n </DocumentScope>\n );\n}\n"],"mappings":";;;;;;;;;AAyCA,SAAgB,SAAS,EACvB,MACA,YACA,QAAQ,KACR,YAAY,UACZ,UACA,YACA,SACgB;CAChB,MAAM,SAAS,UAAU;CACzB,MAAM,SAAS,oBAAoB;CACnC,MAAM,MAAM,OAAuB,IAAI;CACvC,MAAM,QAAQ,cAAc;CAC5B,MAAM,OAAO,QAAQ,OAAO,SAAS,CAAC,CAAC,KAAK,UAAU,SAAS,KAAA;CAC/D,MAAM,OAAO,MAAM,MAAM;CACzB,MAAM,MAAM,MAAM,oBAAoB,OAAO;CAC7C,MAAM,WAAW,MAAM,YAAY;CACnC,MAAM,MAAM,OAAO,WAAW,cAAc,OAAO,oBAAoB,IAAI;CAG3E,MAAM,YAAY,cAEd,cAAc;EACZ,UAAU,OACN;GAAE,OAAO,KAAK,KAAK;GAAO,QAAQ,KAAK,KAAK;EAAO,IACnD;GAAE,OAAO;GAAG,QAAQ;EAAE;EAC1B;EACA,OAAO,OAAO,QAAQ,KAAK,KAAK,QAAQ;EAIxC,WAAY,KAAK,MAAO,MAAM,YAAY;EAC1C;CACF,CAAC,GACH;EAAC,MAAM,KAAK;EAAO,MAAM,KAAK;EAAQ,MAAM;EAAU;EAAU;EAAO;CAAG,CAC5E;CAGA,MAAM,SAAS,MAAM;CACrB,MAAM,MAAM,cAER,gBACE,SAAS,IACT,aAAa,UACb,KACA,MACA,WACA,iBACM,IAAI,QAAS,sBAAsB,CAC3C,GACF;EAAC;EAAO;EAAK;EAAM;EAAW;EAAW;CAAM,CACjD;CASA,MAAM,YAAY,eACT;EACL,OAAO;EACP,WAAW,GAAG,SAAU,MAAM,IAAI,OAAO,IAAI,UAAU,IAAI,aAAa,IAAI,IAAI;EAChF,gBAAgB,GAAG,OAAQ,MAAM,IAAI,OAAO,IAAI,UAAU,IAAI,cAAc,EAAE,IAAI;EAClF,UAAU,MACR,MAAM,IAAI,MACN;GACE,OAAO,IAAI,UAAU;GACrB,UAAU,IAAI,UAAU;GACxB,MAAM,IAAI,UAAU;EACtB,IACA;CACR,IACA,CAAC,GAAG,CACN;CACA,MAAM,mBAAmB,eAChB;EAAE;EAAW,UAAU;EAAK,WAAW;CAAsB,IACpE,CAAC,WAAW,GAAG,CACjB;CACA,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,OAAO;CACrC,MAAM,IAAI;CACV,MAAM,SAAS,EAAE,YAAY,UAAU,OAAO,UAAU;CACxD,MAAM,SAAS,EAAE,aAAa,UAAU,MAAM,UAAU;CACxD,MAAM,cAAc,UAAU,QAAQ,EAAE,YAAY,EAAE,gBAAgB;CACtE,MAAM,aAAa,UAAU,OAAO,EAAE,aAAa,EAAE,iBAAiB;CACtE,OACE,oBAAC,eAAD;EAAe,IAAI;EACjB,UAAA,oBAAC,mBAAD;GAAmB,OAAO;GAC1B,UAAA,oBAAC,OAAD;IAAK,OAAO;KAAE,UAAU;KAAY,OAAO;KAAQ,QAAQ;KAAQ,GAAG;IAAM;IAC1E,UAAA,qBAAC,cAAD;KAAc,OAAO;KAArB,UAAA;MAEE,oBAAC,OAAD,EACE,OAAO;OACL,UAAU;OACV,MAAM,UAAU;OAChB,KAAK,UAAU;OACf,OAAO,EAAE;OACT,QAAQ,EAAE;OACV,WAAW;MACb,EACD,CAAA;MAED,oBAAC,OAAD;OACO;OACL,OAAO;QACL,UAAU;QACV,MAAM;QACN,KAAK;QACL,OAAO,EAAE;QACT,QAAQ,EAAE;QACV,YAAY;QACZ,WAAW,WAAW,UAAU,SAAS,QAAQ,KAAA;QACjD,YAAY;QACZ,kBAAkB;OACpB;OAEC;MACE,CAAA;MACJ;KACW;;GACX,CAAA;EACc,CAAA;CACN,CAAA;AAEnB"}
1
+ {"version":3,"file":"page-view.js","names":["InteractionHostToken"],"sources":["../src/page-view.tsx"],"sourcesContent":["/**\n * <PageView> — a single page surface with no Stage.\n *\n * Same layers + rotation + chrome frame as a `<Stage>` page, but no\n * camera/scroll/zoom and, crucially, no dependency on `@embedpdf/plugin-stage`.\n * It builds its own `PageTransform` from a target content width and shares the\n * exact `PageContext` seam, so every layer (RenderLayer, AnnotationLayer, …)\n * works here identically — and it provides the measured `ViewProjector`, so\n * anchored UI (`<AnnotationMenu>`, `<SelectionMenu>`) works here too, portalled\n * and clipping-immune. With the interaction plugin registered it is also the\n * page's pointer surface, so tools (text selection, annotation editing) work in\n * it as they do on a Stage page.\n */\nimport * as React from 'react';\nimport { useId, useMemo, useRef } from 'react';\nimport { toPageRef } from '@embedpdf/core';\nimport type { PageRef } from '@embedpdf/core';\nimport { NO_FRAME, pageTransform, type PageFrame } from '@embedpdf/core-geometry';\nimport {\n clientPageProjector,\n makePageContext,\n observeClientGeometry,\n pageSurfaceLayout,\n pageViewTransformInput,\n paint,\n} from '@embedpdf/web';\nimport { InteractionToken as InteractionHostToken } from '@embedpdf/plugin-interaction/contract/host';\nimport {\n ProjectorProvider,\n ShownPagesProvider,\n type ProjectorBinding,\n type ShownPages,\n type ViewProjector,\n} from './anchored';\nimport { PagePointerSource } from './interaction';\nimport {\n DocumentScope,\n PageProvider,\n useDocumentId,\n useKernelValue,\n useOptionalCapability,\n useViewerSettings,\n} from './runtime';\n\n/**\n * The page's pointer surface, when the interaction plugin is registered. It sits\n * below the layers, like the Stage's own listener: a press on a layer that lets\n * the pointer through (the picture, the selection highlight) reaches the tools,\n * and a control that takes its own presses (a link, a form field) keeps them.\n */\nfunction PointerSurface() {\n const interaction = useOptionalCapability(InteractionHostToken);\n return interaction ? <PagePointerSource /> : null;\n}\n\nexport interface PageViewProps {\n /** The page: its `ref`, which follows it when pages move, or its index, from 0. */\n page: PageRef | number;\n /** Which document to show. Defaults to the one a `<DocumentScope>` names, else the active one. */\n documentId?: string;\n /** Shown while the document or the page is not available yet (default: nothing). */\n fallback?: React.ReactNode;\n /** The width of the page, in pixels; the display box is the rotated footprint. Default 240. */\n width?: number;\n /** Space reserved around the page for your own labels, in pixels per side; the sides left out are 0. */\n pageFrame?: Partial<PageFrame>;\n /** Page-space content (rotates with the page). */\n children: React.ReactNode;\n /** Box-space chrome (label, border, …) — never rotated. Mirrors `<Stage pageChrome>`. */\n pageChrome?: React.ReactNode;\n /** On the outer box. */\n className?: string;\n /** On the outer box. */\n style?: React.CSSProperties;\n}\n\n/** A single page surface with no Stage — same layers + rotation + chrome frame,\n * no camera/scroll/zoom. */\nexport function PageView({\n page: wanted,\n documentId,\n fallback = null,\n width = 240,\n pageFrame: framePatch,\n children,\n pageChrome,\n className,\n style,\n}: PageViewProps) {\n const wantedRef = typeof wanted === 'number' ? null : wanted;\n const wantedIndex = typeof wanted === 'number' ? wanted : null;\n // The sides left out reserve nothing; memoized by value so the context stays stable.\n const { top = 0, right = 0, bottom = 0, left = 0 } = framePatch ?? NO_FRAME;\n const pageFrame = useMemo<PageFrame>(\n () => ({ top, right, bottom, left }),\n [top, right, bottom, left],\n );\n const inScope = useDocumentId();\n const ref = useRef<HTMLDivElement>(null);\n const docId = documentId ?? inScope;\n // The page-registry entry, subscribed: a rotate or a reorder re-renders\n // this surface like it re-renders a Stage page. Entries are reference-\n // stable per page in the registry, so identity is the right equality.\n const wantedPageObjectNumber = wantedRef?.objectNumber ?? null;\n const base = useKernelValue((kernel) => {\n if (!docId) return null;\n const pages = kernel.documents.listPages(docId);\n const found =\n wantedPageObjectNumber !== null\n ? pages.find((pageInfo) => pageInfo.ref.objectNumber === wantedPageObjectNumber)\n : pages[wantedIndex ?? 0];\n return found ?? null;\n });\n const page = base?.index ?? wantedIndex ?? 0;\n // The page's address is the kernel's (`PageLayout.ref`); a placeholder\n // (object number = 1-based index) only until the layout is known — the\n // surface renders the fallback before that anyway. Memoized by the number so\n // the context's `ref` stays identity-stable across re-renders (layers key\n // effects on it).\n const pageObjectNumber = base?.ref.objectNumber ?? wantedPageObjectNumber ?? page + 1;\n const pageRef = useMemo(() => toPageRef(pageObjectNumber), [pageObjectNumber]);\n const dpr = typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;\n // Standalone (no Stage/camera): build the page's transform from the target\n // content `width` directly. Memoized by value: a new registry entry for an\n // unchanged page keeps the transform.\n const transform = useMemo(\n () => pageTransform(pageViewTransformInput(base, width, dpr)),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- `base` by the values it gives\n [base?.size.width, base?.size.height, base?.userUnit, base?.rotation, width, dpr],\n );\n // This instance's view identity: two PageViews of the same page (a compare\n // strip) must plan rasters independently, like two stage lenses do.\n const viewId = useId();\n const ctx = useMemo(\n () =>\n makePageContext(docId ?? '', `page-view:${viewId}`, pageRef, page, pageFrame, transform, () =>\n ref.current!.getBoundingClientRect(),\n ),\n [docId, pageRef, page, pageFrame, transform, viewId],\n );\n // The PageView's ViewProjector: no camera, so anchored UI positions by\n // measuring the DOM (client space → portal + position:fixed, immune to\n // ancestor overflow clipping). `toScreen` answers null until the page\n // element has committed — <Anchored> forces one post-commit pass to pick\n // it up. The binding's revision covers state-driven changes (a new\n // transform/page); `observeClientGeometry` covers the genuinely\n // browser-driven ones (document scroll, window resize) that no state\n // change announces.\n const projector = useMemo<ViewProjector>(\n () => clientPageProjector(ctx, () => ref.current !== null),\n [ctx],\n );\n const projectorBinding = useMemo<ProjectorBinding>(\n () => ({ projector, revision: ctx, subscribe: observeClientGeometry }),\n [projector, ctx],\n );\n // A PageView shows its one page.\n const shownPages = useMemo<ShownPages>(\n () => new Set([ctx.ref.objectNumber]),\n [ctx.ref.objectNumber],\n );\n // The viewer's `page` settings; `--epdf-page-*` CSS variables win over them.\n const look = useViewerSettings((settings) => settings.page);\n if (!docId || !base) return <>{fallback}</>;\n // The outer box (page and frame), the shadow at the footprint, and the turned content box.\n const layout = pageSurfaceLayout(transform, pageFrame);\n return (\n <DocumentScope id={docId}>\n <ShownPagesProvider value={shownPages}>\n <ProjectorProvider value={projectorBinding}>\n <div\n className={className}\n style={{\n position: 'relative',\n width: layout.outer.width,\n height: layout.outer.height,\n ...style,\n }}\n >\n <PageProvider value={ctx}>\n {/* drop shadow ONLY — transparent, axis-aligned, can't leak behind the bitmap */}\n <div\n style={{\n position: 'absolute',\n ...layout.shadow,\n boxShadow: paint('page-shadow', look.shadow),\n }}\n />\n {/* white backing + content as ONE box; rotation 0 carries no transform */}\n <div\n ref={ref}\n style={{\n position: 'absolute',\n ...layout.content,\n background: paint('page-background', look.background),\n transform: layout.turn ?? undefined,\n userSelect: 'none',\n WebkitUserSelect: 'none',\n }}\n >\n <PointerSurface />\n {children}\n </div>\n {pageChrome}\n </PageProvider>\n </div>\n </ProjectorProvider>\n </ShownPagesProvider>\n </DocumentScope>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkDA,SAAS,iBAAiB;CAExB,OADoB,sBAAsBA,gBACzB,IAAI,oBAAC,mBAAD,CAAoB,CAAA,IAAI;AAC/C;;;AAyBA,SAAgB,SAAS,EACvB,MAAM,QACN,YACA,WAAW,MACX,QAAQ,KACR,WAAW,YACX,UACA,YACA,WACA,SACgB;CAChB,MAAM,YAAY,OAAO,WAAW,WAAW,OAAO;CACtD,MAAM,cAAc,OAAO,WAAW,WAAW,SAAS;CAE1D,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,MAAM,cAAc;CACnE,MAAM,YAAY,eACT;EAAE;EAAK;EAAO;EAAQ;CAAK,IAClC;EAAC;EAAK;EAAO;EAAQ;CAAI,CAC3B;CACA,MAAM,UAAU,cAAc;CAC9B,MAAM,MAAM,OAAuB,IAAI;CACvC,MAAM,QAAQ,cAAc;CAI5B,MAAM,yBAAyB,WAAW,gBAAgB;CAC1D,MAAM,OAAO,gBAAgB,WAAW;EACtC,IAAI,CAAC,OAAO,OAAO;EACnB,MAAM,QAAQ,OAAO,UAAU,UAAU,KAAK;EAK9C,QAHE,2BAA2B,OACvB,MAAM,MAAM,aAAa,SAAS,IAAI,iBAAiB,sBAAsB,IAC7E,MAAM,eAAe,OACX;CAClB,CAAC;CACD,MAAM,OAAO,MAAM,SAAS,eAAe;CAM3C,MAAM,mBAAmB,MAAM,IAAI,gBAAgB,0BAA0B,OAAO;CACpF,MAAM,UAAU,cAAc,UAAU,gBAAgB,GAAG,CAAC,gBAAgB,CAAC;CAC7E,MAAM,MAAM,OAAO,WAAW,cAAc,OAAO,oBAAoB,IAAI;CAI3E,MAAM,YAAY,cACV,cAAc,uBAAuB,MAAM,OAAO,GAAG,CAAC,GAE5D;EAAC,MAAM,KAAK;EAAO,MAAM,KAAK;EAAQ,MAAM;EAAU,MAAM;EAAU;EAAO;CAAG,CAClF;CAGA,MAAM,SAAS,MAAM;CACrB,MAAM,MAAM,cAER,gBAAgB,SAAS,IAAI,aAAa,UAAU,SAAS,MAAM,WAAW,iBAC5E,IAAI,QAAS,sBAAsB,CACrC,GACF;EAAC;EAAO;EAAS;EAAM;EAAW;EAAW;CAAM,CACrD;CASA,MAAM,YAAY,cACV,oBAAoB,WAAW,IAAI,YAAY,IAAI,GACzD,CAAC,GAAG,CACN;CACA,MAAM,mBAAmB,eAChB;EAAE;EAAW,UAAU;EAAK,WAAW;CAAsB,IACpE,CAAC,WAAW,GAAG,CACjB;CAEA,MAAM,aAAa,8BACX,IAAI,IAAI,CAAC,IAAI,IAAI,YAAY,CAAC,GACpC,CAAC,IAAI,IAAI,YAAY,CACvB;CAEA,MAAM,OAAO,mBAAmB,aAAa,SAAS,IAAI;CAC1D,IAAI,CAAC,SAAS,CAAC,MAAM,OAAO,oBAAA,UAAA,EAAA,UAAG,SAAW,CAAA;CAE1C,MAAM,SAAS,kBAAkB,WAAW,SAAS;CACrD,OACE,oBAAC,eAAD;EAAe,IAAI;EACjB,UAAA,oBAAC,oBAAD;GAAoB,OAAO;GACzB,UAAA,oBAAC,mBAAD;IAAmB,OAAO;IACxB,UAAA,oBAAC,OAAD;KACa;KACX,OAAO;MACL,UAAU;MACV,OAAO,OAAO,MAAM;MACpB,QAAQ,OAAO,MAAM;MACrB,GAAG;KACL;KAEA,UAAA,qBAAC,cAAD;MAAc,OAAO;MAArB,UAAA;OAEE,oBAAC,OAAD,EACE,OAAO;QACL,UAAU;QACV,GAAG,OAAO;QACV,WAAW,MAAM,eAAe,KAAK,MAAM;OAC7C,EACD,CAAA;OAED,qBAAC,OAAD;QACO;QACL,OAAO;SACL,UAAU;SACV,GAAG,OAAO;SACV,YAAY,MAAM,mBAAmB,KAAK,UAAU;SACpD,WAAW,OAAO,QAAQ,KAAA;SAC1B,YAAY;SACZ,kBAAkB;QACpB;QATF,UAAA,CAWE,oBAAC,gBAAD,CAAiB,CAAA,GAChB,QACE;;OACJ;MACW;;IACX,CAAA;GACY,CAAA;EACD,CAAA;CACP,CAAA;AAEnB"}
@@ -1,28 +1,43 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  require("./rolldown-runtime-DDXJien1.cjs");
3
- const require_runtime = require("./runtime.cjs");
3
+ const require_runtime = require("./runtime-fzpGv78v.cjs");
4
+ const require_state = require("./state-CsfZy_Eq.cjs");
4
5
  let _embedpdf_plugin_redaction = require("@embedpdf/plugin-redaction");
5
6
  //#region src/redaction.tsx
7
+ /** The redaction capability: marking, the pending marks, and applying them. */
6
8
  function useRedaction() {
7
- const cap = require_runtime.useCapability(_embedpdf_plugin_redaction.RedactionToken);
8
- const applying = require_runtime.useSelector(_embedpdf_plugin_redaction.RedactionToken, (c) => c.isApplying());
9
- const lastApplyResult = require_runtime.useSelector(_embedpdf_plugin_redaction.RedactionToken, (c) => c.lastResult());
10
- return {
11
- ...cap,
12
- applying,
13
- lastApplyResult
14
- };
9
+ return require_runtime.useCapability(_embedpdf_plugin_redaction.RedactionToken);
15
10
  }
16
- /** The pending marks, reactive against the annotation plane. Note the view
17
- * covers LOADED pages — call `preparePending()` (e.g. on panel open) to load
18
- * the whole document. */
19
- function usePendingRedactions() {
20
- return require_runtime.useSelector(_embedpdf_plugin_redaction.RedactionToken, (c) => c.getPending(), pendingEqual);
11
+ /** Subscribe to one redaction event for the mounted lifetime: `useRedactionEvent((redaction) => redaction.onApplied, handler)`. */
12
+ function useRedactionEvent(select, handler) {
13
+ require_runtime.useCapabilityEvent(_embedpdf_plugin_redaction.RedactionToken, select, handler);
14
+ }
15
+ /**
16
+ * The redaction state: how many marks wait, whether marks are being applied,
17
+ * and the last apply's result (the page's State table, declared once in
18
+ * `redactionState`). Takes a selector, and re-renders only when what it
19
+ * returns changes.
20
+ */
21
+ const useRedactionState = require_state.stateHook(_embedpdf_plugin_redaction.redactionState);
22
+ /** The redaction settings (`overlay`), with or without a document. Takes a selector. */
23
+ const useRedactionSettings = require_state.settingsHook(_embedpdf_plugin_redaction.RedactionToken);
24
+ const NO_MARKS = Object.freeze([]);
25
+ /**
26
+ * The marks waiting to be applied, in page order, or one page's (its ref or
27
+ * its index). The lists are reference-stable, so a component re-renders only
28
+ * when its marks change. Empty without a document.
29
+ */
30
+ function usePendingRedactions(filter) {
31
+ const scoped = require_runtime.useDocumentScope();
32
+ const page = filter?.page;
33
+ return require_runtime.useKernelValue((kernel) => kernel.tryCapability(_embedpdf_plugin_redaction.RedactionToken, scoped ?? void 0)?.listPending(page === void 0 ? void 0 : { page }) ?? NO_MARKS);
21
34
  }
22
- const pendingEqual = (a, b) => a.length === b.length && a.every((item, i) => item.id === b[i].id && item.overlayText === b[i].overlayText);
23
35
  //#endregion
24
36
  exports.usePendingRedactions = usePendingRedactions;
25
37
  exports.useRedaction = useRedaction;
38
+ exports.useRedactionEvent = useRedactionEvent;
39
+ exports.useRedactionSettings = useRedactionSettings;
40
+ exports.useRedactionState = useRedactionState;
26
41
  Object.keys(_embedpdf_plugin_redaction).forEach(function(k) {
27
42
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
28
43
  enumerable: true,
@@ -1 +1 @@
1
- {"version":3,"file":"redaction.cjs","names":["useCapability","RedactionToken","useSelector"],"sources":["../src/redaction.tsx"],"sourcesContent":["import { RedactionToken } from '@embedpdf/plugin-redaction';\nimport type {\n RedactionApplyResult,\n RedactionCapability,\n RedactionPendingItem,\n} from '@embedpdf/plugin-redaction';\nimport { useCapability, useSelector } from './runtime';\n\n/**\n * Redaction for the surrounding `DocumentScope`: the pending-marks view plus\n * the destructive apply. Marking rides the annotation plane (the composed\n * `redact` tool); `useRedaction` surfaces the workflow around it.\n *\n * const redaction = useRedaction();\n * redaction.toggleRedact();\n * await redaction.applyAll(); // irreversible — confirm first\n */\n\n// One-line-per-feature: registration travels with the UI.\nexport * from '@embedpdf/plugin-redaction';\n\nexport function useRedaction(): RedactionCapability & {\n applying: boolean;\n lastApplyResult: RedactionApplyResult | null;\n} {\n const cap = useCapability(RedactionToken);\n const applying = useSelector(RedactionToken, (c) => c.isApplying());\n const lastApplyResult = useSelector(RedactionToken, (c) => c.lastResult());\n return { ...cap, applying, lastApplyResult };\n}\n\n/** The pending marks, reactive against the annotation plane. Note the view\n * covers LOADED pages — call `preparePending()` (e.g. on panel open) to load\n * the whole document. */\nexport function usePendingRedactions(): RedactionPendingItem[] {\n return useSelector(RedactionToken, (c) => c.getPending(), pendingEqual);\n}\n\nconst pendingEqual = (a: RedactionPendingItem[], b: RedactionPendingItem[]): boolean =>\n a.length === b.length &&\n a.every((item, i) => item.id === b[i]!.id && item.overlayText === b[i]!.overlayText);\n"],"mappings":";;;;;AAqBA,SAAgB,eAGd;CACA,MAAM,MAAMA,gBAAAA,cAAcC,2BAAAA,cAAc;CACxC,MAAM,WAAWC,gBAAAA,YAAYD,2BAAAA,iBAAiB,MAAM,EAAE,WAAW,CAAC;CAClE,MAAM,kBAAkBC,gBAAAA,YAAYD,2BAAAA,iBAAiB,MAAM,EAAE,WAAW,CAAC;CACzE,OAAO;EAAE,GAAG;EAAK;EAAU;CAAgB;AAC7C;;;;AAKA,SAAgB,uBAA+C;CAC7D,OAAOC,gBAAAA,YAAYD,2BAAAA,iBAAiB,MAAM,EAAE,WAAW,GAAG,YAAY;AACxE;AAEA,MAAM,gBAAgB,GAA2B,MAC/C,EAAE,WAAW,EAAE,UACf,EAAE,OAAO,MAAM,MAAM,KAAK,OAAO,EAAE,EAAE,CAAE,MAAM,KAAK,gBAAgB,EAAE,EAAE,CAAE,WAAW"}
1
+ {"version":3,"file":"redaction.cjs","names":["useCapability","RedactionToken","stateHook","redactionState","settingsHook","useDocumentScope","useKernelValue"],"sources":["../src/redaction.tsx"],"sourcesContent":["/**\n * The React view of @embedpdf/plugin-redaction: the four hooks every plugin\n * has, plus the pending marks. Marking rides the annotation plane (the\n * composed `redact` tool); these hooks surface the workflow around it.\n *\n * const redaction = useRedaction();\n * const { pendingCount, applying } = useRedactionState();\n * await redaction.applyAll(); // irreversible: confirm first\n */\n\n// One-line-per-feature: registration travels with the UI.\nexport * from '@embedpdf/plugin-redaction';\nimport type { EventHook } from '@embedpdf/core';\nimport { RedactionToken, redactionState } from '@embedpdf/plugin-redaction';\nimport type {\n RedactionCapability,\n RedactionMark,\n RedactionMarkFilter,\n} from '@embedpdf/plugin-redaction';\nimport { useCapability, useCapabilityEvent, useDocumentScope, useKernelValue } from './runtime';\nimport { settingsHook, stateHook } from './state';\n\n/** The redaction capability: marking, the pending marks, and applying them. */\nexport function useRedaction(): RedactionCapability {\n return useCapability(RedactionToken);\n}\n\n/** Subscribe to one redaction event for the mounted lifetime: `useRedactionEvent((redaction) => redaction.onApplied, handler)`. */\nexport function useRedactionEvent<T>(\n select: (redaction: RedactionCapability) => EventHook<T>,\n handler: (event: T) => void,\n): void {\n useCapabilityEvent(RedactionToken, select, handler);\n}\n\n/**\n * The redaction state: how many marks wait, whether marks are being applied,\n * and the last apply's result (the page's State table, declared once in\n * `redactionState`). Takes a selector, and re-renders only when what it\n * returns changes.\n */\nexport const useRedactionState = stateHook(redactionState);\n\n/** The redaction settings (`overlay`), with or without a document. Takes a selector. */\nexport const useRedactionSettings = settingsHook(RedactionToken);\n\nconst NO_MARKS: readonly RedactionMark[] = Object.freeze([]);\n\n/**\n * The marks waiting to be applied, in page order, or one page's (its ref or\n * its index). The lists are reference-stable, so a component re-renders only\n * when its marks change. Empty without a document.\n */\nexport function usePendingRedactions(filter?: RedactionMarkFilter): readonly RedactionMark[] {\n const scoped = useDocumentScope();\n const page = filter?.page;\n return useKernelValue(\n (kernel) =>\n kernel\n .tryCapability(RedactionToken, scoped ?? undefined)\n ?.listPending(page === undefined ? undefined : { page }) ?? NO_MARKS,\n );\n}\n"],"mappings":";;;;;;;AAuBA,SAAgB,eAAoC;CAClD,OAAOA,gBAAAA,cAAcC,2BAAAA,cAAc;AACrC;;AAGA,SAAgB,kBACd,QACA,SACM;CACN,gBAAA,mBAAmBA,2BAAAA,gBAAgB,QAAQ,OAAO;AACpD;;;;;;;AAQA,MAAa,oBAAoBC,cAAAA,UAAUC,2BAAAA,cAAc;;AAGzD,MAAa,uBAAuBC,cAAAA,aAAaH,2BAAAA,cAAc;AAE/D,MAAM,WAAqC,OAAO,OAAO,CAAC,CAAC;;;;;;AAO3D,SAAgB,qBAAqB,QAAwD;CAC3F,MAAM,SAASI,gBAAAA,iBAAiB;CAChC,MAAM,OAAO,QAAQ;CACrB,OAAOC,gBAAAA,gBACJ,WACC,OACG,cAAcL,2BAAAA,gBAAgB,UAAU,KAAA,CAAS,CAAC,EACjD,YAAY,SAAS,KAAA,IAAY,KAAA,IAAY,EAAE,KAAK,CAAC,KAAK,QAClE;AACF"}
@@ -1,14 +1,32 @@
1
- import { RedactionApplyResult, RedactionCapability, RedactionPendingItem } from "@embedpdf/plugin-redaction";
1
+ import { n as StateHook, t as SettingsHook } from "./state-0K1I5cM4.cjs";
2
+ import { a as RedactionApplyResult } from "./AnnotationList-CkijRHet-HEFNUIZe.cjs";
3
+ import { EventHook } from "@embedpdf/core";
4
+ import { RedactionCapability, RedactionMark, RedactionMarkFilter } from "@embedpdf/plugin-redaction";
2
5
  export * from "@embedpdf/plugin-redaction";
3
6
  //#region src/redaction.d.ts
4
- declare function useRedaction(): RedactionCapability & {
7
+ /** The redaction capability: marking, the pending marks, and applying them. */
8
+ declare function useRedaction(): RedactionCapability;
9
+ /** Subscribe to one redaction event for the mounted lifetime: `useRedactionEvent((redaction) => redaction.onApplied, handler)`. */
10
+ declare function useRedactionEvent<T>(select: (redaction: RedactionCapability) => EventHook<T>, handler: (event: T) => void): void;
11
+ /**
12
+ * The redaction state: how many marks wait, whether marks are being applied,
13
+ * and the last apply's result (the page's State table, declared once in
14
+ * `redactionState`). Takes a selector, and re-renders only when what it
15
+ * returns changes.
16
+ */
17
+ declare const useRedactionState: StateHook<{
18
+ pendingCount: number;
5
19
  applying: boolean;
6
- lastApplyResult: RedactionApplyResult | null;
7
- };
8
- /** The pending marks, reactive against the annotation plane. Note the view
9
- * covers LOADED pages — call `preparePending()` (e.g. on panel open) to load
10
- * the whole document. */
11
- declare function usePendingRedactions(): RedactionPendingItem[];
20
+ lastResult: RedactionApplyResult | null;
21
+ }>;
22
+ /** The redaction settings (`overlay`), with or without a document. Takes a selector. */
23
+ declare const useRedactionSettings: SettingsHook<import("@embedpdf/plugin-redaction").RedactionSettings>;
24
+ /**
25
+ * The marks waiting to be applied, in page order, or one page's (its ref or
26
+ * its index). The lists are reference-stable, so a component re-renders only
27
+ * when its marks change. Empty without a document.
28
+ */
29
+ declare function usePendingRedactions(filter?: RedactionMarkFilter): readonly RedactionMark[];
12
30
  //#endregion
13
- export { usePendingRedactions, useRedaction };
31
+ export { usePendingRedactions, useRedaction, useRedactionEvent, useRedactionSettings, useRedactionState };
14
32
  //# sourceMappingURL=redaction.d.cts.map
@@ -1,14 +1,32 @@
1
- import { RedactionApplyResult, RedactionCapability, RedactionPendingItem } from "@embedpdf/plugin-redaction";
1
+ import { n as StateHook, t as SettingsHook } from "./state-0K1I5cM4.js";
2
+ import { a as RedactionApplyResult } from "./AnnotationList-CkijRHet-HEFNUIZe.js";
3
+ import { EventHook } from "@embedpdf/core";
4
+ import { RedactionCapability, RedactionMark, RedactionMarkFilter } from "@embedpdf/plugin-redaction";
2
5
  export * from "@embedpdf/plugin-redaction";
3
6
  //#region src/redaction.d.ts
4
- declare function useRedaction(): RedactionCapability & {
7
+ /** The redaction capability: marking, the pending marks, and applying them. */
8
+ declare function useRedaction(): RedactionCapability;
9
+ /** Subscribe to one redaction event for the mounted lifetime: `useRedactionEvent((redaction) => redaction.onApplied, handler)`. */
10
+ declare function useRedactionEvent<T>(select: (redaction: RedactionCapability) => EventHook<T>, handler: (event: T) => void): void;
11
+ /**
12
+ * The redaction state: how many marks wait, whether marks are being applied,
13
+ * and the last apply's result (the page's State table, declared once in
14
+ * `redactionState`). Takes a selector, and re-renders only when what it
15
+ * returns changes.
16
+ */
17
+ declare const useRedactionState: StateHook<{
18
+ pendingCount: number;
5
19
  applying: boolean;
6
- lastApplyResult: RedactionApplyResult | null;
7
- };
8
- /** The pending marks, reactive against the annotation plane. Note the view
9
- * covers LOADED pages — call `preparePending()` (e.g. on panel open) to load
10
- * the whole document. */
11
- declare function usePendingRedactions(): RedactionPendingItem[];
20
+ lastResult: RedactionApplyResult | null;
21
+ }>;
22
+ /** The redaction settings (`overlay`), with or without a document. Takes a selector. */
23
+ declare const useRedactionSettings: SettingsHook<import("@embedpdf/plugin-redaction").RedactionSettings>;
24
+ /**
25
+ * The marks waiting to be applied, in page order, or one page's (its ref or
26
+ * its index). The lists are reference-stable, so a component re-renders only
27
+ * when its marks change. Empty without a document.
28
+ */
29
+ declare function usePendingRedactions(filter?: RedactionMarkFilter): readonly RedactionMark[];
12
30
  //#endregion
13
- export { usePendingRedactions, useRedaction };
31
+ export { usePendingRedactions, useRedaction, useRedactionEvent, useRedactionSettings, useRedactionState };
14
32
  //# sourceMappingURL=redaction.d.ts.map
package/dist/redaction.js CHANGED
@@ -1,26 +1,37 @@
1
- import "./rolldown-runtime-BBjsoOtd.js";
2
- import { useCapability, useSelector } from "./runtime.js";
3
- import { RedactionToken } from "@embedpdf/plugin-redaction";
1
+ import { f as useCapability, g as useDocumentScope, p as useCapabilityEvent, x as useKernelValue } from "./runtime-B6xcPsEb.js";
2
+ import { n as stateHook, t as settingsHook } from "./state-CbgxhwLA.js";
3
+ import { RedactionToken, redactionState } from "@embedpdf/plugin-redaction";
4
4
  export * from "@embedpdf/plugin-redaction";
5
5
  //#region src/redaction.tsx
6
+ /** The redaction capability: marking, the pending marks, and applying them. */
6
7
  function useRedaction() {
7
- const cap = useCapability(RedactionToken);
8
- const applying = useSelector(RedactionToken, (c) => c.isApplying());
9
- const lastApplyResult = useSelector(RedactionToken, (c) => c.lastResult());
10
- return {
11
- ...cap,
12
- applying,
13
- lastApplyResult
14
- };
8
+ return useCapability(RedactionToken);
15
9
  }
16
- /** The pending marks, reactive against the annotation plane. Note the view
17
- * covers LOADED pages — call `preparePending()` (e.g. on panel open) to load
18
- * the whole document. */
19
- function usePendingRedactions() {
20
- return useSelector(RedactionToken, (c) => c.getPending(), pendingEqual);
10
+ /** Subscribe to one redaction event for the mounted lifetime: `useRedactionEvent((redaction) => redaction.onApplied, handler)`. */
11
+ function useRedactionEvent(select, handler) {
12
+ useCapabilityEvent(RedactionToken, select, handler);
13
+ }
14
+ /**
15
+ * The redaction state: how many marks wait, whether marks are being applied,
16
+ * and the last apply's result (the page's State table, declared once in
17
+ * `redactionState`). Takes a selector, and re-renders only when what it
18
+ * returns changes.
19
+ */
20
+ const useRedactionState = stateHook(redactionState);
21
+ /** The redaction settings (`overlay`), with or without a document. Takes a selector. */
22
+ const useRedactionSettings = settingsHook(RedactionToken);
23
+ const NO_MARKS = Object.freeze([]);
24
+ /**
25
+ * The marks waiting to be applied, in page order, or one page's (its ref or
26
+ * its index). The lists are reference-stable, so a component re-renders only
27
+ * when its marks change. Empty without a document.
28
+ */
29
+ function usePendingRedactions(filter) {
30
+ const scoped = useDocumentScope();
31
+ const page = filter?.page;
32
+ return useKernelValue((kernel) => kernel.tryCapability(RedactionToken, scoped ?? void 0)?.listPending(page === void 0 ? void 0 : { page }) ?? NO_MARKS);
21
33
  }
22
- const pendingEqual = (a, b) => a.length === b.length && a.every((item, i) => item.id === b[i].id && item.overlayText === b[i].overlayText);
23
34
  //#endregion
24
- export { usePendingRedactions, useRedaction };
35
+ export { usePendingRedactions, useRedaction, useRedactionEvent, useRedactionSettings, useRedactionState };
25
36
 
26
37
  //# sourceMappingURL=redaction.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"redaction.js","names":[],"sources":["../src/redaction.tsx"],"sourcesContent":["import { RedactionToken } from '@embedpdf/plugin-redaction';\nimport type {\n RedactionApplyResult,\n RedactionCapability,\n RedactionPendingItem,\n} from '@embedpdf/plugin-redaction';\nimport { useCapability, useSelector } from './runtime';\n\n/**\n * Redaction for the surrounding `DocumentScope`: the pending-marks view plus\n * the destructive apply. Marking rides the annotation plane (the composed\n * `redact` tool); `useRedaction` surfaces the workflow around it.\n *\n * const redaction = useRedaction();\n * redaction.toggleRedact();\n * await redaction.applyAll(); // irreversible — confirm first\n */\n\n// One-line-per-feature: registration travels with the UI.\nexport * from '@embedpdf/plugin-redaction';\n\nexport function useRedaction(): RedactionCapability & {\n applying: boolean;\n lastApplyResult: RedactionApplyResult | null;\n} {\n const cap = useCapability(RedactionToken);\n const applying = useSelector(RedactionToken, (c) => c.isApplying());\n const lastApplyResult = useSelector(RedactionToken, (c) => c.lastResult());\n return { ...cap, applying, lastApplyResult };\n}\n\n/** The pending marks, reactive against the annotation plane. Note the view\n * covers LOADED pages — call `preparePending()` (e.g. on panel open) to load\n * the whole document. */\nexport function usePendingRedactions(): RedactionPendingItem[] {\n return useSelector(RedactionToken, (c) => c.getPending(), pendingEqual);\n}\n\nconst pendingEqual = (a: RedactionPendingItem[], b: RedactionPendingItem[]): boolean =>\n a.length === b.length &&\n a.every((item, i) => item.id === b[i]!.id && item.overlayText === b[i]!.overlayText);\n"],"mappings":";;;;;AAqBA,SAAgB,eAGd;CACA,MAAM,MAAM,cAAc,cAAc;CACxC,MAAM,WAAW,YAAY,iBAAiB,MAAM,EAAE,WAAW,CAAC;CAClE,MAAM,kBAAkB,YAAY,iBAAiB,MAAM,EAAE,WAAW,CAAC;CACzE,OAAO;EAAE,GAAG;EAAK;EAAU;CAAgB;AAC7C;;;;AAKA,SAAgB,uBAA+C;CAC7D,OAAO,YAAY,iBAAiB,MAAM,EAAE,WAAW,GAAG,YAAY;AACxE;AAEA,MAAM,gBAAgB,GAA2B,MAC/C,EAAE,WAAW,EAAE,UACf,EAAE,OAAO,MAAM,MAAM,KAAK,OAAO,EAAE,EAAE,CAAE,MAAM,KAAK,gBAAgB,EAAE,EAAE,CAAE,WAAW"}
1
+ {"version":3,"file":"redaction.js","names":[],"sources":["../src/redaction.tsx"],"sourcesContent":["/**\n * The React view of @embedpdf/plugin-redaction: the four hooks every plugin\n * has, plus the pending marks. Marking rides the annotation plane (the\n * composed `redact` tool); these hooks surface the workflow around it.\n *\n * const redaction = useRedaction();\n * const { pendingCount, applying } = useRedactionState();\n * await redaction.applyAll(); // irreversible: confirm first\n */\n\n// One-line-per-feature: registration travels with the UI.\nexport * from '@embedpdf/plugin-redaction';\nimport type { EventHook } from '@embedpdf/core';\nimport { RedactionToken, redactionState } from '@embedpdf/plugin-redaction';\nimport type {\n RedactionCapability,\n RedactionMark,\n RedactionMarkFilter,\n} from '@embedpdf/plugin-redaction';\nimport { useCapability, useCapabilityEvent, useDocumentScope, useKernelValue } from './runtime';\nimport { settingsHook, stateHook } from './state';\n\n/** The redaction capability: marking, the pending marks, and applying them. */\nexport function useRedaction(): RedactionCapability {\n return useCapability(RedactionToken);\n}\n\n/** Subscribe to one redaction event for the mounted lifetime: `useRedactionEvent((redaction) => redaction.onApplied, handler)`. */\nexport function useRedactionEvent<T>(\n select: (redaction: RedactionCapability) => EventHook<T>,\n handler: (event: T) => void,\n): void {\n useCapabilityEvent(RedactionToken, select, handler);\n}\n\n/**\n * The redaction state: how many marks wait, whether marks are being applied,\n * and the last apply's result (the page's State table, declared once in\n * `redactionState`). Takes a selector, and re-renders only when what it\n * returns changes.\n */\nexport const useRedactionState = stateHook(redactionState);\n\n/** The redaction settings (`overlay`), with or without a document. Takes a selector. */\nexport const useRedactionSettings = settingsHook(RedactionToken);\n\nconst NO_MARKS: readonly RedactionMark[] = Object.freeze([]);\n\n/**\n * The marks waiting to be applied, in page order, or one page's (its ref or\n * its index). The lists are reference-stable, so a component re-renders only\n * when its marks change. Empty without a document.\n */\nexport function usePendingRedactions(filter?: RedactionMarkFilter): readonly RedactionMark[] {\n const scoped = useDocumentScope();\n const page = filter?.page;\n return useKernelValue(\n (kernel) =>\n kernel\n .tryCapability(RedactionToken, scoped ?? undefined)\n ?.listPending(page === undefined ? undefined : { page }) ?? NO_MARKS,\n );\n}\n"],"mappings":";;;;;;AAuBA,SAAgB,eAAoC;CAClD,OAAO,cAAc,cAAc;AACrC;;AAGA,SAAgB,kBACd,QACA,SACM;CACN,mBAAmB,gBAAgB,QAAQ,OAAO;AACpD;;;;;;;AAQA,MAAa,oBAAoB,UAAU,cAAc;;AAGzD,MAAa,uBAAuB,aAAa,cAAc;AAE/D,MAAM,WAAqC,OAAO,OAAO,CAAC,CAAC;;;;;;AAO3D,SAAgB,qBAAqB,QAAwD;CAC3F,MAAM,SAAS,iBAAiB;CAChC,MAAM,OAAO,QAAQ;CACrB,OAAO,gBACJ,WACC,OACG,cAAc,gBAAgB,UAAU,KAAA,CAAS,CAAC,EACjD,YAAY,SAAS,KAAA,IAAY,KAAA,IAAY,EAAE,KAAK,CAAC,KAAK,QAClE;AACF"}