@drvillo/react-browser-e-signing 0.3.1 → 0.4.0
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.
- package/INTEGRATION_GUIDELINES.md +197 -16
- package/dist/index.d.ts +41 -8
- package/dist/index.js +257 -70
- package/dist/index.js.map +1 -1
- package/dist/styles.css +73 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { pdfjs, Document, Page } from 'react-pdf';
|
|
2
|
-
import { useEffect, useRef,
|
|
2
|
+
import { useEffect, useRef, useState, useMemo, useCallback } from 'react';
|
|
3
3
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
4
|
import SignaturePadLibrary from 'signature_pad';
|
|
5
5
|
import fontkit from '@pdf-lib/fontkit';
|
|
6
|
-
import { PDFDocument, StandardFonts } from 'pdf-lib';
|
|
6
|
+
import { PDFDocument, StandardFonts, rgb } from 'pdf-lib';
|
|
7
7
|
|
|
8
8
|
// src/lib/config.ts
|
|
9
9
|
var _config = {};
|
|
@@ -240,12 +240,82 @@ function getFieldPreviewText(field, preview) {
|
|
|
240
240
|
if (field.type === "fullName") return preview.fullName;
|
|
241
241
|
if (field.type === "title") return preview.title;
|
|
242
242
|
if (field.type === "date") return preview.dateText;
|
|
243
|
+
if (field.type === "custom" && field.label) return preview.customFields?.[field.label] ?? "";
|
|
243
244
|
return "";
|
|
244
245
|
}
|
|
245
|
-
function SignatureField({
|
|
246
|
+
function SignatureField({
|
|
247
|
+
field,
|
|
248
|
+
onUpdateField,
|
|
249
|
+
onRemoveField,
|
|
250
|
+
preview,
|
|
251
|
+
onUpdateCustomValue,
|
|
252
|
+
onCustomFieldRenamed,
|
|
253
|
+
className
|
|
254
|
+
}) {
|
|
246
255
|
const rootRef = useRef(null);
|
|
247
256
|
const dragStateRef = useRef(null);
|
|
248
257
|
const resizeStateRef = useRef(null);
|
|
258
|
+
const labelInputRef = useRef(null);
|
|
259
|
+
const valueInputRef = useRef(null);
|
|
260
|
+
const nextLabelModeRef = useRef("idle");
|
|
261
|
+
const isCustom = field.type === "custom";
|
|
262
|
+
const [editMode, setEditMode] = useState(
|
|
263
|
+
isCustom && !field.label ? "label" : "idle"
|
|
264
|
+
);
|
|
265
|
+
const [labelDraft, setLabelDraft] = useState(field.label ?? "");
|
|
266
|
+
const [valueDraft, setValueDraft] = useState("");
|
|
267
|
+
useEffect(() => {
|
|
268
|
+
if (editMode !== "label") return;
|
|
269
|
+
const id = setTimeout(() => labelInputRef.current?.focus(), 0);
|
|
270
|
+
return () => clearTimeout(id);
|
|
271
|
+
}, [editMode]);
|
|
272
|
+
useEffect(() => {
|
|
273
|
+
if (editMode !== "value") return;
|
|
274
|
+
const id = setTimeout(() => valueInputRef.current?.focus(), 0);
|
|
275
|
+
return () => clearTimeout(id);
|
|
276
|
+
}, [editMode]);
|
|
277
|
+
useEffect(() => {
|
|
278
|
+
if (editMode === "idle") setLabelDraft(field.label ?? "");
|
|
279
|
+
}, [field.label, editMode]);
|
|
280
|
+
function handleLabelKeyDown(e) {
|
|
281
|
+
if (e.key === "Enter" || e.key === "Tab") {
|
|
282
|
+
e.preventDefault();
|
|
283
|
+
nextLabelModeRef.current = onUpdateCustomValue ? "value" : "idle";
|
|
284
|
+
labelInputRef.current?.blur();
|
|
285
|
+
}
|
|
286
|
+
if (e.key === "Escape") {
|
|
287
|
+
nextLabelModeRef.current = "idle";
|
|
288
|
+
setLabelDraft(field.label ?? "");
|
|
289
|
+
labelInputRef.current?.blur();
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function handleLabelBlur() {
|
|
293
|
+
const trimmed = labelDraft.trim();
|
|
294
|
+
if (trimmed) {
|
|
295
|
+
onUpdateField(field.id, { label: trimmed });
|
|
296
|
+
if (field.label && trimmed !== field.label) {
|
|
297
|
+
onCustomFieldRenamed?.(field.label, trimmed);
|
|
298
|
+
}
|
|
299
|
+
} else {
|
|
300
|
+
setLabelDraft(field.label ?? "");
|
|
301
|
+
}
|
|
302
|
+
const next = nextLabelModeRef.current;
|
|
303
|
+
nextLabelModeRef.current = "idle";
|
|
304
|
+
if (next === "value") {
|
|
305
|
+
setValueDraft(preview.customFields?.[trimmed || field.label || ""] ?? "");
|
|
306
|
+
}
|
|
307
|
+
setEditMode(next);
|
|
308
|
+
}
|
|
309
|
+
function handleValueKeyDown(e) {
|
|
310
|
+
if (e.key === "Enter" || e.key === "Tab" || e.key === "Escape") {
|
|
311
|
+
e.preventDefault();
|
|
312
|
+
valueInputRef.current?.blur();
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
function handleValueBlur() {
|
|
316
|
+
if (field.label && onUpdateCustomValue) onUpdateCustomValue(field.label, valueDraft);
|
|
317
|
+
setEditMode("idle");
|
|
318
|
+
}
|
|
249
319
|
function handleDragPointerDown(event) {
|
|
250
320
|
event.stopPropagation();
|
|
251
321
|
if (event.button !== 0) return;
|
|
@@ -299,13 +369,10 @@ function SignatureField({ field, onUpdateField, onRemoveField, preview, classNam
|
|
|
299
369
|
const deltaHeightPercent = deltaY / parentElement.clientHeight * 100;
|
|
300
370
|
const maxWidth = 100 - field.xPercent;
|
|
301
371
|
const maxHeight = 100 - field.yPercent;
|
|
302
|
-
|
|
303
|
-
Math.min(maxWidth, Math.max(MIN_WIDTH_PERCENT, resizeStateRef.current.startWidthPercent + deltaWidthPercent))
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
Math.min(maxHeight, Math.max(MIN_HEIGHT_PERCENT, resizeStateRef.current.startHeightPercent + deltaHeightPercent))
|
|
307
|
-
);
|
|
308
|
-
onUpdateField(field.id, { widthPercent, heightPercent });
|
|
372
|
+
onUpdateField(field.id, {
|
|
373
|
+
widthPercent: clampPercent(Math.min(maxWidth, Math.max(MIN_WIDTH_PERCENT, resizeStateRef.current.startWidthPercent + deltaWidthPercent))),
|
|
374
|
+
heightPercent: clampPercent(Math.min(maxHeight, Math.max(MIN_HEIGHT_PERCENT, resizeStateRef.current.startHeightPercent + deltaHeightPercent)))
|
|
375
|
+
});
|
|
309
376
|
}
|
|
310
377
|
function handleResizePointerUp(event) {
|
|
311
378
|
resizeStateRef.current = null;
|
|
@@ -313,14 +380,13 @@ function SignatureField({ field, onUpdateField, onRemoveField, preview, classNam
|
|
|
313
380
|
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
314
381
|
}
|
|
315
382
|
const previewText = getFieldPreviewText(field, preview);
|
|
316
|
-
const
|
|
383
|
+
const fieldLabel = isCustom && field.label ? field.label : field.type;
|
|
317
384
|
return /* @__PURE__ */ jsxs(
|
|
318
385
|
"div",
|
|
319
386
|
{
|
|
320
387
|
ref: rootRef,
|
|
321
388
|
"data-slot": "signature-field",
|
|
322
389
|
"data-field-type": field.type,
|
|
323
|
-
"data-locked": isLocked ? true : void 0,
|
|
324
390
|
className: cn(className),
|
|
325
391
|
style: {
|
|
326
392
|
position: "absolute",
|
|
@@ -328,18 +394,11 @@ function SignatureField({ field, onUpdateField, onRemoveField, preview, classNam
|
|
|
328
394
|
top: `${field.yPercent}%`,
|
|
329
395
|
width: `${field.widthPercent}%`,
|
|
330
396
|
height: `${field.heightPercent}%`,
|
|
331
|
-
userSelect: "none"
|
|
332
|
-
cursor: isLocked ? "default" : void 0,
|
|
333
|
-
...isLocked && {
|
|
334
|
-
borderStyle: "dashed",
|
|
335
|
-
borderWidth: 1,
|
|
336
|
-
borderColor: "rgba(100, 116, 139, 0.55)",
|
|
337
|
-
boxSizing: "border-box"
|
|
338
|
-
}
|
|
397
|
+
userSelect: "none"
|
|
339
398
|
},
|
|
340
|
-
onPointerDown:
|
|
341
|
-
onPointerMove:
|
|
342
|
-
onPointerUp:
|
|
399
|
+
onPointerDown: handleDragPointerDown,
|
|
400
|
+
onPointerMove: handleDragPointerMove,
|
|
401
|
+
onPointerUp: handleDragPointerUp,
|
|
343
402
|
children: [
|
|
344
403
|
/* @__PURE__ */ jsxs(
|
|
345
404
|
"div",
|
|
@@ -350,11 +409,37 @@ function SignatureField({ field, onUpdateField, onRemoveField, preview, classNam
|
|
|
350
409
|
height: "100%",
|
|
351
410
|
width: "100%",
|
|
352
411
|
alignItems: "stretch",
|
|
353
|
-
justifyContent: "space-between"
|
|
412
|
+
justifyContent: "space-between",
|
|
413
|
+
boxSizing: "border-box",
|
|
414
|
+
overflow: "hidden"
|
|
354
415
|
},
|
|
355
416
|
children: [
|
|
356
417
|
/* @__PURE__ */ jsxs("div", { "data-slot": "signature-field-preview", children: [
|
|
357
|
-
|
|
418
|
+
isCustom && editMode === "label" ? /* @__PURE__ */ jsx(
|
|
419
|
+
"input",
|
|
420
|
+
{
|
|
421
|
+
ref: labelInputRef,
|
|
422
|
+
"data-slot": "signature-field-label-input",
|
|
423
|
+
value: labelDraft,
|
|
424
|
+
placeholder: "Field name\u2026",
|
|
425
|
+
onChange: (e) => setLabelDraft(e.target.value),
|
|
426
|
+
onBlur: handleLabelBlur,
|
|
427
|
+
onKeyDown: handleLabelKeyDown,
|
|
428
|
+
onPointerDown: (e) => e.stopPropagation()
|
|
429
|
+
}
|
|
430
|
+
) : /* @__PURE__ */ jsx(
|
|
431
|
+
"div",
|
|
432
|
+
{
|
|
433
|
+
"data-slot": "signature-field-label",
|
|
434
|
+
title: isCustom ? "Click to rename" : void 0,
|
|
435
|
+
style: { cursor: isCustom ? "text" : void 0 },
|
|
436
|
+
onClick: isCustom ? () => {
|
|
437
|
+
setLabelDraft(field.label ?? "");
|
|
438
|
+
setEditMode("label");
|
|
439
|
+
} : void 0,
|
|
440
|
+
children: fieldLabel
|
|
441
|
+
}
|
|
442
|
+
),
|
|
358
443
|
field.type === "signature" && preview.signatureDataUrl ? /* @__PURE__ */ jsx(
|
|
359
444
|
"img",
|
|
360
445
|
{
|
|
@@ -363,41 +448,32 @@ function SignatureField({ field, onUpdateField, onRemoveField, preview, classNam
|
|
|
363
448
|
alt: "signature preview",
|
|
364
449
|
draggable: false
|
|
365
450
|
}
|
|
366
|
-
) :
|
|
451
|
+
) : isCustom && editMode === "value" ? /* @__PURE__ */ jsx(
|
|
452
|
+
"input",
|
|
453
|
+
{
|
|
454
|
+
ref: valueInputRef,
|
|
455
|
+
"data-slot": "signature-field-value-input",
|
|
456
|
+
value: valueDraft,
|
|
457
|
+
placeholder: "Value\u2026",
|
|
458
|
+
onChange: (e) => setValueDraft(e.target.value),
|
|
459
|
+
onBlur: handleValueBlur,
|
|
460
|
+
onKeyDown: handleValueKeyDown,
|
|
461
|
+
onPointerDown: (e) => e.stopPropagation()
|
|
462
|
+
}
|
|
463
|
+
) : /* @__PURE__ */ jsx(
|
|
464
|
+
"div",
|
|
465
|
+
{
|
|
466
|
+
"data-slot": "signature-field-preview-text",
|
|
467
|
+
style: { cursor: isCustom && editMode === "idle" ? "text" : void 0 },
|
|
468
|
+
onClick: isCustom && editMode === "idle" ? () => {
|
|
469
|
+
setValueDraft(preview.customFields?.[field.label ?? ""] ?? "");
|
|
470
|
+
setEditMode("value");
|
|
471
|
+
} : void 0,
|
|
472
|
+
children: previewText || "\u2014"
|
|
473
|
+
}
|
|
474
|
+
)
|
|
367
475
|
] }),
|
|
368
|
-
|
|
369
|
-
"div",
|
|
370
|
-
{
|
|
371
|
-
"data-slot": "signature-field-lock",
|
|
372
|
-
"aria-label": "Locked field",
|
|
373
|
-
style: {
|
|
374
|
-
flexShrink: 0,
|
|
375
|
-
display: "flex",
|
|
376
|
-
alignItems: "flex-start",
|
|
377
|
-
justifyContent: "center",
|
|
378
|
-
padding: "2px",
|
|
379
|
-
color: "rgba(71, 85, 105, 0.9)"
|
|
380
|
-
},
|
|
381
|
-
children: /* @__PURE__ */ jsxs(
|
|
382
|
-
"svg",
|
|
383
|
-
{
|
|
384
|
-
width: "14",
|
|
385
|
-
height: "14",
|
|
386
|
-
viewBox: "0 0 24 24",
|
|
387
|
-
fill: "none",
|
|
388
|
-
stroke: "currentColor",
|
|
389
|
-
strokeWidth: "2",
|
|
390
|
-
strokeLinecap: "round",
|
|
391
|
-
strokeLinejoin: "round",
|
|
392
|
-
"aria-hidden": true,
|
|
393
|
-
children: [
|
|
394
|
-
/* @__PURE__ */ jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }),
|
|
395
|
-
/* @__PURE__ */ jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })
|
|
396
|
-
]
|
|
397
|
-
}
|
|
398
|
-
)
|
|
399
|
-
}
|
|
400
|
-
) : /* @__PURE__ */ jsx(
|
|
476
|
+
/* @__PURE__ */ jsx(
|
|
401
477
|
"button",
|
|
402
478
|
{
|
|
403
479
|
type: "button",
|
|
@@ -414,7 +490,7 @@ function SignatureField({ field, onUpdateField, onRemoveField, preview, classNam
|
|
|
414
490
|
]
|
|
415
491
|
}
|
|
416
492
|
),
|
|
417
|
-
|
|
493
|
+
/* @__PURE__ */ jsx(
|
|
418
494
|
"div",
|
|
419
495
|
{
|
|
420
496
|
"data-slot": "signature-field-resize",
|
|
@@ -430,7 +506,7 @@ function SignatureField({ field, onUpdateField, onRemoveField, preview, classNam
|
|
|
430
506
|
onPointerMove: handleResizePointerMove,
|
|
431
507
|
onPointerUp: handleResizePointerUp
|
|
432
508
|
}
|
|
433
|
-
)
|
|
509
|
+
)
|
|
434
510
|
]
|
|
435
511
|
}
|
|
436
512
|
);
|
|
@@ -442,6 +518,8 @@ function FieldOverlay({
|
|
|
442
518
|
onAddField,
|
|
443
519
|
onUpdateField,
|
|
444
520
|
onRemoveField,
|
|
521
|
+
onUpdateCustomValue,
|
|
522
|
+
onCustomFieldRenamed,
|
|
445
523
|
preview,
|
|
446
524
|
className
|
|
447
525
|
}) {
|
|
@@ -480,6 +558,8 @@ function FieldOverlay({
|
|
|
480
558
|
field,
|
|
481
559
|
onUpdateField,
|
|
482
560
|
onRemoveField,
|
|
561
|
+
onUpdateCustomValue,
|
|
562
|
+
onCustomFieldRenamed,
|
|
483
563
|
preview
|
|
484
564
|
},
|
|
485
565
|
field.id
|
|
@@ -491,11 +571,12 @@ var FIELD_LABELS = {
|
|
|
491
571
|
signature: "Signature",
|
|
492
572
|
fullName: "Full Name",
|
|
493
573
|
title: "Title",
|
|
494
|
-
date: "Date"
|
|
574
|
+
date: "Date",
|
|
575
|
+
custom: "Custom"
|
|
495
576
|
};
|
|
496
|
-
var
|
|
497
|
-
function FieldPalette({ selectedFieldType, onSelectFieldType, className }) {
|
|
498
|
-
return /* @__PURE__ */ jsx("div", { "data-slot": "field-palette", className: cn(className), children:
|
|
577
|
+
var DEFAULT_FIELD_TYPES = ["signature", "fullName", "title", "date"];
|
|
578
|
+
function FieldPalette({ selectedFieldType, onSelectFieldType, fieldTypes = DEFAULT_FIELD_TYPES, className }) {
|
|
579
|
+
return /* @__PURE__ */ jsx("div", { "data-slot": "field-palette", className: cn(className), children: fieldTypes.map((fieldType) => {
|
|
499
580
|
const isSelected = selectedFieldType === fieldType;
|
|
500
581
|
return /* @__PURE__ */ jsx(
|
|
501
582
|
"button",
|
|
@@ -704,6 +785,74 @@ function SigningComplete({
|
|
|
704
785
|
] })
|
|
705
786
|
] });
|
|
706
787
|
}
|
|
788
|
+
function CustomFieldInputs({ labels, values, onValuesChange, className }) {
|
|
789
|
+
if (labels.length === 0) return null;
|
|
790
|
+
function handleChange(label, value) {
|
|
791
|
+
onValuesChange({ ...values, [label]: value });
|
|
792
|
+
}
|
|
793
|
+
function toInputId(label) {
|
|
794
|
+
const normalized = label.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
795
|
+
return normalized ? `custom-field-${normalized}` : "custom-field";
|
|
796
|
+
}
|
|
797
|
+
const uniqueLabels = [...new Set(labels)];
|
|
798
|
+
return /* @__PURE__ */ jsx("div", { "data-slot": "custom-field-inputs", className: cn(className), children: uniqueLabels.map((label) => /* @__PURE__ */ jsxs("div", { "data-slot": "custom-field-inputs-field", children: [
|
|
799
|
+
/* @__PURE__ */ jsx("label", { "data-slot": "custom-field-inputs-label", htmlFor: toInputId(label), children: label }),
|
|
800
|
+
/* @__PURE__ */ jsx(
|
|
801
|
+
"input",
|
|
802
|
+
{
|
|
803
|
+
"data-slot": "custom-field-inputs-input",
|
|
804
|
+
id: toInputId(label),
|
|
805
|
+
type: "text",
|
|
806
|
+
value: values[label] ?? "",
|
|
807
|
+
onChange: (event) => handleChange(label, event.target.value)
|
|
808
|
+
}
|
|
809
|
+
)
|
|
810
|
+
] }, label)) });
|
|
811
|
+
}
|
|
812
|
+
function CustomFieldsPanel({
|
|
813
|
+
fields,
|
|
814
|
+
values,
|
|
815
|
+
onValuesChange,
|
|
816
|
+
isPlacingField,
|
|
817
|
+
onTogglePlacing,
|
|
818
|
+
className
|
|
819
|
+
}) {
|
|
820
|
+
const seen = /* @__PURE__ */ new Set();
|
|
821
|
+
const uniqueLabels = [];
|
|
822
|
+
for (const f of fields) {
|
|
823
|
+
if (f.type === "custom" && f.label && !seen.has(f.label)) {
|
|
824
|
+
seen.add(f.label);
|
|
825
|
+
uniqueLabels.push(f.label);
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
function handleChange(label, value) {
|
|
829
|
+
onValuesChange({ ...values, [label]: value });
|
|
830
|
+
}
|
|
831
|
+
return /* @__PURE__ */ jsxs("div", { "data-slot": "custom-fields-panel", className: cn(className), children: [
|
|
832
|
+
/* @__PURE__ */ jsx("h2", { "data-slot": "custom-fields-panel-heading", children: "Custom Fields" }),
|
|
833
|
+
uniqueLabels.map((label) => /* @__PURE__ */ jsxs("label", { "data-slot": "custom-fields-panel-label", children: [
|
|
834
|
+
label,
|
|
835
|
+
/* @__PURE__ */ jsx(
|
|
836
|
+
"input",
|
|
837
|
+
{
|
|
838
|
+
"data-slot": "custom-fields-panel-input",
|
|
839
|
+
value: values[label] ?? "",
|
|
840
|
+
onChange: (e) => handleChange(label, e.target.value)
|
|
841
|
+
}
|
|
842
|
+
)
|
|
843
|
+
] }, label)),
|
|
844
|
+
/* @__PURE__ */ jsx(
|
|
845
|
+
"button",
|
|
846
|
+
{
|
|
847
|
+
type: "button",
|
|
848
|
+
"data-slot": "custom-fields-panel-add-button",
|
|
849
|
+
"data-state": isPlacingField ? "placing" : "idle",
|
|
850
|
+
onClick: onTogglePlacing,
|
|
851
|
+
children: isPlacingField ? "Click on the PDF to place\u2026" : "+ New field"
|
|
852
|
+
}
|
|
853
|
+
)
|
|
854
|
+
] });
|
|
855
|
+
}
|
|
707
856
|
function isArrayBuffer(value) {
|
|
708
857
|
return value instanceof ArrayBuffer;
|
|
709
858
|
}
|
|
@@ -879,7 +1028,7 @@ function useFieldPlacement(options = {}) {
|
|
|
879
1028
|
const defaultHeightPercent = options.defaultHeightPercent ?? 5;
|
|
880
1029
|
const [fields, setFields] = useState(options.initialFields ?? []);
|
|
881
1030
|
const addField = useCallback(
|
|
882
|
-
({ pageIndex, type, xPercent, yPercent }) => {
|
|
1031
|
+
({ pageIndex, type, xPercent, yPercent, label }) => {
|
|
883
1032
|
const field = {
|
|
884
1033
|
id: buildFieldId(),
|
|
885
1034
|
pageIndex,
|
|
@@ -887,13 +1036,23 @@ function useFieldPlacement(options = {}) {
|
|
|
887
1036
|
xPercent: clampPercent2(xPercent),
|
|
888
1037
|
yPercent: clampPercent2(yPercent),
|
|
889
1038
|
widthPercent: clampPercent2(defaultWidthPercent),
|
|
890
|
-
heightPercent: clampPercent2(defaultHeightPercent)
|
|
1039
|
+
heightPercent: clampPercent2(defaultHeightPercent),
|
|
1040
|
+
...label !== void 0 && { label }
|
|
891
1041
|
};
|
|
892
1042
|
setFields((previousFields) => [...previousFields, field]);
|
|
893
1043
|
return field;
|
|
894
1044
|
},
|
|
895
1045
|
[defaultHeightPercent, defaultWidthPercent]
|
|
896
1046
|
);
|
|
1047
|
+
const appendFields = useCallback((nextFields) => {
|
|
1048
|
+
if (!nextFields.length) return;
|
|
1049
|
+
setFields((previousFields) => {
|
|
1050
|
+
const existingIds = new Set(previousFields.map((field) => field.id));
|
|
1051
|
+
const uniqueNextFields = nextFields.filter((field) => !existingIds.has(field.id));
|
|
1052
|
+
if (!uniqueNextFields.length) return previousFields;
|
|
1053
|
+
return [...previousFields, ...uniqueNextFields];
|
|
1054
|
+
});
|
|
1055
|
+
}, []);
|
|
897
1056
|
const updateField = useCallback((id, partial) => {
|
|
898
1057
|
setFields(
|
|
899
1058
|
(previousFields) => previousFields.map((field) => {
|
|
@@ -918,11 +1077,12 @@ function useFieldPlacement(options = {}) {
|
|
|
918
1077
|
const fieldActions = useMemo(
|
|
919
1078
|
() => ({
|
|
920
1079
|
addField,
|
|
1080
|
+
appendFields,
|
|
921
1081
|
updateField,
|
|
922
1082
|
removeField,
|
|
923
1083
|
clearFields
|
|
924
1084
|
}),
|
|
925
|
-
[addField, clearFields, removeField, updateField]
|
|
1085
|
+
[addField, appendFields, clearFields, removeField, updateField]
|
|
926
1086
|
);
|
|
927
1087
|
return {
|
|
928
1088
|
fields,
|
|
@@ -1108,6 +1268,27 @@ async function modifyPdf({
|
|
|
1108
1268
|
});
|
|
1109
1269
|
continue;
|
|
1110
1270
|
}
|
|
1271
|
+
if (field.type === "custom") {
|
|
1272
|
+
const pad = 2;
|
|
1273
|
+
page.drawRectangle({
|
|
1274
|
+
x: pointRect.x - pad,
|
|
1275
|
+
y: pointRect.y - pad,
|
|
1276
|
+
width: pointRect.width + pad * 2,
|
|
1277
|
+
height: pointRect.height + pad * 2,
|
|
1278
|
+
color: rgb(1, 1, 1)
|
|
1279
|
+
});
|
|
1280
|
+
const customValue = field.label ? signer.customFields?.[field.label] ?? "" : "";
|
|
1281
|
+
if (customValue) {
|
|
1282
|
+
const textSize2 = Math.max(9, Math.min(16, pointRect.height * 0.6));
|
|
1283
|
+
page.drawText(customValue, {
|
|
1284
|
+
x: pointRect.x + 2,
|
|
1285
|
+
y: pointRect.y + Math.max(0, (pointRect.height - textSize2) / 2),
|
|
1286
|
+
size: textSize2,
|
|
1287
|
+
font: helveticaFont
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
1290
|
+
continue;
|
|
1291
|
+
}
|
|
1111
1292
|
const textValue = field.type === "fullName" ? fullNameFromSigner(signer) : field.type === "title" ? signer.title : field.type === "date" ? resolvedDateText : "";
|
|
1112
1293
|
if (!textValue) continue;
|
|
1113
1294
|
const textSize = Math.max(9, Math.min(16, pointRect.height * 0.6));
|
|
@@ -1155,7 +1336,13 @@ var SLOTS = {
|
|
|
1155
1336
|
signatureFieldPreviewText: "signature-field-preview-text",
|
|
1156
1337
|
signatureFieldRemove: "signature-field-remove",
|
|
1157
1338
|
signatureFieldResize: "signature-field-resize",
|
|
1158
|
-
|
|
1339
|
+
signatureFieldLabelInput: "signature-field-label-input",
|
|
1340
|
+
signatureFieldValueInput: "signature-field-value-input",
|
|
1341
|
+
customFieldsPanel: "custom-fields-panel",
|
|
1342
|
+
customFieldsPanelHeading: "custom-fields-panel-heading",
|
|
1343
|
+
customFieldsPanelLabel: "custom-fields-panel-label",
|
|
1344
|
+
customFieldsPanelInput: "custom-fields-panel-input",
|
|
1345
|
+
customFieldsPanelAddButton: "custom-fields-panel-add-button",
|
|
1159
1346
|
fieldPalette: "field-palette",
|
|
1160
1347
|
fieldPaletteButton: "field-palette-button",
|
|
1161
1348
|
signerPanel: "signer-panel",
|
|
@@ -1193,6 +1380,6 @@ var defaults = {
|
|
|
1193
1380
|
DEFAULT_FIELD_HEIGHT_PERCENT: 5
|
|
1194
1381
|
};
|
|
1195
1382
|
|
|
1196
|
-
export { FieldOverlay, FieldPalette, PdfPageNavigator, PdfViewer, SIGNATURE_FONTS, SLOTS, SignatureField, SignaturePad, SignaturePreview, SignerDetailsPanel, SigningComplete, configure, defaults, loadSignatureFont, mapFromPoints, mapToPoints, modifyPdf, sha256, useFieldPlacement, usePdfDocument, usePdfPageVisibility, useSignatureRenderer };
|
|
1383
|
+
export { CustomFieldInputs, CustomFieldsPanel, FieldOverlay, FieldPalette, PdfPageNavigator, PdfViewer, SIGNATURE_FONTS, SLOTS, SignatureField, SignaturePad, SignaturePreview, SignerDetailsPanel, SigningComplete, configure, defaults, loadSignatureFont, mapFromPoints, mapToPoints, modifyPdf, sha256, useFieldPlacement, usePdfDocument, usePdfPageVisibility, useSignatureRenderer };
|
|
1197
1384
|
//# sourceMappingURL=index.js.map
|
|
1198
1385
|
//# sourceMappingURL=index.js.map
|