@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
@@ -54,7 +54,7 @@ function initializePdfJs() {
54
54
  async function checkPdfJsVersion(viewerBasePath = "/pdfjs") {
55
55
  const workerVersion = pdfjsLib.version;
56
56
  try {
57
- const versionUrl = `${viewerBasePath}/.version`;
57
+ const versionUrl = `${viewerBasePath}/version.txt`;
58
58
  const response = await fetch(versionUrl);
59
59
  if (!response.ok) {
60
60
  return {
@@ -159,6 +159,79 @@ var PdfViewerCore = forwardRef(
159
159
  }
160
160
  return PDFViewerApplication;
161
161
  }, [getPDFViewerApplication]);
162
+ const fieldMetadataRef = useRef([]);
163
+ const setFieldMetadata = useCallback((fields) => {
164
+ fieldMetadataRef.current = fields;
165
+ logger.info("[FIELD METADATA] Updated field metadata:", fields.map((f) => ({ name: f.name, fontSize: f.fontSize, type: f.type })));
166
+ }, []);
167
+ const extractFieldFontSizes = useCallback(async () => {
168
+ const fontSizeMap = {};
169
+ for (const field of fieldMetadataRef.current) {
170
+ if (field.type === "text" /* TEXT */) {
171
+ if (field.fontSize && field.fontSize >= 8 && field.fontSize <= 72) {
172
+ fontSizeMap[field.name] = field.fontSize;
173
+ }
174
+ }
175
+ }
176
+ if (Object.keys(fontSizeMap).length === 0) {
177
+ try {
178
+ const PDFViewerApplication = await waitForInitialization();
179
+ if (PDFViewerApplication?.pdfDocument?.getFieldObjects) {
180
+ const fieldObjects = await PDFViewerApplication.pdfDocument.getFieldObjects();
181
+ for (const [fieldName, fields] of Object.entries(fieldObjects)) {
182
+ const fieldArray = fields;
183
+ for (const field of fieldArray) {
184
+ if (field.alternateText) {
185
+ const match = field.alternateText.match(/\|fontSize:(\d+)$/);
186
+ if (match) {
187
+ fontSizeMap[fieldName] = parseInt(match[1], 10);
188
+ break;
189
+ }
190
+ }
191
+ }
192
+ }
193
+ }
194
+ } catch (error) {
195
+ logger.warn("[FONT SIZE] Error extracting from PDF:", error);
196
+ }
197
+ }
198
+ return fontSizeMap;
199
+ }, [waitForInitialization]);
200
+ const injectFormFieldFontSizeCSS = useCallback(async (doc) => {
201
+ const styleId = "signiphi-pdf-font-size-style";
202
+ const existingStyle = doc.getElementById(styleId);
203
+ if (existingStyle) {
204
+ existingStyle.remove();
205
+ }
206
+ const fontSizeMap = await extractFieldFontSizes();
207
+ const cssRules = [];
208
+ for (const [fieldName, fontSize] of Object.entries(fontSizeMap)) {
209
+ cssRules.push(`
210
+ input[name="${fieldName}"],
211
+ input[name="${fieldName}_date"],
212
+ select[name="${fieldName}"] {
213
+ font-size: ${fontSize}px !important;
214
+ }
215
+ `);
216
+ }
217
+ cssRules.push(`
218
+ input[data-element-id][name*="date"],
219
+ select[data-element-id] {
220
+ font-size: 18px !important;
221
+ }
222
+ `);
223
+ cssRules.push(`
224
+ input[type="text"][data-element-id]:not([style*="font-size"]),
225
+ select[data-element-id]:not([style*="font-size"]) {
226
+ font-size: 12px !important; /* Default fallback */
227
+ }
228
+ `);
229
+ const style = doc.createElement("style");
230
+ style.id = styleId;
231
+ style.textContent = `/* Dynamic font sizes from PDF metadata */
232
+ ${cssRules.join("\n")}`;
233
+ doc.head.appendChild(style);
234
+ }, [extractFieldFontSizes]);
162
235
  const loadPdf = useCallback(
163
236
  async (pdfUrl) => {
164
237
  const iframe = iframeRef.current;
@@ -189,7 +262,10 @@ var PdfViewerCore = forwardRef(
189
262
  try {
190
263
  const PDFViewerApplication = getPDFViewerApplication();
191
264
  if (PDFViewerApplication && PDFViewerApplication.initializedPromise) {
192
- PDFViewerApplication.initializedPromise.then(() => {
265
+ PDFViewerApplication.initializedPromise.then(async () => {
266
+ if (iframe.contentDocument) {
267
+ await injectFormFieldFontSizeCSS(iframe.contentDocument);
268
+ }
193
269
  resolve();
194
270
  }).catch(reject);
195
271
  } else {
@@ -269,6 +345,7 @@ var PdfViewerCore = forwardRef(
269
345
  }
270
346
  }
271
347
  logger.info(`[RADIO DETECT] Found ${Object.keys(radioGroups).length} radio groups:`, Object.keys(radioGroups));
348
+ const processedRadioFieldNames = new Set(Object.keys(radioGroups));
272
349
  for (const [fieldName, radioButtons] of Object.entries(radioGroups)) {
273
350
  const selectedRadio = radioButtons.find(
274
351
  (rb) => rb.data && typeof rb.data === "object" && rb.data.value === true
@@ -294,7 +371,7 @@ var PdfViewerCore = forwardRef(
294
371
  }
295
372
  for (const [id, data] of Object.entries(storedData)) {
296
373
  const fieldName = idToNameMap[id];
297
- if (fieldName && values[fieldName]) {
374
+ if (fieldName && (fieldName in values || processedRadioFieldNames.has(fieldName))) {
298
375
  continue;
299
376
  }
300
377
  if (fieldName) {
@@ -311,13 +388,13 @@ var PdfViewerCore = forwardRef(
311
388
  } else if (data !== void 0 && data !== null) {
312
389
  extractedValue = String(data);
313
390
  }
314
- if (extractedValue !== void 0 && extractedValue !== "") {
391
+ if (extractedValue !== void 0) {
315
392
  values[fieldName] = extractedValue;
316
393
  }
317
394
  }
318
395
  }
319
396
  for (const [name, fields] of Object.entries(fieldObjects)) {
320
- if (!values[name]) {
397
+ if (!(name in values)) {
321
398
  const fieldArray = fields;
322
399
  const field = fieldArray[0];
323
400
  if (field && field.value !== void 0 && field.value !== null) {
@@ -518,6 +595,8 @@ var PdfViewerCore = forwardRef(
518
595
  }
519
596
  }, 1e3);
520
597
  }, []);
598
+ const injectRadioLabels = useCallback((_fields) => {
599
+ }, []);
521
600
  const zoomIn = useCallback(async () => {
522
601
  try {
523
602
  const PDFViewerApplication = await waitForInitialization();
@@ -588,7 +667,7 @@ var PdfViewerCore = forwardRef(
588
667
  return null;
589
668
  }
590
669
  }, [waitForInitialization]);
591
- const attachFieldClickInterceptors = useCallback((onFieldClick) => {
670
+ const attachFieldClickInterceptors = useCallback(async (onFieldClick) => {
592
671
  const iframe = iframeRef.current;
593
672
  if (!iframe?.contentDocument) {
594
673
  logger.warn("Cannot attach field interceptors: iframe not ready");
@@ -596,6 +675,7 @@ var PdfViewerCore = forwardRef(
596
675
  }
597
676
  try {
598
677
  const doc = iframe.contentDocument;
678
+ await injectFormFieldFontSizeCSS(doc);
599
679
  const clickHighlightStyleId = "signiphi-click-highlight-style";
600
680
  if (!doc.getElementById(clickHighlightStyleId)) {
601
681
  const style = doc.createElement("style");
@@ -666,7 +746,7 @@ var PdfViewerCore = forwardRef(
666
746
  return;
667
747
  }
668
748
  logger.info(`Field click intercepted: ${fieldName}`, e.type);
669
- const shouldProceed = onFieldClick(fieldName);
749
+ const shouldProceed = onFieldClick(fieldName, target);
670
750
  logger.info(`Field ${fieldName} shouldProceed: ${shouldProceed}`);
671
751
  if (e.type !== "pointerdown" && e.type !== "mousedown") {
672
752
  if (!shouldProceed) {
@@ -742,6 +822,57 @@ var PdfViewerCore = forwardRef(
742
822
  logger.error("Error attaching field click interceptors:", error);
743
823
  }
744
824
  }, []);
825
+ const attachFieldChangeListeners = useCallback(async (onFieldChange) => {
826
+ try {
827
+ const iframe = iframeRef.current;
828
+ if (!iframe?.contentDocument) {
829
+ logger.warn("Cannot attach field change listeners: iframe not ready");
830
+ return () => {
831
+ };
832
+ }
833
+ const doc = iframe.contentDocument;
834
+ const handleChange = (event) => {
835
+ const target = event.target;
836
+ if (!target || !["INPUT", "SELECT", "TEXTAREA"].includes(target.tagName)) {
837
+ return;
838
+ }
839
+ const fieldName = target.getAttribute("name") || target.getAttribute("data-element-id") || target.getAttribute("id") || "";
840
+ if (!fieldName) return;
841
+ let value = "";
842
+ if (target.tagName === "INPUT") {
843
+ const inputElement = target;
844
+ if (inputElement.type === "checkbox") {
845
+ value = inputElement.checked ? "true" : "false";
846
+ } else if (inputElement.type === "radio") {
847
+ if (inputElement.checked) {
848
+ value = inputElement.value || "true";
849
+ } else {
850
+ return;
851
+ }
852
+ } else {
853
+ value = inputElement.value;
854
+ }
855
+ } else if (target.tagName === "SELECT") {
856
+ value = target.value;
857
+ } else if (target.tagName === "TEXTAREA") {
858
+ value = target.value;
859
+ }
860
+ onFieldChange(fieldName, value, target);
861
+ };
862
+ doc.addEventListener("change", handleChange, true);
863
+ doc.addEventListener("input", handleChange, true);
864
+ logger.info("Attached field change listeners to iframe document");
865
+ return () => {
866
+ doc.removeEventListener("change", handleChange, true);
867
+ doc.removeEventListener("input", handleChange, true);
868
+ logger.info("Removed field change listeners from iframe document");
869
+ };
870
+ } catch (error) {
871
+ logger.error("Error attaching field change listeners:", error);
872
+ return () => {
873
+ };
874
+ }
875
+ }, []);
745
876
  const addFieldIndicator = useCallback(async (fieldName, indicatorType = "completed", allowedFieldIds) => {
746
877
  try {
747
878
  const iframe = iframeRef.current;
@@ -957,6 +1088,275 @@ var PdfViewerCore = forwardRef(
957
1088
  logger.error("Error removing field indicator:", error);
958
1089
  }
959
1090
  }, []);
1091
+ const addDateFieldIndicator = useCallback((fieldName) => {
1092
+ try {
1093
+ const iframe = iframeRef.current;
1094
+ if (!iframe?.contentDocument) {
1095
+ logger.warn("Cannot add date field indicator: iframe not ready");
1096
+ return;
1097
+ }
1098
+ const doc = iframe.contentDocument;
1099
+ const formElement = doc.querySelector(
1100
+ `input[name="${fieldName}"], input[data-element-id="${fieldName}"], textarea[name="${fieldName}"], textarea[data-element-id="${fieldName}"]`
1101
+ );
1102
+ if (!formElement) {
1103
+ logger.warn(`Cannot add date indicator: field not found for "${fieldName}"`);
1104
+ return;
1105
+ }
1106
+ const annotationSection = formElement.closest("section");
1107
+ if (!annotationSection) {
1108
+ logger.warn(`Cannot add date indicator: no annotation section for "${fieldName}"`);
1109
+ return;
1110
+ }
1111
+ const existingIndicator = annotationSection.querySelector(".signiphi-date-field-indicator");
1112
+ if (existingIndicator) {
1113
+ existingIndicator.remove();
1114
+ }
1115
+ const indicator = doc.createElement("div");
1116
+ indicator.className = "signiphi-date-field-indicator";
1117
+ indicator.setAttribute("role", "button");
1118
+ indicator.setAttribute("aria-label", "Open calendar picker");
1119
+ indicator.setAttribute("tabindex", "0");
1120
+ indicator.innerHTML = `
1121
+ <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
1122
+ <rect x="2" y="3" width="14" height="13" rx="2" stroke="#6b7280" stroke-width="1.5" fill="white"/>
1123
+ <line x1="2" y1="6.5" x2="16" y2="6.5" stroke="#6b7280" stroke-width="1.5"/>
1124
+ <line x1="5.5" y1="1" x2="5.5" y2="5" stroke="#6b7280" stroke-width="1.5" stroke-linecap="round"/>
1125
+ <line x1="12.5" y1="1" x2="12.5" y2="5" stroke="#6b7280" stroke-width="1.5" stroke-linecap="round"/>
1126
+ <circle cx="5.5" cy="9.5" r="0.8" fill="#6b7280"/>
1127
+ <circle cx="9" cy="9.5" r="0.8" fill="#6b7280"/>
1128
+ <circle cx="12.5" cy="9.5" r="0.8" fill="#6b7280"/>
1129
+ <circle cx="5.5" cy="12.5" r="0.8" fill="#6b7280"/>
1130
+ <circle cx="9" cy="12.5" r="0.8" fill="#6b7280"/>
1131
+ <circle cx="12.5" cy="12.5" r="0.8" fill="#6b7280"/>
1132
+ </svg>
1133
+ `;
1134
+ Object.assign(indicator.style, {
1135
+ position: "absolute",
1136
+ top: "50%",
1137
+ right: "4px",
1138
+ transform: "translateY(-50%)",
1139
+ width: "24px",
1140
+ height: "24px",
1141
+ display: "flex",
1142
+ alignItems: "center",
1143
+ justifyContent: "center",
1144
+ zIndex: "1000",
1145
+ cursor: "pointer",
1146
+ opacity: "0.7",
1147
+ transition: "opacity 0.2s ease-in-out",
1148
+ pointerEvents: "auto",
1149
+ padding: "3px",
1150
+ borderRadius: "4px"
1151
+ });
1152
+ indicator.addEventListener("mouseenter", () => {
1153
+ indicator.style.opacity = "1";
1154
+ indicator.style.backgroundColor = "#f3f4f6";
1155
+ });
1156
+ indicator.addEventListener("mouseleave", () => {
1157
+ indicator.style.opacity = "0.7";
1158
+ indicator.style.backgroundColor = "transparent";
1159
+ });
1160
+ indicator.addEventListener("keydown", (e) => {
1161
+ if (e.key === "Enter" || e.key === " ") {
1162
+ e.preventDefault();
1163
+ indicator.click();
1164
+ }
1165
+ });
1166
+ const currentPosition = window.getComputedStyle(annotationSection).position;
1167
+ if (currentPosition === "static") {
1168
+ annotationSection.style.position = "relative";
1169
+ }
1170
+ annotationSection.appendChild(indicator);
1171
+ logger.info(`Added date field indicator for: ${fieldName}`);
1172
+ } catch (error) {
1173
+ logger.error("Error adding date field indicator:", error);
1174
+ }
1175
+ }, []);
1176
+ const removeDateFieldIndicator = useCallback((fieldName) => {
1177
+ try {
1178
+ const iframe = iframeRef.current;
1179
+ if (!iframe?.contentDocument) return;
1180
+ const doc = iframe.contentDocument;
1181
+ const formElement = doc.querySelector(
1182
+ `input[name="${fieldName}"], input[data-element-id="${fieldName}"], textarea[name="${fieldName}"], textarea[data-element-id="${fieldName}"]`
1183
+ );
1184
+ if (!formElement) return;
1185
+ const annotationSection = formElement.closest("section");
1186
+ if (!annotationSection) return;
1187
+ const indicator = annotationSection.querySelector(".signiphi-date-field-indicator");
1188
+ if (indicator) {
1189
+ indicator.remove();
1190
+ logger.info(`Removed date field indicator from: ${fieldName}`);
1191
+ }
1192
+ } catch (error) {
1193
+ logger.error("Error removing date field indicator:", error);
1194
+ }
1195
+ }, []);
1196
+ const findFieldElements = useCallback((fieldName) => {
1197
+ const iframe = iframeRef.current;
1198
+ if (!iframe?.contentDocument) return [];
1199
+ const doc = iframe.contentDocument;
1200
+ const targetElements = [];
1201
+ if (fieldName === "signature_field_main") {
1202
+ const allInputs = doc.querySelectorAll("input[name], input[data-element-id]");
1203
+ allInputs.forEach((input) => {
1204
+ const name = input.getAttribute("name") || input.getAttribute("data-element-id") || "";
1205
+ if (name.toLowerCase().includes("signature") && !name.toLowerCase().includes("initials")) {
1206
+ targetElements.push(input);
1207
+ }
1208
+ });
1209
+ } else if (fieldName === "initials_field_main") {
1210
+ const allInputs = doc.querySelectorAll("input[name], input[data-element-id]");
1211
+ allInputs.forEach((input) => {
1212
+ const name = input.getAttribute("name") || input.getAttribute("data-element-id") || "";
1213
+ if (name.toLowerCase().includes("initials")) {
1214
+ targetElements.push(input);
1215
+ }
1216
+ });
1217
+ } else {
1218
+ const formElement = doc.querySelector(
1219
+ `input[name="${fieldName}"], input[data-element-id="${fieldName}"]`
1220
+ );
1221
+ if (formElement) {
1222
+ targetElements.push(formElement);
1223
+ }
1224
+ }
1225
+ return targetElements;
1226
+ }, []);
1227
+ const previewSignature = useCallback((fieldName, dataUrl) => {
1228
+ try {
1229
+ const iframe = iframeRef.current;
1230
+ if (!iframe?.contentDocument) {
1231
+ logger.warn("Cannot preview signature: iframe not ready");
1232
+ return;
1233
+ }
1234
+ const doc = iframe.contentDocument;
1235
+ const targetElements = findFieldElements(fieldName);
1236
+ targetElements.forEach((formElement) => {
1237
+ const annotationSection = formElement.closest("section");
1238
+ if (!annotationSection) return;
1239
+ const existing = annotationSection.querySelector(".signiphi-signature-preview");
1240
+ if (existing) existing.remove();
1241
+ if (!dataUrl) return;
1242
+ const preview = doc.createElement("div");
1243
+ preview.className = "signiphi-signature-preview";
1244
+ preview.setAttribute("aria-hidden", "true");
1245
+ const img = doc.createElement("img");
1246
+ img.src = dataUrl;
1247
+ img.alt = "";
1248
+ Object.assign(img.style, {
1249
+ width: "100%",
1250
+ height: "100%",
1251
+ objectFit: "contain",
1252
+ pointerEvents: "none"
1253
+ });
1254
+ preview.appendChild(img);
1255
+ Object.assign(preview.style, {
1256
+ position: "absolute",
1257
+ top: "0",
1258
+ left: "0",
1259
+ width: "100%",
1260
+ height: "100%",
1261
+ display: "flex",
1262
+ alignItems: "center",
1263
+ justifyContent: "center",
1264
+ zIndex: "999",
1265
+ pointerEvents: "none",
1266
+ padding: "2px",
1267
+ boxSizing: "border-box",
1268
+ backgroundColor: "rgba(255, 255, 255, 0.85)",
1269
+ opacity: "0",
1270
+ transition: "opacity 0.3s ease-in-out"
1271
+ });
1272
+ const currentPosition = annotationSection.style.position || getComputedStyle(annotationSection).position;
1273
+ if (currentPosition === "static" || !currentPosition) {
1274
+ annotationSection.style.position = "relative";
1275
+ }
1276
+ annotationSection.appendChild(preview);
1277
+ requestAnimationFrame(() => {
1278
+ preview.style.opacity = "1";
1279
+ });
1280
+ });
1281
+ logger.info(`Previewed signature on ${targetElements.length} field(s) for: ${fieldName}`);
1282
+ } catch (error) {
1283
+ logger.error("Error previewing signature:", error);
1284
+ }
1285
+ }, [findFieldElements]);
1286
+ const previewInitials = useCallback((fieldName, text) => {
1287
+ try {
1288
+ const iframe = iframeRef.current;
1289
+ if (!iframe?.contentDocument) {
1290
+ logger.warn("Cannot preview initials: iframe not ready");
1291
+ return;
1292
+ }
1293
+ const doc = iframe.contentDocument;
1294
+ const targetElements = findFieldElements(fieldName);
1295
+ targetElements.forEach((formElement) => {
1296
+ const annotationSection = formElement.closest("section");
1297
+ if (!annotationSection) return;
1298
+ const existing = annotationSection.querySelector(".signiphi-initials-preview");
1299
+ if (existing) existing.remove();
1300
+ if (!text) return;
1301
+ const preview = doc.createElement("div");
1302
+ preview.className = "signiphi-initials-preview";
1303
+ preview.setAttribute("aria-hidden", "true");
1304
+ preview.textContent = text;
1305
+ Object.assign(preview.style, {
1306
+ position: "absolute",
1307
+ top: "0",
1308
+ left: "0",
1309
+ width: "100%",
1310
+ height: "100%",
1311
+ display: "flex",
1312
+ alignItems: "center",
1313
+ justifyContent: "center",
1314
+ zIndex: "999",
1315
+ pointerEvents: "none",
1316
+ fontFamily: "'Dancing Script', 'Brush Script MT', cursive",
1317
+ fontStyle: "italic",
1318
+ fontSize: "70%",
1319
+ color: "#000000",
1320
+ backgroundColor: "rgba(255, 255, 255, 0.85)",
1321
+ overflow: "hidden",
1322
+ opacity: "0",
1323
+ transition: "opacity 0.3s ease-in-out"
1324
+ });
1325
+ const currentPosition = annotationSection.style.position || getComputedStyle(annotationSection).position;
1326
+ if (currentPosition === "static" || !currentPosition) {
1327
+ annotationSection.style.position = "relative";
1328
+ }
1329
+ annotationSection.appendChild(preview);
1330
+ requestAnimationFrame(() => {
1331
+ preview.style.opacity = "1";
1332
+ });
1333
+ });
1334
+ logger.info(`Previewed initials on ${targetElements.length} field(s) for: ${fieldName}`);
1335
+ } catch (error) {
1336
+ logger.error("Error previewing initials:", error);
1337
+ }
1338
+ }, [findFieldElements]);
1339
+ const clearFieldPreviews = useCallback((fieldName) => {
1340
+ try {
1341
+ const iframe = iframeRef.current;
1342
+ if (!iframe?.contentDocument) return;
1343
+ const doc = iframe.contentDocument;
1344
+ const selectors = ".signiphi-signature-preview, .signiphi-initials-preview";
1345
+ if (fieldName) {
1346
+ const targetElements = findFieldElements(fieldName);
1347
+ targetElements.forEach((el) => {
1348
+ const section = el.closest("section");
1349
+ if (section) {
1350
+ section.querySelectorAll(selectors).forEach((p) => p.remove());
1351
+ }
1352
+ });
1353
+ } else {
1354
+ doc.querySelectorAll(selectors).forEach((el) => el.remove());
1355
+ }
1356
+ } catch (error) {
1357
+ logger.error("Error clearing field previews:", error);
1358
+ }
1359
+ }, [findFieldElements]);
960
1360
  useEffect(() => {
961
1361
  if (!versionChecked) {
962
1362
  const config = getPdfJsConfig();
@@ -1018,22 +1418,14 @@ Or check your configuration.`;
1018
1418
  await initializationPromise.current;
1019
1419
  isLoadingRef.current = false;
1020
1420
  onLoad?.();
1021
- } else {
1022
- const PDFViewerApplication = getPDFViewerApplication();
1023
- if (PDFViewerApplication) {
1024
- isLoadingRef.current = false;
1025
- onLoad?.();
1026
- } else {
1027
- throw new Error("PDFViewerApplication not found after iframe load");
1028
- }
1029
1421
  }
1030
1422
  } catch (error) {
1031
- const errorMessage = error instanceof Error ? error.message : "Unknown error loading PDF viewer";
1032
- logger.error("Error in PDF.js initialization:", error);
1423
+ const errorMessage = error instanceof Error ? error.message : "Failed to load PDF viewer";
1424
+ logger.error("Error in handleIframeLoad:", errorMessage);
1033
1425
  isLoadingRef.current = false;
1034
1426
  onError?.(errorMessage);
1035
1427
  }
1036
- }, 1e3);
1428
+ }, 100);
1037
1429
  } catch (error) {
1038
1430
  const errorMessage = error instanceof Error ? error.message : "Unknown error in iframe load handler";
1039
1431
  logger.error("Error in iframe load handler:", error);
@@ -1051,6 +1443,8 @@ Or check your configuration.`;
1051
1443
  saveDocument,
1052
1444
  getPDFViewerApplication,
1053
1445
  injectPlaceholders,
1446
+ injectRadioLabels,
1447
+ setFieldMetadata,
1054
1448
  zoomIn,
1055
1449
  zoomOut,
1056
1450
  nextPage,
@@ -1058,10 +1452,16 @@ Or check your configuration.`;
1058
1452
  getCurrentPage,
1059
1453
  getTotalPages,
1060
1454
  attachFieldClickInterceptors,
1455
+ attachFieldChangeListeners,
1061
1456
  addFieldIndicator,
1062
- removeFieldIndicator
1457
+ removeFieldIndicator,
1458
+ addDateFieldIndicator,
1459
+ removeDateFieldIndicator,
1460
+ previewSignature,
1461
+ previewInitials,
1462
+ clearFieldPreviews
1063
1463
  }),
1064
- [loadPdf, getFormFieldValues, setFormFieldValues, getAllFieldNames, saveDocument, getPDFViewerApplication, injectPlaceholders, zoomIn, zoomOut, nextPage, previousPage, getCurrentPage, getTotalPages, attachFieldClickInterceptors, addFieldIndicator, removeFieldIndicator]
1464
+ [loadPdf, getFormFieldValues, setFormFieldValues, getAllFieldNames, saveDocument, getPDFViewerApplication, injectPlaceholders, injectRadioLabels, setFieldMetadata, zoomIn, zoomOut, nextPage, previousPage, getCurrentPage, getTotalPages, attachFieldClickInterceptors, attachFieldChangeListeners, addFieldIndicator, removeFieldIndicator, addDateFieldIndicator, removeDateFieldIndicator, previewSignature, previewInitials, clearFieldPreviews]
1065
1465
  );
1066
1466
  return /* @__PURE__ */ jsx(Fragment, { children: children({ iframeRef, handleIframeLoad }) });
1067
1467
  }