@arbidocs/blocks 0.4.100 → 0.4.102

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 (225) hide show
  1. package/dist/agents/index.cjs +207 -207
  2. package/dist/agents/index.js +2 -2
  3. package/dist/{chunk-NJX774HB.js → chunk-5NQIBJPP.js} +3 -3
  4. package/dist/{chunk-NJX774HB.js.map → chunk-5NQIBJPP.js.map} +1 -1
  5. package/dist/chunk-6MG62I5B.cjs +272 -0
  6. package/dist/chunk-6MG62I5B.cjs.map +1 -0
  7. package/dist/{chunk-NW3LFDZL.cjs → chunk-DDYXFALG.cjs} +3 -3
  8. package/dist/{chunk-NW3LFDZL.cjs.map → chunk-DDYXFALG.cjs.map} +1 -1
  9. package/dist/chunk-EQB3WELX.js +269 -0
  10. package/dist/chunk-EQB3WELX.js.map +1 -0
  11. package/dist/{chunk-B7P73VHX.cjs → chunk-FAGQTB3D.cjs} +30 -214
  12. package/dist/chunk-FAGQTB3D.cjs.map +1 -0
  13. package/dist/{chunk-6HZNFOHW.js → chunk-G5JH2YMQ.js} +3 -3
  14. package/dist/{chunk-6HZNFOHW.js.map → chunk-G5JH2YMQ.js.map} +1 -1
  15. package/dist/{chunk-72PQ42YI.js → chunk-MYALCKDR.js} +34 -217
  16. package/dist/chunk-MYALCKDR.js.map +1 -0
  17. package/dist/{chunk-O24WPHLD.cjs → chunk-Y5XW57U4.cjs} +5 -5
  18. package/dist/{chunk-O24WPHLD.cjs.map → chunk-Y5XW57U4.cjs.map} +1 -1
  19. package/dist/{chunk-E2QWWLK5.js → chunk-YGREW5TZ.js} +3 -3
  20. package/dist/{chunk-E2QWWLK5.js.map → chunk-YGREW5TZ.js.map} +1 -1
  21. package/dist/{chunk-IE55TWIG.cjs → chunk-ZT2EBBSC.cjs} +5 -5
  22. package/dist/{chunk-IE55TWIG.cjs.map → chunk-ZT2EBBSC.cjs.map} +1 -1
  23. package/dist/connect/docx.cjs +6 -6
  24. package/dist/connect/docx.js +4 -4
  25. package/dist/connect/index.cjs +3 -3
  26. package/dist/connect/index.js +2 -2
  27. package/dist/document-tools/AdoptSignatureDialog.d.ts +25 -0
  28. package/dist/document-tools/DocumentToolButtons.d.ts +2 -0
  29. package/dist/document-tools/SignatureRequestBanner.d.ts +18 -0
  30. package/dist/document-tools/index.cjs +175 -0
  31. package/dist/document-tools/index.cjs.map +1 -1
  32. package/dist/document-tools/index.d.ts +3 -1
  33. package/dist/document-tools/index.js +168 -3
  34. package/dist/document-tools/index.js.map +1 -1
  35. package/dist/document-tools/viewer/GuidedSigningViewer.d.ts +26 -0
  36. package/dist/document-tools/viewer/SignatureFieldsOverlay.d.ts +41 -0
  37. package/dist/document-tools/viewer/SignatureRequestEditor.d.ts +26 -0
  38. package/dist/document-tools/viewer/index.cjs +983 -0
  39. package/dist/document-tools/viewer/index.cjs.map +1 -1
  40. package/dist/document-tools/viewer/index.d.ts +3 -0
  41. package/dist/document-tools/viewer/index.js +983 -5
  42. package/dist/document-tools/viewer/index.js.map +1 -1
  43. package/dist/docx/NativeDocxEditor.d.ts +1 -1
  44. package/dist/docx/definitions/DefinedTerms.d.ts +1 -12
  45. package/dist/docx/definitions/commands.d.ts +3 -27
  46. package/dist/docx/index.cjs +35 -39
  47. package/dist/docx/index.d.ts +1 -1
  48. package/dist/docx/index.js +3 -3
  49. package/dist/facts/index.cjs +1 -1
  50. package/dist/facts/index.js +1 -1
  51. package/dist/files/index.cjs +1 -1
  52. package/dist/files/index.js +1 -1
  53. package/dist/home/index.cjs +1 -1
  54. package/dist/home/index.js +1 -1
  55. package/dist/index.cjs +253 -253
  56. package/dist/index.js +3 -3
  57. package/dist/shell/index.cjs +1 -1
  58. package/dist/shell/index.js +1 -1
  59. package/dist/studio/index.cjs +1 -1
  60. package/dist/studio/index.js +1 -1
  61. package/dist/workflow-canvas/index.cjs +9 -9
  62. package/dist/workflow-canvas/index.js +2 -2
  63. package/node_modules/@arbidocs/coedit/LICENSE +21 -0
  64. package/node_modules/@arbidocs/coedit/dist/encoding.cjs +751 -0
  65. package/node_modules/@arbidocs/coedit/dist/encoding.cjs.map +1 -0
  66. package/node_modules/@arbidocs/coedit/dist/encoding.d.cts +192 -0
  67. package/node_modules/@arbidocs/coedit/dist/encoding.d.ts +192 -0
  68. package/node_modules/@arbidocs/coedit/dist/encoding.js +716 -0
  69. package/node_modules/@arbidocs/coedit/dist/encoding.js.map +1 -0
  70. package/node_modules/@arbidocs/coedit/dist/hocuspocus.cjs +1759 -0
  71. package/node_modules/@arbidocs/coedit/dist/hocuspocus.cjs.map +1 -0
  72. package/node_modules/@arbidocs/coedit/dist/hocuspocus.d.cts +39 -0
  73. package/node_modules/@arbidocs/coedit/dist/hocuspocus.d.ts +39 -0
  74. package/node_modules/@arbidocs/coedit/dist/hocuspocus.js +1736 -0
  75. package/node_modules/@arbidocs/coedit/dist/hocuspocus.js.map +1 -0
  76. package/node_modules/@arbidocs/coedit/dist/index.cjs +1692 -0
  77. package/node_modules/@arbidocs/coedit/dist/index.cjs.map +1 -0
  78. package/node_modules/@arbidocs/coedit/dist/index.d.cts +16 -0
  79. package/node_modules/@arbidocs/coedit/dist/index.d.ts +16 -0
  80. package/node_modules/@arbidocs/coedit/dist/index.js +1664 -0
  81. package/node_modules/@arbidocs/coedit/dist/index.js.map +1 -0
  82. package/node_modules/@arbidocs/coedit/dist/server.cjs +1852 -0
  83. package/node_modules/@arbidocs/coedit/dist/server.cjs.map +1 -0
  84. package/node_modules/@arbidocs/coedit/dist/server.d.cts +43 -0
  85. package/node_modules/@arbidocs/coedit/dist/server.d.ts +43 -0
  86. package/node_modules/@arbidocs/coedit/dist/server.js +1822 -0
  87. package/node_modules/@arbidocs/coedit/dist/server.js.map +1 -0
  88. package/node_modules/@arbidocs/coedit/dist/session-Cf9iu1Vt.d.cts +82 -0
  89. package/node_modules/@arbidocs/coedit/dist/session-Cf9iu1Vt.d.ts +82 -0
  90. package/node_modules/@arbidocs/coedit/dist/template.cjs +1627 -0
  91. package/node_modules/@arbidocs/coedit/dist/template.cjs.map +1 -0
  92. package/node_modules/@arbidocs/coedit/dist/template.d.cts +125 -0
  93. package/node_modules/@arbidocs/coedit/dist/template.d.ts +125 -0
  94. package/node_modules/@arbidocs/coedit/dist/template.js +1612 -0
  95. package/node_modules/@arbidocs/coedit/dist/template.js.map +1 -0
  96. package/node_modules/@arbidocs/coedit/dist/versions-DXiFQMA6.d.cts +8 -0
  97. package/node_modules/@arbidocs/coedit/dist/versions-DXiFQMA6.d.ts +8 -0
  98. package/node_modules/@arbidocs/coedit/package.json +68 -0
  99. package/node_modules/@docx-editor.dev/core/LICENSE +201 -0
  100. package/node_modules/@docx-editor.dev/core/README.md +125 -0
  101. package/node_modules/@docx-editor.dev/core/THIRD_PARTY_NOTICES.md +56 -0
  102. package/node_modules/@docx-editor.dev/core/dist/automation.cjs +1 -0
  103. package/node_modules/@docx-editor.dev/core/dist/automation.d.ts +162 -0
  104. package/node_modules/@docx-editor.dev/core/dist/automation.js +1 -0
  105. package/node_modules/@docx-editor.dev/core/dist/binding.cjs +1 -0
  106. package/node_modules/@docx-editor.dev/core/dist/binding.d.ts +164 -0
  107. package/node_modules/@docx-editor.dev/core/dist/binding.js +1 -0
  108. package/node_modules/@docx-editor.dev/core/dist/chunk-2GO5T2JU.cjs +1 -0
  109. package/node_modules/@docx-editor.dev/core/dist/chunk-2RC2EPND.js +3 -0
  110. package/node_modules/@docx-editor.dev/core/dist/chunk-4GBTELJV.cjs +28 -0
  111. package/node_modules/@docx-editor.dev/core/dist/chunk-4R3TEXMN.js +18 -0
  112. package/node_modules/@docx-editor.dev/core/dist/chunk-5CSUYANV.js +1 -0
  113. package/node_modules/@docx-editor.dev/core/dist/chunk-6APGXLBB.cjs +3 -0
  114. package/node_modules/@docx-editor.dev/core/dist/chunk-6AWEKBLB.cjs +1 -0
  115. package/node_modules/@docx-editor.dev/core/dist/chunk-6EYYL7FL.js +1 -0
  116. package/node_modules/@docx-editor.dev/core/dist/chunk-6JIJOZDW.js +1 -0
  117. package/node_modules/@docx-editor.dev/core/dist/chunk-BTQKU64Q.cjs +1 -0
  118. package/node_modules/@docx-editor.dev/core/dist/chunk-E7BQA6UP.js +2 -0
  119. package/node_modules/@docx-editor.dev/core/dist/chunk-EO4C5QJW.cjs +2 -0
  120. package/node_modules/@docx-editor.dev/core/dist/chunk-ETTO6GK3.js +1 -0
  121. package/node_modules/@docx-editor.dev/core/dist/chunk-FIJZIQXA.cjs +18 -0
  122. package/node_modules/@docx-editor.dev/core/dist/chunk-FRXAOVTB.js +28 -0
  123. package/node_modules/@docx-editor.dev/core/dist/chunk-J6BVWIDB.js +2 -0
  124. package/node_modules/@docx-editor.dev/core/dist/chunk-JGNVNT2A.cjs +2 -0
  125. package/node_modules/@docx-editor.dev/core/dist/chunk-K5U2PLDP.cjs +2 -0
  126. package/node_modules/@docx-editor.dev/core/dist/chunk-KKIJG3C6.js +2 -0
  127. package/node_modules/@docx-editor.dev/core/dist/chunk-LWDSDCMO.js +27 -0
  128. package/node_modules/@docx-editor.dev/core/dist/chunk-NBCVVZOM.cjs +1 -0
  129. package/node_modules/@docx-editor.dev/core/dist/chunk-O2AL2HSJ.cjs +1 -0
  130. package/node_modules/@docx-editor.dev/core/dist/chunk-O5INAWZQ.js +1 -0
  131. package/node_modules/@docx-editor.dev/core/dist/chunk-QMLCVPCD.cjs +1 -0
  132. package/node_modules/@docx-editor.dev/core/dist/chunk-RCHS4ZEH.cjs +27 -0
  133. package/node_modules/@docx-editor.dev/core/dist/chunk-RIYSCEFQ.js +2 -0
  134. package/node_modules/@docx-editor.dev/core/dist/chunk-S6J4O5XP.js +1 -0
  135. package/node_modules/@docx-editor.dev/core/dist/chunk-SRPILEWV.cjs +5 -0
  136. package/node_modules/@docx-editor.dev/core/dist/chunk-TSLBZ26X.js +1 -0
  137. package/node_modules/@docx-editor.dev/core/dist/chunk-UKVVUHZL.cjs +1 -0
  138. package/node_modules/@docx-editor.dev/core/dist/chunk-VDNNLG6X.js +2 -0
  139. package/node_modules/@docx-editor.dev/core/dist/chunk-VHAVHCQY.js +7 -0
  140. package/node_modules/@docx-editor.dev/core/dist/chunk-VX43VBAX.cjs +7 -0
  141. package/node_modules/@docx-editor.dev/core/dist/chunk-Z6WBFXJU.js +5 -0
  142. package/node_modules/@docx-editor.dev/core/dist/chunk-ZUHOMK52.cjs +2 -0
  143. package/node_modules/@docx-editor.dev/core/dist/collaboration/replication.cjs +1 -0
  144. package/node_modules/@docx-editor.dev/core/dist/collaboration/replication.d.ts +270 -0
  145. package/node_modules/@docx-editor.dev/core/dist/collaboration/replication.js +1 -0
  146. package/node_modules/@docx-editor.dev/core/dist/collaboration.cjs +1 -0
  147. package/node_modules/@docx-editor.dev/core/dist/collaboration.d.ts +269 -0
  148. package/node_modules/@docx-editor.dev/core/dist/collaboration.js +1 -0
  149. package/node_modules/@docx-editor.dev/core/dist/contracts/document.cjs +1 -0
  150. package/node_modules/@docx-editor.dev/core/dist/contracts/document.d.ts +290 -0
  151. package/node_modules/@docx-editor.dev/core/dist/contracts/document.js +0 -0
  152. package/node_modules/@docx-editor.dev/core/dist/contracts/editor.cjs +1 -0
  153. package/node_modules/@docx-editor.dev/core/dist/contracts/editor.d.ts +22 -0
  154. package/node_modules/@docx-editor.dev/core/dist/contracts/editor.js +1 -0
  155. package/node_modules/@docx-editor.dev/core/dist/contracts/interaction.cjs +1 -0
  156. package/node_modules/@docx-editor.dev/core/dist/contracts/interaction.d.ts +103 -0
  157. package/node_modules/@docx-editor.dev/core/dist/contracts/interaction.js +0 -0
  158. package/node_modules/@docx-editor.dev/core/dist/contracts/modules.cjs +1 -0
  159. package/node_modules/@docx-editor.dev/core/dist/contracts/modules.d.ts +143 -0
  160. package/node_modules/@docx-editor.dev/core/dist/contracts/modules.js +1 -0
  161. package/node_modules/@docx-editor.dev/core/dist/contracts/types.cjs +1 -0
  162. package/node_modules/@docx-editor.dev/core/dist/contracts/types.d.ts +11 -0
  163. package/node_modules/@docx-editor.dev/core/dist/contracts/types.js +0 -0
  164. package/node_modules/@docx-editor.dev/core/dist/custom-node-writes-cvL5rhcD.d.ts +323 -0
  165. package/node_modules/@docx-editor.dev/core/dist/dist-PKZR6RSH.js +2 -0
  166. package/node_modules/@docx-editor.dev/core/dist/document-protection-BAGVGqaP.d.ts +20 -0
  167. package/node_modules/@docx-editor.dev/core/dist/editor-Ci7IZGmG.d.ts +2448 -0
  168. package/node_modules/@docx-editor.dev/core/dist/editor-scope-OHPwVQ5l.d.ts +84 -0
  169. package/node_modules/@docx-editor.dev/core/dist/editor.cjs +1 -0
  170. package/node_modules/@docx-editor.dev/core/dist/editor.css +15 -0
  171. package/node_modules/@docx-editor.dev/core/dist/editor.d.ts +1394 -0
  172. package/node_modules/@docx-editor.dev/core/dist/editor.js +1 -0
  173. package/node_modules/@docx-editor.dev/core/dist/export.cjs +2 -0
  174. package/node_modules/@docx-editor.dev/core/dist/export.d.ts +391 -0
  175. package/node_modules/@docx-editor.dev/core/dist/export.js +2 -0
  176. package/node_modules/@docx-editor.dev/core/dist/failure-NS2lsya4.d.ts +115 -0
  177. package/node_modules/@docx-editor.dev/core/dist/font-resolver-BVQB14qT.d.ts +256 -0
  178. package/node_modules/@docx-editor.dev/core/dist/harfbuzz.wasm +0 -0
  179. package/node_modules/@docx-editor.dev/core/dist/headless-document-view-qH331moE.d.ts +143 -0
  180. package/node_modules/@docx-editor.dev/core/dist/image-resources-BN-hUgCn.d.ts +211 -0
  181. package/node_modules/@docx-editor.dev/core/dist/index-Bsg7oIKP.d.ts +3869 -0
  182. package/node_modules/@docx-editor.dev/core/dist/index.cjs +1 -0
  183. package/node_modules/@docx-editor.dev/core/dist/index.d.ts +53 -0
  184. package/node_modules/@docx-editor.dev/core/dist/index.js +1 -0
  185. package/node_modules/@docx-editor.dev/core/dist/layout-shaping-BEyuiQOk.d.ts +246 -0
  186. package/node_modules/@docx-editor.dev/core/dist/layout.cjs +1 -0
  187. package/node_modules/@docx-editor.dev/core/dist/layout.d.ts +3151 -0
  188. package/node_modules/@docx-editor.dev/core/dist/layout.js +1 -0
  189. package/node_modules/@docx-editor.dev/core/dist/node-module-shim-TTKTT66I.js +1 -0
  190. package/node_modules/@docx-editor.dev/core/dist/note-properties-4Y9o6Gyk.d.ts +68 -0
  191. package/node_modules/@docx-editor.dev/core/dist/omml-equation-CuzBL5DD.d.ts +85 -0
  192. package/node_modules/@docx-editor.dev/core/dist/output.cjs +1 -0
  193. package/node_modules/@docx-editor.dev/core/dist/output.d.ts +97 -0
  194. package/node_modules/@docx-editor.dev/core/dist/output.js +1 -0
  195. package/node_modules/@docx-editor.dev/core/dist/protocol-Bqk4Izjc.d.ts +1651 -0
  196. package/node_modules/@docx-editor.dev/core/dist/review-pane-D9jm8DcY.d.ts +128 -0
  197. package/node_modules/@docx-editor.dev/core/dist/review-paragraph-order-DT-n6ouC.d.ts +85 -0
  198. package/node_modules/@docx-editor.dev/core/dist/revision-projection-DZ4kKVev.d.ts +242 -0
  199. package/node_modules/@docx-editor.dev/core/dist/semantic-cell-selection-D9D1KSXq.d.ts +464 -0
  200. package/node_modules/@docx-editor.dev/core/dist/semantic-interaction-CIC-PooQ.d.ts +135 -0
  201. package/node_modules/@docx-editor.dev/core/dist/semantic-paint-BME37OMv.d.ts +326 -0
  202. package/node_modules/@docx-editor.dev/core/dist/semantic-record-queries-CBlZqZNa.d.ts +177 -0
  203. package/node_modules/@docx-editor.dev/core/dist/semantic-records-4B3WwFAi.d.ts +3532 -0
  204. package/node_modules/@docx-editor.dev/core/dist/store.cjs +1 -0
  205. package/node_modules/@docx-editor.dev/core/dist/store.d.ts +2706 -0
  206. package/node_modules/@docx-editor.dev/core/dist/store.js +1 -0
  207. package/node_modules/@docx-editor.dev/core/dist/tree-package-fragment-BeeKxDw8.d.ts +1201 -0
  208. package/node_modules/@docx-editor.dev/core/dist/tree-session-contract-CVbmlMlq.d.ts +664 -0
  209. package/node_modules/@docx-editor.dev/core/dist/types-barrel-D3xCgQX6.d.ts +4269 -0
  210. package/node_modules/@docx-editor.dev/core/licenses/HarfBuzz-COPYING.txt +42 -0
  211. package/node_modules/@docx-editor.dev/core/package.json +140 -0
  212. package/node_modules/@docx-editor.dev/react/LICENSE +201 -0
  213. package/node_modules/@docx-editor.dev/react/README.md +141 -0
  214. package/node_modules/@docx-editor.dev/react/THIRD_PARTY_NOTICES.md +18 -0
  215. package/node_modules/@docx-editor.dev/react/dist/index.d.mts +4928 -0
  216. package/node_modules/@docx-editor.dev/react/dist/index.d.ts +4928 -0
  217. package/node_modules/@docx-editor.dev/react/dist/index.js +4 -0
  218. package/node_modules/@docx-editor.dev/react/dist/index.mjs +4 -0
  219. package/node_modules/@docx-editor.dev/react/package.json +74 -0
  220. package/node_modules/@docx-editor.dev/react/src/styles/editor.css +6 -0
  221. package/node_modules/@docx-editor.dev/react/src/styles/zIndex.ts +28 -0
  222. package/package.json +26 -15
  223. package/src/docx/README.md +2 -3
  224. package/dist/chunk-72PQ42YI.js.map +0 -1
  225. package/dist/chunk-B7P73VHX.cjs.map +0 -1
@@ -1,6 +1,8 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
+ var chunk6MG62I5B_cjs = require('../../chunk-6MG62I5B.cjs');
5
+ var chunkULWRNGGE_cjs = require('../../chunk-ULWRNGGE.cjs');
4
6
  require('../../chunk-DES3K4SD.cjs');
5
7
  var react = require('react');
6
8
  var annotations = require('@arbidocs/react/annotations');
@@ -264,10 +266,991 @@ function SignaturePlacementViewer({
264
266
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(PdfViewer, { ...viewerProps, file, renderPageOverlay }) })
265
267
  ] });
266
268
  }
269
+ var SIGNER_COLORS = ["#1c7ed6", "#e8590c", "#2f9e44", "#9c36b5", "#c2255c", "#0c8599"];
270
+ var MIN_DRAG = 0.01;
271
+ var clamp = (v, lo, hi) => Math.min(hi, Math.max(lo, v));
272
+ var round = (v) => Math.round(v * 1e4) / 1e4;
273
+ function fit(box) {
274
+ const width = clamp(box.width, 0.02, 1);
275
+ const height = clamp(box.height, 0.015, 1);
276
+ return {
277
+ x: round(clamp(box.x, 0, 1 - width)),
278
+ y: round(clamp(box.y, 0, 1 - height)),
279
+ width: round(width),
280
+ height: round(height)
281
+ };
282
+ }
283
+ function SignatureFieldsOverlay({
284
+ page,
285
+ fields,
286
+ colorOf,
287
+ labelOf = (f) => documentTools.FIELD_TYPE_LABELS[f.type],
288
+ editable = false,
289
+ placing = null,
290
+ selectedId = null,
291
+ onSelect,
292
+ onCreate,
293
+ onChange,
294
+ onRemove,
295
+ activeId = null,
296
+ onActivate,
297
+ renderContent
298
+ }) {
299
+ const ref = react.useRef(null);
300
+ const [drag, setDrag] = react.useState(null);
301
+ const [preview, setPreview] = react.useState(null);
302
+ const onPage = fields.filter((f) => f.page === page);
303
+ const point = (e) => {
304
+ const r = ref.current.getBoundingClientRect();
305
+ return { x: (e.clientX - r.left) / r.width, y: (e.clientY - r.top) / r.height };
306
+ };
307
+ const startCreate = (e) => {
308
+ if (!editable || e.target !== e.currentTarget || e.button !== 0) return;
309
+ if (!placing) {
310
+ onSelect?.(null);
311
+ return;
312
+ }
313
+ const p = point(e);
314
+ e.currentTarget.setPointerCapture?.(e.pointerId);
315
+ setDrag({ kind: "create", startX: p.x, startY: p.y, box: { ...p, width: 0, height: 0 } });
316
+ };
317
+ const startField = (e, field, kind) => {
318
+ if (!editable || e.button !== 0) return;
319
+ e.stopPropagation();
320
+ onSelect?.(field.id);
321
+ const p = point(e);
322
+ ref.current?.setPointerCapture?.(e.pointerId);
323
+ setDrag({
324
+ kind,
325
+ id: field.id,
326
+ startX: p.x,
327
+ startY: p.y,
328
+ origin: { x: field.x, y: field.y, width: field.width, height: field.height }
329
+ });
330
+ };
331
+ const onMove = (e) => {
332
+ if (!drag) return;
333
+ const p = point(e);
334
+ const dx = p.x - drag.startX;
335
+ const dy = p.y - drag.startY;
336
+ if (drag.kind === "create") {
337
+ setPreview({
338
+ x: Math.min(p.x, drag.startX),
339
+ y: Math.min(p.y, drag.startY),
340
+ width: Math.abs(dx),
341
+ height: Math.abs(dy)
342
+ });
343
+ } else if (drag.kind === "move") {
344
+ setPreview(fit({ ...drag.origin, x: drag.origin.x + dx, y: drag.origin.y + dy }));
345
+ } else {
346
+ setPreview(
347
+ fit({ ...drag.origin, width: drag.origin.width + dx, height: drag.origin.height + dy })
348
+ );
349
+ }
350
+ };
351
+ const onUp = (e) => {
352
+ if (!drag) return;
353
+ const p = point(e);
354
+ if (drag.kind === "create" && placing) {
355
+ const drawn = Math.abs(p.x - drag.startX) > MIN_DRAG && Math.abs(p.y - drag.startY) > MIN_DRAG;
356
+ const size = documentTools.DEFAULT_FIELD_SIZE[placing];
357
+ onCreate?.(
358
+ fit(
359
+ drawn && preview ? preview : { x: drag.startX - size.width / 2, y: drag.startY - size.height / 2, ...size }
360
+ )
361
+ );
362
+ } else if (drag.kind !== "create" && preview) {
363
+ onChange?.(drag.id, preview);
364
+ }
365
+ setDrag(null);
366
+ setPreview(null);
367
+ };
368
+ return /* @__PURE__ */ jsxRuntime.jsxs(
369
+ "div",
370
+ {
371
+ ref,
372
+ className: ui.cn(
373
+ "absolute inset-0",
374
+ editable && placing && "cursor-crosshair",
375
+ !editable && "pointer-events-none"
376
+ ),
377
+ onPointerDown: startCreate,
378
+ onPointerMove: onMove,
379
+ onPointerUp: onUp,
380
+ onPointerCancel: () => {
381
+ setDrag(null);
382
+ setPreview(null);
383
+ },
384
+ "data-testid": `signature-fields-page-${page}`,
385
+ children: [
386
+ onPage.map((field) => {
387
+ const dragging = drag && drag.kind !== "create" && drag.id === field.id && preview;
388
+ const box = dragging ? preview : field;
389
+ const color = colorOf(field.signer);
390
+ const selected = editable && selectedId === field.id;
391
+ const active = !editable && activeId === field.id;
392
+ const content = renderContent?.(field);
393
+ return /* @__PURE__ */ jsxRuntime.jsxs(
394
+ "div",
395
+ {
396
+ role: editable ? void 0 : "button",
397
+ tabIndex: editable ? void 0 : 0,
398
+ "aria-label": editable ? void 0 : `${labelOf(field)}${content ? " (done)" : ""}`,
399
+ className: ui.cn(
400
+ "pointer-events-auto absolute flex items-center justify-center overflow-visible rounded-sm border-2 text-[11px] font-medium select-none",
401
+ editable ? "cursor-move" : "cursor-pointer",
402
+ active && "ring-4 ring-offset-1 motion-safe:animate-pulse",
403
+ selected && "ring-2 ring-offset-1"
404
+ ),
405
+ style: {
406
+ left: `${box.x * 100}%`,
407
+ top: `${box.y * 100}%`,
408
+ width: `${box.width * 100}%`,
409
+ height: `${box.height * 100}%`,
410
+ borderColor: color,
411
+ borderStyle: content ? "solid" : "dashed",
412
+ backgroundColor: content ? "transparent" : `${color}22`,
413
+ color,
414
+ ["--tw-ring-color"]: color
415
+ },
416
+ onPointerDown: (e) => startField(e, field, "move"),
417
+ onClick: () => !editable && onActivate?.(field.id),
418
+ onKeyDown: (e) => {
419
+ if (!editable && (e.key === "Enter" || e.key === " ")) {
420
+ e.preventDefault();
421
+ onActivate?.(field.id);
422
+ }
423
+ if (editable && selected && (e.key === "Delete" || e.key === "Backspace")) {
424
+ onRemove?.(field.id);
425
+ }
426
+ },
427
+ "data-testid": `signature-field-${field.id}`,
428
+ "data-field-type": field.type,
429
+ "data-field-done": content ? "true" : void 0,
430
+ children: [
431
+ content ?? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "truncate px-1", children: [
432
+ labelOf(field),
433
+ field.required ? "" : " (optional)"
434
+ ] }),
435
+ selected && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
436
+ /* @__PURE__ */ jsxRuntime.jsx(
437
+ "button",
438
+ {
439
+ type: "button",
440
+ "aria-label": "Remove field",
441
+ className: "absolute -top-2.5 -right-2.5 flex size-5 items-center justify-center rounded-full border bg-background text-foreground shadow",
442
+ onPointerDown: (e) => e.stopPropagation(),
443
+ onClick: () => onRemove?.(field.id),
444
+ "data-testid": "signature-field-remove",
445
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-3" })
446
+ }
447
+ ),
448
+ /* @__PURE__ */ jsxRuntime.jsx(
449
+ "span",
450
+ {
451
+ "aria-hidden": true,
452
+ className: "absolute -right-1.5 -bottom-1.5 size-3 cursor-nwse-resize rounded-sm border bg-background",
453
+ style: { borderColor: color },
454
+ onPointerDown: (e) => startField(e, field, "resize"),
455
+ "data-testid": "signature-field-resize"
456
+ }
457
+ )
458
+ ] })
459
+ ]
460
+ },
461
+ field.id
462
+ );
463
+ }),
464
+ drag?.kind === "create" && preview && /* @__PURE__ */ jsxRuntime.jsx(
465
+ "div",
466
+ {
467
+ className: "pointer-events-none absolute rounded-sm border-2 border-dashed",
468
+ style: {
469
+ left: `${preview.x * 100}%`,
470
+ top: `${preview.y * 100}%`,
471
+ width: `${preview.width * 100}%`,
472
+ height: `${preview.height * 100}%`,
473
+ borderColor: "#868e96"
474
+ }
475
+ }
476
+ )
477
+ ]
478
+ }
479
+ );
480
+ }
481
+ var INK = "#1c7ed6";
482
+ function signingDate(date = /* @__PURE__ */ new Date()) {
483
+ return `${date.getDate()} ${date.toLocaleString("en-GB", { month: "long" })} ${date.getFullYear()}`;
484
+ }
485
+ function GuidedSigningViewer({
486
+ file,
487
+ request,
488
+ signer,
489
+ onClose,
490
+ onSigned,
491
+ viewer: PdfViewer = viewers.PdfViewer,
492
+ ...viewerProps
493
+ }) {
494
+ const { user, notify } = documentTools.useDocumentTools();
495
+ const sign = documentTools.useSignSignatureRequest();
496
+ const decline = documentTools.useDeclineSignatureRequest();
497
+ const mine = react.useMemo(() => documentTools.fieldsInSigningOrder(request.fields, signer), [request.fields, signer]);
498
+ const [mark, setMark] = react.useState(null);
499
+ const [applied, setApplied] = react.useState(/* @__PURE__ */ new Set());
500
+ const [index, setIndex] = react.useState(-1);
501
+ const [page, setPage] = react.useState(1);
502
+ const [trigger, setTrigger] = react.useState(0);
503
+ const [adoptFor, setAdoptFor] = react.useState(null);
504
+ const [finishing, setFinishing] = react.useState(false);
505
+ const [password, setPassword] = react.useState("");
506
+ const [error, setError] = react.useState(null);
507
+ const [declining, setDeclining] = react.useState(false);
508
+ const [declineReason, setDeclineReason] = react.useState("");
509
+ const scrollTimer = react.useRef(void 0);
510
+ const required = mine.filter((f) => f.required);
511
+ const done = mine.filter((f) => applied.has(f.id)).length;
512
+ const ready = required.every((f) => applied.has(f.id));
513
+ const current = index >= 0 ? mine[index] : void 0;
514
+ react.useEffect(() => () => window.clearTimeout(scrollTimer.current), []);
515
+ const goTo = react.useCallback(
516
+ (i) => {
517
+ const field = mine[i];
518
+ if (!field) return;
519
+ setIndex(i);
520
+ setPage(field.page + 1);
521
+ setTrigger((t) => t + 1);
522
+ window.clearTimeout(scrollTimer.current);
523
+ scrollTimer.current = window.setTimeout(() => {
524
+ document.querySelector(`[data-testid="signature-field-${field.id}"]`)?.scrollIntoView({ block: "center", behavior: "smooth" });
525
+ }, 300);
526
+ },
527
+ [mine]
528
+ );
529
+ const nextOpen = (from, filled) => {
530
+ for (let k = 1; k <= mine.length; k++) {
531
+ const i = (from + k) % mine.length;
532
+ if (!filled.has(mine[i].id)) return i;
533
+ }
534
+ return -1;
535
+ };
536
+ const apply = (field, base = applied) => {
537
+ const next = new Set(base);
538
+ next.add(field.id);
539
+ setApplied(next);
540
+ const i = nextOpen(mine.indexOf(field), next);
541
+ if (i >= 0) goTo(i);
542
+ else setIndex(mine.indexOf(field));
543
+ };
544
+ const activate = (id) => {
545
+ const field = mine.find((f) => f.id === id);
546
+ if (!field) return;
547
+ setIndex(mine.indexOf(field));
548
+ if (applied.has(id)) {
549
+ setApplied((a) => {
550
+ const next = new Set(a);
551
+ next.delete(id);
552
+ return next;
553
+ });
554
+ return;
555
+ }
556
+ if (!mark) {
557
+ setAdoptFor(field);
558
+ return;
559
+ }
560
+ apply(field);
561
+ };
562
+ const onAdopt = (adopted) => {
563
+ setMark(adopted);
564
+ const field = adoptFor;
565
+ setAdoptFor(null);
566
+ const filled = new Set(applied);
567
+ for (const f of mine)
568
+ if (f.required && (f.type === "date" || f.type === "name")) filled.add(f.id);
569
+ if (field) apply(field, filled);
570
+ else setApplied(filled);
571
+ };
572
+ const renderContent = react.useCallback(
573
+ (field) => {
574
+ if (!applied.has(field.id) || !mark) return null;
575
+ const { adopted, signatureUrl } = mark;
576
+ if (field.type === "signature" && signatureUrl) {
577
+ return /* @__PURE__ */ jsxRuntime.jsx("img", { src: signatureUrl, alt: "Your signature", className: "h-full w-full object-contain" });
578
+ }
579
+ const text = field.type === "signature" ? adopted.name : field.type === "initials" ? adopted.initials : field.type === "date" ? signingDate() : adopted.name;
580
+ const typed = documentTools.MARK_FIELD_TYPES.includes(field.type);
581
+ return /* @__PURE__ */ jsxRuntime.jsx(
582
+ "span",
583
+ {
584
+ className: "flex h-full w-full items-center px-1 whitespace-nowrap [container-type:size]",
585
+ style: typed ? chunk6MG62I5B_cjs.TYPED_SIGNATURE_STYLE : { color: "#1a1a26" },
586
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: typed ? "70cqh" : "62cqh", lineHeight: 1 }, children: text })
587
+ }
588
+ );
589
+ },
590
+ [applied, mark]
591
+ );
592
+ const renderPageOverlay = react.useCallback(
593
+ ({ pageNumber }) => /* @__PURE__ */ jsxRuntime.jsx(
594
+ SignatureFieldsOverlay,
595
+ {
596
+ page: pageNumber - 1,
597
+ fields: mine,
598
+ colorOf: () => INK,
599
+ labelOf: (f) => documentTools.MARK_FIELD_TYPES.includes(f.type) ? `Sign: ${documentTools.FIELD_TYPE_LABELS[f.type]}` : documentTools.FIELD_TYPE_LABELS[f.type],
600
+ activeId: current?.id ?? null,
601
+ onActivate: activate,
602
+ renderContent
603
+ }
604
+ ),
605
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- activate reads the latest state
606
+ [mine, current?.id, renderContent, mark, applied]
607
+ );
608
+ const submit = async (e) => {
609
+ e.preventDefault();
610
+ if (!mark || !user?.email) return;
611
+ setError(null);
612
+ try {
613
+ const result = await sign.mutateAsync({
614
+ request,
615
+ pdfBlob: file,
616
+ email: user.email,
617
+ password,
618
+ adopted: mark.adopted,
619
+ fields: mine.filter((f) => applied.has(f.id)).map((f) => f.id)
620
+ });
621
+ setPassword("");
622
+ setFinishing(false);
623
+ notify(
624
+ result.completed ? `Signed. Everyone has signed: the signed copy is version ${result.signed_version}.` : "Signed. The others are still to sign; you will see the signed copy when they have.",
625
+ "success"
626
+ );
627
+ onSigned?.(result);
628
+ } catch (err) {
629
+ setError(err instanceof Error ? err.message : "Signing failed");
630
+ if (err instanceof documentTools.SigningError && err.reason === "stale") setFinishing(false);
631
+ }
632
+ };
633
+ const onDecline = async (e) => {
634
+ e.preventDefault();
635
+ try {
636
+ await decline.mutateAsync({ requestId: request.external_id, reason: declineReason.trim() });
637
+ setDeclining(false);
638
+ notify("You declined to sign. The sender has been told.", "info");
639
+ onClose();
640
+ } catch (err) {
641
+ notify(err instanceof Error ? err.message : "Could not decline", "error");
642
+ }
643
+ };
644
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full min-h-0 flex-col", "data-testid": "guided-signing-viewer", children: [
645
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 border-b border-border px-3 py-2 text-sm", children: [
646
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
647
+ index < 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "mr-auto", "data-testid": "guided-signing-intro", children: [
648
+ "You are asked to complete ",
649
+ mine.length,
650
+ " field",
651
+ mine.length === 1 ? "" : "s",
652
+ ".",
653
+ request.message ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
654
+ " \u201C",
655
+ request.message,
656
+ "\u201D"
657
+ ] }) : null
658
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "mr-auto font-medium", "data-testid": "guided-signing-position", children: [
659
+ "Field ",
660
+ index + 1,
661
+ " of ",
662
+ mine.length,
663
+ ": ",
664
+ current ? documentTools.FIELD_TYPE_LABELS[current.type] : "",
665
+ current && !current.required ? " (optional)" : "",
666
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-2 font-normal text-muted-foreground", children: [
667
+ "Page ",
668
+ current ? current.page + 1 : ""
669
+ ] })
670
+ ] }),
671
+ /* @__PURE__ */ jsxRuntime.jsx(
672
+ ui.Button,
673
+ {
674
+ type: "button",
675
+ variant: "ghost",
676
+ size: "sm",
677
+ onClick: () => setDeclining(true),
678
+ "data-testid": "guided-signing-decline",
679
+ children: "Decline"
680
+ }
681
+ ),
682
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { type: "button", variant: "outline", size: "sm", onClick: onClose, children: "Close" }),
683
+ index < 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
684
+ ui.Button,
685
+ {
686
+ type: "button",
687
+ size: "sm",
688
+ onClick: () => goTo(0),
689
+ "data-testid": "guided-signing-start",
690
+ children: [
691
+ "Start",
692
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRight, { className: "ml-1 size-4", "aria-hidden": true })
693
+ ]
694
+ }
695
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
696
+ /* @__PURE__ */ jsxRuntime.jsx(
697
+ ui.Button,
698
+ {
699
+ type: "button",
700
+ variant: "outline",
701
+ size: "sm",
702
+ onClick: () => goTo(Math.max(0, index - 1)),
703
+ disabled: index === 0,
704
+ "aria-label": "Previous field",
705
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { className: "size-4", "aria-hidden": true })
706
+ }
707
+ ),
708
+ /* @__PURE__ */ jsxRuntime.jsx(
709
+ ui.Button,
710
+ {
711
+ type: "button",
712
+ variant: "outline",
713
+ size: "sm",
714
+ onClick: () => goTo(Math.min(mine.length - 1, index + 1)),
715
+ disabled: index >= mine.length - 1,
716
+ "aria-label": "Next field",
717
+ "data-testid": "guided-signing-next",
718
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRight, { className: "size-4", "aria-hidden": true })
719
+ }
720
+ ),
721
+ current && !applied.has(current.id) && /* @__PURE__ */ jsxRuntime.jsx(
722
+ ui.Button,
723
+ {
724
+ type: "button",
725
+ size: "sm",
726
+ onClick: () => activate(current.id),
727
+ "data-testid": "guided-signing-apply",
728
+ children: documentTools.MARK_FIELD_TYPES.includes(current.type) ? "Sign here" : "Fill in"
729
+ }
730
+ )
731
+ ] }),
732
+ /* @__PURE__ */ jsxRuntime.jsxs(
733
+ ui.Button,
734
+ {
735
+ type: "button",
736
+ size: "sm",
737
+ variant: ready ? "default" : "outline",
738
+ disabled: !ready || !mark,
739
+ onClick: () => setFinishing(true),
740
+ "data-testid": "guided-signing-finish",
741
+ children: [
742
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "mr-1 size-4", "aria-hidden": true }),
743
+ "Finish"
744
+ ]
745
+ }
746
+ )
747
+ ] }),
748
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
749
+ /* @__PURE__ */ jsxRuntime.jsx(
750
+ ui.Progress,
751
+ {
752
+ value: mine.length ? done / mine.length * 100 : 0,
753
+ className: "h-1.5 max-w-xs"
754
+ }
755
+ ),
756
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", "data-testid": "guided-signing-progress", children: [
757
+ done,
758
+ " of ",
759
+ mine.length,
760
+ " done"
761
+ ] })
762
+ ] })
763
+ ] }),
764
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
765
+ PdfViewer,
766
+ {
767
+ ...viewerProps,
768
+ file,
769
+ currentPage: page,
770
+ scrollTrigger: trigger,
771
+ renderPageOverlay
772
+ }
773
+ ) }),
774
+ /* @__PURE__ */ jsxRuntime.jsx(
775
+ chunk6MG62I5B_cjs.AdoptSignatureDialog,
776
+ {
777
+ open: !!adoptFor,
778
+ onOpenChange: (open) => !open && setAdoptFor(null),
779
+ defaultName: user?.name ?? "",
780
+ onAdopt
781
+ }
782
+ ),
783
+ /* @__PURE__ */ jsxRuntime.jsx(
784
+ chunkULWRNGGE_cjs.ModalScaffold,
785
+ {
786
+ open: declining,
787
+ onOpenChange: (open) => !decline.isPending && setDeclining(open),
788
+ title: "Decline to sign",
789
+ description: "The request ends for everyone and the sender is told. The document is unchanged.",
790
+ showDescription: true,
791
+ testId: "guided-signing-decline-dialog",
792
+ children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: onDecline, children: [
793
+ /* @__PURE__ */ jsxRuntime.jsx(chunkULWRNGGE_cjs.ModalScaffold.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
794
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "guided-decline-reason", children: "Reason (optional)" }),
795
+ /* @__PURE__ */ jsxRuntime.jsx(
796
+ ui.Input,
797
+ {
798
+ id: "guided-decline-reason",
799
+ value: declineReason,
800
+ maxLength: 1e3,
801
+ onChange: (e) => setDeclineReason(e.target.value)
802
+ }
803
+ )
804
+ ] }) }),
805
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkULWRNGGE_cjs.ModalScaffold.Footer, { children: [
806
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { type: "button", variant: "outline", onClick: () => setDeclining(false), children: "Cancel" }),
807
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { type: "submit", variant: "destructive", disabled: decline.isPending, children: "Decline" })
808
+ ] })
809
+ ] })
810
+ }
811
+ ),
812
+ /* @__PURE__ */ jsxRuntime.jsx(
813
+ chunkULWRNGGE_cjs.ModalScaffold,
814
+ {
815
+ open: finishing,
816
+ onOpenChange: (open) => !sign.isPending && setFinishing(open),
817
+ title: "Sign the document",
818
+ description: "Confirm with your password. Your signature is applied to every field you completed.",
819
+ showDescription: true,
820
+ testId: "guided-signing-confirm",
821
+ children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: submit, children: [
822
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkULWRNGGE_cjs.ModalScaffold.Body, { children: [
823
+ mark && /* @__PURE__ */ jsxRuntime.jsx("blockquote", { className: "border-l-2 border-border pl-3 text-sm text-muted-foreground", children: documentTools.intentText({ name: mark.adopted.name }) }),
824
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
825
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "guided-sign-password", children: "Password" }),
826
+ /* @__PURE__ */ jsxRuntime.jsx(
827
+ ui.Input,
828
+ {
829
+ id: "guided-sign-password",
830
+ type: "password",
831
+ autoComplete: "current-password",
832
+ value: password,
833
+ onChange: (e) => setPassword(e.target.value),
834
+ "data-testid": "guided-signing-password",
835
+ required: true
836
+ }
837
+ )
838
+ ] }),
839
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-red-text", role: "alert", "data-testid": "guided-signing-error", children: error })
840
+ ] }),
841
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkULWRNGGE_cjs.ModalScaffold.Footer, { children: [
842
+ /* @__PURE__ */ jsxRuntime.jsx(
843
+ ui.Button,
844
+ {
845
+ type: "button",
846
+ variant: "outline",
847
+ onClick: () => setFinishing(false),
848
+ disabled: sign.isPending,
849
+ children: "Cancel"
850
+ }
851
+ ),
852
+ /* @__PURE__ */ jsxRuntime.jsx(
853
+ ui.Button,
854
+ {
855
+ type: "submit",
856
+ disabled: sign.isPending || !password,
857
+ "data-testid": "guided-signing-submit",
858
+ children: sign.isPending ? "Signing\u2026" : "Sign"
859
+ }
860
+ )
861
+ ] })
862
+ ] })
863
+ }
864
+ )
865
+ ] });
866
+ }
867
+ var selectClass = "h-8 rounded-md border border-input bg-background px-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring";
868
+ function SignatureRequestEditor({
869
+ file,
870
+ documentId,
871
+ version,
872
+ draft,
873
+ onCancel,
874
+ onSaved,
875
+ viewer: PdfViewer = viewers.PdfViewer,
876
+ ...viewerProps
877
+ }) {
878
+ const { client, notify } = documentTools.useDocumentTools();
879
+ const candidates = documentTools.useSignerCandidates();
880
+ const save = documentTools.useSaveSignatureRequest();
881
+ const [fields, setFields] = react.useState(() => draft?.fields ?? []);
882
+ const [signers, setSigners] = react.useState(() => [
883
+ ...new Set((draft?.fields ?? []).map((f) => f.signer))
884
+ ]);
885
+ const [current, setCurrent] = react.useState(signers[0] ?? null);
886
+ const [placing, setPlacing] = react.useState(null);
887
+ const [selectedId, setSelectedId] = react.useState(null);
888
+ const [message, setMessage] = react.useState(draft?.message ?? "");
889
+ const [suggestions, setSuggestions] = react.useState(null);
890
+ const [assign, setAssign] = react.useState({});
891
+ const [finding, setFinding] = react.useState(false);
892
+ const [error, setError] = react.useState(null);
893
+ const people = react.useMemo(() => candidates.data ?? [], [candidates.data]);
894
+ const nameOf = react.useCallback(
895
+ (ext) => people.find((p) => p.externalId === ext)?.name ?? ext,
896
+ [people]
897
+ );
898
+ const colorOf = react.useCallback(
899
+ (ext) => {
900
+ const i = signers.indexOf(ext);
901
+ return SIGNER_COLORS[(i < 0 ? 0 : i) % SIGNER_COLORS.length];
902
+ },
903
+ [signers]
904
+ );
905
+ const selected = fields.find((f) => f.id === selectedId) ?? null;
906
+ const blocker = signers.length === 0 ? "Add a signer." : documentTools.sendBlocker(fields);
907
+ const addSigner = (ext) => {
908
+ if (!ext || signers.includes(ext)) return;
909
+ setSigners((s) => [...s, ext]);
910
+ setCurrent(ext);
911
+ setPlacing((p) => p ?? "signature");
912
+ };
913
+ const removeSigner = (ext) => {
914
+ setSigners((s) => s.filter((x) => x !== ext));
915
+ setFields((fs) => fs.filter((f) => f.signer !== ext));
916
+ if (current === ext) setCurrent(signers.find((x) => x !== ext) ?? null);
917
+ };
918
+ const updateField = (id, patch) => setFields((fs) => fs.map((f) => f.id === id ? { ...f, ...patch } : f));
919
+ const findBlocks = async () => {
920
+ setFinding(true);
921
+ setError(null);
922
+ try {
923
+ const found = await documentTools.suggestSignatureFields(client, documentId, version);
924
+ setSuggestions(found);
925
+ const groups2 = [...new Set(found.map((s) => s.group))];
926
+ setAssign(Object.fromEntries(groups2.map((g, i) => [g, signers[i]])));
927
+ if (found.length === 0) notify("No signature blocks were found in this document.", "info");
928
+ } catch (err) {
929
+ setError(err instanceof Error ? err.message : "Signature blocks could not be read");
930
+ } finally {
931
+ setFinding(false);
932
+ }
933
+ };
934
+ const applySuggestions = () => {
935
+ if (!suggestions) return;
936
+ const added = documentTools.fieldsFromSuggestions(suggestions, assign);
937
+ setFields((fs) => [...fs, ...added]);
938
+ const assigned = [...new Set(added.map((f) => f.signer))];
939
+ setSigners((s) => [...s, ...assigned.filter((ext) => !s.includes(ext))]);
940
+ if (!current && assigned[0]) setCurrent(assigned[0]);
941
+ setSuggestions(null);
942
+ notify(`${added.length} field${added.length === 1 ? "" : "s"} added.`, "success");
943
+ };
944
+ const submit = async (send) => {
945
+ setError(null);
946
+ try {
947
+ const request = await save.mutateAsync({
948
+ documentId,
949
+ version,
950
+ fields,
951
+ message: message.trim() || void 0,
952
+ requestId: draft?.status === "draft" ? draft.external_id : void 0,
953
+ send
954
+ });
955
+ notify(
956
+ send ? `Sent for signature to ${request.signers.length} signer${request.signers.length === 1 ? "" : "s"}.` : "Draft saved.",
957
+ "success"
958
+ );
959
+ onSaved(request);
960
+ } catch (err) {
961
+ setError(err instanceof Error ? err.message : "The request could not be saved");
962
+ }
963
+ };
964
+ const renderPageOverlay = react.useCallback(
965
+ ({ pageNumber }) => /* @__PURE__ */ jsxRuntime.jsx(
966
+ SignatureFieldsOverlay,
967
+ {
968
+ page: pageNumber - 1,
969
+ fields,
970
+ colorOf,
971
+ labelOf: (f) => `${documentTools.FIELD_TYPE_LABELS[f.type]} \xB7 ${nameOf(f.signer).split(" ")[0]}`,
972
+ editable: true,
973
+ placing: current ? placing : null,
974
+ selectedId,
975
+ onSelect: setSelectedId,
976
+ onCreate: (box) => {
977
+ if (!current || !placing) return;
978
+ const field = {
979
+ id: documentTools.newFieldId(),
980
+ type: placing,
981
+ page: pageNumber - 1,
982
+ signer: current,
983
+ required: true,
984
+ ...box
985
+ };
986
+ setFields((fs) => [...fs, field]);
987
+ setSelectedId(field.id);
988
+ },
989
+ onChange: (id, box) => updateField(id, box),
990
+ onRemove: (id) => {
991
+ setFields((fs) => fs.filter((f) => f.id !== id));
992
+ setSelectedId(null);
993
+ }
994
+ }
995
+ ),
996
+ [fields, colorOf, nameOf, current, placing, selectedId]
997
+ );
998
+ const groups = suggestions ? [...new Set(suggestions.map((s) => s.group))] : [];
999
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full min-h-0 flex-col", "data-testid": "signature-request-editor", children: [
1000
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 border-b border-border px-3 py-2 text-sm", children: [
1001
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
1002
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Signers" }),
1003
+ signers.map((ext) => /* @__PURE__ */ jsxRuntime.jsxs(
1004
+ "span",
1005
+ {
1006
+ className: ui.cn(
1007
+ "inline-flex items-center gap-1.5 rounded-full border py-0.5 pr-1 pl-2",
1008
+ current === ext && "bg-muted"
1009
+ ),
1010
+ style: { borderColor: colorOf(ext) },
1011
+ children: [
1012
+ /* @__PURE__ */ jsxRuntime.jsxs(
1013
+ "button",
1014
+ {
1015
+ type: "button",
1016
+ className: "inline-flex items-center gap-1.5",
1017
+ onClick: () => setCurrent(ext),
1018
+ "aria-pressed": current === ext,
1019
+ "data-testid": `signer-chip-${ext}`,
1020
+ children: [
1021
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-2.5 rounded-full", style: { background: colorOf(ext) } }),
1022
+ nameOf(ext)
1023
+ ]
1024
+ }
1025
+ ),
1026
+ /* @__PURE__ */ jsxRuntime.jsx(
1027
+ "button",
1028
+ {
1029
+ type: "button",
1030
+ "aria-label": `Remove ${nameOf(ext)}`,
1031
+ className: "rounded-full p-0.5 hover:bg-accent",
1032
+ onClick: () => removeSigner(ext),
1033
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-3" })
1034
+ }
1035
+ )
1036
+ ]
1037
+ },
1038
+ ext
1039
+ )),
1040
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-1 text-muted-foreground", children: [
1041
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UserPlus, { className: "size-4", "aria-hidden": true }),
1042
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add a signer" }),
1043
+ /* @__PURE__ */ jsxRuntime.jsxs(
1044
+ "select",
1045
+ {
1046
+ className: selectClass,
1047
+ value: "",
1048
+ onChange: (e) => addSigner(e.target.value),
1049
+ disabled: candidates.isLoading,
1050
+ "data-testid": "signature-add-signer",
1051
+ children: [
1052
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: candidates.isLoading ? "Loading members\u2026" : "Add a signer\u2026" }),
1053
+ people.filter((p) => !signers.includes(p.externalId)).map((p) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: p.externalId, children: [
1054
+ p.name,
1055
+ " (",
1056
+ p.email,
1057
+ ")"
1058
+ ] }, p.externalId))
1059
+ ]
1060
+ }
1061
+ )
1062
+ ] })
1063
+ ] }),
1064
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
1065
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: current ? `Place for ${nameOf(current)}:` : "Add a signer, then place their fields." }),
1066
+ documentTools.SIGNATURE_FIELD_TYPES.map((type) => /* @__PURE__ */ jsxRuntime.jsx(
1067
+ ui.Button,
1068
+ {
1069
+ type: "button",
1070
+ size: "sm",
1071
+ variant: placing === type && current ? "default" : "outline",
1072
+ disabled: !current,
1073
+ onClick: () => setPlacing(placing === type ? null : type),
1074
+ "data-testid": `signature-place-${type}`,
1075
+ children: documentTools.FIELD_TYPE_LABELS[type]
1076
+ },
1077
+ type
1078
+ )),
1079
+ /* @__PURE__ */ jsxRuntime.jsxs(
1080
+ ui.Button,
1081
+ {
1082
+ type: "button",
1083
+ size: "sm",
1084
+ variant: "ghost",
1085
+ onClick: findBlocks,
1086
+ disabled: finding,
1087
+ "data-testid": "signature-find-blocks",
1088
+ children: [
1089
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ScanSearch, { className: "mr-1 size-4", "aria-hidden": true }),
1090
+ finding ? "Looking\u2026" : "Find signature blocks"
1091
+ ]
1092
+ }
1093
+ ),
1094
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-auto flex items-center gap-2", children: [
1095
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { type: "button", variant: "outline", size: "sm", onClick: onCancel, children: "Cancel" }),
1096
+ /* @__PURE__ */ jsxRuntime.jsx(
1097
+ ui.Button,
1098
+ {
1099
+ type: "button",
1100
+ variant: "outline",
1101
+ size: "sm",
1102
+ onClick: () => submit(false),
1103
+ disabled: save.isPending || fields.length === 0,
1104
+ "data-testid": "signature-save-draft",
1105
+ children: "Save draft"
1106
+ }
1107
+ ),
1108
+ /* @__PURE__ */ jsxRuntime.jsxs(
1109
+ ui.Button,
1110
+ {
1111
+ type: "button",
1112
+ size: "sm",
1113
+ onClick: () => submit(true),
1114
+ disabled: save.isPending || !!blocker,
1115
+ title: blocker ?? void 0,
1116
+ "data-testid": "signature-send",
1117
+ children: [
1118
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "mr-1 size-4", "aria-hidden": true }),
1119
+ save.isPending ? "Sending\u2026" : "Send for signature"
1120
+ ]
1121
+ }
1122
+ )
1123
+ ] })
1124
+ ] }),
1125
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
1126
+ /* @__PURE__ */ jsxRuntime.jsx(
1127
+ ui.Input,
1128
+ {
1129
+ value: message,
1130
+ onChange: (e) => setMessage(e.target.value),
1131
+ maxLength: 2e3,
1132
+ placeholder: "Message to the signers (optional)",
1133
+ className: "h-8 max-w-md",
1134
+ "data-testid": "signature-message"
1135
+ }
1136
+ ),
1137
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", "data-testid": "signature-editor-summary", children: [
1138
+ fields.length,
1139
+ " field",
1140
+ fields.length === 1 ? "" : "s",
1141
+ blocker ? ` \xB7 ${blocker}` : " \xB7 ready to send"
1142
+ ] })
1143
+ ] }),
1144
+ selected && /* @__PURE__ */ jsxRuntime.jsxs(
1145
+ "div",
1146
+ {
1147
+ className: "flex flex-wrap items-center gap-3 rounded-md bg-muted px-2 py-1.5",
1148
+ "data-testid": "signature-field-details",
1149
+ children: [
1150
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PenLine, { className: "size-4", "aria-hidden": true }),
1151
+ /* @__PURE__ */ jsxRuntime.jsx(
1152
+ "select",
1153
+ {
1154
+ className: selectClass,
1155
+ value: selected.type,
1156
+ "aria-label": "Field type",
1157
+ onChange: (e) => updateField(selected.id, { type: e.target.value }),
1158
+ children: documentTools.SIGNATURE_FIELD_TYPES.map((t) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: t, children: documentTools.FIELD_TYPE_LABELS[t] }, t))
1159
+ }
1160
+ ),
1161
+ /* @__PURE__ */ jsxRuntime.jsx(
1162
+ "select",
1163
+ {
1164
+ className: selectClass,
1165
+ value: selected.signer,
1166
+ "aria-label": "Signer",
1167
+ onChange: (e) => updateField(selected.id, { signer: e.target.value }),
1168
+ "data-testid": "signature-field-signer",
1169
+ children: signers.map((ext) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: ext, children: nameOf(ext) }, ext))
1170
+ }
1171
+ ),
1172
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1.5", children: [
1173
+ /* @__PURE__ */ jsxRuntime.jsx(
1174
+ ui.Checkbox,
1175
+ {
1176
+ id: "signature-field-required",
1177
+ checked: selected.required,
1178
+ onCheckedChange: (c) => updateField(selected.id, { required: c === true })
1179
+ }
1180
+ ),
1181
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "signature-field-required", className: "font-normal", children: "Required" })
1182
+ ] })
1183
+ ]
1184
+ }
1185
+ ),
1186
+ suggestions && suggestions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5 rounded-md border p-2", "data-testid": "signature-suggestions", children: [
1187
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "font-medium", children: [
1188
+ "Found ",
1189
+ groups.length,
1190
+ " signature block",
1191
+ groups.length === 1 ? "" : "s",
1192
+ ". Choose who signs each."
1193
+ ] }),
1194
+ groups.map((g) => {
1195
+ const inBlock = suggestions.filter((s) => s.group === g);
1196
+ const role = inBlock.find((s) => s.role)?.role;
1197
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
1198
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-40", children: [
1199
+ role ?? `Block ${g + 1}`,
1200
+ " ",
1201
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
1202
+ "(p. ",
1203
+ inBlock[0].page + 1,
1204
+ ":",
1205
+ " ",
1206
+ inBlock.map((s) => documentTools.FIELD_TYPE_LABELS[s.type]).join(", "),
1207
+ ")"
1208
+ ] })
1209
+ ] }),
1210
+ /* @__PURE__ */ jsxRuntime.jsxs(
1211
+ "select",
1212
+ {
1213
+ className: selectClass,
1214
+ value: assign[g] ?? "",
1215
+ onChange: (e) => setAssign((a) => ({ ...a, [g]: e.target.value || void 0 })),
1216
+ "data-testid": `signature-suggestion-signer-${g}`,
1217
+ children: [
1218
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Skip" }),
1219
+ people.map((p) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: p.externalId, children: p.name }, p.externalId))
1220
+ ]
1221
+ }
1222
+ )
1223
+ ] }, g);
1224
+ }),
1225
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
1226
+ /* @__PURE__ */ jsxRuntime.jsx(
1227
+ ui.Button,
1228
+ {
1229
+ type: "button",
1230
+ size: "sm",
1231
+ onClick: applySuggestions,
1232
+ disabled: !Object.values(assign).some(Boolean),
1233
+ "data-testid": "signature-suggestions-apply",
1234
+ children: "Add fields"
1235
+ }
1236
+ ),
1237
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { type: "button", size: "sm", variant: "ghost", onClick: () => setSuggestions(null), children: "Dismiss" })
1238
+ ] })
1239
+ ] }),
1240
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-red-text", role: "alert", "data-testid": "signature-editor-error", children: error })
1241
+ ] }),
1242
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(PdfViewer, { ...viewerProps, file, renderPageOverlay }) })
1243
+ ] });
1244
+ }
267
1245
 
268
1246
  exports.AnnotatedPdfViewer = AnnotatedPdfViewer;
1247
+ exports.GuidedSigningViewer = GuidedSigningViewer;
269
1248
  exports.MARKUP_AUTOSAVE_MS = MARKUP_AUTOSAVE_MS;
270
1249
  exports.MARKUP_PULL_MS = MARKUP_PULL_MS;
1250
+ exports.SIGNER_COLORS = SIGNER_COLORS;
1251
+ exports.SignatureFieldsOverlay = SignatureFieldsOverlay;
271
1252
  exports.SignaturePlacementViewer = SignaturePlacementViewer;
1253
+ exports.SignatureRequestEditor = SignatureRequestEditor;
1254
+ exports.signingDate = signingDate;
272
1255
  //# sourceMappingURL=index.cjs.map
273
1256
  //# sourceMappingURL=index.cjs.map