@drvillo/react-browser-e-signing 0.2.0 → 0.3.1
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 +471 -0
- package/dist/index.d.ts +41 -3
- package/dist/index.js +188 -11
- package/dist/index.js.map +1 -1
- package/dist/styles.css +48 -0
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -101,8 +101,11 @@ function PdfViewer({
|
|
|
101
101
|
onDocumentLoadSuccess,
|
|
102
102
|
onPageDimensions,
|
|
103
103
|
renderOverlay,
|
|
104
|
+
renderToolbarContent,
|
|
104
105
|
className,
|
|
105
|
-
workerSrc
|
|
106
|
+
workerSrc,
|
|
107
|
+
pageMode = "scroll",
|
|
108
|
+
currentPageIndex = 0
|
|
106
109
|
}) {
|
|
107
110
|
useEffect(() => {
|
|
108
111
|
if (typeof window === "undefined") return;
|
|
@@ -112,12 +115,16 @@ function PdfViewer({
|
|
|
112
115
|
}, [workerSrc]);
|
|
113
116
|
if (!pdfData)
|
|
114
117
|
return /* @__PURE__ */ jsx("div", { "data-slot": "pdf-viewer-empty", className: cn(className), children: "Upload a PDF to begin" });
|
|
118
|
+
const maxPageIndex = Math.max(0, numPages - 1);
|
|
119
|
+
const resolvedCurrentPageIndex = Math.min(maxPageIndex, Math.max(0, currentPageIndex));
|
|
120
|
+
const pageIndices = pageMode === "single" ? [resolvedCurrentPageIndex] : Array.from({ length: numPages }, (_, pageIndex) => pageIndex);
|
|
115
121
|
return /* @__PURE__ */ jsxs("div", { "data-slot": "pdf-viewer", className: cn(className), children: [
|
|
116
122
|
/* @__PURE__ */ jsxs("div", { "data-slot": "pdf-viewer-toolbar", children: [
|
|
117
123
|
/* @__PURE__ */ jsxs("div", { "data-slot": "pdf-viewer-page-count", children: [
|
|
118
124
|
"Pages: ",
|
|
119
125
|
numPages || "\u2014"
|
|
120
126
|
] }),
|
|
127
|
+
renderToolbarContent ? /* @__PURE__ */ jsx("div", { "data-slot": "pdf-viewer-toolbar-content", children: renderToolbarContent() }) : null,
|
|
121
128
|
/* @__PURE__ */ jsxs("div", { "data-slot": "pdf-viewer-zoom", children: [
|
|
122
129
|
/* @__PURE__ */ jsx(
|
|
123
130
|
"button",
|
|
@@ -150,7 +157,7 @@ function PdfViewer({
|
|
|
150
157
|
onLoadSuccess: (loadedPdf) => onDocumentLoadSuccess(loadedPdf.numPages),
|
|
151
158
|
loading: /* @__PURE__ */ jsx("div", { "data-slot": "pdf-viewer-loading", children: "Loading PDF..." }),
|
|
152
159
|
error: /* @__PURE__ */ jsx("div", { "data-slot": "pdf-viewer-error", children: "Unable to render this PDF." }),
|
|
153
|
-
children: /* @__PURE__ */ jsx("div", { "data-slot": "pdf-viewer-pages", children:
|
|
160
|
+
children: /* @__PURE__ */ jsx("div", { "data-slot": "pdf-viewer-pages", children: pageIndices.map((pageIndex) => /* @__PURE__ */ jsxs(
|
|
154
161
|
"div",
|
|
155
162
|
{
|
|
156
163
|
"data-slot": "pdf-viewer-page",
|
|
@@ -179,6 +186,49 @@ function PdfViewer({
|
|
|
179
186
|
)
|
|
180
187
|
] });
|
|
181
188
|
}
|
|
189
|
+
function clampPageIndex(pageIndex, numPages) {
|
|
190
|
+
if (numPages <= 0) return 0;
|
|
191
|
+
if (pageIndex < 0) return 0;
|
|
192
|
+
if (pageIndex > numPages - 1) return numPages - 1;
|
|
193
|
+
return pageIndex;
|
|
194
|
+
}
|
|
195
|
+
function PdfPageNavigator({ currentPageIndex, numPages, onPageChange, className }) {
|
|
196
|
+
const resolvedPageIndex = clampPageIndex(currentPageIndex, numPages);
|
|
197
|
+
const isEmpty = numPages <= 0;
|
|
198
|
+
function handlePreviousPage() {
|
|
199
|
+
if (isEmpty) return;
|
|
200
|
+
onPageChange(clampPageIndex(resolvedPageIndex - 1, numPages));
|
|
201
|
+
}
|
|
202
|
+
function handleNextPage() {
|
|
203
|
+
if (isEmpty) return;
|
|
204
|
+
onPageChange(clampPageIndex(resolvedPageIndex + 1, numPages));
|
|
205
|
+
}
|
|
206
|
+
return /* @__PURE__ */ jsxs("div", { "data-slot": "pdf-page-navigator", className: cn(className), children: [
|
|
207
|
+
/* @__PURE__ */ jsx(
|
|
208
|
+
"button",
|
|
209
|
+
{
|
|
210
|
+
type: "button",
|
|
211
|
+
"data-slot": "pdf-page-navigator-button",
|
|
212
|
+
disabled: isEmpty || resolvedPageIndex <= 0,
|
|
213
|
+
onClick: handlePreviousPage,
|
|
214
|
+
"aria-label": "Previous page",
|
|
215
|
+
children: "<"
|
|
216
|
+
}
|
|
217
|
+
),
|
|
218
|
+
/* @__PURE__ */ jsx("span", { "data-slot": "pdf-page-navigator-label", children: isEmpty ? "0 / 0" : `${resolvedPageIndex + 1} / ${numPages}` }),
|
|
219
|
+
/* @__PURE__ */ jsx(
|
|
220
|
+
"button",
|
|
221
|
+
{
|
|
222
|
+
type: "button",
|
|
223
|
+
"data-slot": "pdf-page-navigator-button",
|
|
224
|
+
disabled: isEmpty || resolvedPageIndex >= numPages - 1,
|
|
225
|
+
onClick: handleNextPage,
|
|
226
|
+
"aria-label": "Next page",
|
|
227
|
+
children: ">"
|
|
228
|
+
}
|
|
229
|
+
)
|
|
230
|
+
] });
|
|
231
|
+
}
|
|
182
232
|
var MIN_WIDTH_PERCENT = 8;
|
|
183
233
|
var MIN_HEIGHT_PERCENT = 3;
|
|
184
234
|
function clampPercent(value) {
|
|
@@ -263,12 +313,14 @@ function SignatureField({ field, onUpdateField, onRemoveField, preview, classNam
|
|
|
263
313
|
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
264
314
|
}
|
|
265
315
|
const previewText = getFieldPreviewText(field, preview);
|
|
316
|
+
const isLocked = field.locked === true;
|
|
266
317
|
return /* @__PURE__ */ jsxs(
|
|
267
318
|
"div",
|
|
268
319
|
{
|
|
269
320
|
ref: rootRef,
|
|
270
321
|
"data-slot": "signature-field",
|
|
271
322
|
"data-field-type": field.type,
|
|
323
|
+
"data-locked": isLocked ? true : void 0,
|
|
272
324
|
className: cn(className),
|
|
273
325
|
style: {
|
|
274
326
|
position: "absolute",
|
|
@@ -276,11 +328,18 @@ function SignatureField({ field, onUpdateField, onRemoveField, preview, classNam
|
|
|
276
328
|
top: `${field.yPercent}%`,
|
|
277
329
|
width: `${field.widthPercent}%`,
|
|
278
330
|
height: `${field.heightPercent}%`,
|
|
279
|
-
userSelect: "none"
|
|
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
|
+
}
|
|
280
339
|
},
|
|
281
|
-
onPointerDown: handleDragPointerDown,
|
|
282
|
-
onPointerMove: handleDragPointerMove,
|
|
283
|
-
onPointerUp: handleDragPointerUp,
|
|
340
|
+
onPointerDown: isLocked ? void 0 : handleDragPointerDown,
|
|
341
|
+
onPointerMove: isLocked ? void 0 : handleDragPointerMove,
|
|
342
|
+
onPointerUp: isLocked ? void 0 : handleDragPointerUp,
|
|
284
343
|
children: [
|
|
285
344
|
/* @__PURE__ */ jsxs(
|
|
286
345
|
"div",
|
|
@@ -306,7 +365,39 @@ function SignatureField({ field, onUpdateField, onRemoveField, preview, classNam
|
|
|
306
365
|
}
|
|
307
366
|
) : /* @__PURE__ */ jsx("div", { "data-slot": "signature-field-preview-text", children: previewText || "\u2014" })
|
|
308
367
|
] }),
|
|
309
|
-
/* @__PURE__ */ jsx(
|
|
368
|
+
isLocked ? /* @__PURE__ */ jsx(
|
|
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(
|
|
310
401
|
"button",
|
|
311
402
|
{
|
|
312
403
|
type: "button",
|
|
@@ -323,7 +414,7 @@ function SignatureField({ field, onUpdateField, onRemoveField, preview, classNam
|
|
|
323
414
|
]
|
|
324
415
|
}
|
|
325
416
|
),
|
|
326
|
-
/* @__PURE__ */ jsx(
|
|
417
|
+
!isLocked ? /* @__PURE__ */ jsx(
|
|
327
418
|
"div",
|
|
328
419
|
{
|
|
329
420
|
"data-slot": "signature-field-resize",
|
|
@@ -339,7 +430,7 @@ function SignatureField({ field, onUpdateField, onRemoveField, preview, classNam
|
|
|
339
430
|
onPointerMove: handleResizePointerMove,
|
|
340
431
|
onPointerUp: handleResizePointerUp
|
|
341
432
|
}
|
|
342
|
-
)
|
|
433
|
+
) : null
|
|
343
434
|
]
|
|
344
435
|
}
|
|
345
436
|
);
|
|
@@ -690,6 +781,87 @@ function usePdfDocument(pdfInput) {
|
|
|
690
781
|
errorMessage
|
|
691
782
|
};
|
|
692
783
|
}
|
|
784
|
+
var PAGE_SLOT_SELECTOR = '[data-slot="pdf-viewer-page"]';
|
|
785
|
+
function clampPageIndex2(pageIndex, numPages) {
|
|
786
|
+
if (numPages <= 0) return 0;
|
|
787
|
+
if (pageIndex < 0) return 0;
|
|
788
|
+
if (pageIndex > numPages - 1) return numPages - 1;
|
|
789
|
+
return pageIndex;
|
|
790
|
+
}
|
|
791
|
+
function usePdfPageVisibility({
|
|
792
|
+
containerRef,
|
|
793
|
+
numPages,
|
|
794
|
+
threshold = 0.5
|
|
795
|
+
}) {
|
|
796
|
+
const [currentPageIndex, setCurrentPageIndex] = useState(0);
|
|
797
|
+
const [visiblePageIndices, setVisiblePageIndices] = useState([]);
|
|
798
|
+
const resolvedThreshold = useMemo(() => {
|
|
799
|
+
if (Number.isNaN(threshold)) return 0.5;
|
|
800
|
+
if (threshold < 0) return 0;
|
|
801
|
+
if (threshold > 1) return 1;
|
|
802
|
+
return threshold;
|
|
803
|
+
}, [threshold]);
|
|
804
|
+
const scrollToPage = useCallback(
|
|
805
|
+
(pageIndex) => {
|
|
806
|
+
const container = containerRef.current;
|
|
807
|
+
if (!container || numPages <= 0) return;
|
|
808
|
+
const clampedIndex = clampPageIndex2(pageIndex, numPages);
|
|
809
|
+
const pages = container.querySelectorAll(PAGE_SLOT_SELECTOR);
|
|
810
|
+
const pageElement = pages.item(clampedIndex);
|
|
811
|
+
if (!pageElement) return;
|
|
812
|
+
pageElement.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
813
|
+
},
|
|
814
|
+
[containerRef, numPages]
|
|
815
|
+
);
|
|
816
|
+
useEffect(() => {
|
|
817
|
+
if (numPages <= 0) {
|
|
818
|
+
setCurrentPageIndex(0);
|
|
819
|
+
setVisiblePageIndices([]);
|
|
820
|
+
return;
|
|
821
|
+
}
|
|
822
|
+
const container = containerRef.current;
|
|
823
|
+
if (!container) return;
|
|
824
|
+
const pages = Array.from(container.querySelectorAll(PAGE_SLOT_SELECTOR));
|
|
825
|
+
if (!pages.length) return;
|
|
826
|
+
if (typeof IntersectionObserver !== "function") {
|
|
827
|
+
setCurrentPageIndex(0);
|
|
828
|
+
setVisiblePageIndices([0]);
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
const ratioByIndex = /* @__PURE__ */ new Map();
|
|
832
|
+
for (let index = 0; index < pages.length; index += 1) ratioByIndex.set(index, 0);
|
|
833
|
+
const observer = new IntersectionObserver(
|
|
834
|
+
(entries) => {
|
|
835
|
+
for (const entry of entries) {
|
|
836
|
+
const index = pages.indexOf(entry.target);
|
|
837
|
+
if (index < 0) continue;
|
|
838
|
+
ratioByIndex.set(index, entry.isIntersecting ? entry.intersectionRatio : 0);
|
|
839
|
+
}
|
|
840
|
+
const nextVisible = Array.from(ratioByIndex.entries()).filter(([, ratio]) => ratio > 0).map(([index]) => index).sort((a, b) => a - b);
|
|
841
|
+
setVisiblePageIndices(nextVisible);
|
|
842
|
+
let maxRatio = -1;
|
|
843
|
+
let mostVisibleIndex = 0;
|
|
844
|
+
for (const [index, ratio] of ratioByIndex.entries()) {
|
|
845
|
+
if (ratio > maxRatio) {
|
|
846
|
+
maxRatio = ratio;
|
|
847
|
+
mostVisibleIndex = index;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
setCurrentPageIndex(clampPageIndex2(mostVisibleIndex, numPages));
|
|
851
|
+
},
|
|
852
|
+
{ threshold: [0, resolvedThreshold, 1] }
|
|
853
|
+
);
|
|
854
|
+
for (const pageElement of pages) observer.observe(pageElement);
|
|
855
|
+
return () => {
|
|
856
|
+
observer.disconnect();
|
|
857
|
+
};
|
|
858
|
+
}, [containerRef, numPages, resolvedThreshold]);
|
|
859
|
+
return {
|
|
860
|
+
currentPageIndex: clampPageIndex2(currentPageIndex, numPages),
|
|
861
|
+
visiblePageIndices,
|
|
862
|
+
scrollToPage
|
|
863
|
+
};
|
|
864
|
+
}
|
|
693
865
|
function clampPercent2(value) {
|
|
694
866
|
if (Number.isNaN(value)) return 0;
|
|
695
867
|
if (value < 0) return 0;
|
|
@@ -705,7 +877,7 @@ function buildFieldId() {
|
|
|
705
877
|
function useFieldPlacement(options = {}) {
|
|
706
878
|
const defaultWidthPercent = options.defaultWidthPercent ?? 25;
|
|
707
879
|
const defaultHeightPercent = options.defaultHeightPercent ?? 5;
|
|
708
|
-
const [fields, setFields] = useState([]);
|
|
880
|
+
const [fields, setFields] = useState(options.initialFields ?? []);
|
|
709
881
|
const addField = useCallback(
|
|
710
882
|
({ pageIndex, type, xPercent, yPercent }) => {
|
|
711
883
|
const field = {
|
|
@@ -962,6 +1134,7 @@ var SLOTS = {
|
|
|
962
1134
|
pdfViewer: "pdf-viewer",
|
|
963
1135
|
pdfViewerEmpty: "pdf-viewer-empty",
|
|
964
1136
|
pdfViewerToolbar: "pdf-viewer-toolbar",
|
|
1137
|
+
pdfViewerToolbarContent: "pdf-viewer-toolbar-content",
|
|
965
1138
|
pdfViewerPageCount: "pdf-viewer-page-count",
|
|
966
1139
|
pdfViewerZoom: "pdf-viewer-zoom",
|
|
967
1140
|
pdfViewerZoomButton: "pdf-viewer-zoom-button",
|
|
@@ -970,6 +1143,9 @@ var SLOTS = {
|
|
|
970
1143
|
pdfViewerPage: "pdf-viewer-page",
|
|
971
1144
|
pdfViewerLoading: "pdf-viewer-loading",
|
|
972
1145
|
pdfViewerError: "pdf-viewer-error",
|
|
1146
|
+
pdfPageNavigator: "pdf-page-navigator",
|
|
1147
|
+
pdfPageNavigatorButton: "pdf-page-navigator-button",
|
|
1148
|
+
pdfPageNavigatorLabel: "pdf-page-navigator-label",
|
|
973
1149
|
fieldOverlay: "field-overlay",
|
|
974
1150
|
signatureField: "signature-field",
|
|
975
1151
|
signatureFieldContent: "signature-field-content",
|
|
@@ -979,6 +1155,7 @@ var SLOTS = {
|
|
|
979
1155
|
signatureFieldPreviewText: "signature-field-preview-text",
|
|
980
1156
|
signatureFieldRemove: "signature-field-remove",
|
|
981
1157
|
signatureFieldResize: "signature-field-resize",
|
|
1158
|
+
signatureFieldLock: "signature-field-lock",
|
|
982
1159
|
fieldPalette: "field-palette",
|
|
983
1160
|
fieldPaletteButton: "field-palette-button",
|
|
984
1161
|
signerPanel: "signer-panel",
|
|
@@ -1016,6 +1193,6 @@ var defaults = {
|
|
|
1016
1193
|
DEFAULT_FIELD_HEIGHT_PERCENT: 5
|
|
1017
1194
|
};
|
|
1018
1195
|
|
|
1019
|
-
export { FieldOverlay, FieldPalette, PdfViewer, SIGNATURE_FONTS, SLOTS, SignatureField, SignaturePad, SignaturePreview, SignerDetailsPanel, SigningComplete, configure, defaults, loadSignatureFont, mapFromPoints, mapToPoints, modifyPdf, sha256, useFieldPlacement, usePdfDocument, useSignatureRenderer };
|
|
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 };
|
|
1020
1197
|
//# sourceMappingURL=index.js.map
|
|
1021
1198
|
//# sourceMappingURL=index.js.map
|