@josephomills/esign 0.7.1 → 0.9.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/dist/{ports-CkBaAepo.d.cts → ports--YsOnh8H.d.cts} +120 -15
- package/dist/{ports-CkBaAepo.d.ts → ports--YsOnh8H.d.ts} +120 -15
- package/dist/prisma/index.cjs +21 -4
- package/dist/prisma/index.cjs.map +1 -1
- package/dist/prisma/index.d.cts +1 -1
- package/dist/prisma/index.d.ts +1 -1
- package/dist/prisma/index.js +21 -4
- package/dist/prisma/index.js.map +1 -1
- package/dist/server/index.cjs +112 -12
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +9 -5
- package/dist/server/index.d.ts +9 -5
- package/dist/server/index.js +108 -13
- package/dist/server/index.js.map +1 -1
- package/dist/ui/index.cjs +246 -29
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.d.cts +23 -1
- package/dist/ui/index.d.ts +23 -1
- package/dist/ui/index.js +246 -29
- package/dist/ui/index.js.map +1 -1
- package/package.json +1 -1
package/dist/ui/index.cjs
CHANGED
|
@@ -319,7 +319,7 @@ function PdfViewer({ url, placements, workerSrc, primaryColor = "#4f46e5" }) {
|
|
|
319
319
|
opacity: 0.85,
|
|
320
320
|
whiteSpace: "nowrap"
|
|
321
321
|
},
|
|
322
|
-
children: "\u270D Sign here"
|
|
322
|
+
children: pl.type === "date" ? "\u{1F4C5} Select a date" : "\u270D Sign here"
|
|
323
323
|
}
|
|
324
324
|
)
|
|
325
325
|
},
|
|
@@ -330,6 +330,27 @@ function PdfViewer({ url, placements, workerSrc, primaryColor = "#4f46e5" }) {
|
|
|
330
330
|
)
|
|
331
331
|
] });
|
|
332
332
|
}
|
|
333
|
+
|
|
334
|
+
// src/shared/fields.ts
|
|
335
|
+
var DATE_FORMATS = [
|
|
336
|
+
"DD/MM/YYYY",
|
|
337
|
+
"MM/DD/YYYY",
|
|
338
|
+
"YYYY-MM-DD",
|
|
339
|
+
"D MMM YYYY",
|
|
340
|
+
"Do MMM YYYY",
|
|
341
|
+
"Do MMMM YYYY",
|
|
342
|
+
"MMMM D, YYYY"
|
|
343
|
+
];
|
|
344
|
+
var DEFAULT_DATE_FORMAT = "Do MMMM YYYY";
|
|
345
|
+
var DATE_FORMAT_LABELS = {
|
|
346
|
+
"DD/MM/YYYY": "02/10/2026",
|
|
347
|
+
"MM/DD/YYYY": "10/02/2026",
|
|
348
|
+
"YYYY-MM-DD": "2026-10-02",
|
|
349
|
+
"D MMM YYYY": "2 Oct 2026",
|
|
350
|
+
"Do MMM YYYY": "2nd Oct 2026",
|
|
351
|
+
"Do MMMM YYYY": "2nd October 2026",
|
|
352
|
+
"MMMM D, YYYY": "October 2, 2026"
|
|
353
|
+
};
|
|
333
354
|
var clamp = (v, min, max) => Math.min(Math.max(v, min), max);
|
|
334
355
|
var MIN_W = 0.04;
|
|
335
356
|
var MIN_H = 0.02;
|
|
@@ -339,13 +360,16 @@ function FieldDesigner({
|
|
|
339
360
|
value,
|
|
340
361
|
onChange,
|
|
341
362
|
workerSrc,
|
|
342
|
-
primaryColor = "#4f46e5"
|
|
363
|
+
primaryColor = "#4f46e5",
|
|
364
|
+
hideFieldList = false
|
|
343
365
|
}) {
|
|
344
366
|
const [numPages, setNumPages] = react.useState(0);
|
|
345
367
|
const [page, setPage] = react.useState(value[0]?.page ?? 1);
|
|
346
368
|
const [failed, setFailed] = react.useState(false);
|
|
347
369
|
const [selectedId, setSelectedId] = react.useState(value[0]?.id ?? null);
|
|
348
370
|
const [drawMode, setDrawMode] = react.useState(false);
|
|
371
|
+
const [pendingType, setPendingType] = react.useState("signature");
|
|
372
|
+
const [configId, setConfigId] = react.useState(null);
|
|
349
373
|
const [drag, setDrag] = react.useState(null);
|
|
350
374
|
const [live, setLive] = react.useState(null);
|
|
351
375
|
const stageRef = react.useRef(null);
|
|
@@ -438,15 +462,21 @@ function FieldDesigner({
|
|
|
438
462
|
function onPointerUp() {
|
|
439
463
|
if (drag && live && live.w >= MIN_W && live.h >= MIN_H) {
|
|
440
464
|
if (drag.mode === "new") {
|
|
465
|
+
const isDate = pendingType === "date";
|
|
466
|
+
const n = value.filter((v) => v.type === pendingType).length + 1;
|
|
467
|
+
const base = isDate ? "Date" : "Signature";
|
|
441
468
|
const f = {
|
|
442
469
|
id: newId(),
|
|
443
|
-
label:
|
|
470
|
+
label: n === 1 ? base : `${base} ${n}`,
|
|
471
|
+
type: pendingType,
|
|
472
|
+
...isDate ? { dateFormat: DEFAULT_DATE_FORMAT, minDate: null } : {},
|
|
444
473
|
page,
|
|
445
474
|
...live
|
|
446
475
|
};
|
|
447
476
|
onChange([...value, f]);
|
|
448
477
|
setSelectedId(f.id);
|
|
449
478
|
setDrawMode(false);
|
|
479
|
+
if (isDate) setConfigId(f.id);
|
|
450
480
|
} else {
|
|
451
481
|
onChange(value.map((x) => x.id === drag.id ? { ...x, ...live } : x));
|
|
452
482
|
}
|
|
@@ -457,10 +487,15 @@ function FieldDesigner({
|
|
|
457
487
|
function removeField(id) {
|
|
458
488
|
onChange(value.filter((f) => f.id !== id));
|
|
459
489
|
if (selectedId === id) setSelectedId(null);
|
|
490
|
+
if (configId === id) setConfigId(null);
|
|
460
491
|
}
|
|
461
492
|
function rename(id, label) {
|
|
462
493
|
onChange(value.map((f) => f.id === id ? { ...f, label } : f));
|
|
463
494
|
}
|
|
495
|
+
function setConfig(id, patch) {
|
|
496
|
+
onChange(value.map((f) => f.id === id ? { ...f, ...patch } : f));
|
|
497
|
+
}
|
|
498
|
+
const configField = value.find((f) => f.id === configId && f.type === "date") ?? null;
|
|
464
499
|
const handle = (id, geom, c) => {
|
|
465
500
|
const cx = c[1] === "w" ? geom.x : geom.x + geom.w;
|
|
466
501
|
const cy = c[0] === "n" ? geom.y : geom.y + geom.h;
|
|
@@ -506,25 +541,35 @@ function FieldDesigner({
|
|
|
506
541
|
flexWrap: "wrap"
|
|
507
542
|
},
|
|
508
543
|
children: [
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
544
|
+
["signature", "date"].map((t) => {
|
|
545
|
+
const active = drawMode && pendingType === t;
|
|
546
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
547
|
+
"button",
|
|
548
|
+
{
|
|
549
|
+
type: "button",
|
|
550
|
+
onClick: () => {
|
|
551
|
+
if (active) setDrawMode(false);
|
|
552
|
+
else {
|
|
553
|
+
setPendingType(t);
|
|
554
|
+
setDrawMode(true);
|
|
555
|
+
}
|
|
556
|
+
},
|
|
557
|
+
style: {
|
|
558
|
+
fontSize: 13,
|
|
559
|
+
fontWeight: 600,
|
|
560
|
+
padding: "5px 12px",
|
|
561
|
+
borderRadius: 6,
|
|
562
|
+
border: `1px solid ${primaryColor}`,
|
|
563
|
+
background: active ? primaryColor : "#fff",
|
|
564
|
+
color: active ? "#fff" : primaryColor,
|
|
565
|
+
cursor: "pointer"
|
|
566
|
+
},
|
|
567
|
+
children: t === "date" ? "+ Date" : "+ Signature"
|
|
523
568
|
},
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
),
|
|
527
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 12, color: "#6b7280" }, children: "or drag on the page
|
|
569
|
+
t
|
|
570
|
+
);
|
|
571
|
+
}),
|
|
572
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 12, color: "#6b7280" }, children: drawMode ? `Drag a ${pendingType} box on the page\u2026` : "or drag on the page." }),
|
|
528
573
|
numPages > 1 ? /* @__PURE__ */ jsxRuntime.jsxs("label", { style: { marginLeft: "auto", fontSize: 13, color: "#374151" }, children: [
|
|
529
574
|
"Page",
|
|
530
575
|
" ",
|
|
@@ -595,8 +640,9 @@ function FieldDesigner({
|
|
|
595
640
|
padding: "0 4px"
|
|
596
641
|
},
|
|
597
642
|
children: [
|
|
598
|
-
"\
|
|
599
|
-
|
|
643
|
+
f.type === "date" ? "\u{1F4C5}" : "\u270D",
|
|
644
|
+
" ",
|
|
645
|
+
f.label || (f.type === "date" ? "Date" : "Signature")
|
|
600
646
|
]
|
|
601
647
|
}
|
|
602
648
|
)
|
|
@@ -635,7 +681,39 @@ function FieldDesigner({
|
|
|
635
681
|
},
|
|
636
682
|
children: "\xD7"
|
|
637
683
|
}
|
|
638
|
-
)
|
|
684
|
+
),
|
|
685
|
+
f.type === "date" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
686
|
+
"button",
|
|
687
|
+
{
|
|
688
|
+
type: "button",
|
|
689
|
+
"aria-label": `Configure ${f.label}`,
|
|
690
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
691
|
+
onClick: (e) => {
|
|
692
|
+
e.stopPropagation();
|
|
693
|
+
setConfigId(f.id);
|
|
694
|
+
},
|
|
695
|
+
style: {
|
|
696
|
+
position: "absolute",
|
|
697
|
+
left: `${geom.x * 100}%`,
|
|
698
|
+
top: `${geom.y * 100}%`,
|
|
699
|
+
transform: "translate(-50%, -50%)",
|
|
700
|
+
marginTop: -18,
|
|
701
|
+
width: 22,
|
|
702
|
+
height: 22,
|
|
703
|
+
borderRadius: "50%",
|
|
704
|
+
background: "#fff",
|
|
705
|
+
color: primaryColor,
|
|
706
|
+
border: `2px solid ${primaryColor}`,
|
|
707
|
+
boxShadow: "0 1px 3px rgba(0,0,0,0.3)",
|
|
708
|
+
fontSize: 12,
|
|
709
|
+
lineHeight: "14px",
|
|
710
|
+
cursor: "pointer",
|
|
711
|
+
padding: 0,
|
|
712
|
+
touchAction: "none"
|
|
713
|
+
},
|
|
714
|
+
children: "\u2699"
|
|
715
|
+
}
|
|
716
|
+
) : null
|
|
639
717
|
] }) : null
|
|
640
718
|
] }, f.id);
|
|
641
719
|
}),
|
|
@@ -657,11 +735,99 @@ function FieldDesigner({
|
|
|
657
735
|
) : null
|
|
658
736
|
]
|
|
659
737
|
}
|
|
660
|
-
)
|
|
738
|
+
),
|
|
739
|
+
configField ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
740
|
+
"div",
|
|
741
|
+
{
|
|
742
|
+
style: {
|
|
743
|
+
marginTop: 10,
|
|
744
|
+
border: `1px solid ${primaryColor}66`,
|
|
745
|
+
borderRadius: 8,
|
|
746
|
+
padding: 12,
|
|
747
|
+
background: "#fff",
|
|
748
|
+
fontSize: 13,
|
|
749
|
+
color: "#374151"
|
|
750
|
+
},
|
|
751
|
+
children: [
|
|
752
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
753
|
+
"div",
|
|
754
|
+
{
|
|
755
|
+
style: {
|
|
756
|
+
display: "flex",
|
|
757
|
+
alignItems: "center",
|
|
758
|
+
justifyContent: "space-between",
|
|
759
|
+
marginBottom: 8
|
|
760
|
+
},
|
|
761
|
+
children: [
|
|
762
|
+
/* @__PURE__ */ jsxRuntime.jsxs("strong", { children: [
|
|
763
|
+
"\u{1F4C5} ",
|
|
764
|
+
configField.label || "Date"
|
|
765
|
+
] }),
|
|
766
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
767
|
+
"button",
|
|
768
|
+
{
|
|
769
|
+
type: "button",
|
|
770
|
+
onClick: () => setConfigId(null),
|
|
771
|
+
style: {
|
|
772
|
+
fontSize: 12,
|
|
773
|
+
padding: "3px 10px",
|
|
774
|
+
borderRadius: 6,
|
|
775
|
+
border: `1px solid ${primaryColor}`,
|
|
776
|
+
background: primaryColor,
|
|
777
|
+
color: "#fff",
|
|
778
|
+
cursor: "pointer"
|
|
779
|
+
},
|
|
780
|
+
children: "Done"
|
|
781
|
+
}
|
|
782
|
+
)
|
|
783
|
+
]
|
|
784
|
+
}
|
|
785
|
+
),
|
|
786
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { style: { display: "block", marginBottom: 8 }, children: [
|
|
787
|
+
"Display format",
|
|
788
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
789
|
+
"select",
|
|
790
|
+
{
|
|
791
|
+
value: configField.dateFormat ?? DEFAULT_DATE_FORMAT,
|
|
792
|
+
onChange: (e) => setConfig(configField.id, { dateFormat: e.target.value }),
|
|
793
|
+
style: {
|
|
794
|
+
display: "block",
|
|
795
|
+
marginTop: 4,
|
|
796
|
+
width: "100%",
|
|
797
|
+
padding: "4px 6px",
|
|
798
|
+
borderRadius: 6,
|
|
799
|
+
border: "1px solid #d1d5db"
|
|
800
|
+
},
|
|
801
|
+
children: DATE_FORMATS.map((fmt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: fmt, children: DATE_FORMAT_LABELS[fmt] }, fmt))
|
|
802
|
+
}
|
|
803
|
+
)
|
|
804
|
+
] }),
|
|
805
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { style: { display: "block" }, children: [
|
|
806
|
+
"Earliest date",
|
|
807
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
808
|
+
"input",
|
|
809
|
+
{
|
|
810
|
+
type: "date",
|
|
811
|
+
value: configField.minDate ?? "",
|
|
812
|
+
onChange: (e) => setConfig(configField.id, { minDate: e.target.value || null }),
|
|
813
|
+
style: {
|
|
814
|
+
display: "block",
|
|
815
|
+
marginTop: 4,
|
|
816
|
+
padding: "4px 6px",
|
|
817
|
+
borderRadius: 6,
|
|
818
|
+
border: "1px solid #d1d5db"
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
),
|
|
822
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#9ca3af", fontSize: 11 }, children: "Leave blank to use the document's creation date." })
|
|
823
|
+
] })
|
|
824
|
+
]
|
|
825
|
+
}
|
|
826
|
+
) : null
|
|
661
827
|
] }),
|
|
662
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: "1 1 200px", minWidth: 180, maxWidth: 300 }, children: [
|
|
828
|
+
hideFieldList ? null : /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: "1 1 200px", minWidth: 180, maxWidth: 300 }, children: [
|
|
663
829
|
/* @__PURE__ */ jsxRuntime.jsxs("p", { style: { fontSize: 13, fontWeight: 600, color: "#374151", margin: "0 0 8px" }, children: [
|
|
664
|
-
"
|
|
830
|
+
"Fields (",
|
|
665
831
|
value.length,
|
|
666
832
|
")"
|
|
667
833
|
] }),
|
|
@@ -683,6 +849,7 @@ function FieldDesigner({
|
|
|
683
849
|
cursor: "pointer"
|
|
684
850
|
},
|
|
685
851
|
children: [
|
|
852
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 13 }, children: f.type === "date" ? "\u{1F4C5}" : "\u270D" }),
|
|
686
853
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
687
854
|
"input",
|
|
688
855
|
{
|
|
@@ -704,6 +871,27 @@ function FieldDesigner({
|
|
|
704
871
|
"p",
|
|
705
872
|
f.page
|
|
706
873
|
] }),
|
|
874
|
+
f.type === "date" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
875
|
+
"button",
|
|
876
|
+
{
|
|
877
|
+
type: "button",
|
|
878
|
+
"aria-label": `Configure ${f.label}`,
|
|
879
|
+
onClick: (e) => {
|
|
880
|
+
e.stopPropagation();
|
|
881
|
+
setConfigId(f.id);
|
|
882
|
+
},
|
|
883
|
+
style: {
|
|
884
|
+
border: "none",
|
|
885
|
+
background: "transparent",
|
|
886
|
+
color: "#6b7280",
|
|
887
|
+
cursor: "pointer",
|
|
888
|
+
fontSize: 13,
|
|
889
|
+
lineHeight: 1,
|
|
890
|
+
padding: 0
|
|
891
|
+
},
|
|
892
|
+
children: "\u2699"
|
|
893
|
+
}
|
|
894
|
+
) : null,
|
|
707
895
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
708
896
|
"button",
|
|
709
897
|
{
|
|
@@ -736,9 +924,12 @@ function SigningExperience(props) {
|
|
|
736
924
|
const primary = props.branding?.primaryColor ?? "#4f46e5";
|
|
737
925
|
const [signaturePng, setSignaturePng] = react.useState(null);
|
|
738
926
|
const [consent, setConsent] = react.useState({ signerName: "", consent: false });
|
|
927
|
+
const [dateValues, setDateValues] = react.useState({});
|
|
739
928
|
const [submitting, setSubmitting] = react.useState(false);
|
|
740
929
|
const [error, setError] = react.useState(null);
|
|
741
|
-
const
|
|
930
|
+
const dateFields = (props.placements ?? []).filter((p) => p.type === "date" && p.id);
|
|
931
|
+
const allDatesFilled = dateFields.every((f) => dateValues[f.id]);
|
|
932
|
+
const canSubmit = !!signaturePng && consent.consent && consent.signerName.trim().length > 0 && allDatesFilled && !submitting;
|
|
742
933
|
async function submit() {
|
|
743
934
|
if (!canSubmit) return;
|
|
744
935
|
setSubmitting(true);
|
|
@@ -750,7 +941,8 @@ function SigningExperience(props) {
|
|
|
750
941
|
body: JSON.stringify({
|
|
751
942
|
signaturePng,
|
|
752
943
|
signerName: consent.signerName.trim(),
|
|
753
|
-
consent: true
|
|
944
|
+
consent: true,
|
|
945
|
+
dateValues
|
|
754
946
|
})
|
|
755
947
|
});
|
|
756
948
|
if (!res.ok) {
|
|
@@ -795,6 +987,31 @@ function SigningExperience(props) {
|
|
|
795
987
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: { fontSize: 13, fontWeight: 600, color: "#374151" }, children: "Your signature" }),
|
|
796
988
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 6 }, children: /* @__PURE__ */ jsxRuntime.jsx(SignaturePad, { primaryColor: primary, onChange: setSignaturePng }) })
|
|
797
989
|
] }),
|
|
990
|
+
dateFields.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: 12 }, children: dateFields.map((f) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
991
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { style: { fontSize: 13, fontWeight: 600, color: "#374151" }, children: [
|
|
992
|
+
"\u{1F4C5} ",
|
|
993
|
+
f.label || "Date"
|
|
994
|
+
] }),
|
|
995
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
996
|
+
"input",
|
|
997
|
+
{
|
|
998
|
+
type: "date",
|
|
999
|
+
value: dateValues[f.id] ?? "",
|
|
1000
|
+
min: f.minDate ?? void 0,
|
|
1001
|
+
onChange: (e) => setDateValues((prev) => ({ ...prev, [f.id]: e.target.value })),
|
|
1002
|
+
style: {
|
|
1003
|
+
display: "block",
|
|
1004
|
+
marginTop: 6,
|
|
1005
|
+
padding: "10px 12px",
|
|
1006
|
+
borderRadius: 8,
|
|
1007
|
+
border: "1px solid #d1d5db",
|
|
1008
|
+
fontSize: 15,
|
|
1009
|
+
width: "100%",
|
|
1010
|
+
maxWidth: 280
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
)
|
|
1014
|
+
] }, f.id)) }) : null,
|
|
798
1015
|
/* @__PURE__ */ jsxRuntime.jsx(ConsentBlock, { value: consent, onChange: setConsent, primaryColor: primary }),
|
|
799
1016
|
error ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
800
1017
|
"div",
|