@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,895 +0,0 @@
1
- import { shallowArray, useCapability, useOptionalCapability, useOptionalSelector, usePage, useSelector } from "./runtime.js";
2
- import { t as useAnnotationSelected } from "./annotation-hooks-Df8EmzDO.js";
3
- import { jsx, jsxs } from "react/jsx-runtime";
4
- import { useCallback, useEffect, useMemo, useRef, useState } from "react";
5
- import { InteractionToken } from "@embedpdf/plugin-interaction/contract";
6
- import { FormToken } from "@embedpdf/plugin-form";
7
- import { SignatureToken } from "@embedpdf/plugin-signature/contract";
8
- //#region src/form-focus-ring.tsx
9
- /**
10
- * Paint the form focus indicator above baked PDF appearances and transparent
11
- * native controls. Putting an inset outline on the widget wrapper lets an
12
- * opaque child cover it, which makes rectangular checkboxes and combo boxes
13
- * appear unfocused even though they are active in the native Tab order.
14
- */
15
- function FormFocusRing({ visible }) {
16
- if (!visible) return null;
17
- return /* @__PURE__ */ jsx("span", {
18
- "aria-hidden": "true",
19
- "data-embedpdf-form-focus-ring": "",
20
- style: {
21
- position: "absolute",
22
- inset: 0,
23
- zIndex: 1,
24
- boxSizing: "border-box",
25
- outline: "2px solid rgba(66, 133, 244, 0.8)",
26
- outlineOffset: -2,
27
- pointerEvents: "none"
28
- }
29
- });
30
- }
31
- //#endregion
32
- //#region src/form-listbox.tsx
33
- /**
34
- * A PDF list box needs one owner for pixels, hit-testing, and scrolling. A
35
- * baked /AP picture with an invisible native select cannot provide that: the
36
- * browser and PDF each keep an independent top-visible row. This visible
37
- * native control keeps a local optimistic selection while the engine write is
38
- * pending and synchronizes when engine truth changes, without remounting the
39
- * DOM node or resetting its scroll position.
40
- */
41
- function NativeListBox({ ariaLabel, disabled, multi, options, selected, onSelect, onFocus, onBlur, style }) {
42
- const [draft, setDraft] = useState(() => [...selected]);
43
- const controlRef = useRef(null);
44
- const selectedRef = useRef(selected);
45
- selectedRef.current = selected;
46
- const selectedSignature = JSON.stringify(selected);
47
- useEffect(() => {
48
- const control = controlRef.current;
49
- if (!control) return;
50
- const isolateWheel = (event) => event.stopPropagation();
51
- control.addEventListener("wheel", isolateWheel);
52
- return () => control.removeEventListener("wheel", isolateWheel);
53
- }, []);
54
- useEffect(() => {
55
- setDraft([...selectedRef.current]);
56
- }, [selectedSignature]);
57
- const rollback = () => setDraft([...selectedRef.current]);
58
- const choose = (values) => {
59
- setDraft(values);
60
- try {
61
- const result = onSelect(values);
62
- if (result) result.catch(rollback);
63
- } catch {
64
- rollback();
65
- }
66
- };
67
- return /* @__PURE__ */ jsx("select", {
68
- ref: controlRef,
69
- "aria-label": ariaLabel,
70
- multiple: multi,
71
- size: Math.max(2, options.length),
72
- disabled,
73
- value: multi ? draft : draft[0] ?? "",
74
- onFocus,
75
- onBlur,
76
- onChange: (event) => choose(Array.from(event.currentTarget.selectedOptions).map((option) => option.value)),
77
- style,
78
- children: options.map((option, index) => /* @__PURE__ */ jsx("option", {
79
- value: option.value,
80
- children: option.label
81
- }, index))
82
- });
83
- }
84
- //#endregion
85
- //#region src/form.tsx
86
- /** Content rect → a view-px box (the page wrapper's own coordinate space). */
87
- function viewBox(r, page) {
88
- const tl = page.transform.toPixels({
89
- x: r.x,
90
- y: r.y
91
- });
92
- const br = page.transform.toPixels({
93
- x: r.x + r.width,
94
- y: r.y + r.height
95
- });
96
- return {
97
- left: tl.x,
98
- top: tl.y,
99
- width: br.x - tl.x,
100
- height: br.y - tl.y
101
- };
102
- }
103
- /**
104
- * Keep the interaction hub out of gestures that begin inside a fill control.
105
- * Native listener (not React's) so it runs during real DOM bubbling, before
106
- * the Stage's own native listener on an ancestor — same trick as FreeText.
107
- */
108
- function useIsolated() {
109
- const ref = useRef(null);
110
- useEffect(() => {
111
- const el = ref.current;
112
- if (!el) return;
113
- const stop = (e) => e.stopPropagation();
114
- el.addEventListener("pointerdown", stop);
115
- return () => el.removeEventListener("pointerdown", stop);
116
- }, []);
117
- return ref;
118
- }
119
- /**
120
- * The widget DOM-event feed (Phase 2): wire one widget surface's pointer and
121
- * focus events to `form.notifyWidgetEvent` — the `/AA` E/X/D/U/Fo/Bl trigger
122
- * door. Handlers live on the ALWAYS-ACTIVE event surface, never the inner
123
- * control: "may edit this field" and "may receive PDF action events" are
124
- * different rights, and a read-only session (no `doc.forms.fill`) must still
125
- * see hover tooltips (session Hide needs no write authority).
126
- */
127
- function useWidgetEvents(key, annotationRef) {
128
- const form = useCapability(FormToken);
129
- const refBox = useRef(annotationRef);
130
- refBox.current = annotationRef;
131
- return useMemo(() => {
132
- const notify = (event) => {
133
- const target = refBox.current;
134
- if (target) form.notifyWidgetEvent(key, target, event);
135
- };
136
- return {
137
- onPointerEnter: () => notify("cursorEnter"),
138
- onPointerLeave: () => notify("cursorExit"),
139
- onPointerDown: () => notify("mouseDown"),
140
- onPointerUp: () => notify("mouseUp"),
141
- onFocus: () => notify("focus"),
142
- onBlur: () => notify("blur")
143
- };
144
- }, [form, key]);
145
- }
146
- /**
147
- * Widget ACTIVATION: a click on ANY widget runs its `/A`. ISO puts the
148
- * activate action on the annotation dictionary — any subtype, any field
149
- * type — so activation is a WIDGET behavior, not a push-button behavior:
150
- * real-world producers ship "buttons" as read-only text fields carrying an
151
- * `/A` (the Test Lab's Reset/Next/Hide controls), and Acrobat runs them.
152
- * A widget without an `/A` resolves inert — dispatching is the cheap,
153
- * honest way to ask (the dispatcher owns `/A`-vs-`/AA U` precedence).
154
- * Push buttons keep their own gated door: `disabled` still blocks
155
- * activation there — unchanged shipped semantics.
156
- */
157
- function useWidgetActivation(key, annotationRef) {
158
- const form = useCapability(FormToken);
159
- const refBox = useRef(annotationRef);
160
- refBox.current = annotationRef;
161
- return useCallback(() => {
162
- const target = refBox.current;
163
- if (target) form.activateWidget(key, target);
164
- }, [form, key]);
165
- }
166
- /** The baked /AP raster, blitted by its OWN box (exactly like BakedImage). */
167
- function Picture({ page, appearance, apBox, frame, hidden }) {
168
- if (!appearance) return null;
169
- const b = viewBox(apBox ?? appearance.box, page);
170
- return /* @__PURE__ */ jsx("img", {
171
- src: appearance.url,
172
- alt: "",
173
- draggable: false,
174
- style: {
175
- position: "absolute",
176
- left: b.left - (frame?.left ?? 0),
177
- top: b.top - (frame?.top ?? 0),
178
- width: b.width,
179
- height: b.height,
180
- maxWidth: "none",
181
- pointerEvents: "none",
182
- visibility: hidden ? "hidden" : "visible"
183
- }
184
- });
185
- }
186
- /**
187
- * Dispatch one engaged widget to its fill control. The FIELD plane (value,
188
- * behavior, disabled) comes from the form plugin's single-widget projection;
189
- * the WIDGET plane (live box, /DA font, baked raster) rides in on the
190
- * renderer props — no geometry is read from the form model here.
191
- */
192
- function FormWidget({ item, page, appearance }) {
193
- const annot = item.ref?.kind === "objectNumber" ? item.ref.annotObjectNumber : 0;
194
- const fill = useSelector(FormToken, (c) => annot > 0 ? c.fillItem(annot) : null);
195
- if (!fill) return /* @__PURE__ */ jsx(Picture, {
196
- page,
197
- appearance,
198
- apBox: item.apBox
199
- });
200
- switch (fill.control) {
201
- case "text": return /* @__PURE__ */ jsx(TextWidget, {
202
- fill,
203
- item,
204
- page,
205
- appearance
206
- });
207
- case "toggle": return /* @__PURE__ */ jsx(ToggleWidget, {
208
- fill,
209
- item,
210
- page,
211
- appearance
212
- });
213
- case "choice": return /* @__PURE__ */ jsx(ChoiceWidget, {
214
- fill,
215
- item,
216
- page,
217
- appearance
218
- });
219
- case "button": return /* @__PURE__ */ jsx(ButtonWidget, {
220
- fill,
221
- item,
222
- page,
223
- appearance
224
- });
225
- case "signature": return /* @__PURE__ */ jsx(SignatureWidget, {
226
- fill,
227
- item,
228
- page,
229
- appearance
230
- });
231
- }
232
- }
233
- /** The form plugin's field key → the engine ref (the inverse of `fieldKeyOf`). */
234
- const fieldRefOfKey = (key) => key.startsWith("obj:") ? {
235
- kind: "objectNumber",
236
- fieldObjectNumber: Number(key.slice(4))
237
- } : {
238
- kind: "fqn",
239
- name: key.slice(4)
240
- };
241
- /**
242
- * A signature field's widget: the picture (the mark drawn into it, once
243
- * there is one) with a click target on top. Unsigned → "sign here": the
244
- * field becomes the signature plugin's TARGET, so the next mark picked
245
- * from a signatures panel goes into it. Signed → `inspect`: the chrome shows
246
- * what the signature says. Without the signature plugin the widget is
247
- * picture only — the field plane has no fill control of its own here.
248
- */
249
- function SignatureWidget({ fill, item, page, appearance }) {
250
- const signature = useOptionalCapability(SignatureToken);
251
- const wrap = useIsolated();
252
- const events = useWidgetEvents(fill.key, item.ref);
253
- const b = viewBox(item.box, page);
254
- const ref = fieldRefOfKey(fill.key);
255
- const signed = useOptionalSelector(SignatureToken, (c) => c.signatureOf(ref)?.signed ?? fill.signed, fill.signed);
256
- const actionable = signature != null && (signed || !fill.disabled);
257
- return /* @__PURE__ */ jsxs("div", {
258
- ref: wrap,
259
- ...events,
260
- style: {
261
- position: "absolute",
262
- left: b.left,
263
- top: b.top,
264
- width: b.width,
265
- height: b.height
266
- },
267
- children: [/* @__PURE__ */ jsx(Picture, {
268
- page,
269
- appearance,
270
- apBox: item.apBox,
271
- frame: b
272
- }), actionable ? /* @__PURE__ */ jsx("button", {
273
- type: "button",
274
- "aria-label": fill.label,
275
- "data-signed": signed ? "" : void 0,
276
- onClick: () => signed ? signature.inspect(ref) : signature.setTarget(ref),
277
- style: {
278
- ...fillControl,
279
- padding: 0,
280
- border: 0,
281
- background: "transparent",
282
- cursor: "pointer"
283
- }
284
- }) : null]
285
- });
286
- }
287
- function ButtonWidget({ fill, item, page, appearance }) {
288
- const form = useCapability(FormToken);
289
- const wrap = useIsolated();
290
- const events = useWidgetEvents(fill.key, item.ref);
291
- const b = viewBox(item.box, page);
292
- return /* @__PURE__ */ jsx("div", {
293
- ref: wrap,
294
- ...events,
295
- style: {
296
- position: "absolute",
297
- left: b.left,
298
- top: b.top,
299
- width: b.width,
300
- height: b.height,
301
- cursor: fill.disabled ? "default" : "pointer",
302
- pointerEvents: "auto"
303
- },
304
- children: /* @__PURE__ */ jsx("button", {
305
- type: "button",
306
- "aria-label": fill.label,
307
- disabled: fill.disabled,
308
- onClick: () => {
309
- if (item.ref) form.activateWidget(fill.key, item.ref);
310
- },
311
- style: {
312
- position: "absolute",
313
- inset: 0,
314
- width: "100%",
315
- height: "100%",
316
- boxSizing: "border-box",
317
- padding: 0,
318
- border: 0,
319
- background: "transparent",
320
- cursor: "inherit",
321
- pointerEvents: fill.disabled ? "none" : "auto"
322
- },
323
- children: /* @__PURE__ */ jsx(Picture, {
324
- page,
325
- appearance,
326
- apBox: item.apBox,
327
- frame: b
328
- })
329
- })
330
- });
331
- }
332
- function TextWidget({ fill, item, page, appearance }) {
333
- const form = useCapability(FormToken);
334
- const wrap = useIsolated();
335
- const events = useWidgetEvents(fill.key, item.ref);
336
- const activate = useWidgetActivation(fill.key, item.ref);
337
- const [focused, setFocused] = useState(false);
338
- const [draft, setDraft] = useState(fill.value);
339
- const cancelled = useRef(false);
340
- useEffect(() => {
341
- if (!focused) setDraft(fill.value);
342
- }, [fill.value, focused]);
343
- const b = viewBox(item.box, page);
344
- const scale = item.box.width > 0 ? b.width / item.box.width : 1;
345
- const fontSize = item.text && item.text.fontSize > 0 ? item.text.fontSize * scale : fill.multiline ? 12 * scale : Math.max(6, b.height * .72);
346
- const editorStyle = {
347
- position: "absolute",
348
- inset: 0,
349
- width: "100%",
350
- height: "100%",
351
- boxSizing: "border-box",
352
- border: "none",
353
- outline: focused ? "2px solid rgba(66, 133, 244, 0.8)" : "none",
354
- outlineOffset: -2,
355
- padding: "0 2px",
356
- margin: 0,
357
- background: item.style.interiorColor ?? "#fff",
358
- color: item.text?.fontColor ?? "#000",
359
- fontFamily: item.text?.fontFamily ?? "Helvetica, Arial, sans-serif",
360
- fontSize,
361
- textAlign: item.text?.textAlign ?? "left",
362
- resize: "none",
363
- cursor: "text",
364
- opacity: focused ? 1 : 0,
365
- ...fill.disabled ? { pointerEvents: "none" } : {}
366
- };
367
- const editorProps = {
368
- value: draft,
369
- maxLength: fill.maxLength ?? void 0,
370
- "aria-label": fill.label,
371
- disabled: fill.disabled,
372
- onFocus: () => setFocused(true),
373
- onChange: (e) => setDraft(e.target.value),
374
- onBlur: () => {
375
- setFocused(false);
376
- if (cancelled.current) {
377
- cancelled.current = false;
378
- setDraft(fill.value);
379
- return;
380
- }
381
- if (draft !== fill.value) form.setText(fill.key, draft);
382
- },
383
- style: editorStyle
384
- };
385
- const onKeys = (e) => {
386
- if (e.key === "Escape") {
387
- cancelled.current = true;
388
- e.currentTarget.blur();
389
- }
390
- if (e.key === "Enter" && !fill.multiline) e.currentTarget.blur();
391
- };
392
- return /* @__PURE__ */ jsxs("div", {
393
- ref: wrap,
394
- ...events,
395
- onClick: activate,
396
- style: {
397
- position: "absolute",
398
- left: b.left,
399
- top: b.top,
400
- width: b.width,
401
- height: b.height,
402
- pointerEvents: "auto"
403
- },
404
- children: [/* @__PURE__ */ jsx(Picture, {
405
- page,
406
- appearance,
407
- apBox: item.apBox,
408
- frame: b,
409
- hidden: focused
410
- }), fill.multiline ? /* @__PURE__ */ jsx("textarea", {
411
- ...editorProps,
412
- onKeyDown: onKeys
413
- }) : /* @__PURE__ */ jsx("input", {
414
- ...editorProps,
415
- type: fill.password ? "password" : "text",
416
- onKeyDown: onKeys
417
- })]
418
- });
419
- }
420
- function ToggleWidget({ fill, item, page, appearance }) {
421
- const form = useCapability(FormToken);
422
- const wrap = useIsolated();
423
- const events = useWidgetEvents(fill.key, item.ref);
424
- const activate = useWidgetActivation(fill.key, item.ref);
425
- const [focused, setFocused] = useState(false);
426
- const b = viewBox(item.box, page);
427
- const press = () => {
428
- const flipped = fill.disabled ? void 0 : form.toggle(fill.key, fill.kind === "checkbox" && fill.checked ? null : fill.onState);
429
- Promise.resolve(flipped).then(activate, activate);
430
- };
431
- return /* @__PURE__ */ jsxs("div", {
432
- ref: wrap,
433
- role: fill.kind === "checkbox" ? "checkbox" : "radio",
434
- "aria-checked": fill.checked,
435
- "aria-label": fill.label,
436
- tabIndex: fill.disabled ? -1 : 0,
437
- ...events,
438
- onClick: press,
439
- onFocus: (e) => {
440
- setFocused(true);
441
- events.onFocus?.(e);
442
- },
443
- onBlur: (e) => {
444
- setFocused(false);
445
- events.onBlur?.(e);
446
- },
447
- onKeyDown: (e) => {
448
- if (e.key === " " || e.key === "Enter") {
449
- e.preventDefault();
450
- press();
451
- }
452
- },
453
- style: {
454
- position: "absolute",
455
- left: b.left,
456
- top: b.top,
457
- width: b.width,
458
- height: b.height,
459
- cursor: fill.disabled ? "default" : "pointer",
460
- pointerEvents: "auto",
461
- outline: "none"
462
- },
463
- children: [/* @__PURE__ */ jsx(Picture, {
464
- page,
465
- appearance,
466
- apBox: item.apBox,
467
- frame: b
468
- }), /* @__PURE__ */ jsx(FormFocusRing, { visible: focused })]
469
- });
470
- }
471
- function ChoiceWidget(props) {
472
- return props.fill.kind === "list" ? /* @__PURE__ */ jsx(ListBoxWidget, { ...props }) : /* @__PURE__ */ jsx(ComboBoxWidget, { ...props });
473
- }
474
- function ChoiceFrame({ fill, item, page, focused, innerRef, children }) {
475
- const events = useWidgetEvents(fill.key, item.ref);
476
- const activate = useWidgetActivation(fill.key, item.ref);
477
- const b = viewBox(item.box, page);
478
- return /* @__PURE__ */ jsxs("div", {
479
- ref: innerRef,
480
- ...events,
481
- onClick: activate,
482
- style: {
483
- position: "absolute",
484
- left: b.left,
485
- top: b.top,
486
- width: b.width,
487
- height: b.height,
488
- pointerEvents: "auto",
489
- outline: "none"
490
- },
491
- children: [children, /* @__PURE__ */ jsx(FormFocusRing, { visible: focused })]
492
- });
493
- }
494
- function ComboBoxWidget({ fill, item, page, appearance }) {
495
- const form = useCapability(FormToken);
496
- const wrap = useIsolated();
497
- const [focused, setFocused] = useState(false);
498
- const b = viewBox(item.box, page);
499
- return /* @__PURE__ */ jsxs(ChoiceFrame, {
500
- fill,
501
- item,
502
- page,
503
- focused,
504
- innerRef: wrap,
505
- children: [/* @__PURE__ */ jsx(Picture, {
506
- page,
507
- appearance,
508
- apBox: item.apBox,
509
- frame: b
510
- }), /* @__PURE__ */ jsx("select", {
511
- defaultValue: fill.selected[0] ?? "",
512
- "aria-label": fill.label,
513
- disabled: fill.disabled,
514
- onFocus: () => setFocused(true),
515
- onBlur: () => setFocused(false),
516
- onChange: (e) => {
517
- const values = Array.from(e.currentTarget.selectedOptions).map((o) => o.value);
518
- form.choose(fill.key, values);
519
- },
520
- style: {
521
- position: "absolute",
522
- inset: 0,
523
- width: "100%",
524
- height: "100%",
525
- opacity: 0,
526
- cursor: fill.disabled ? "default" : "pointer",
527
- ...fill.disabled ? { pointerEvents: "none" } : {}
528
- },
529
- children: fill.options.map((o, i) => /* @__PURE__ */ jsx("option", {
530
- value: o.value,
531
- children: o.label
532
- }, i))
533
- }, fill.selected.join("\0"))]
534
- });
535
- }
536
- function ListBoxWidget({ fill, item, page }) {
537
- const form = useCapability(FormToken);
538
- const wrap = useIsolated();
539
- const [focused, setFocused] = useState(false);
540
- const b = viewBox(item.box, page);
541
- const scale = item.box.width > 0 ? b.width / item.box.width : 1;
542
- const strokeWidth = item.style.strokeWidth * scale;
543
- const borderStyle = item.style.border.kind === "dashed" ? "dashed" : "solid";
544
- return /* @__PURE__ */ jsx(ChoiceFrame, {
545
- fill,
546
- item,
547
- page,
548
- focused,
549
- innerRef: wrap,
550
- children: /* @__PURE__ */ jsx(NativeListBox, {
551
- ariaLabel: fill.label,
552
- disabled: fill.disabled,
553
- multi: fill.multi,
554
- options: fill.options,
555
- selected: fill.selected,
556
- onFocus: () => setFocused(true),
557
- onBlur: () => setFocused(false),
558
- onSelect: (values) => form.choose(fill.key, values),
559
- style: {
560
- position: "absolute",
561
- inset: 0,
562
- width: "100%",
563
- height: "100%",
564
- boxSizing: "border-box",
565
- margin: 0,
566
- padding: 0,
567
- borderWidth: strokeWidth,
568
- borderStyle,
569
- borderColor: item.style.color,
570
- borderRadius: 0,
571
- outline: "none",
572
- background: item.style.interiorColor ?? "#fff",
573
- color: item.text?.fontColor ?? "#000",
574
- fontFamily: item.text?.fontFamily ?? "Helvetica, Arial, sans-serif",
575
- fontSize: (item.text?.fontSize || 12) * scale,
576
- textAlign: item.text?.textAlign ?? "left",
577
- cursor: fill.disabled ? "default" : "pointer",
578
- ...fill.disabled ? { pointerEvents: "none" } : {}
579
- }
580
- })
581
- });
582
- }
583
- /**
584
- * The form plugin's renderer entry, ready for
585
- * `<AnnotationLayer renderers={[formWidgetRenderer]} />`. It answers for the
586
- * PLUGIN-registered 'form-widgets' Behavior — the form plugin decides when
587
- * widgets are fill controls vs. editable annotations, never the app.
588
- */
589
- const formWidgetRenderer = {
590
- behavior: "form-widgets",
591
- component: FormWidget
592
- };
593
- const controlBase = {
594
- position: "absolute",
595
- boxSizing: "border-box",
596
- border: "1px solid rgba(56, 88, 233, 0.55)",
597
- background: "rgba(255, 255, 255, 0.92)",
598
- borderRadius: 2,
599
- font: "inherit"
600
- };
601
- const fillBox = (item, page) => viewBox(item.box, page);
602
- /** The standalone layer's event surface: positions ONE control's box and
603
- * carries the /AA DOM-event feed — always pointer-active (see
604
- * useWidgetEvents); the control inside fills it and self-gates edits.
605
- * With `activate`, a click on the box runs the widget's /A (see
606
- * useWidgetActivation — activation is a WIDGET behavior); push buttons
607
- * keep their own gated inner door and do NOT set it. */
608
- function FillEventBox({ item, page, cursor, activate, children }) {
609
- const events = useWidgetEvents(item.key, {
610
- kind: "objectNumber",
611
- pageObjectNumber: page.pon,
612
- annotObjectNumber: item.annotObjectNumber
613
- });
614
- const onActivate = useWidgetActivation(item.key, {
615
- kind: "objectNumber",
616
- pageObjectNumber: page.pon,
617
- annotObjectNumber: item.annotObjectNumber
618
- });
619
- const css = fillBox(item, page);
620
- return /* @__PURE__ */ jsx("div", {
621
- ...events,
622
- onClick: activate ? onActivate : void 0,
623
- style: {
624
- position: "absolute",
625
- ...css,
626
- pointerEvents: "auto",
627
- ...cursor ? { cursor } : {}
628
- },
629
- children
630
- });
631
- }
632
- const fillControl = {
633
- position: "absolute",
634
- inset: 0,
635
- width: "100%",
636
- height: "100%"
637
- };
638
- /** Text control: keystrokes stay LOCAL (the input is the draft store);
639
- * the engine write happens on blur or Enter. */
640
- function FillText({ item, page }) {
641
- const form = useCapability(FormToken);
642
- const [draft, setDraft] = useState(item.value);
643
- useEffect(() => setDraft(item.value), [item.value]);
644
- const css = fillBox(item, page);
645
- const fontSize = Math.max(9, Math.min(css.height * .62, 24));
646
- const commit = () => {
647
- if (draft !== item.value) form.setText(item.key, draft).catch(() => setDraft(item.value));
648
- };
649
- const shared = {
650
- ...controlBase,
651
- ...fillControl,
652
- fontSize,
653
- padding: "0 3px",
654
- ...item.comb ? { letterSpacing: css.width / Math.max(1, item.maxLength ?? 1) / 2 } : {}
655
- };
656
- const editorGate = item.disabled ? { pointerEvents: "none" } : {};
657
- return /* @__PURE__ */ jsx(FillEventBox, {
658
- item,
659
- page,
660
- activate: true,
661
- children: item.multiline ? /* @__PURE__ */ jsx("textarea", {
662
- "aria-label": item.label,
663
- value: draft,
664
- disabled: item.disabled,
665
- onChange: (e) => setDraft(e.target.value),
666
- onBlur: commit,
667
- style: {
668
- ...shared,
669
- resize: "none",
670
- ...editorGate
671
- }
672
- }) : /* @__PURE__ */ jsx("input", {
673
- "aria-label": item.label,
674
- type: item.password ? "password" : "text",
675
- value: draft,
676
- maxLength: item.maxLength ?? void 0,
677
- disabled: item.disabled,
678
- onChange: (e) => setDraft(e.target.value),
679
- onBlur: commit,
680
- onKeyDown: (e) => {
681
- if (e.key === "Enter") e.target.blur();
682
- },
683
- style: {
684
- ...shared,
685
- ...editorGate
686
- }
687
- })
688
- });
689
- }
690
- function FillToggle({ item, page }) {
691
- const form = useCapability(FormToken);
692
- const activate = useWidgetActivation(item.key, {
693
- kind: "objectNumber",
694
- pageObjectNumber: page.pon,
695
- annotObjectNumber: item.annotObjectNumber
696
- });
697
- const css = fillBox(item, page);
698
- const glyphSize = Math.min(css.width, css.height) * .72;
699
- return /* @__PURE__ */ jsx(FillEventBox, {
700
- item,
701
- page,
702
- cursor: item.disabled ? "default" : "pointer",
703
- activate: true,
704
- children: /* @__PURE__ */ jsx("button", {
705
- role: item.kind,
706
- "aria-checked": item.checked,
707
- "aria-label": item.label,
708
- disabled: item.disabled,
709
- onClick: (e) => {
710
- e.stopPropagation();
711
- Promise.resolve(form.toggle(item.key, item.kind === "checkbox" && item.checked ? null : item.onState)).then(activate, activate);
712
- },
713
- style: {
714
- ...controlBase,
715
- ...fillControl,
716
- cursor: "inherit",
717
- display: "grid",
718
- placeItems: "center",
719
- padding: 0,
720
- borderRadius: item.kind === "radio" ? "50%" : 2,
721
- fontSize: glyphSize,
722
- lineHeight: 1,
723
- color: "#1f2a44",
724
- ...item.disabled ? { pointerEvents: "none" } : {}
725
- },
726
- children: item.checked ? item.kind === "radio" ? "●" : "✓" : ""
727
- })
728
- });
729
- }
730
- function FillChoice({ item, page }) {
731
- const form = useCapability(FormToken);
732
- const css = fillBox(item, page);
733
- const controlGate = item.disabled ? { pointerEvents: "none" } : {};
734
- if (item.kind === "list") return /* @__PURE__ */ jsx(FillEventBox, {
735
- item,
736
- page,
737
- activate: true,
738
- children: /* @__PURE__ */ jsx(NativeListBox, {
739
- ariaLabel: item.label,
740
- disabled: item.disabled,
741
- multi: item.multi,
742
- options: item.options,
743
- selected: item.selected,
744
- onSelect: (values) => form.choose(item.key, values),
745
- style: {
746
- ...controlBase,
747
- ...fillControl,
748
- fontSize: Math.max(9, Math.min(css.height * .55, 18)),
749
- ...controlGate
750
- }
751
- })
752
- });
753
- return /* @__PURE__ */ jsx(FillEventBox, {
754
- item,
755
- page,
756
- activate: true,
757
- children: /* @__PURE__ */ jsxs("select", {
758
- "aria-label": item.label,
759
- disabled: item.disabled,
760
- value: item.selected[0] ?? "",
761
- onChange: (e) => void form.choose(item.key, [e.target.value]),
762
- style: {
763
- ...controlBase,
764
- ...fillControl,
765
- fontSize: Math.max(9, Math.min(css.height * .55, 18)),
766
- ...controlGate
767
- },
768
- children: [item.selected.length === 0 && /* @__PURE__ */ jsx("option", { value: "" }), item.options.map((o) => /* @__PURE__ */ jsx("option", {
769
- value: o.value,
770
- children: o.label
771
- }, o.value))]
772
- })
773
- });
774
- }
775
- function FillButton({ item, page }) {
776
- const form = useCapability(FormToken);
777
- return /* @__PURE__ */ jsx(FillEventBox, {
778
- item,
779
- page,
780
- cursor: item.disabled ? "default" : "pointer",
781
- children: /* @__PURE__ */ jsx("button", {
782
- type: "button",
783
- "aria-label": item.label,
784
- disabled: item.disabled,
785
- onClick: () => void form.activateWidget(item.key, {
786
- kind: "objectNumber",
787
- pageObjectNumber: page.pon,
788
- annotObjectNumber: item.annotObjectNumber
789
- }),
790
- style: {
791
- ...controlBase,
792
- ...fillControl,
793
- padding: 0,
794
- border: 0,
795
- background: "transparent",
796
- cursor: "inherit",
797
- pointerEvents: item.disabled ? "none" : "auto"
798
- }
799
- })
800
- });
801
- }
802
- /** The standalone layer's signature control: the same target/inspect
803
- * hand-off as {@link SignatureWidget}, over the page raster. */
804
- function FillSignature({ item, page }) {
805
- const signature = useOptionalCapability(SignatureToken);
806
- const ref = fieldRefOfKey(item.key);
807
- const signed = useOptionalSelector(SignatureToken, (c) => c.signatureOf(ref)?.signed ?? item.signed, item.signed);
808
- const actionable = signature != null && (signed || !item.disabled);
809
- return /* @__PURE__ */ jsx(FillEventBox, {
810
- item,
811
- page,
812
- cursor: actionable ? "pointer" : "default",
813
- children: actionable ? /* @__PURE__ */ jsx("button", {
814
- type: "button",
815
- "aria-label": item.label,
816
- "data-signed": signed ? "" : void 0,
817
- onClick: () => signed ? signature.inspect(ref) : signature.setTarget(ref),
818
- style: {
819
- ...fillControl,
820
- padding: 0,
821
- border: 0,
822
- background: "transparent",
823
- cursor: "inherit"
824
- }
825
- }) : null
826
- });
827
- }
828
- /**
829
- * Fill-mode form controls for one page, positioned from the form model's own
830
- * widget geometry — the ANNOTATION-LESS path (a fill-only viewer whose page
831
- * pixels come from an annotated RenderLayer raster). Active whenever the
832
- * active tool carries the 'form-fill' tag (the built-in pointer/pan tools
833
- * do); any other tool stands the controls down. Do not mount next to an
834
- * AnnotationLayer wired with `formWidgetBehaviors`.
835
- */
836
- function FormLayer() {
837
- const page = usePage();
838
- const form = useCapability(FormToken);
839
- const active = useSelector(InteractionToken, (c) => c.activeTool().enables.has("form-fill"));
840
- useEffect(() => {
841
- if (active) form.ensureGeom(page.pon);
842
- }, [
843
- active,
844
- form,
845
- page.pon
846
- ]);
847
- const items = useSelector(FormToken, (c) => c.fillItems(page.pon), shallowArray);
848
- if (!active) return null;
849
- return /* @__PURE__ */ jsx("div", {
850
- style: {
851
- position: "absolute",
852
- inset: 0
853
- },
854
- children: items.map((item) => item.control === "text" ? /* @__PURE__ */ jsx(FillText, {
855
- item,
856
- page
857
- }, `${item.key}:${item.annotObjectNumber}`) : item.control === "toggle" ? /* @__PURE__ */ jsx(FillToggle, {
858
- item,
859
- page
860
- }, `${item.key}:${item.annotObjectNumber}`) : item.control === "choice" ? /* @__PURE__ */ jsx(FillChoice, {
861
- item,
862
- page
863
- }, `${item.key}:${item.annotObjectNumber}`) : item.control === "button" ? /* @__PURE__ */ jsx(FillButton, {
864
- item,
865
- page
866
- }, `${item.key}:${item.annotObjectNumber}`) : item.control === "signature" ? /* @__PURE__ */ jsx(FillSignature, {
867
- item,
868
- page
869
- }, `${item.key}:${item.annotObjectNumber}`) : null)
870
- });
871
- }
872
- /** The form capability — values, interchange, design-mode verbs. */
873
- function useForm() {
874
- return useCapability(FormToken);
875
- }
876
- /** The reconciled form snapshot (null until the first load lands),
877
- * re-rendering on every form model change. */
878
- function useFormSnapshot() {
879
- return useSelector(FormToken, (c) => c.snapshot());
880
- }
881
- /**
882
- * The FIELD behind the currently selected widget annotation (single
883
- * selection), or null. The design-mode join: widget selection lives in the
884
- * annotation plane, field properties live here.
885
- */
886
- function useFormField() {
887
- const selected = useAnnotationSelected();
888
- const widget = selected.length === 1 && selected[0].subtype === "widget" ? selected[0] : null;
889
- const objnum = widget && widget.ref.kind === "objectNumber" ? widget.ref.annotObjectNumber : 0;
890
- return useSelector(FormToken, (c) => objnum > 0 ? c.fieldForWidget(objnum) : null);
891
- }
892
- //#endregion
893
- export { useFormSnapshot as a, useFormField as i, formWidgetRenderer as n, useForm as r, FormLayer as t };
894
-
895
- //# sourceMappingURL=form-CK3mp99m.js.map