@signiphi/pdf-signer 0.2.0-beta.2 → 0.2.0-beta.21

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 (197) hide show
  1. package/assets/viewer.html +1 -5
  2. package/dist/components/index.js +2746 -901
  3. package/dist/components/index.js.map +1 -1
  4. package/dist/components/index.mjs +2513 -669
  5. package/dist/components/index.mjs.map +1 -1
  6. package/dist/core/index.js +420 -20
  7. package/dist/core/index.js.map +1 -1
  8. package/dist/core/index.mjs +420 -20
  9. package/dist/core/index.mjs.map +1 -1
  10. package/dist/hooks/index.js +506 -211
  11. package/dist/hooks/index.js.map +1 -1
  12. package/dist/hooks/index.mjs +507 -212
  13. package/dist/hooks/index.mjs.map +1 -1
  14. package/dist/index.css +214 -191
  15. package/dist/index.css.map +1 -1
  16. package/dist/index.js +3019 -893
  17. package/dist/index.js.map +1 -1
  18. package/dist/index.mjs +2762 -653
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/styles/index.css +202 -172
  21. package/dist/types/index.js.map +1 -1
  22. package/dist/types/index.mjs.map +1 -1
  23. package/dist/utils/index.js +792 -147
  24. package/dist/utils/index.js.map +1 -1
  25. package/dist/utils/index.mjs +777 -148
  26. package/dist/utils/index.mjs.map +1 -1
  27. package/package.json +2 -2
  28. package/scripts/copy-utils.js +14 -3
  29. package/src/styles/index.css +33 -3
  30. package/dist/__tests__/helpers/fixtures.d.ts +0 -43
  31. package/dist/__tests__/helpers/fixtures.d.ts.map +0 -1
  32. package/dist/__tests__/helpers/mocks.d.ts +0 -333
  33. package/dist/__tests__/helpers/mocks.d.ts.map +0 -1
  34. package/dist/__tests__/setup.d.ts +0 -6
  35. package/dist/__tests__/setup.d.ts.map +0 -1
  36. package/dist/components/AcknowledgementModal.d.ts +0 -21
  37. package/dist/components/AcknowledgementModal.d.ts.map +0 -1
  38. package/dist/components/AcknowledgementsSidebar.d.ts +0 -22
  39. package/dist/components/AcknowledgementsSidebar.d.ts.map +0 -1
  40. package/dist/components/AttachmentUpload.d.ts +0 -17
  41. package/dist/components/AttachmentUpload.d.ts.map +0 -1
  42. package/dist/components/EditableFieldsPanel.d.ts +0 -30
  43. package/dist/components/EditableFieldsPanel.d.ts.map +0 -1
  44. package/dist/components/ErrorBoundary.d.ts +0 -67
  45. package/dist/components/ErrorBoundary.d.ts.map +0 -1
  46. package/dist/components/FormFieldsView.d.ts +0 -46
  47. package/dist/components/FormFieldsView.d.ts.map +0 -1
  48. package/dist/components/InitialsModal.d.ts +0 -16
  49. package/dist/components/InitialsModal.d.ts.map +0 -1
  50. package/dist/components/PdfViewerStyled.d.ts +0 -16
  51. package/dist/components/PdfViewerStyled.d.ts.map +0 -1
  52. package/dist/components/PoweredBySigniphi.d.ts +0 -11
  53. package/dist/components/PoweredBySigniphi.d.ts.map +0 -1
  54. package/dist/components/RequiredFieldNavigation.d.ts +0 -18
  55. package/dist/components/RequiredFieldNavigation.d.ts.map +0 -1
  56. package/dist/components/SignatureCanvas.d.ts +0 -12
  57. package/dist/components/SignatureCanvas.d.ts.map +0 -1
  58. package/dist/components/SignatureInitialsBox.d.ts +0 -25
  59. package/dist/components/SignatureInitialsBox.d.ts.map +0 -1
  60. package/dist/components/SignatureModal.d.ts +0 -21
  61. package/dist/components/SignatureModal.d.ts.map +0 -1
  62. package/dist/components/SigningInstructions.d.ts +0 -12
  63. package/dist/components/SigningInstructions.d.ts.map +0 -1
  64. package/dist/components/SubmissionForm.d.ts +0 -52
  65. package/dist/components/SubmissionForm.d.ts.map +0 -1
  66. package/dist/components/UnacknowledgedFieldsModal.d.ts +0 -23
  67. package/dist/components/UnacknowledgedFieldsModal.d.ts.map +0 -1
  68. package/dist/components/ViewToggleToolbar.d.ts +0 -38
  69. package/dist/components/ViewToggleToolbar.d.ts.map +0 -1
  70. package/dist/components/form-fields/CheckboxRenderer.d.ts +0 -10
  71. package/dist/components/form-fields/CheckboxRenderer.d.ts.map +0 -1
  72. package/dist/components/form-fields/DateFieldRenderer.d.ts +0 -14
  73. package/dist/components/form-fields/DateFieldRenderer.d.ts.map +0 -1
  74. package/dist/components/form-fields/DropdownRenderer.d.ts +0 -14
  75. package/dist/components/form-fields/DropdownRenderer.d.ts.map +0 -1
  76. package/dist/components/form-fields/FormFieldRenderer.d.ts +0 -22
  77. package/dist/components/form-fields/FormFieldRenderer.d.ts.map +0 -1
  78. package/dist/components/form-fields/InitialsFieldRenderer.d.ts +0 -16
  79. package/dist/components/form-fields/InitialsFieldRenderer.d.ts.map +0 -1
  80. package/dist/components/form-fields/RadioGroupRenderer.d.ts +0 -10
  81. package/dist/components/form-fields/RadioGroupRenderer.d.ts.map +0 -1
  82. package/dist/components/form-fields/SignatureFieldRenderer.d.ts +0 -16
  83. package/dist/components/form-fields/SignatureFieldRenderer.d.ts.map +0 -1
  84. package/dist/components/form-fields/TextFieldRenderer.d.ts +0 -14
  85. package/dist/components/form-fields/TextFieldRenderer.d.ts.map +0 -1
  86. package/dist/components/form-fields/TextLabelRenderer.d.ts +0 -14
  87. package/dist/components/form-fields/TextLabelRenderer.d.ts.map +0 -1
  88. package/dist/components/form-fields/index.d.ts +0 -14
  89. package/dist/components/form-fields/index.d.ts.map +0 -1
  90. package/dist/components/index.d.ts +0 -17
  91. package/dist/components/index.d.ts.map +0 -1
  92. package/dist/core/PdfViewerCore.d.ts +0 -19
  93. package/dist/core/PdfViewerCore.d.ts.map +0 -1
  94. package/dist/core/SignatureCaptureCore.d.ts +0 -37
  95. package/dist/core/SignatureCaptureCore.d.ts.map +0 -1
  96. package/dist/core/index.d.ts +0 -3
  97. package/dist/core/index.d.ts.map +0 -1
  98. package/dist/hooks/index.d.ts +0 -9
  99. package/dist/hooks/index.d.ts.map +0 -1
  100. package/dist/hooks/useAcknowledgements.d.ts +0 -50
  101. package/dist/hooks/useAcknowledgements.d.ts.map +0 -1
  102. package/dist/hooks/useAttachments.d.ts +0 -25
  103. package/dist/hooks/useAttachments.d.ts.map +0 -1
  104. package/dist/hooks/useFieldFiltering.d.ts +0 -29
  105. package/dist/hooks/useFieldFiltering.d.ts.map +0 -1
  106. package/dist/hooks/useFormFields.d.ts +0 -23
  107. package/dist/hooks/useFormFields.d.ts.map +0 -1
  108. package/dist/hooks/useMultiSignerContext.d.ts +0 -25
  109. package/dist/hooks/useMultiSignerContext.d.ts.map +0 -1
  110. package/dist/hooks/usePdfViewer.d.ts +0 -52
  111. package/dist/hooks/usePdfViewer.d.ts.map +0 -1
  112. package/dist/hooks/useRequiredFieldNavigation.d.ts +0 -16
  113. package/dist/hooks/useRequiredFieldNavigation.d.ts.map +0 -1
  114. package/dist/hooks/useSignatureCapture.d.ts +0 -17
  115. package/dist/hooks/useSignatureCapture.d.ts.map +0 -1
  116. package/dist/hooks/useSignatures.d.ts +0 -29
  117. package/dist/hooks/useSignatures.d.ts.map +0 -1
  118. package/dist/index.d.ts +0 -17
  119. package/dist/index.d.ts.map +0 -1
  120. package/dist/integrations/index.d.ts +0 -6
  121. package/dist/integrations/index.d.ts.map +0 -1
  122. package/dist/integrations/next-config.d.ts +0 -46
  123. package/dist/integrations/next-config.d.ts.map +0 -1
  124. package/dist/integrations/vite-plugin.d.ts +0 -48
  125. package/dist/integrations/vite-plugin.d.ts.map +0 -1
  126. package/dist/lib/index.d.ts +0 -3
  127. package/dist/lib/index.d.ts.map +0 -1
  128. package/dist/lib/ui/accordion.d.ts +0 -8
  129. package/dist/lib/ui/accordion.d.ts.map +0 -1
  130. package/dist/lib/ui/alert.d.ts +0 -9
  131. package/dist/lib/ui/alert.d.ts.map +0 -1
  132. package/dist/lib/ui/button.d.ts +0 -12
  133. package/dist/lib/ui/button.d.ts.map +0 -1
  134. package/dist/lib/ui/calendar.d.ts +0 -10
  135. package/dist/lib/ui/calendar.d.ts.map +0 -1
  136. package/dist/lib/ui/card.d.ts +0 -9
  137. package/dist/lib/ui/card.d.ts.map +0 -1
  138. package/dist/lib/ui/checkbox.d.ts +0 -5
  139. package/dist/lib/ui/checkbox.d.ts.map +0 -1
  140. package/dist/lib/ui/dialog.d.ts +0 -20
  141. package/dist/lib/ui/dialog.d.ts.map +0 -1
  142. package/dist/lib/ui/index.d.ts +0 -13
  143. package/dist/lib/ui/index.d.ts.map +0 -1
  144. package/dist/lib/ui/input.d.ts +0 -6
  145. package/dist/lib/ui/input.d.ts.map +0 -1
  146. package/dist/lib/ui/label.d.ts +0 -6
  147. package/dist/lib/ui/label.d.ts.map +0 -1
  148. package/dist/lib/ui/popover.d.ts +0 -7
  149. package/dist/lib/ui/popover.d.ts.map +0 -1
  150. package/dist/lib/ui/radio-group.d.ts +0 -6
  151. package/dist/lib/ui/radio-group.d.ts.map +0 -1
  152. package/dist/lib/ui/select.d.ts +0 -14
  153. package/dist/lib/ui/select.d.ts.map +0 -1
  154. package/dist/lib/utils.d.ts +0 -7
  155. package/dist/lib/utils.d.ts.map +0 -1
  156. package/dist/types/index.d.ts +0 -278
  157. package/dist/types/index.d.ts.map +0 -1
  158. package/dist/utils/attachment-validators.d.ts +0 -118
  159. package/dist/utils/attachment-validators.d.ts.map +0 -1
  160. package/dist/utils/audit-trail.d.ts +0 -27
  161. package/dist/utils/audit-trail.d.ts.map +0 -1
  162. package/dist/utils/date-validation.d.ts +0 -30
  163. package/dist/utils/date-validation.d.ts.map +0 -1
  164. package/dist/utils/errors.d.ts +0 -106
  165. package/dist/utils/errors.d.ts.map +0 -1
  166. package/dist/utils/field-extraction.d.ts +0 -36
  167. package/dist/utils/field-extraction.d.ts.map +0 -1
  168. package/dist/utils/field-visibility.d.ts +0 -104
  169. package/dist/utils/field-visibility.d.ts.map +0 -1
  170. package/dist/utils/index.d.ts +0 -18
  171. package/dist/utils/index.d.ts.map +0 -1
  172. package/dist/utils/logger.d.ts +0 -16
  173. package/dist/utils/logger.d.ts.map +0 -1
  174. package/dist/utils/pdf-field-type-helpers.d.ts +0 -78
  175. package/dist/utils/pdf-field-type-helpers.d.ts.map +0 -1
  176. package/dist/utils/pdf-helpers.d.ts +0 -38
  177. package/dist/utils/pdf-helpers.d.ts.map +0 -1
  178. package/dist/utils/pdf-lib-loader.d.ts +0 -45
  179. package/dist/utils/pdf-lib-loader.d.ts.map +0 -1
  180. package/dist/utils/pdf-manipulation.d.ts +0 -93
  181. package/dist/utils/pdf-manipulation.d.ts.map +0 -1
  182. package/dist/utils/pdf-metadata.d.ts +0 -41
  183. package/dist/utils/pdf-metadata.d.ts.map +0 -1
  184. package/dist/utils/pdf-validators.d.ts +0 -149
  185. package/dist/utils/pdf-validators.d.ts.map +0 -1
  186. package/dist/utils/pdf-viewer-filter.d.ts +0 -35
  187. package/dist/utils/pdf-viewer-filter.d.ts.map +0 -1
  188. package/dist/utils/pdf-widget-helpers.d.ts +0 -98
  189. package/dist/utils/pdf-widget-helpers.d.ts.map +0 -1
  190. package/dist/utils/pdfjs-config.d.ts +0 -56
  191. package/dist/utils/pdfjs-config.d.ts.map +0 -1
  192. package/dist/utils/pdfjs-version-check.d.ts +0 -28
  193. package/dist/utils/pdfjs-version-check.d.ts.map +0 -1
  194. package/dist/utils/performance-monitor.d.ts +0 -172
  195. package/dist/utils/performance-monitor.d.ts.map +0 -1
  196. package/dist/utils/tracking.d.ts +0 -89
  197. package/dist/utils/tracking.d.ts.map +0 -1
@@ -76,7 +76,7 @@ function initializePdfJs() {
76
76
  async function checkPdfJsVersion(viewerBasePath = "/pdfjs") {
77
77
  const workerVersion = pdfjsLib__namespace.version;
78
78
  try {
79
- const versionUrl = `${viewerBasePath}/.version`;
79
+ const versionUrl = `${viewerBasePath}/version.txt`;
80
80
  const response = await fetch(versionUrl);
81
81
  if (!response.ok) {
82
82
  return {
@@ -181,6 +181,79 @@ var PdfViewerCore = react.forwardRef(
181
181
  }
182
182
  return PDFViewerApplication;
183
183
  }, [getPDFViewerApplication]);
184
+ const fieldMetadataRef = react.useRef([]);
185
+ const setFieldMetadata = react.useCallback((fields) => {
186
+ fieldMetadataRef.current = fields;
187
+ logger.info("[FIELD METADATA] Updated field metadata:", fields.map((f) => ({ name: f.name, fontSize: f.fontSize, type: f.type })));
188
+ }, []);
189
+ const extractFieldFontSizes = react.useCallback(async () => {
190
+ const fontSizeMap = {};
191
+ for (const field of fieldMetadataRef.current) {
192
+ if (field.type === "text" /* TEXT */) {
193
+ if (field.fontSize && field.fontSize >= 8 && field.fontSize <= 72) {
194
+ fontSizeMap[field.name] = field.fontSize;
195
+ }
196
+ }
197
+ }
198
+ if (Object.keys(fontSizeMap).length === 0) {
199
+ try {
200
+ const PDFViewerApplication = await waitForInitialization();
201
+ if (PDFViewerApplication?.pdfDocument?.getFieldObjects) {
202
+ const fieldObjects = await PDFViewerApplication.pdfDocument.getFieldObjects();
203
+ for (const [fieldName, fields] of Object.entries(fieldObjects)) {
204
+ const fieldArray = fields;
205
+ for (const field of fieldArray) {
206
+ if (field.alternateText) {
207
+ const match = field.alternateText.match(/\|fontSize:(\d+)$/);
208
+ if (match) {
209
+ fontSizeMap[fieldName] = parseInt(match[1], 10);
210
+ break;
211
+ }
212
+ }
213
+ }
214
+ }
215
+ }
216
+ } catch (error) {
217
+ logger.warn("[FONT SIZE] Error extracting from PDF:", error);
218
+ }
219
+ }
220
+ return fontSizeMap;
221
+ }, [waitForInitialization]);
222
+ const injectFormFieldFontSizeCSS = react.useCallback(async (doc) => {
223
+ const styleId = "signiphi-pdf-font-size-style";
224
+ const existingStyle = doc.getElementById(styleId);
225
+ if (existingStyle) {
226
+ existingStyle.remove();
227
+ }
228
+ const fontSizeMap = await extractFieldFontSizes();
229
+ const cssRules = [];
230
+ for (const [fieldName, fontSize] of Object.entries(fontSizeMap)) {
231
+ cssRules.push(`
232
+ input[name="${fieldName}"],
233
+ input[name="${fieldName}_date"],
234
+ select[name="${fieldName}"] {
235
+ font-size: ${fontSize}px !important;
236
+ }
237
+ `);
238
+ }
239
+ cssRules.push(`
240
+ input[data-element-id][name*="date"],
241
+ select[data-element-id] {
242
+ font-size: 18px !important;
243
+ }
244
+ `);
245
+ cssRules.push(`
246
+ input[type="text"][data-element-id]:not([style*="font-size"]),
247
+ select[data-element-id]:not([style*="font-size"]) {
248
+ font-size: 12px !important; /* Default fallback */
249
+ }
250
+ `);
251
+ const style = doc.createElement("style");
252
+ style.id = styleId;
253
+ style.textContent = `/* Dynamic font sizes from PDF metadata */
254
+ ${cssRules.join("\n")}`;
255
+ doc.head.appendChild(style);
256
+ }, [extractFieldFontSizes]);
184
257
  const loadPdf = react.useCallback(
185
258
  async (pdfUrl) => {
186
259
  const iframe = iframeRef.current;
@@ -211,7 +284,10 @@ var PdfViewerCore = react.forwardRef(
211
284
  try {
212
285
  const PDFViewerApplication = getPDFViewerApplication();
213
286
  if (PDFViewerApplication && PDFViewerApplication.initializedPromise) {
214
- PDFViewerApplication.initializedPromise.then(() => {
287
+ PDFViewerApplication.initializedPromise.then(async () => {
288
+ if (iframe.contentDocument) {
289
+ await injectFormFieldFontSizeCSS(iframe.contentDocument);
290
+ }
215
291
  resolve();
216
292
  }).catch(reject);
217
293
  } else {
@@ -291,6 +367,7 @@ var PdfViewerCore = react.forwardRef(
291
367
  }
292
368
  }
293
369
  logger.info(`[RADIO DETECT] Found ${Object.keys(radioGroups).length} radio groups:`, Object.keys(radioGroups));
370
+ const processedRadioFieldNames = new Set(Object.keys(radioGroups));
294
371
  for (const [fieldName, radioButtons] of Object.entries(radioGroups)) {
295
372
  const selectedRadio = radioButtons.find(
296
373
  (rb) => rb.data && typeof rb.data === "object" && rb.data.value === true
@@ -316,7 +393,7 @@ var PdfViewerCore = react.forwardRef(
316
393
  }
317
394
  for (const [id, data] of Object.entries(storedData)) {
318
395
  const fieldName = idToNameMap[id];
319
- if (fieldName && values[fieldName]) {
396
+ if (fieldName && (fieldName in values || processedRadioFieldNames.has(fieldName))) {
320
397
  continue;
321
398
  }
322
399
  if (fieldName) {
@@ -333,13 +410,13 @@ var PdfViewerCore = react.forwardRef(
333
410
  } else if (data !== void 0 && data !== null) {
334
411
  extractedValue = String(data);
335
412
  }
336
- if (extractedValue !== void 0 && extractedValue !== "") {
413
+ if (extractedValue !== void 0) {
337
414
  values[fieldName] = extractedValue;
338
415
  }
339
416
  }
340
417
  }
341
418
  for (const [name, fields] of Object.entries(fieldObjects)) {
342
- if (!values[name]) {
419
+ if (!(name in values)) {
343
420
  const fieldArray = fields;
344
421
  const field = fieldArray[0];
345
422
  if (field && field.value !== void 0 && field.value !== null) {
@@ -540,6 +617,8 @@ var PdfViewerCore = react.forwardRef(
540
617
  }
541
618
  }, 1e3);
542
619
  }, []);
620
+ const injectRadioLabels = react.useCallback((_fields) => {
621
+ }, []);
543
622
  const zoomIn = react.useCallback(async () => {
544
623
  try {
545
624
  const PDFViewerApplication = await waitForInitialization();
@@ -610,7 +689,7 @@ var PdfViewerCore = react.forwardRef(
610
689
  return null;
611
690
  }
612
691
  }, [waitForInitialization]);
613
- const attachFieldClickInterceptors = react.useCallback((onFieldClick) => {
692
+ const attachFieldClickInterceptors = react.useCallback(async (onFieldClick) => {
614
693
  const iframe = iframeRef.current;
615
694
  if (!iframe?.contentDocument) {
616
695
  logger.warn("Cannot attach field interceptors: iframe not ready");
@@ -618,6 +697,7 @@ var PdfViewerCore = react.forwardRef(
618
697
  }
619
698
  try {
620
699
  const doc = iframe.contentDocument;
700
+ await injectFormFieldFontSizeCSS(doc);
621
701
  const clickHighlightStyleId = "signiphi-click-highlight-style";
622
702
  if (!doc.getElementById(clickHighlightStyleId)) {
623
703
  const style = doc.createElement("style");
@@ -688,7 +768,7 @@ var PdfViewerCore = react.forwardRef(
688
768
  return;
689
769
  }
690
770
  logger.info(`Field click intercepted: ${fieldName}`, e.type);
691
- const shouldProceed = onFieldClick(fieldName);
771
+ const shouldProceed = onFieldClick(fieldName, target);
692
772
  logger.info(`Field ${fieldName} shouldProceed: ${shouldProceed}`);
693
773
  if (e.type !== "pointerdown" && e.type !== "mousedown") {
694
774
  if (!shouldProceed) {
@@ -764,6 +844,57 @@ var PdfViewerCore = react.forwardRef(
764
844
  logger.error("Error attaching field click interceptors:", error);
765
845
  }
766
846
  }, []);
847
+ const attachFieldChangeListeners = react.useCallback(async (onFieldChange) => {
848
+ try {
849
+ const iframe = iframeRef.current;
850
+ if (!iframe?.contentDocument) {
851
+ logger.warn("Cannot attach field change listeners: iframe not ready");
852
+ return () => {
853
+ };
854
+ }
855
+ const doc = iframe.contentDocument;
856
+ const handleChange = (event) => {
857
+ const target = event.target;
858
+ if (!target || !["INPUT", "SELECT", "TEXTAREA"].includes(target.tagName)) {
859
+ return;
860
+ }
861
+ const fieldName = target.getAttribute("name") || target.getAttribute("data-element-id") || target.getAttribute("id") || "";
862
+ if (!fieldName) return;
863
+ let value = "";
864
+ if (target.tagName === "INPUT") {
865
+ const inputElement = target;
866
+ if (inputElement.type === "checkbox") {
867
+ value = inputElement.checked ? "true" : "false";
868
+ } else if (inputElement.type === "radio") {
869
+ if (inputElement.checked) {
870
+ value = inputElement.value || "true";
871
+ } else {
872
+ return;
873
+ }
874
+ } else {
875
+ value = inputElement.value;
876
+ }
877
+ } else if (target.tagName === "SELECT") {
878
+ value = target.value;
879
+ } else if (target.tagName === "TEXTAREA") {
880
+ value = target.value;
881
+ }
882
+ onFieldChange(fieldName, value, target);
883
+ };
884
+ doc.addEventListener("change", handleChange, true);
885
+ doc.addEventListener("input", handleChange, true);
886
+ logger.info("Attached field change listeners to iframe document");
887
+ return () => {
888
+ doc.removeEventListener("change", handleChange, true);
889
+ doc.removeEventListener("input", handleChange, true);
890
+ logger.info("Removed field change listeners from iframe document");
891
+ };
892
+ } catch (error) {
893
+ logger.error("Error attaching field change listeners:", error);
894
+ return () => {
895
+ };
896
+ }
897
+ }, []);
767
898
  const addFieldIndicator = react.useCallback(async (fieldName, indicatorType = "completed", allowedFieldIds) => {
768
899
  try {
769
900
  const iframe = iframeRef.current;
@@ -979,6 +1110,275 @@ var PdfViewerCore = react.forwardRef(
979
1110
  logger.error("Error removing field indicator:", error);
980
1111
  }
981
1112
  }, []);
1113
+ const addDateFieldIndicator = react.useCallback((fieldName) => {
1114
+ try {
1115
+ const iframe = iframeRef.current;
1116
+ if (!iframe?.contentDocument) {
1117
+ logger.warn("Cannot add date field indicator: iframe not ready");
1118
+ return;
1119
+ }
1120
+ const doc = iframe.contentDocument;
1121
+ const formElement = doc.querySelector(
1122
+ `input[name="${fieldName}"], input[data-element-id="${fieldName}"], textarea[name="${fieldName}"], textarea[data-element-id="${fieldName}"]`
1123
+ );
1124
+ if (!formElement) {
1125
+ logger.warn(`Cannot add date indicator: field not found for "${fieldName}"`);
1126
+ return;
1127
+ }
1128
+ const annotationSection = formElement.closest("section");
1129
+ if (!annotationSection) {
1130
+ logger.warn(`Cannot add date indicator: no annotation section for "${fieldName}"`);
1131
+ return;
1132
+ }
1133
+ const existingIndicator = annotationSection.querySelector(".signiphi-date-field-indicator");
1134
+ if (existingIndicator) {
1135
+ existingIndicator.remove();
1136
+ }
1137
+ const indicator = doc.createElement("div");
1138
+ indicator.className = "signiphi-date-field-indicator";
1139
+ indicator.setAttribute("role", "button");
1140
+ indicator.setAttribute("aria-label", "Open calendar picker");
1141
+ indicator.setAttribute("tabindex", "0");
1142
+ indicator.innerHTML = `
1143
+ <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
1144
+ <rect x="2" y="3" width="14" height="13" rx="2" stroke="#6b7280" stroke-width="1.5" fill="white"/>
1145
+ <line x1="2" y1="6.5" x2="16" y2="6.5" stroke="#6b7280" stroke-width="1.5"/>
1146
+ <line x1="5.5" y1="1" x2="5.5" y2="5" stroke="#6b7280" stroke-width="1.5" stroke-linecap="round"/>
1147
+ <line x1="12.5" y1="1" x2="12.5" y2="5" stroke="#6b7280" stroke-width="1.5" stroke-linecap="round"/>
1148
+ <circle cx="5.5" cy="9.5" r="0.8" fill="#6b7280"/>
1149
+ <circle cx="9" cy="9.5" r="0.8" fill="#6b7280"/>
1150
+ <circle cx="12.5" cy="9.5" r="0.8" fill="#6b7280"/>
1151
+ <circle cx="5.5" cy="12.5" r="0.8" fill="#6b7280"/>
1152
+ <circle cx="9" cy="12.5" r="0.8" fill="#6b7280"/>
1153
+ <circle cx="12.5" cy="12.5" r="0.8" fill="#6b7280"/>
1154
+ </svg>
1155
+ `;
1156
+ Object.assign(indicator.style, {
1157
+ position: "absolute",
1158
+ top: "50%",
1159
+ right: "4px",
1160
+ transform: "translateY(-50%)",
1161
+ width: "24px",
1162
+ height: "24px",
1163
+ display: "flex",
1164
+ alignItems: "center",
1165
+ justifyContent: "center",
1166
+ zIndex: "1000",
1167
+ cursor: "pointer",
1168
+ opacity: "0.7",
1169
+ transition: "opacity 0.2s ease-in-out",
1170
+ pointerEvents: "auto",
1171
+ padding: "3px",
1172
+ borderRadius: "4px"
1173
+ });
1174
+ indicator.addEventListener("mouseenter", () => {
1175
+ indicator.style.opacity = "1";
1176
+ indicator.style.backgroundColor = "#f3f4f6";
1177
+ });
1178
+ indicator.addEventListener("mouseleave", () => {
1179
+ indicator.style.opacity = "0.7";
1180
+ indicator.style.backgroundColor = "transparent";
1181
+ });
1182
+ indicator.addEventListener("keydown", (e) => {
1183
+ if (e.key === "Enter" || e.key === " ") {
1184
+ e.preventDefault();
1185
+ indicator.click();
1186
+ }
1187
+ });
1188
+ const currentPosition = window.getComputedStyle(annotationSection).position;
1189
+ if (currentPosition === "static") {
1190
+ annotationSection.style.position = "relative";
1191
+ }
1192
+ annotationSection.appendChild(indicator);
1193
+ logger.info(`Added date field indicator for: ${fieldName}`);
1194
+ } catch (error) {
1195
+ logger.error("Error adding date field indicator:", error);
1196
+ }
1197
+ }, []);
1198
+ const removeDateFieldIndicator = react.useCallback((fieldName) => {
1199
+ try {
1200
+ const iframe = iframeRef.current;
1201
+ if (!iframe?.contentDocument) return;
1202
+ const doc = iframe.contentDocument;
1203
+ const formElement = doc.querySelector(
1204
+ `input[name="${fieldName}"], input[data-element-id="${fieldName}"], textarea[name="${fieldName}"], textarea[data-element-id="${fieldName}"]`
1205
+ );
1206
+ if (!formElement) return;
1207
+ const annotationSection = formElement.closest("section");
1208
+ if (!annotationSection) return;
1209
+ const indicator = annotationSection.querySelector(".signiphi-date-field-indicator");
1210
+ if (indicator) {
1211
+ indicator.remove();
1212
+ logger.info(`Removed date field indicator from: ${fieldName}`);
1213
+ }
1214
+ } catch (error) {
1215
+ logger.error("Error removing date field indicator:", error);
1216
+ }
1217
+ }, []);
1218
+ const findFieldElements = react.useCallback((fieldName) => {
1219
+ const iframe = iframeRef.current;
1220
+ if (!iframe?.contentDocument) return [];
1221
+ const doc = iframe.contentDocument;
1222
+ const targetElements = [];
1223
+ if (fieldName === "signature_field_main") {
1224
+ const allInputs = doc.querySelectorAll("input[name], input[data-element-id]");
1225
+ allInputs.forEach((input) => {
1226
+ const name = input.getAttribute("name") || input.getAttribute("data-element-id") || "";
1227
+ if (name.toLowerCase().includes("signature") && !name.toLowerCase().includes("initials")) {
1228
+ targetElements.push(input);
1229
+ }
1230
+ });
1231
+ } else if (fieldName === "initials_field_main") {
1232
+ const allInputs = doc.querySelectorAll("input[name], input[data-element-id]");
1233
+ allInputs.forEach((input) => {
1234
+ const name = input.getAttribute("name") || input.getAttribute("data-element-id") || "";
1235
+ if (name.toLowerCase().includes("initials")) {
1236
+ targetElements.push(input);
1237
+ }
1238
+ });
1239
+ } else {
1240
+ const formElement = doc.querySelector(
1241
+ `input[name="${fieldName}"], input[data-element-id="${fieldName}"]`
1242
+ );
1243
+ if (formElement) {
1244
+ targetElements.push(formElement);
1245
+ }
1246
+ }
1247
+ return targetElements;
1248
+ }, []);
1249
+ const previewSignature = react.useCallback((fieldName, dataUrl) => {
1250
+ try {
1251
+ const iframe = iframeRef.current;
1252
+ if (!iframe?.contentDocument) {
1253
+ logger.warn("Cannot preview signature: iframe not ready");
1254
+ return;
1255
+ }
1256
+ const doc = iframe.contentDocument;
1257
+ const targetElements = findFieldElements(fieldName);
1258
+ targetElements.forEach((formElement) => {
1259
+ const annotationSection = formElement.closest("section");
1260
+ if (!annotationSection) return;
1261
+ const existing = annotationSection.querySelector(".signiphi-signature-preview");
1262
+ if (existing) existing.remove();
1263
+ if (!dataUrl) return;
1264
+ const preview = doc.createElement("div");
1265
+ preview.className = "signiphi-signature-preview";
1266
+ preview.setAttribute("aria-hidden", "true");
1267
+ const img = doc.createElement("img");
1268
+ img.src = dataUrl;
1269
+ img.alt = "";
1270
+ Object.assign(img.style, {
1271
+ width: "100%",
1272
+ height: "100%",
1273
+ objectFit: "contain",
1274
+ pointerEvents: "none"
1275
+ });
1276
+ preview.appendChild(img);
1277
+ Object.assign(preview.style, {
1278
+ position: "absolute",
1279
+ top: "0",
1280
+ left: "0",
1281
+ width: "100%",
1282
+ height: "100%",
1283
+ display: "flex",
1284
+ alignItems: "center",
1285
+ justifyContent: "center",
1286
+ zIndex: "999",
1287
+ pointerEvents: "none",
1288
+ padding: "2px",
1289
+ boxSizing: "border-box",
1290
+ backgroundColor: "rgba(255, 255, 255, 0.85)",
1291
+ opacity: "0",
1292
+ transition: "opacity 0.3s ease-in-out"
1293
+ });
1294
+ const currentPosition = annotationSection.style.position || getComputedStyle(annotationSection).position;
1295
+ if (currentPosition === "static" || !currentPosition) {
1296
+ annotationSection.style.position = "relative";
1297
+ }
1298
+ annotationSection.appendChild(preview);
1299
+ requestAnimationFrame(() => {
1300
+ preview.style.opacity = "1";
1301
+ });
1302
+ });
1303
+ logger.info(`Previewed signature on ${targetElements.length} field(s) for: ${fieldName}`);
1304
+ } catch (error) {
1305
+ logger.error("Error previewing signature:", error);
1306
+ }
1307
+ }, [findFieldElements]);
1308
+ const previewInitials = react.useCallback((fieldName, text) => {
1309
+ try {
1310
+ const iframe = iframeRef.current;
1311
+ if (!iframe?.contentDocument) {
1312
+ logger.warn("Cannot preview initials: iframe not ready");
1313
+ return;
1314
+ }
1315
+ const doc = iframe.contentDocument;
1316
+ const targetElements = findFieldElements(fieldName);
1317
+ targetElements.forEach((formElement) => {
1318
+ const annotationSection = formElement.closest("section");
1319
+ if (!annotationSection) return;
1320
+ const existing = annotationSection.querySelector(".signiphi-initials-preview");
1321
+ if (existing) existing.remove();
1322
+ if (!text) return;
1323
+ const preview = doc.createElement("div");
1324
+ preview.className = "signiphi-initials-preview";
1325
+ preview.setAttribute("aria-hidden", "true");
1326
+ preview.textContent = text;
1327
+ Object.assign(preview.style, {
1328
+ position: "absolute",
1329
+ top: "0",
1330
+ left: "0",
1331
+ width: "100%",
1332
+ height: "100%",
1333
+ display: "flex",
1334
+ alignItems: "center",
1335
+ justifyContent: "center",
1336
+ zIndex: "999",
1337
+ pointerEvents: "none",
1338
+ fontFamily: "'Dancing Script', 'Brush Script MT', cursive",
1339
+ fontStyle: "italic",
1340
+ fontSize: "70%",
1341
+ color: "#000000",
1342
+ backgroundColor: "rgba(255, 255, 255, 0.85)",
1343
+ overflow: "hidden",
1344
+ opacity: "0",
1345
+ transition: "opacity 0.3s ease-in-out"
1346
+ });
1347
+ const currentPosition = annotationSection.style.position || getComputedStyle(annotationSection).position;
1348
+ if (currentPosition === "static" || !currentPosition) {
1349
+ annotationSection.style.position = "relative";
1350
+ }
1351
+ annotationSection.appendChild(preview);
1352
+ requestAnimationFrame(() => {
1353
+ preview.style.opacity = "1";
1354
+ });
1355
+ });
1356
+ logger.info(`Previewed initials on ${targetElements.length} field(s) for: ${fieldName}`);
1357
+ } catch (error) {
1358
+ logger.error("Error previewing initials:", error);
1359
+ }
1360
+ }, [findFieldElements]);
1361
+ const clearFieldPreviews = react.useCallback((fieldName) => {
1362
+ try {
1363
+ const iframe = iframeRef.current;
1364
+ if (!iframe?.contentDocument) return;
1365
+ const doc = iframe.contentDocument;
1366
+ const selectors = ".signiphi-signature-preview, .signiphi-initials-preview";
1367
+ if (fieldName) {
1368
+ const targetElements = findFieldElements(fieldName);
1369
+ targetElements.forEach((el) => {
1370
+ const section = el.closest("section");
1371
+ if (section) {
1372
+ section.querySelectorAll(selectors).forEach((p) => p.remove());
1373
+ }
1374
+ });
1375
+ } else {
1376
+ doc.querySelectorAll(selectors).forEach((el) => el.remove());
1377
+ }
1378
+ } catch (error) {
1379
+ logger.error("Error clearing field previews:", error);
1380
+ }
1381
+ }, [findFieldElements]);
982
1382
  react.useEffect(() => {
983
1383
  if (!versionChecked) {
984
1384
  const config = getPdfJsConfig();
@@ -1040,22 +1440,14 @@ Or check your configuration.`;
1040
1440
  await initializationPromise.current;
1041
1441
  isLoadingRef.current = false;
1042
1442
  onLoad?.();
1043
- } else {
1044
- const PDFViewerApplication = getPDFViewerApplication();
1045
- if (PDFViewerApplication) {
1046
- isLoadingRef.current = false;
1047
- onLoad?.();
1048
- } else {
1049
- throw new Error("PDFViewerApplication not found after iframe load");
1050
- }
1051
1443
  }
1052
1444
  } catch (error) {
1053
- const errorMessage = error instanceof Error ? error.message : "Unknown error loading PDF viewer";
1054
- logger.error("Error in PDF.js initialization:", error);
1445
+ const errorMessage = error instanceof Error ? error.message : "Failed to load PDF viewer";
1446
+ logger.error("Error in handleIframeLoad:", errorMessage);
1055
1447
  isLoadingRef.current = false;
1056
1448
  onError?.(errorMessage);
1057
1449
  }
1058
- }, 1e3);
1450
+ }, 100);
1059
1451
  } catch (error) {
1060
1452
  const errorMessage = error instanceof Error ? error.message : "Unknown error in iframe load handler";
1061
1453
  logger.error("Error in iframe load handler:", error);
@@ -1073,6 +1465,8 @@ Or check your configuration.`;
1073
1465
  saveDocument,
1074
1466
  getPDFViewerApplication,
1075
1467
  injectPlaceholders,
1468
+ injectRadioLabels,
1469
+ setFieldMetadata,
1076
1470
  zoomIn,
1077
1471
  zoomOut,
1078
1472
  nextPage,
@@ -1080,10 +1474,16 @@ Or check your configuration.`;
1080
1474
  getCurrentPage,
1081
1475
  getTotalPages,
1082
1476
  attachFieldClickInterceptors,
1477
+ attachFieldChangeListeners,
1083
1478
  addFieldIndicator,
1084
- removeFieldIndicator
1479
+ removeFieldIndicator,
1480
+ addDateFieldIndicator,
1481
+ removeDateFieldIndicator,
1482
+ previewSignature,
1483
+ previewInitials,
1484
+ clearFieldPreviews
1085
1485
  }),
1086
- [loadPdf, getFormFieldValues, setFormFieldValues, getAllFieldNames, saveDocument, getPDFViewerApplication, injectPlaceholders, zoomIn, zoomOut, nextPage, previousPage, getCurrentPage, getTotalPages, attachFieldClickInterceptors, addFieldIndicator, removeFieldIndicator]
1486
+ [loadPdf, getFormFieldValues, setFormFieldValues, getAllFieldNames, saveDocument, getPDFViewerApplication, injectPlaceholders, injectRadioLabels, setFieldMetadata, zoomIn, zoomOut, nextPage, previousPage, getCurrentPage, getTotalPages, attachFieldClickInterceptors, attachFieldChangeListeners, addFieldIndicator, removeFieldIndicator, addDateFieldIndicator, removeDateFieldIndicator, previewSignature, previewInitials, clearFieldPreviews]
1087
1487
  );
1088
1488
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: children({ iframeRef, handleIframeLoad }) });
1089
1489
  }