@drvillo/react-browser-e-signing 0.1.1 → 0.1.3
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/README.md +83 -1
- package/dist/index.d.ts +24 -6
- package/dist/index.js +145 -46
- package/dist/index.js.map +1 -1
- package/dist/styles.css +8 -2
- package/package.json +16 -16
package/README.md
CHANGED
|
@@ -59,6 +59,11 @@ pnpm demo
|
|
|
59
59
|
- `SIGNATURE_FONTS`
|
|
60
60
|
- `sha256`
|
|
61
61
|
|
|
62
|
+
### Configuration
|
|
63
|
+
|
|
64
|
+
- `configure(options)` — PDF worker URL, signature font mode (`network` | `local-only`), optional `fontUrlResolver`, optional `onWarning` callback
|
|
65
|
+
- Types: `ESigningConfig`, `SignatureFontWarning`
|
|
66
|
+
|
|
62
67
|
### Types
|
|
63
68
|
|
|
64
69
|
- `FieldPlacement`
|
|
@@ -123,10 +128,87 @@ pnpm typecheck
|
|
|
123
128
|
|
|
124
129
|
## Notes
|
|
125
130
|
|
|
126
|
-
-
|
|
131
|
+
- **PDF worker:** the package does **not** inject a third-party worker URL. Set `configure({ pdfWorkerSrc })` and/or `<PdfViewer workerSrc="..." />` so PDF.js can load a worker (recommended for production). See **Production hardening** below.
|
|
127
132
|
- Browser test config skips execution when Playwright Chromium is not available in the environment.
|
|
128
133
|
- Demo theme switcher (`default` / `custom`) shows how a container app can fully re-theme the same components.
|
|
129
134
|
|
|
135
|
+
## Production hardening
|
|
136
|
+
|
|
137
|
+
Runtime calls to external CDNs (PDF.js worker, Google Fonts) often fail in real apps: **CSP** (`worker-src`, `connect-src`, `font-src`), ad blockers, corporate proxies, or offline users. They also add noisy console errors (`Failed to fetch`) even when the rest of the UI works. This library defaults to **no injected worker URL** and lets you control loading explicitly.
|
|
138
|
+
|
|
139
|
+
### Self-hosted PDF.js worker (recommended)
|
|
140
|
+
|
|
141
|
+
Copy the worker file that matches your installed `pdfjs-dist` (same major/minor as `react-pdf` / PDF.js):
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
cp node_modules/pdfjs-dist/build/pdf.worker.min.mjs public/pdf.worker.min.mjs
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Then configure once (e.g. in your app entry or root layout client component):
|
|
148
|
+
|
|
149
|
+
```tsx
|
|
150
|
+
import { configure } from '@drvillo/react-browser-e-signing'
|
|
151
|
+
|
|
152
|
+
configure({ pdfWorkerSrc: '/pdf.worker.min.mjs' })
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Or per viewer:
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
<PdfViewer workerSrc="/pdf.worker.min.mjs" {...pdfViewerProps} />
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
`workerSrc` on `PdfViewer` overrides `configure({ pdfWorkerSrc })`.
|
|
162
|
+
|
|
163
|
+
### Typed signatures: local-only fonts (no network)
|
|
164
|
+
|
|
165
|
+
Skip all font fetches (handwriting fonts won’t load from Google; the browser uses whatever faces are already available, with sensible fallback):
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
configure({ fontMode: 'local-only' })
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Default is `fontMode: 'network'`, which keeps the previous Google Fonts behavior but **does not throw** on failure; failures are reported via `onWarning` when set.
|
|
172
|
+
|
|
173
|
+
### Custom font URLs (self-hosted woff/woff2)
|
|
174
|
+
|
|
175
|
+
```tsx
|
|
176
|
+
configure({
|
|
177
|
+
fontUrlResolver: (family) => `/fonts/${family.replace(/\s+/g, '-')}.woff2`,
|
|
178
|
+
})
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Return `null` to fall back to Google Fonts for that family (when `fontMode` is `'network'`).
|
|
182
|
+
|
|
183
|
+
### Observability
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
configure({
|
|
187
|
+
onWarning: (w) => {
|
|
188
|
+
console.warn(`[react-browser-e-signing] ${w.code}: ${w.message}`)
|
|
189
|
+
},
|
|
190
|
+
})
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Warnings are non-throwing; signing flow should remain usable.
|
|
194
|
+
|
|
195
|
+
### CSP-oriented example
|
|
196
|
+
|
|
197
|
+
If everything is same-origin:
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
Content-Security-Policy: worker-src 'self'; script-src 'self'; connect-src 'self'; font-src 'self';
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Adjust `connect-src` / `font-src` if you still use Google Fonts or a CDN for the worker.
|
|
204
|
+
|
|
205
|
+
### Migration from v0.1.2 and earlier
|
|
206
|
+
|
|
207
|
+
Previously, `PdfViewer` set the worker to unpkg at module load, and typed fonts fetched Google Fonts CSS + files at runtime.
|
|
208
|
+
|
|
209
|
+
- **Worker:** to restore the old CDN behavior (not recommended for production), set `pdfWorkerSrc` to the unpkg URL for your PDF.js version, e.g. `https://unpkg.com/pdfjs-dist@<version>/build/pdf.worker.min.mjs` (match `pdfjs.version` from `react-pdf` / `pdfjs-dist`).
|
|
210
|
+
- **Fonts:** behavior is unchanged when you omit `configure()` except that network failures no longer surface as thrown errors from `loadSignatureFont`; use `fontMode: 'local-only'` for strict no-network deployments.
|
|
211
|
+
|
|
130
212
|
## Limitations
|
|
131
213
|
|
|
132
214
|
- Single signer workflow in v0.1
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,25 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import { ReactNode } from 'react';
|
|
4
4
|
|
|
5
|
+
declare const SIGNATURE_FONTS: readonly ["Caveat", "Homemade Apple", "Reenie Beanie", "Mr Dafoe", "Pacifico", "Qwitcher Grypen"];
|
|
6
|
+
declare function loadSignatureFont(fontFamily: string): Promise<void>;
|
|
7
|
+
|
|
8
|
+
interface SignatureFontWarning {
|
|
9
|
+
code: string;
|
|
10
|
+
message: string;
|
|
11
|
+
}
|
|
12
|
+
interface ESigningConfig {
|
|
13
|
+
/** PDF.js worker script URL (e.g. self-hosted `/pdf.worker.min.mjs`). When unset, `PdfViewer` does not set `GlobalWorkerOptions.workerSrc`. */
|
|
14
|
+
pdfWorkerSrc?: string;
|
|
15
|
+
/** `network`: fetch Google Fonts when loading typed signature fonts (default). `local-only`: no fetches; browser uses available/system fonts. */
|
|
16
|
+
fontMode?: 'network' | 'local-only';
|
|
17
|
+
/** Return a woff/woff2 URL for a font family, or `null` to fall back to Google Fonts (when `fontMode` is `network`). */
|
|
18
|
+
fontUrlResolver?: (fontFamily: string) => string | null;
|
|
19
|
+
/** Non-throwing callback for recoverable issues (font/worker setup). */
|
|
20
|
+
onWarning?: (warning: SignatureFontWarning) => void;
|
|
21
|
+
}
|
|
22
|
+
declare function configure(options: ESigningConfig): void;
|
|
23
|
+
|
|
5
24
|
interface PdfViewerProps {
|
|
6
25
|
pdfData: ArrayBuffer | null;
|
|
7
26
|
numPages: number;
|
|
@@ -15,8 +34,10 @@ interface PdfViewerProps {
|
|
|
15
34
|
}) => void;
|
|
16
35
|
renderOverlay?: (pageIndex: number) => ReactNode;
|
|
17
36
|
className?: string;
|
|
37
|
+
/** PDF.js worker script URL. Overrides `configure({ pdfWorkerSrc })`. When neither is set, worker URL is left unset (no CDN injection). */
|
|
38
|
+
workerSrc?: string;
|
|
18
39
|
}
|
|
19
|
-
declare function PdfViewer({ pdfData, numPages, scale, onScaleChange, onDocumentLoadSuccess, onPageDimensions, renderOverlay, className, }: PdfViewerProps): react_jsx_runtime.JSX.Element;
|
|
40
|
+
declare function PdfViewer({ pdfData, numPages, scale, onScaleChange, onDocumentLoadSuccess, onPageDimensions, renderOverlay, className, workerSrc, }: PdfViewerProps): react_jsx_runtime.JSX.Element;
|
|
20
41
|
|
|
21
42
|
type FieldType = 'signature' | 'fullName' | 'title' | 'date';
|
|
22
43
|
interface FieldPlacement {
|
|
@@ -186,9 +207,6 @@ declare function modifyPdf({ pdfBytes, fields, signer, signatureDataUrl, pageDim
|
|
|
186
207
|
declare function mapToPoints(field: FieldPlacement, page: PdfPageDimensions): PointRect;
|
|
187
208
|
declare function mapFromPoints(rect: PointRect, page: PdfPageDimensions): Pick<FieldPlacement, 'xPercent' | 'yPercent' | 'widthPercent' | 'heightPercent'>;
|
|
188
209
|
|
|
189
|
-
declare const SIGNATURE_FONTS: readonly ["Dancing Script", "Great Vibes", "Sacramento", "Alex Brush"];
|
|
190
|
-
declare function loadSignatureFont(fontFamily: string): Promise<void>;
|
|
191
|
-
|
|
192
210
|
declare function sha256(data: Uint8Array): Promise<string>;
|
|
193
211
|
|
|
194
212
|
declare const SLOTS: {
|
|
@@ -243,9 +261,9 @@ declare const SLOTS: {
|
|
|
243
261
|
};
|
|
244
262
|
|
|
245
263
|
declare const defaults: {
|
|
246
|
-
readonly SIGNATURE_FONTS: readonly ["
|
|
264
|
+
readonly SIGNATURE_FONTS: readonly ["Caveat", "Homemade Apple", "Reenie Beanie", "Mr Dafoe", "Pacifico", "Qwitcher Grypen"];
|
|
247
265
|
readonly DEFAULT_FIELD_WIDTH_PERCENT: 25;
|
|
248
266
|
readonly DEFAULT_FIELD_HEIGHT_PERCENT: 5;
|
|
249
267
|
};
|
|
250
268
|
|
|
251
|
-
export { FieldOverlay, FieldPalette, type FieldPlacement, type FieldType, type PdfPageDimensions, PdfViewer, SIGNATURE_FONTS, SLOTS, SignatureField, type SignatureFieldPreview, SignaturePad, SignaturePreview, type SignatureStyle, SignerDetailsPanel, type SignerInfo, SigningComplete, type SigningResult, defaults, loadSignatureFont, mapFromPoints, mapToPoints, modifyPdf, sha256, useFieldPlacement, usePdfDocument, useSignatureRenderer };
|
|
269
|
+
export { type ESigningConfig, FieldOverlay, FieldPalette, type FieldPlacement, type FieldType, type PdfPageDimensions, PdfViewer, SIGNATURE_FONTS, SLOTS, SignatureField, type SignatureFieldPreview, type SignatureFontWarning, SignaturePad, SignaturePreview, type SignatureStyle, SignerDetailsPanel, type SignerInfo, SigningComplete, type SigningResult, configure, defaults, loadSignatureFont, mapFromPoints, mapToPoints, modifyPdf, sha256, useFieldPlacement, usePdfDocument, useSignatureRenderer };
|
package/dist/index.js
CHANGED
|
@@ -1,19 +1,95 @@
|
|
|
1
1
|
import { pdfjs, Document, Page } from 'react-pdf';
|
|
2
|
+
import { useEffect, useRef, useMemo, useState, useCallback } from 'react';
|
|
2
3
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
-
import { useRef, useEffect, useMemo, useState, useCallback } from 'react';
|
|
4
4
|
import SignaturePadLibrary from 'signature_pad';
|
|
5
5
|
import fontkit from '@pdf-lib/fontkit';
|
|
6
6
|
import { PDFDocument, StandardFonts } from 'pdf-lib';
|
|
7
7
|
|
|
8
|
-
// src/
|
|
8
|
+
// src/lib/config.ts
|
|
9
|
+
var _config = {};
|
|
10
|
+
function configure(options) {
|
|
11
|
+
_config = { ..._config, ...options };
|
|
12
|
+
}
|
|
13
|
+
function getConfig() {
|
|
14
|
+
return _config;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// src/lib/signature-fonts.ts
|
|
18
|
+
var loadedFonts = /* @__PURE__ */ new Set();
|
|
19
|
+
var SIGNATURE_FONTS = [
|
|
20
|
+
"Caveat",
|
|
21
|
+
"Homemade Apple",
|
|
22
|
+
"Reenie Beanie",
|
|
23
|
+
"Mr Dafoe",
|
|
24
|
+
"Pacifico",
|
|
25
|
+
"Qwitcher Grypen"
|
|
26
|
+
];
|
|
27
|
+
function buildGoogleFontsCssUrl(family) {
|
|
28
|
+
const encoded = family.trim().replace(/\s+/g, "+");
|
|
29
|
+
return `https://fonts.googleapis.com/css2?family=${encoded}&display=swap`;
|
|
30
|
+
}
|
|
31
|
+
async function loadCssFromGoogleFonts(url) {
|
|
32
|
+
const response = await fetch(url);
|
|
33
|
+
if (!response.ok) throw new Error(`Unable to load font css from ${url}`);
|
|
34
|
+
return response.text();
|
|
35
|
+
}
|
|
36
|
+
function extractFontSource(cssText) {
|
|
37
|
+
const sourceMatch = cssText.match(/src:\s*url\(([^)]+)\)\s*format\(['"]?([^'")]+)['"]?\)/i);
|
|
38
|
+
if (!sourceMatch) return null;
|
|
39
|
+
return sourceMatch[1].replace(/['"]/g, "");
|
|
40
|
+
}
|
|
41
|
+
function warnFontLoad(message) {
|
|
42
|
+
try {
|
|
43
|
+
getConfig().onWarning?.({ code: "FONT_LOAD_FAILED", message });
|
|
44
|
+
} catch {
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async function loadFontFaceFromUrl(fontFamily, url) {
|
|
48
|
+
if (typeof FontFace === "undefined" || typeof document === "undefined") return;
|
|
49
|
+
const fontFace = new FontFace(fontFamily, `url(${url})`);
|
|
50
|
+
await fontFace.load();
|
|
51
|
+
const fontSet = document.fonts;
|
|
52
|
+
fontSet.add(fontFace);
|
|
53
|
+
}
|
|
54
|
+
async function loadSignatureFont(fontFamily) {
|
|
55
|
+
if (loadedFonts.has(fontFamily)) return;
|
|
56
|
+
if (typeof document === "undefined") return;
|
|
57
|
+
if (typeof FontFace === "undefined") return;
|
|
58
|
+
const { fontMode = "network", fontUrlResolver } = getConfig();
|
|
59
|
+
if (fontMode === "local-only") {
|
|
60
|
+
loadedFonts.add(fontFamily);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const tryLoadFromGoogle = async () => {
|
|
64
|
+
try {
|
|
65
|
+
const cssUrl = buildGoogleFontsCssUrl(fontFamily);
|
|
66
|
+
const cssText = await loadCssFromGoogleFonts(cssUrl);
|
|
67
|
+
const fontSource = extractFontSource(cssText);
|
|
68
|
+
if (!fontSource) throw new Error(`Unable to extract font source for ${fontFamily}`);
|
|
69
|
+
await loadFontFaceFromUrl(fontFamily, fontSource);
|
|
70
|
+
} catch (error) {
|
|
71
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
72
|
+
warnFontLoad(`Google Fonts load failed for "${fontFamily}": ${detail}`);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
if (fontUrlResolver) {
|
|
76
|
+
try {
|
|
77
|
+
const resolved = fontUrlResolver(fontFamily);
|
|
78
|
+
if (resolved) await loadFontFaceFromUrl(fontFamily, resolved);
|
|
79
|
+
else await tryLoadFromGoogle();
|
|
80
|
+
} catch (error) {
|
|
81
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
82
|
+
warnFontLoad(`Custom font load failed for "${fontFamily}": ${detail}`);
|
|
83
|
+
await tryLoadFromGoogle();
|
|
84
|
+
}
|
|
85
|
+
} else await tryLoadFromGoogle();
|
|
86
|
+
loadedFonts.add(fontFamily);
|
|
87
|
+
}
|
|
9
88
|
|
|
10
89
|
// src/lib/cn.ts
|
|
11
90
|
function cn(...values) {
|
|
12
91
|
return values.filter(Boolean).join(" ");
|
|
13
92
|
}
|
|
14
|
-
if (typeof window !== "undefined") {
|
|
15
|
-
pdfjs.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`;
|
|
16
|
-
}
|
|
17
93
|
var MIN_SCALE = 0.5;
|
|
18
94
|
var MAX_SCALE = 2;
|
|
19
95
|
var SCALE_STEP = 0.1;
|
|
@@ -25,8 +101,15 @@ function PdfViewer({
|
|
|
25
101
|
onDocumentLoadSuccess,
|
|
26
102
|
onPageDimensions,
|
|
27
103
|
renderOverlay,
|
|
28
|
-
className
|
|
104
|
+
className,
|
|
105
|
+
workerSrc
|
|
29
106
|
}) {
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
if (typeof window === "undefined") return;
|
|
109
|
+
const fromConfig = getConfig().pdfWorkerSrc;
|
|
110
|
+
const next = workerSrc ?? fromConfig;
|
|
111
|
+
if (next) pdfjs.GlobalWorkerOptions.workerSrc = next;
|
|
112
|
+
}, [workerSrc]);
|
|
30
113
|
if (!pdfData)
|
|
31
114
|
return /* @__PURE__ */ jsx("div", { "data-slot": "pdf-viewer-empty", className: cn(className), children: "Upload a PDF to begin" });
|
|
32
115
|
return /* @__PURE__ */ jsxs("div", { "data-slot": "pdf-viewer", className: cn(className), children: [
|
|
@@ -207,7 +290,7 @@ function SignatureField({ field, onUpdateField, onRemoveField, preview, classNam
|
|
|
207
290
|
display: "flex",
|
|
208
291
|
height: "100%",
|
|
209
292
|
width: "100%",
|
|
210
|
-
alignItems: "
|
|
293
|
+
alignItems: "stretch",
|
|
211
294
|
justifyContent: "space-between"
|
|
212
295
|
},
|
|
213
296
|
children: [
|
|
@@ -381,38 +464,6 @@ function SignerDetailsPanel({ signerInfo, onSignerInfoChange, className }) {
|
|
|
381
464
|
] })
|
|
382
465
|
] });
|
|
383
466
|
}
|
|
384
|
-
|
|
385
|
-
// src/lib/signature-fonts.ts
|
|
386
|
-
var loadedFonts = /* @__PURE__ */ new Set();
|
|
387
|
-
var SIGNATURE_FONTS = ["Dancing Script", "Great Vibes", "Sacramento", "Alex Brush"];
|
|
388
|
-
function buildGoogleFontsCssUrl(family) {
|
|
389
|
-
const encoded = family.trim().replace(/\s+/g, "+");
|
|
390
|
-
return `https://fonts.googleapis.com/css2?family=${encoded}&display=swap`;
|
|
391
|
-
}
|
|
392
|
-
async function loadCssFromGoogleFonts(url) {
|
|
393
|
-
const response = await fetch(url);
|
|
394
|
-
if (!response.ok) throw new Error(`Unable to load font css from ${url}`);
|
|
395
|
-
return response.text();
|
|
396
|
-
}
|
|
397
|
-
function extractFontSource(cssText) {
|
|
398
|
-
const sourceMatch = cssText.match(/src:\s*url\(([^)]+)\)\s*format\(['"]?([^'")]+)['"]?\)/i);
|
|
399
|
-
if (!sourceMatch) return null;
|
|
400
|
-
return sourceMatch[1].replace(/['"]/g, "");
|
|
401
|
-
}
|
|
402
|
-
async function loadSignatureFont(fontFamily) {
|
|
403
|
-
if (loadedFonts.has(fontFamily)) return;
|
|
404
|
-
if (typeof document === "undefined") return;
|
|
405
|
-
if (typeof FontFace === "undefined") return;
|
|
406
|
-
const cssUrl = buildGoogleFontsCssUrl(fontFamily);
|
|
407
|
-
const cssText = await loadCssFromGoogleFonts(cssUrl);
|
|
408
|
-
const fontSource = extractFontSource(cssText);
|
|
409
|
-
if (!fontSource) throw new Error(`Unable to extract font source for ${fontFamily}`);
|
|
410
|
-
const fontFace = new FontFace(fontFamily, `url(${fontSource})`);
|
|
411
|
-
await fontFace.load();
|
|
412
|
-
const fontSet = document.fonts;
|
|
413
|
-
fontSet.add(fontFace);
|
|
414
|
-
loadedFonts.add(fontFamily);
|
|
415
|
-
}
|
|
416
467
|
function SignaturePad({ onDrawn, className }) {
|
|
417
468
|
const canvasRef = useRef(null);
|
|
418
469
|
const signaturePadRef = useRef(null);
|
|
@@ -709,6 +760,41 @@ function useFieldPlacement(options = {}) {
|
|
|
709
760
|
function buildCanvas() {
|
|
710
761
|
return document.createElement("canvas");
|
|
711
762
|
}
|
|
763
|
+
function hashString(s) {
|
|
764
|
+
let h = 2166136261;
|
|
765
|
+
for (let i = 0; i < s.length; i++) {
|
|
766
|
+
h ^= s.charCodeAt(i);
|
|
767
|
+
h = Math.imul(h, 16777619);
|
|
768
|
+
}
|
|
769
|
+
return h >>> 0;
|
|
770
|
+
}
|
|
771
|
+
function mulberry32(seed) {
|
|
772
|
+
return function() {
|
|
773
|
+
let t = seed += 1831565813;
|
|
774
|
+
t = Math.imul(t ^ t >>> 15, t | 1);
|
|
775
|
+
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
|
|
776
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
function layoutTypedGlyphs({
|
|
780
|
+
signerName,
|
|
781
|
+
fontFamily,
|
|
782
|
+
fontSize,
|
|
783
|
+
context
|
|
784
|
+
}) {
|
|
785
|
+
const rng = mulberry32(hashString(`${signerName}\0${fontFamily}`));
|
|
786
|
+
context.font = `${fontSize}px "${fontFamily}"`;
|
|
787
|
+
const chars = Array.from(signerName);
|
|
788
|
+
const layouts = [];
|
|
789
|
+
for (let i = 0; i < chars.length; i++) {
|
|
790
|
+
const char = chars[i];
|
|
791
|
+
const width = context.measureText(char).width;
|
|
792
|
+
const rotation = (rng() * 2 - 1) * 0.07;
|
|
793
|
+
const gapAfter = i < chars.length - 1 ? (rng() * 2 - 1) * 1.25 : 0;
|
|
794
|
+
layouts.push({ char, width, rotation, gapAfter });
|
|
795
|
+
}
|
|
796
|
+
return layouts;
|
|
797
|
+
}
|
|
712
798
|
function drawTypedSignature({
|
|
713
799
|
signerName,
|
|
714
800
|
fontFamily
|
|
@@ -718,15 +804,27 @@ function drawTypedSignature({
|
|
|
718
804
|
if (!context) return "";
|
|
719
805
|
const padding = 16;
|
|
720
806
|
const fontSize = 56;
|
|
721
|
-
|
|
722
|
-
const
|
|
723
|
-
|
|
807
|
+
const baselineY = 50;
|
|
808
|
+
const glyphs = layoutTypedGlyphs({ signerName, fontFamily, fontSize, context });
|
|
809
|
+
const textWidth = glyphs.reduce((sum, g) => sum + g.width + g.gapAfter, 0);
|
|
810
|
+
canvas.width = Math.max(240, Math.ceil(textWidth + padding * 2));
|
|
724
811
|
canvas.height = 100;
|
|
725
812
|
context.clearRect(0, 0, canvas.width, canvas.height);
|
|
726
813
|
context.font = `${fontSize}px "${fontFamily}"`;
|
|
727
814
|
context.fillStyle = "#111827";
|
|
815
|
+
context.textAlign = "center";
|
|
728
816
|
context.textBaseline = "middle";
|
|
729
|
-
|
|
817
|
+
let x = padding;
|
|
818
|
+
for (const glyph of glyphs) {
|
|
819
|
+
const { char, width, rotation, gapAfter } = glyph;
|
|
820
|
+
const cx = x + width / 2;
|
|
821
|
+
context.save();
|
|
822
|
+
context.translate(cx, baselineY);
|
|
823
|
+
context.rotate(rotation);
|
|
824
|
+
context.fillText(char, 0, 0);
|
|
825
|
+
context.restore();
|
|
826
|
+
x += width + gapAfter;
|
|
827
|
+
}
|
|
730
828
|
return canvas.toDataURL("image/png");
|
|
731
829
|
}
|
|
732
830
|
function useSignatureRenderer({ signerName, style }) {
|
|
@@ -750,7 +848,8 @@ function useSignatureRenderer({ signerName, style }) {
|
|
|
750
848
|
setSignatureDataUrl(dataUrl || null);
|
|
751
849
|
}).catch(() => {
|
|
752
850
|
if (!isActive) return;
|
|
753
|
-
|
|
851
|
+
const dataUrl = drawTypedSignature({ signerName: normalizedName, fontFamily: style.fontFamily });
|
|
852
|
+
setSignatureDataUrl(dataUrl || null);
|
|
754
853
|
}).finally(() => {
|
|
755
854
|
if (!isActive) return;
|
|
756
855
|
setIsRendering(false);
|
|
@@ -912,11 +1011,11 @@ var SLOTS = {
|
|
|
912
1011
|
|
|
913
1012
|
// src/index.ts
|
|
914
1013
|
var defaults = {
|
|
915
|
-
SIGNATURE_FONTS: [
|
|
1014
|
+
SIGNATURE_FONTS: [...SIGNATURE_FONTS],
|
|
916
1015
|
DEFAULT_FIELD_WIDTH_PERCENT: 25,
|
|
917
1016
|
DEFAULT_FIELD_HEIGHT_PERCENT: 5
|
|
918
1017
|
};
|
|
919
1018
|
|
|
920
|
-
export { FieldOverlay, FieldPalette, PdfViewer, SIGNATURE_FONTS, SLOTS, SignatureField, SignaturePad, SignaturePreview, SignerDetailsPanel, SigningComplete, defaults, loadSignatureFont, mapFromPoints, mapToPoints, modifyPdf, sha256, useFieldPlacement, usePdfDocument, useSignatureRenderer };
|
|
1019
|
+
export { FieldOverlay, FieldPalette, PdfViewer, SIGNATURE_FONTS, SLOTS, SignatureField, SignaturePad, SignaturePreview, SignerDetailsPanel, SigningComplete, configure, defaults, loadSignatureFont, mapFromPoints, mapToPoints, modifyPdf, sha256, useFieldPlacement, usePdfDocument, useSignatureRenderer };
|
|
921
1020
|
//# sourceMappingURL=index.js.map
|
|
922
1021
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/cn.ts","../src/components/pdf-viewer.tsx","../src/components/signature-field.tsx","../src/components/field-overlay.tsx","../src/components/field-palette.tsx","../src/components/signer-details-panel.tsx","../src/lib/signature-fonts.ts","../src/components/signature-pad.tsx","../src/components/signature-preview.tsx","../src/components/signing-complete.tsx","../src/hooks/use-pdf-document.ts","../src/hooks/use-field-placement.ts","../src/hooks/use-signature-renderer.ts","../src/lib/coordinate-mapper.ts","../src/lib/pdf-modifier.ts","../src/lib/hash.ts","../src/lib/slots.ts","../src/index.ts"],"names":["jsxs","jsx","useRef","useEffect","useMemo","clampPercent","useState"],"mappings":"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","file":"index.js","sourcesContent":["export function cn(...values: Array<string | false | null | undefined>): string {\n return values.filter(Boolean).join(' ')\n}\n","import { Document, Page, pdfjs } from 'react-pdf'\nimport type { ReactNode } from 'react'\nimport { cn } from '../lib/cn'\n\nif (typeof window !== 'undefined') {\n pdfjs.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`\n}\n\ninterface PdfViewerProps {\n pdfData: ArrayBuffer | null\n numPages: number\n scale: number\n onScaleChange: (nextScale: number) => void\n onDocumentLoadSuccess: (numPages: number) => void\n onPageDimensions: (input: { pageIndex: number; widthPt: number; heightPt: number }) => void\n renderOverlay?: (pageIndex: number) => ReactNode\n className?: string\n}\n\nconst MIN_SCALE = 0.5\nconst MAX_SCALE = 2\nconst SCALE_STEP = 0.1\n\nexport function PdfViewer({\n pdfData,\n numPages,\n scale,\n onScaleChange,\n onDocumentLoadSuccess,\n onPageDimensions,\n renderOverlay,\n className,\n}: PdfViewerProps) {\n if (!pdfData)\n return (\n <div data-slot=\"pdf-viewer-empty\" className={cn(className)}>\n Upload a PDF to begin\n </div>\n )\n\n return (\n <div data-slot=\"pdf-viewer\" className={cn(className)}>\n <div data-slot=\"pdf-viewer-toolbar\">\n <div data-slot=\"pdf-viewer-page-count\">Pages: {numPages || '—'}</div>\n <div data-slot=\"pdf-viewer-zoom\">\n <button\n type=\"button\"\n data-slot=\"pdf-viewer-zoom-button\"\n onClick={() => onScaleChange(Math.max(MIN_SCALE, Number((scale - SCALE_STEP).toFixed(2))))}\n >\n -\n </button>\n <span data-slot=\"pdf-viewer-zoom-value\">{Math.round(scale * 100)}%</span>\n <button\n type=\"button\"\n data-slot=\"pdf-viewer-zoom-button\"\n onClick={() => onScaleChange(Math.min(MAX_SCALE, Number((scale + SCALE_STEP).toFixed(2))))}\n >\n +\n </button>\n </div>\n </div>\n\n <Document\n file={pdfData}\n onLoadSuccess={(loadedPdf) => onDocumentLoadSuccess(loadedPdf.numPages)}\n loading={<div data-slot=\"pdf-viewer-loading\">Loading PDF...</div>}\n error={<div data-slot=\"pdf-viewer-error\">Unable to render this PDF.</div>}\n >\n <div data-slot=\"pdf-viewer-pages\">\n {Array.from({ length: numPages }, (_, pageIndex) => (\n <div\n key={`pdf-page-${pageIndex}`}\n data-slot=\"pdf-viewer-page\"\n style={{ position: 'relative', margin: '0 auto', width: 'fit-content' }}\n >\n <Page\n pageNumber={pageIndex + 1}\n scale={scale}\n renderTextLayer={false}\n renderAnnotationLayer={false}\n onLoadSuccess={(page) =>\n onPageDimensions({\n pageIndex,\n widthPt: page.view[2],\n heightPt: page.view[3],\n })\n }\n />\n {renderOverlay?.(pageIndex)}\n </div>\n ))}\n </div>\n </Document>\n </div>\n )\n}\n","import { useRef } from 'react'\nimport type { FieldPlacement, SignatureFieldPreview } from '../types'\nimport type { PointerEvent } from 'react'\nimport { cn } from '../lib/cn'\n\ninterface SignatureFieldProps {\n field: FieldPlacement\n onUpdateField: (fieldId: string, partial: Partial<FieldPlacement>) => void\n onRemoveField: (fieldId: string) => void\n preview: SignatureFieldPreview\n className?: string\n}\n\ninterface DragState {\n startClientX: number\n startClientY: number\n startXPercent: number\n startYPercent: number\n}\n\ninterface ResizeState {\n startClientX: number\n startClientY: number\n startWidthPercent: number\n startHeightPercent: number\n}\n\nconst MIN_WIDTH_PERCENT = 8\nconst MIN_HEIGHT_PERCENT = 3\n\nfunction clampPercent(value: number): number {\n if (value < 0) return 0\n if (value > 100) return 100\n return value\n}\n\nfunction getFieldPreviewText(field: FieldPlacement, preview: SignatureFieldPreview): string {\n if (field.type === 'fullName') return preview.fullName\n if (field.type === 'title') return preview.title\n if (field.type === 'date') return preview.dateText\n return ''\n}\n\nexport function SignatureField({ field, onUpdateField, onRemoveField, preview, className }: SignatureFieldProps) {\n const rootRef = useRef<HTMLDivElement | null>(null)\n const dragStateRef = useRef<DragState | null>(null)\n const resizeStateRef = useRef<ResizeState | null>(null)\n\n function handleDragPointerDown(event: PointerEvent<HTMLDivElement>): void {\n event.stopPropagation()\n if (event.button !== 0) return\n if (!rootRef.current?.parentElement) return\n\n dragStateRef.current = {\n startClientX: event.clientX,\n startClientY: event.clientY,\n startXPercent: field.xPercent,\n startYPercent: field.yPercent,\n }\n\n event.currentTarget.setPointerCapture(event.pointerId)\n }\n\n function handleDragPointerMove(event: PointerEvent<HTMLDivElement>): void {\n if (!dragStateRef.current) return\n const parentElement = rootRef.current?.parentElement\n if (!parentElement) return\n\n const deltaX = event.clientX - dragStateRef.current.startClientX\n const deltaY = event.clientY - dragStateRef.current.startClientY\n const deltaXPercent = (deltaX / parentElement.clientWidth) * 100\n const deltaYPercent = (deltaY / parentElement.clientHeight) * 100\n const maxX = 100 - field.widthPercent\n const maxY = 100 - field.heightPercent\n\n onUpdateField(field.id, {\n xPercent: clampPercent(Math.min(maxX, dragStateRef.current.startXPercent + deltaXPercent)),\n yPercent: clampPercent(Math.min(maxY, dragStateRef.current.startYPercent + deltaYPercent)),\n })\n }\n\n function handleDragPointerUp(event: PointerEvent<HTMLDivElement>): void {\n dragStateRef.current = null\n if (event.currentTarget.hasPointerCapture(event.pointerId))\n event.currentTarget.releasePointerCapture(event.pointerId)\n }\n\n function handleResizePointerDown(event: PointerEvent<HTMLDivElement>): void {\n event.stopPropagation()\n if (event.button !== 0) return\n\n resizeStateRef.current = {\n startClientX: event.clientX,\n startClientY: event.clientY,\n startWidthPercent: field.widthPercent,\n startHeightPercent: field.heightPercent,\n }\n\n event.currentTarget.setPointerCapture(event.pointerId)\n }\n\n function handleResizePointerMove(event: PointerEvent<HTMLDivElement>): void {\n if (!resizeStateRef.current) return\n const parentElement = rootRef.current?.parentElement\n if (!parentElement) return\n\n const deltaX = event.clientX - resizeStateRef.current.startClientX\n const deltaY = event.clientY - resizeStateRef.current.startClientY\n const deltaWidthPercent = (deltaX / parentElement.clientWidth) * 100\n const deltaHeightPercent = (deltaY / parentElement.clientHeight) * 100\n\n const maxWidth = 100 - field.xPercent\n const maxHeight = 100 - field.yPercent\n const widthPercent = clampPercent(\n Math.min(maxWidth, Math.max(MIN_WIDTH_PERCENT, resizeStateRef.current.startWidthPercent + deltaWidthPercent))\n )\n const heightPercent = clampPercent(\n Math.min(maxHeight, Math.max(MIN_HEIGHT_PERCENT, resizeStateRef.current.startHeightPercent + deltaHeightPercent))\n )\n\n onUpdateField(field.id, { widthPercent, heightPercent })\n }\n\n function handleResizePointerUp(event: PointerEvent<HTMLDivElement>): void {\n resizeStateRef.current = null\n if (event.currentTarget.hasPointerCapture(event.pointerId))\n event.currentTarget.releasePointerCapture(event.pointerId)\n }\n\n const previewText = getFieldPreviewText(field, preview)\n\n return (\n <div\n ref={rootRef}\n data-slot=\"signature-field\"\n data-field-type={field.type}\n className={cn(className)}\n style={{\n position: 'absolute',\n left: `${field.xPercent}%`,\n top: `${field.yPercent}%`,\n width: `${field.widthPercent}%`,\n height: `${field.heightPercent}%`,\n userSelect: 'none',\n }}\n onPointerDown={handleDragPointerDown}\n onPointerMove={handleDragPointerMove}\n onPointerUp={handleDragPointerUp}\n >\n <div\n data-slot=\"signature-field-content\"\n style={{\n display: 'flex',\n height: '100%',\n width: '100%',\n alignItems: 'flex-start',\n justifyContent: 'space-between',\n }}\n >\n <div data-slot=\"signature-field-preview\">\n <div data-slot=\"signature-field-label\">{field.type}</div>\n {field.type === 'signature' && preview.signatureDataUrl ? (\n <img\n data-slot=\"signature-field-preview-image\"\n src={preview.signatureDataUrl}\n alt=\"signature preview\"\n draggable={false}\n />\n ) : (\n <div data-slot=\"signature-field-preview-text\">{previewText || '—'}</div>\n )}\n </div>\n <button\n type=\"button\"\n data-slot=\"signature-field-remove\"\n onPointerDown={(event) => event.stopPropagation()}\n onClick={(event) => {\n event.stopPropagation()\n onRemoveField(field.id)\n }}\n aria-label=\"Remove field\"\n >\n ×\n </button>\n </div>\n\n <div\n data-slot=\"signature-field-resize\"\n style={{\n position: 'absolute',\n right: '-0.375rem',\n bottom: '-0.375rem',\n width: '0.75rem',\n height: '0.75rem',\n cursor: 'nwse-resize',\n }}\n onPointerDown={handleResizePointerDown}\n onPointerMove={handleResizePointerMove}\n onPointerUp={handleResizePointerUp}\n />\n </div>\n )\n}\n","import type { FieldPlacement, FieldType, SignatureFieldPreview } from '../types'\nimport { SignatureField } from './signature-field'\nimport type { PointerEvent } from 'react'\nimport { cn } from '../lib/cn'\n\ninterface FieldOverlayProps {\n pageIndex: number\n fields: FieldPlacement[]\n selectedFieldType: FieldType | null\n onAddField: (input: { pageIndex: number; type: FieldType; xPercent: number; yPercent: number }) => void\n onUpdateField: (fieldId: string, partial: Partial<FieldPlacement>) => void\n onRemoveField: (fieldId: string) => void\n preview: SignatureFieldPreview\n className?: string\n}\n\nexport function FieldOverlay({\n pageIndex,\n fields,\n selectedFieldType,\n onAddField,\n onUpdateField,\n onRemoveField,\n preview,\n className,\n}: FieldOverlayProps) {\n function handleOverlayPointerDown(event: PointerEvent<HTMLDivElement>): void {\n if (!selectedFieldType) return\n if (event.button !== 0) return\n if (event.target !== event.currentTarget) return\n const rect = event.currentTarget.getBoundingClientRect()\n const xPercent = ((event.clientX - rect.left) / rect.width) * 100\n const yPercent = ((event.clientY - rect.top) / rect.height) * 100\n onAddField({\n pageIndex,\n type: selectedFieldType,\n xPercent,\n yPercent,\n })\n }\n\n const pageFields = fields.filter((field) => field.pageIndex === pageIndex)\n\n return (\n <div\n data-slot=\"field-overlay\"\n data-state={selectedFieldType ? 'placing' : 'idle'}\n className={cn(className)}\n style={{\n position: 'absolute',\n inset: 0,\n zIndex: 20,\n cursor: selectedFieldType ? 'crosshair' : 'default',\n }}\n onPointerDown={handleOverlayPointerDown}\n aria-label={`Field overlay page ${pageIndex + 1}`}\n >\n {pageFields.map((field) => (\n <SignatureField\n key={field.id}\n field={field}\n onUpdateField={onUpdateField}\n onRemoveField={onRemoveField}\n preview={preview}\n />\n ))}\n </div>\n )\n}\n","import type { FieldType } from '../types'\nimport { cn } from '../lib/cn'\n\ninterface FieldPaletteProps {\n selectedFieldType: FieldType | null\n onSelectFieldType: (fieldType: FieldType | null) => void\n className?: string\n}\n\nconst FIELD_LABELS: Record<FieldType, string> = {\n signature: 'Signature',\n fullName: 'Full Name',\n title: 'Title',\n date: 'Date',\n}\n\nconst FIELD_TYPES: FieldType[] = ['signature', 'fullName', 'title', 'date']\n\nexport function FieldPalette({ selectedFieldType, onSelectFieldType, className }: FieldPaletteProps) {\n return (\n <div data-slot=\"field-palette\" className={cn(className)}>\n {FIELD_TYPES.map((fieldType) => {\n const isSelected = selectedFieldType === fieldType\n return (\n <button\n key={fieldType}\n type=\"button\"\n data-slot=\"field-palette-button\"\n data-state={isSelected ? 'selected' : 'idle'}\n onClick={() => onSelectFieldType(isSelected ? null : fieldType)}\n aria-pressed={isSelected}\n >\n {FIELD_LABELS[fieldType]}\n </button>\n )\n })}\n </div>\n )\n}\n","import type { SignerInfo } from '../types'\nimport { cn } from '../lib/cn'\n\ninterface SignerDetailsPanelProps {\n signerInfo: SignerInfo\n onSignerInfoChange: (nextSignerInfo: SignerInfo) => void\n className?: string\n}\n\nexport function SignerDetailsPanel({ signerInfo, onSignerInfoChange, className }: SignerDetailsPanelProps) {\n function handleInputChange(fieldName: keyof SignerInfo, fieldValue: string): void {\n onSignerInfoChange({\n ...signerInfo,\n [fieldName]: fieldValue,\n })\n }\n\n return (\n <div data-slot=\"signer-panel\" className={cn(className)}>\n <h2 data-slot=\"signer-panel-heading\">Signer Details</h2>\n\n <label data-slot=\"signer-panel-label\">\n First Name\n <input\n data-slot=\"signer-panel-input\"\n value={signerInfo.firstName}\n onChange={(event) => handleInputChange('firstName', event.target.value)}\n />\n </label>\n\n <label data-slot=\"signer-panel-label\">\n Last Name\n <input\n data-slot=\"signer-panel-input\"\n value={signerInfo.lastName}\n onChange={(event) => handleInputChange('lastName', event.target.value)}\n />\n </label>\n\n <label data-slot=\"signer-panel-label\">\n Title\n <input\n data-slot=\"signer-panel-input\"\n value={signerInfo.title}\n onChange={(event) => handleInputChange('title', event.target.value)}\n />\n </label>\n </div>\n )\n}\n","const loadedFonts = new Set<string>()\n\nexport const SIGNATURE_FONTS = ['Dancing Script', 'Great Vibes', 'Sacramento', 'Alex Brush'] as const\n\nfunction buildGoogleFontsCssUrl(family: string): string {\n const encoded = family.trim().replace(/\\s+/g, '+')\n return `https://fonts.googleapis.com/css2?family=${encoded}&display=swap`\n}\n\nasync function loadCssFromGoogleFonts(url: string): Promise<string> {\n const response = await fetch(url)\n if (!response.ok) throw new Error(`Unable to load font css from ${url}`)\n return response.text()\n}\n\nfunction extractFontSource(cssText: string): string | null {\n const sourceMatch = cssText.match(/src:\\s*url\\(([^)]+)\\)\\s*format\\(['\"]?([^'\")]+)['\"]?\\)/i)\n if (!sourceMatch) return null\n return sourceMatch[1].replace(/['\"]/g, '')\n}\n\nexport async function loadSignatureFont(fontFamily: string): Promise<void> {\n if (loadedFonts.has(fontFamily)) return\n if (typeof document === 'undefined') return\n if (typeof FontFace === 'undefined') return\n\n const cssUrl = buildGoogleFontsCssUrl(fontFamily)\n const cssText = await loadCssFromGoogleFonts(cssUrl)\n const fontSource = extractFontSource(cssText)\n if (!fontSource) throw new Error(`Unable to extract font source for ${fontFamily}`)\n\n const fontFace = new FontFace(fontFamily, `url(${fontSource})`)\n await fontFace.load()\n const fontSet = document.fonts as unknown as { add: (font: FontFace) => void }\n fontSet.add(fontFace)\n loadedFonts.add(fontFamily)\n}\n\nexport function buildSignatureFontCssUrl(fontFamily: string): string {\n return buildGoogleFontsCssUrl(fontFamily)\n}\n","import SignaturePadLibrary from 'signature_pad'\nimport { useEffect, useRef } from 'react'\nimport { cn } from '../lib/cn'\n\ninterface SignaturePadProps {\n onDrawn: (signatureDataUrl: string) => void\n className?: string\n}\n\nexport function SignaturePad({ onDrawn, className }: SignaturePadProps) {\n const canvasRef = useRef<HTMLCanvasElement | null>(null)\n const signaturePadRef = useRef<SignaturePadLibrary | null>(null)\n\n useEffect(() => {\n if (!canvasRef.current) return\n\n const signaturePad = new SignaturePadLibrary(canvasRef.current, {\n minWidth: 1,\n maxWidth: 2.5,\n penColor: '#111827',\n backgroundColor: 'rgba(255,255,255,0)',\n })\n\n signaturePadRef.current = signaturePad\n\n function emitSignatureIfNotEmpty(): void {\n if (signaturePad.isEmpty()) return\n onDrawn(signaturePad.toDataURL('image/png'))\n }\n\n signaturePad.addEventListener('endStroke', emitSignatureIfNotEmpty)\n\n return () => {\n signaturePad.removeEventListener('endStroke', emitSignatureIfNotEmpty)\n signaturePad.off()\n signaturePadRef.current = null\n }\n }, [onDrawn])\n\n function handleClear(): void {\n signaturePadRef.current?.clear()\n onDrawn('')\n }\n\n return (\n <div data-slot=\"signature-pad\" className={cn(className)}>\n <canvas data-slot=\"signature-pad-canvas\" ref={canvasRef} width={420} height={140} />\n <div data-slot=\"signature-pad-actions\">\n <button\n type=\"button\"\n data-slot=\"signature-pad-clear\"\n onClick={handleClear}\n >\n Clear\n </button>\n </div>\n </div>\n )\n}\n","import { useMemo } from 'react'\nimport { SIGNATURE_FONTS } from '../lib/signature-fonts'\nimport type { SignatureStyle } from '../types'\nimport { SignaturePad } from './signature-pad'\nimport { cn } from '../lib/cn'\n\ninterface SignaturePreviewProps {\n signerName: string\n style: SignatureStyle\n signatureDataUrl: string | null\n isRendering: boolean\n onStyleChange: (nextStyle: SignatureStyle) => void\n className?: string\n}\n\nexport function SignaturePreview({\n signerName,\n style,\n signatureDataUrl,\n isRendering,\n onStyleChange,\n className,\n}: SignaturePreviewProps) {\n const canShowPreview = useMemo(() => signerName.trim().length > 0, [signerName])\n\n return (\n <div data-slot=\"signature-preview\" className={cn(className)}>\n <h2 data-slot=\"signature-preview-heading\">Signature</h2>\n\n <div data-slot=\"signature-preview-mode-toggle\">\n <button\n type=\"button\"\n data-slot=\"signature-preview-mode-button\"\n data-mode=\"typed\"\n data-state={style.mode === 'typed' ? 'active' : 'idle'}\n onClick={() => onStyleChange({ mode: 'typed', fontFamily: style.mode === 'typed' ? style.fontFamily : SIGNATURE_FONTS[0] })}\n >\n Typed\n </button>\n <button\n type=\"button\"\n data-slot=\"signature-preview-mode-button\"\n data-mode=\"drawn\"\n data-state={style.mode === 'drawn' ? 'active' : 'idle'}\n onClick={() => onStyleChange({ mode: 'drawn', dataUrl: style.mode === 'drawn' ? style.dataUrl : '' })}\n >\n Drawn\n </button>\n </div>\n\n {style.mode === 'typed' ? (\n <label data-slot=\"signature-preview-font-label\">\n Font\n <select\n data-slot=\"signature-preview-font-select\"\n value={style.fontFamily}\n onChange={(event) => onStyleChange({ mode: 'typed', fontFamily: event.target.value })}\n >\n {SIGNATURE_FONTS.map((fontFamily) => (\n <option key={fontFamily} value={fontFamily}>\n {fontFamily}\n </option>\n ))}\n </select>\n </label>\n ) : (\n <SignaturePad onDrawn={(dataUrl) => onStyleChange({ mode: 'drawn', dataUrl })} />\n )}\n\n <div\n data-slot=\"signature-preview-display\"\n data-state={\n !canShowPreview ? 'empty' : isRendering ? 'rendering' : signatureDataUrl ? 'ready' : 'missing-signature'\n }\n >\n {!canShowPreview ? (\n <p data-slot=\"signature-preview-placeholder\">Enter signer first and last name to render a signature.</p>\n ) : isRendering ? (\n <p data-slot=\"signature-preview-placeholder\">Rendering signature...</p>\n ) : signatureDataUrl ? (\n <img data-slot=\"signature-preview-image\" src={signatureDataUrl} alt=\"Signature preview\" />\n ) : (\n <p data-slot=\"signature-preview-placeholder\">No signature available yet.</p>\n )}\n </div>\n </div>\n )\n}\n","import { cn } from '../lib/cn'\n\ninterface SigningCompleteProps {\n signerName: string\n fieldCount: number\n signedAt: string\n documentHash: string\n downloadUrl: string\n fileName?: string\n onReset: () => void\n className?: string\n}\n\nexport function SigningComplete({\n signerName,\n fieldCount,\n signedAt,\n documentHash,\n downloadUrl,\n fileName = 'signed-document.pdf',\n onReset,\n className,\n}: SigningCompleteProps) {\n return (\n <div data-slot=\"signing-complete\" className={cn(className)}>\n <h2 data-slot=\"signing-complete-heading\">Document Signed</h2>\n <div data-slot=\"signing-complete-details\">\n <p>Signer: {signerName || 'Unknown'}</p>\n <p>Fields applied: {fieldCount}</p>\n <p>Signed at: {signedAt}</p>\n </div>\n\n <div data-slot=\"signing-complete-hash\">\n <p data-slot=\"signing-complete-hash-label\">SHA-256</p>\n <p data-slot=\"signing-complete-hash-value\">{documentHash}</p>\n </div>\n\n <div data-slot=\"signing-complete-actions\">\n <a\n href={downloadUrl}\n download={fileName}\n data-slot=\"signing-complete-download\"\n >\n Download Signed PDF\n </a>\n <button\n type=\"button\"\n data-slot=\"signing-complete-reset\"\n onClick={onReset}\n >\n Sign Another\n </button>\n </div>\n </div>\n )\n}\n","import { useEffect, useMemo, useState } from 'react'\nimport type { PdfPageDimensions } from '../types'\n\nexport type PdfInput = File | Blob | ArrayBuffer | Uint8Array | null\n\nfunction isArrayBuffer(value: unknown): value is ArrayBuffer {\n return value instanceof ArrayBuffer\n}\n\nfunction isUint8Array(value: unknown): value is Uint8Array {\n return value instanceof Uint8Array\n}\n\nasync function convertPdfInputToArrayBuffer(pdfInput: Exclude<PdfInput, null>): Promise<ArrayBuffer> {\n if (isArrayBuffer(pdfInput)) return pdfInput\n if (isUint8Array(pdfInput)) {\n const copy = new Uint8Array(pdfInput.byteLength)\n copy.set(pdfInput)\n return copy.buffer\n }\n return pdfInput.arrayBuffer()\n}\n\nexport function usePdfDocument(pdfInput: PdfInput) {\n const [pdfData, setPdfData] = useState<ArrayBuffer | null>(null)\n const [numPages, setNumPages] = useState(0)\n const [scale, setScale] = useState(1)\n const [pageDimensions, setPageDimensions] = useState<PdfPageDimensions[]>([])\n const [errorMessage, setErrorMessage] = useState<string | null>(null)\n const [isLoading, setIsLoading] = useState(false)\n\n useEffect(() => {\n if (!pdfInput) {\n setPdfData(null)\n setNumPages(0)\n setPageDimensions([])\n setErrorMessage(null)\n return\n }\n\n let isMounted = true\n\n setIsLoading(true)\n setErrorMessage(null)\n convertPdfInputToArrayBuffer(pdfInput)\n .then((arrayBuffer) => {\n if (!isMounted) return\n setPdfData(arrayBuffer)\n })\n .catch((error: unknown) => {\n if (!isMounted) return\n const message = error instanceof Error ? error.message : 'Unable to read PDF data'\n setErrorMessage(message)\n setPdfData(null)\n })\n .finally(() => {\n if (!isMounted) return\n setIsLoading(false)\n })\n\n return () => {\n isMounted = false\n }\n }, [pdfInput])\n\n function handleDocumentLoadSuccess(loadedPages: number): void {\n setNumPages(loadedPages)\n setPageDimensions((previousDimensions) =>\n previousDimensions\n .filter((dimension) => dimension.pageIndex < loadedPages)\n .sort((left, right) => left.pageIndex - right.pageIndex)\n )\n }\n\n function setPageDimension(pageIndex: number, widthPt: number, heightPt: number): void {\n setPageDimensions((previousDimensions) => {\n const nextDimensions = previousDimensions.filter((entry) => entry.pageIndex !== pageIndex)\n nextDimensions.push({ pageIndex, widthPt, heightPt })\n nextDimensions.sort((left, right) => left.pageIndex - right.pageIndex)\n return nextDimensions\n })\n }\n\n const hasPdf = useMemo(() => pdfData !== null, [pdfData])\n\n return {\n pdfData,\n numPages,\n scale,\n setScale,\n pageDimensions,\n setPageDimension,\n handleDocumentLoadSuccess,\n hasPdf,\n isLoading,\n errorMessage,\n }\n}\n","import { useCallback, useMemo, useState } from 'react'\nimport type { FieldPlacement, FieldType } from '../types'\n\ninterface UseFieldPlacementOptions {\n defaultWidthPercent?: number\n defaultHeightPercent?: number\n}\n\ninterface AddFieldInput {\n pageIndex: number\n type: FieldType\n xPercent: number\n yPercent: number\n}\n\nfunction clampPercent(value: number): number {\n if (Number.isNaN(value)) return 0\n if (value < 0) return 0\n if (value > 100) return 100\n return value\n}\n\nfunction buildFieldId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID()\n }\n\n return `field-${Date.now()}-${Math.random().toString(16).slice(2)}`\n}\n\nexport function useFieldPlacement(options: UseFieldPlacementOptions = {}) {\n const defaultWidthPercent = options.defaultWidthPercent ?? 25\n const defaultHeightPercent = options.defaultHeightPercent ?? 5\n const [fields, setFields] = useState<FieldPlacement[]>([])\n\n const addField = useCallback(\n ({ pageIndex, type, xPercent, yPercent }: AddFieldInput) => {\n const field: FieldPlacement = {\n id: buildFieldId(),\n pageIndex,\n type,\n xPercent: clampPercent(xPercent),\n yPercent: clampPercent(yPercent),\n widthPercent: clampPercent(defaultWidthPercent),\n heightPercent: clampPercent(defaultHeightPercent),\n }\n setFields((previousFields) => [...previousFields, field])\n return field\n },\n [defaultHeightPercent, defaultWidthPercent]\n )\n\n const updateField = useCallback((id: string, partial: Partial<FieldPlacement>) => {\n setFields((previousFields) =>\n previousFields.map((field) => {\n if (field.id !== id) return field\n return {\n ...field,\n ...partial,\n xPercent: partial.xPercent === undefined ? field.xPercent : clampPercent(partial.xPercent),\n yPercent: partial.yPercent === undefined ? field.yPercent : clampPercent(partial.yPercent),\n widthPercent:\n partial.widthPercent === undefined ? field.widthPercent : clampPercent(partial.widthPercent),\n heightPercent:\n partial.heightPercent === undefined ? field.heightPercent : clampPercent(partial.heightPercent),\n }\n })\n )\n }, [])\n\n const removeField = useCallback((id: string) => {\n setFields((previousFields) => previousFields.filter((field) => field.id !== id))\n }, [])\n\n const clearFields = useCallback(() => {\n setFields([])\n }, [])\n\n const fieldActions = useMemo(\n () => ({\n addField,\n updateField,\n removeField,\n clearFields,\n }),\n [addField, clearFields, removeField, updateField]\n )\n\n return {\n fields,\n ...fieldActions,\n }\n}\n","import { useEffect, useMemo, useState } from 'react'\nimport { loadSignatureFont } from '../lib/signature-fonts'\nimport type { SignatureStyle } from '../types'\n\ninterface UseSignatureRendererInput {\n signerName: string\n style: SignatureStyle\n}\n\nfunction buildCanvas(): HTMLCanvasElement {\n return document.createElement('canvas')\n}\n\nfunction drawTypedSignature({\n signerName,\n fontFamily,\n}: {\n signerName: string\n fontFamily: string\n}): string {\n const canvas = buildCanvas()\n const context = canvas.getContext('2d')\n if (!context) return ''\n\n const padding = 16\n const fontSize = 56\n context.font = `${fontSize}px \"${fontFamily}\"`\n const metrics = context.measureText(signerName)\n\n canvas.width = Math.max(240, Math.ceil(metrics.width + padding * 2))\n canvas.height = 100\n\n context.clearRect(0, 0, canvas.width, canvas.height)\n context.font = `${fontSize}px \"${fontFamily}\"`\n context.fillStyle = '#111827'\n context.textBaseline = 'middle'\n context.fillText(signerName, padding, canvas.height / 2)\n\n return canvas.toDataURL('image/png')\n}\n\nexport function useSignatureRenderer({ signerName, style }: UseSignatureRendererInput) {\n const [signatureDataUrl, setSignatureDataUrl] = useState<string | null>(null)\n const [isRendering, setIsRendering] = useState(false)\n\n const normalizedName = useMemo(() => signerName.trim(), [signerName])\n\n useEffect(() => {\n if (!normalizedName) {\n setSignatureDataUrl(null)\n return\n }\n\n if (style.mode === 'drawn') {\n setSignatureDataUrl(style.dataUrl || null)\n return\n }\n\n let isActive = true\n setIsRendering(true)\n\n loadSignatureFont(style.fontFamily)\n .then(() => {\n if (!isActive) return\n const dataUrl = drawTypedSignature({ signerName: normalizedName, fontFamily: style.fontFamily })\n setSignatureDataUrl(dataUrl || null)\n })\n .catch(() => {\n if (!isActive) return\n setSignatureDataUrl(null)\n })\n .finally(() => {\n if (!isActive) return\n setIsRendering(false)\n })\n\n return () => {\n isActive = false\n }\n }, [normalizedName, style])\n\n return {\n signatureDataUrl,\n isRendering,\n }\n}\n","import type { FieldPlacement, PdfPageDimensions, PointRect } from '../types'\n\nfunction clampPercent(value: number): number {\n if (Number.isNaN(value)) return 0\n if (value < 0) return 0\n if (value > 100) return 100\n return value\n}\n\nexport function mapToPoints(field: FieldPlacement, page: PdfPageDimensions): PointRect {\n const xPercent = clampPercent(field.xPercent)\n const yPercent = clampPercent(field.yPercent)\n const widthPercent = clampPercent(field.widthPercent)\n const heightPercent = clampPercent(field.heightPercent)\n\n const width = (widthPercent / 100) * page.widthPt\n const height = (heightPercent / 100) * page.heightPt\n const x = (xPercent / 100) * page.widthPt\n const y = page.heightPt - (yPercent / 100) * page.heightPt - height\n\n return { x, y, width, height }\n}\n\nexport function mapFromPoints(\n rect: PointRect,\n page: PdfPageDimensions\n): Pick<FieldPlacement, 'xPercent' | 'yPercent' | 'widthPercent' | 'heightPercent'> {\n const widthPercent = (rect.width / page.widthPt) * 100\n const heightPercent = (rect.height / page.heightPt) * 100\n const xPercent = (rect.x / page.widthPt) * 100\n const yPercent = ((page.heightPt - rect.y - rect.height) / page.heightPt) * 100\n\n return {\n xPercent: clampPercent(xPercent),\n yPercent: clampPercent(yPercent),\n widthPercent: clampPercent(widthPercent),\n heightPercent: clampPercent(heightPercent),\n }\n}\n","import fontkit from '@pdf-lib/fontkit'\nimport { PDFDocument, StandardFonts } from 'pdf-lib'\nimport { mapToPoints } from './coordinate-mapper'\nimport type { FieldPlacement, PdfPageDimensions, SignerInfo } from '../types'\n\ninterface ModifyPdfInput {\n pdfBytes: Uint8Array\n fields: FieldPlacement[]\n signer: SignerInfo\n signatureDataUrl: string\n pageDimensions: PdfPageDimensions[]\n dateText?: string\n}\n\nfunction fullNameFromSigner(signer: SignerInfo): string {\n return [signer.firstName, signer.lastName].filter(Boolean).join(' ').trim()\n}\n\nfunction dataUrlToBytes(dataUrl: string): Uint8Array {\n const base64 = dataUrl.split(',')[1]\n if (!base64) throw new Error('Invalid signature data URL')\n const binary =\n typeof atob === 'function'\n ? atob(base64)\n : Buffer.from(base64, 'base64').toString('binary')\n const bytes = new Uint8Array(binary.length)\n for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index)\n return bytes\n}\n\nexport async function modifyPdf({\n pdfBytes,\n fields,\n signer,\n signatureDataUrl,\n pageDimensions,\n dateText,\n}: ModifyPdfInput): Promise<Uint8Array> {\n const pdfDocument = await PDFDocument.load(pdfBytes)\n pdfDocument.registerFontkit(fontkit)\n const pages = pdfDocument.getPages()\n const helveticaFont = await pdfDocument.embedFont(StandardFonts.Helvetica)\n\n const signatureImageBytes = signatureDataUrl ? dataUrlToBytes(signatureDataUrl) : null\n const signatureImage = signatureImageBytes ? await pdfDocument.embedPng(signatureImageBytes) : null\n const resolvedDateText = dateText || new Date().toLocaleDateString()\n\n for (const field of fields) {\n const page = pages[field.pageIndex]\n const pageDimension = pageDimensions.find((entry) => entry.pageIndex === field.pageIndex)\n if (!page || !pageDimension) continue\n\n const pointRect = mapToPoints(field, pageDimension)\n if (field.type === 'signature' && signatureImage) {\n page.drawImage(signatureImage, {\n x: pointRect.x,\n y: pointRect.y,\n width: pointRect.width,\n height: pointRect.height,\n })\n continue\n }\n\n const textValue =\n field.type === 'fullName'\n ? fullNameFromSigner(signer)\n : field.type === 'title'\n ? signer.title\n : field.type === 'date'\n ? resolvedDateText\n : ''\n if (!textValue) continue\n\n const textSize = Math.max(9, Math.min(16, pointRect.height * 0.6))\n page.drawText(textValue, {\n x: pointRect.x + 2,\n y: pointRect.y + Math.max(0, (pointRect.height - textSize) / 2),\n size: textSize,\n font: helveticaFont,\n })\n }\n\n return pdfDocument.save()\n}\n","export async function sha256(data: Uint8Array): Promise<string> {\n const dataBuffer = new Uint8Array(data.byteLength)\n dataBuffer.set(data)\n const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer)\n return Array.from(new Uint8Array(hashBuffer))\n .map((byte) => byte.toString(16).padStart(2, '0'))\n .join('')\n}\n","export const SLOTS = {\n pdfViewer: 'pdf-viewer',\n pdfViewerEmpty: 'pdf-viewer-empty',\n pdfViewerToolbar: 'pdf-viewer-toolbar',\n pdfViewerPageCount: 'pdf-viewer-page-count',\n pdfViewerZoom: 'pdf-viewer-zoom',\n pdfViewerZoomButton: 'pdf-viewer-zoom-button',\n pdfViewerZoomValue: 'pdf-viewer-zoom-value',\n pdfViewerPages: 'pdf-viewer-pages',\n pdfViewerPage: 'pdf-viewer-page',\n pdfViewerLoading: 'pdf-viewer-loading',\n pdfViewerError: 'pdf-viewer-error',\n fieldOverlay: 'field-overlay',\n signatureField: 'signature-field',\n signatureFieldContent: 'signature-field-content',\n signatureFieldLabel: 'signature-field-label',\n signatureFieldPreview: 'signature-field-preview',\n signatureFieldPreviewImage: 'signature-field-preview-image',\n signatureFieldPreviewText: 'signature-field-preview-text',\n signatureFieldRemove: 'signature-field-remove',\n signatureFieldResize: 'signature-field-resize',\n fieldPalette: 'field-palette',\n fieldPaletteButton: 'field-palette-button',\n signerPanel: 'signer-panel',\n signerPanelHeading: 'signer-panel-heading',\n signerPanelLabel: 'signer-panel-label',\n signerPanelInput: 'signer-panel-input',\n signaturePreview: 'signature-preview',\n signaturePreviewHeading: 'signature-preview-heading',\n signaturePreviewModeToggle: 'signature-preview-mode-toggle',\n signaturePreviewModeButton: 'signature-preview-mode-button',\n signaturePreviewFontLabel: 'signature-preview-font-label',\n signaturePreviewFontSelect: 'signature-preview-font-select',\n signaturePreviewDisplay: 'signature-preview-display',\n signaturePreviewImage: 'signature-preview-image',\n signaturePreviewPlaceholder: 'signature-preview-placeholder',\n signaturePad: 'signature-pad',\n signaturePadCanvas: 'signature-pad-canvas',\n signaturePadActions: 'signature-pad-actions',\n signaturePadClear: 'signature-pad-clear',\n signingComplete: 'signing-complete',\n signingCompleteHeading: 'signing-complete-heading',\n signingCompleteDetails: 'signing-complete-details',\n signingCompleteHash: 'signing-complete-hash',\n signingCompleteHashLabel: 'signing-complete-hash-label',\n signingCompleteHashValue: 'signing-complete-hash-value',\n signingCompleteActions: 'signing-complete-actions',\n signingCompleteDownload: 'signing-complete-download',\n signingCompleteReset: 'signing-complete-reset',\n} as const\n","export { PdfViewer } from './components/pdf-viewer'\nexport { FieldOverlay } from './components/field-overlay'\nexport { SignatureField } from './components/signature-field'\nexport { FieldPalette } from './components/field-palette'\nexport { SignerDetailsPanel } from './components/signer-details-panel'\nexport { SignaturePreview } from './components/signature-preview'\nexport { SignaturePad } from './components/signature-pad'\nexport { SigningComplete } from './components/signing-complete'\n\nexport { usePdfDocument } from './hooks/use-pdf-document'\nexport { useFieldPlacement } from './hooks/use-field-placement'\nexport { useSignatureRenderer } from './hooks/use-signature-renderer'\n\nexport { modifyPdf } from './lib/pdf-modifier'\nexport { mapToPoints, mapFromPoints } from './lib/coordinate-mapper'\nexport { loadSignatureFont, SIGNATURE_FONTS } from './lib/signature-fonts'\nexport { sha256 } from './lib/hash'\nexport { SLOTS } from './lib/slots'\n\nexport type {\n FieldPlacement,\n FieldType,\n SignerInfo,\n SignatureStyle,\n SigningResult,\n PdfPageDimensions,\n SignatureFieldPreview,\n} from './types'\n\nexport const defaults = {\n SIGNATURE_FONTS: ['Dancing Script', 'Great Vibes', 'Sacramento', 'Alex Brush'],\n DEFAULT_FIELD_WIDTH_PERCENT: 25,\n DEFAULT_FIELD_HEIGHT_PERCENT: 5,\n} as const\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/config.ts","../src/lib/signature-fonts.ts","../src/lib/cn.ts","../src/components/pdf-viewer.tsx","../src/components/signature-field.tsx","../src/components/field-overlay.tsx","../src/components/field-palette.tsx","../src/components/signer-details-panel.tsx","../src/components/signature-pad.tsx","../src/components/signature-preview.tsx","../src/components/signing-complete.tsx","../src/hooks/use-pdf-document.ts","../src/hooks/use-field-placement.ts","../src/hooks/use-signature-renderer.ts","../src/lib/coordinate-mapper.ts","../src/lib/pdf-modifier.ts","../src/lib/hash.ts","../src/lib/slots.ts","../src/index.ts"],"names":["jsxs","jsx","useRef","useEffect","useMemo","clampPercent","useState"],"mappings":"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","file":"index.js","sourcesContent":["export interface SignatureFontWarning {\n code: string\n message: string\n}\n\nexport interface ESigningConfig {\n /** PDF.js worker script URL (e.g. self-hosted `/pdf.worker.min.mjs`). When unset, `PdfViewer` does not set `GlobalWorkerOptions.workerSrc`. */\n pdfWorkerSrc?: string\n /** `network`: fetch Google Fonts when loading typed signature fonts (default). `local-only`: no fetches; browser uses available/system fonts. */\n fontMode?: 'network' | 'local-only'\n /** Return a woff/woff2 URL for a font family, or `null` to fall back to Google Fonts (when `fontMode` is `network`). */\n fontUrlResolver?: (fontFamily: string) => string | null\n /** Non-throwing callback for recoverable issues (font/worker setup). */\n onWarning?: (warning: SignatureFontWarning) => void\n}\n\nlet _config: ESigningConfig = {}\n\nexport function configure(options: ESigningConfig): void {\n _config = { ..._config, ...options }\n}\n\nexport function getConfig(): Readonly<ESigningConfig> {\n return _config\n}\n\n/** @internal Reset for tests */\nexport function resetConfig(): void {\n _config = {}\n}\n","import { getConfig } from './config'\n\nconst loadedFonts = new Set<string>()\n\nexport const SIGNATURE_FONTS = [\n 'Caveat',\n 'Homemade Apple',\n 'Reenie Beanie',\n 'Mr Dafoe',\n 'Pacifico',\n 'Qwitcher Grypen',\n] as const\n\nfunction buildGoogleFontsCssUrl(family: string): string {\n const encoded = family.trim().replace(/\\s+/g, '+')\n return `https://fonts.googleapis.com/css2?family=${encoded}&display=swap`\n}\n\nasync function loadCssFromGoogleFonts(url: string): Promise<string> {\n const response = await fetch(url)\n if (!response.ok) throw new Error(`Unable to load font css from ${url}`)\n return response.text()\n}\n\nfunction extractFontSource(cssText: string): string | null {\n const sourceMatch = cssText.match(/src:\\s*url\\(([^)]+)\\)\\s*format\\(['\"]?([^'\")]+)['\"]?\\)/i)\n if (!sourceMatch) return null\n return sourceMatch[1].replace(/['\"]/g, '')\n}\n\nfunction warnFontLoad(message: string): void {\n try {\n getConfig().onWarning?.({ code: 'FONT_LOAD_FAILED', message })\n } catch {\n // never throw from observability hook\n }\n}\n\nasync function loadFontFaceFromUrl(fontFamily: string, url: string): Promise<void> {\n if (typeof FontFace === 'undefined' || typeof document === 'undefined') return\n const fontFace = new FontFace(fontFamily, `url(${url})`)\n await fontFace.load()\n const fontSet = document.fonts as unknown as { add: (font: FontFace) => void }\n fontSet.add(fontFace)\n}\n\nexport async function loadSignatureFont(fontFamily: string): Promise<void> {\n if (loadedFonts.has(fontFamily)) return\n if (typeof document === 'undefined') return\n if (typeof FontFace === 'undefined') return\n\n const { fontMode = 'network', fontUrlResolver } = getConfig()\n\n if (fontMode === 'local-only') {\n loadedFonts.add(fontFamily)\n return\n }\n\n const tryLoadFromGoogle = async (): Promise<void> => {\n try {\n const cssUrl = buildGoogleFontsCssUrl(fontFamily)\n const cssText = await loadCssFromGoogleFonts(cssUrl)\n const fontSource = extractFontSource(cssText)\n if (!fontSource) throw new Error(`Unable to extract font source for ${fontFamily}`)\n await loadFontFaceFromUrl(fontFamily, fontSource)\n } catch (error: unknown) {\n const detail = error instanceof Error ? error.message : String(error)\n warnFontLoad(`Google Fonts load failed for \"${fontFamily}\": ${detail}`)\n }\n }\n\n if (fontUrlResolver) {\n try {\n const resolved = fontUrlResolver(fontFamily)\n if (resolved) await loadFontFaceFromUrl(fontFamily, resolved)\n else await tryLoadFromGoogle()\n } catch (error: unknown) {\n const detail = error instanceof Error ? error.message : String(error)\n warnFontLoad(`Custom font load failed for \"${fontFamily}\": ${detail}`)\n await tryLoadFromGoogle()\n }\n } else await tryLoadFromGoogle()\n\n loadedFonts.add(fontFamily)\n}\n\n/** @internal Clears loaded-font bookkeeping (for unit tests). */\nexport function resetSignatureFontCache(): void {\n loadedFonts.clear()\n}\n\nexport function buildSignatureFontCssUrl(fontFamily: string): string {\n return buildGoogleFontsCssUrl(fontFamily)\n}\n","export function cn(...values: Array<string | false | null | undefined>): string {\n return values.filter(Boolean).join(' ')\n}\n","import { Document, Page, pdfjs } from 'react-pdf'\nimport { useEffect } from 'react'\nimport type { ReactNode } from 'react'\nimport { getConfig } from '../lib/config'\nimport { cn } from '../lib/cn'\n\ninterface PdfViewerProps {\n pdfData: ArrayBuffer | null\n numPages: number\n scale: number\n onScaleChange: (nextScale: number) => void\n onDocumentLoadSuccess: (numPages: number) => void\n onPageDimensions: (input: { pageIndex: number; widthPt: number; heightPt: number }) => void\n renderOverlay?: (pageIndex: number) => ReactNode\n className?: string\n /** PDF.js worker script URL. Overrides `configure({ pdfWorkerSrc })`. When neither is set, worker URL is left unset (no CDN injection). */\n workerSrc?: string\n}\n\nconst MIN_SCALE = 0.5\nconst MAX_SCALE = 2\nconst SCALE_STEP = 0.1\n\nexport function PdfViewer({\n pdfData,\n numPages,\n scale,\n onScaleChange,\n onDocumentLoadSuccess,\n onPageDimensions,\n renderOverlay,\n className,\n workerSrc,\n}: PdfViewerProps) {\n useEffect(() => {\n if (typeof window === 'undefined') return\n const fromConfig = getConfig().pdfWorkerSrc\n const next = workerSrc ?? fromConfig\n if (next) pdfjs.GlobalWorkerOptions.workerSrc = next\n }, [workerSrc])\n\n if (!pdfData)\n return (\n <div data-slot=\"pdf-viewer-empty\" className={cn(className)}>\n Upload a PDF to begin\n </div>\n )\n\n return (\n <div data-slot=\"pdf-viewer\" className={cn(className)}>\n <div data-slot=\"pdf-viewer-toolbar\">\n <div data-slot=\"pdf-viewer-page-count\">Pages: {numPages || '—'}</div>\n <div data-slot=\"pdf-viewer-zoom\">\n <button\n type=\"button\"\n data-slot=\"pdf-viewer-zoom-button\"\n onClick={() => onScaleChange(Math.max(MIN_SCALE, Number((scale - SCALE_STEP).toFixed(2))))}\n >\n -\n </button>\n <span data-slot=\"pdf-viewer-zoom-value\">{Math.round(scale * 100)}%</span>\n <button\n type=\"button\"\n data-slot=\"pdf-viewer-zoom-button\"\n onClick={() => onScaleChange(Math.min(MAX_SCALE, Number((scale + SCALE_STEP).toFixed(2))))}\n >\n +\n </button>\n </div>\n </div>\n\n <Document\n file={pdfData}\n onLoadSuccess={(loadedPdf) => onDocumentLoadSuccess(loadedPdf.numPages)}\n loading={<div data-slot=\"pdf-viewer-loading\">Loading PDF...</div>}\n error={<div data-slot=\"pdf-viewer-error\">Unable to render this PDF.</div>}\n >\n <div data-slot=\"pdf-viewer-pages\">\n {Array.from({ length: numPages }, (_, pageIndex) => (\n <div\n key={`pdf-page-${pageIndex}`}\n data-slot=\"pdf-viewer-page\"\n style={{ position: 'relative', margin: '0 auto', width: 'fit-content' }}\n >\n <Page\n pageNumber={pageIndex + 1}\n scale={scale}\n renderTextLayer={false}\n renderAnnotationLayer={false}\n onLoadSuccess={(page) =>\n onPageDimensions({\n pageIndex,\n widthPt: page.view[2],\n heightPt: page.view[3],\n })\n }\n />\n {renderOverlay?.(pageIndex)}\n </div>\n ))}\n </div>\n </Document>\n </div>\n )\n}\n","import { useRef } from 'react'\nimport type { FieldPlacement, SignatureFieldPreview } from '../types'\nimport type { PointerEvent } from 'react'\nimport { cn } from '../lib/cn'\n\ninterface SignatureFieldProps {\n field: FieldPlacement\n onUpdateField: (fieldId: string, partial: Partial<FieldPlacement>) => void\n onRemoveField: (fieldId: string) => void\n preview: SignatureFieldPreview\n className?: string\n}\n\ninterface DragState {\n startClientX: number\n startClientY: number\n startXPercent: number\n startYPercent: number\n}\n\ninterface ResizeState {\n startClientX: number\n startClientY: number\n startWidthPercent: number\n startHeightPercent: number\n}\n\nconst MIN_WIDTH_PERCENT = 8\nconst MIN_HEIGHT_PERCENT = 3\n\nfunction clampPercent(value: number): number {\n if (value < 0) return 0\n if (value > 100) return 100\n return value\n}\n\nfunction getFieldPreviewText(field: FieldPlacement, preview: SignatureFieldPreview): string {\n if (field.type === 'fullName') return preview.fullName\n if (field.type === 'title') return preview.title\n if (field.type === 'date') return preview.dateText\n return ''\n}\n\nexport function SignatureField({ field, onUpdateField, onRemoveField, preview, className }: SignatureFieldProps) {\n const rootRef = useRef<HTMLDivElement | null>(null)\n const dragStateRef = useRef<DragState | null>(null)\n const resizeStateRef = useRef<ResizeState | null>(null)\n\n function handleDragPointerDown(event: PointerEvent<HTMLDivElement>): void {\n event.stopPropagation()\n if (event.button !== 0) return\n if (!rootRef.current?.parentElement) return\n\n dragStateRef.current = {\n startClientX: event.clientX,\n startClientY: event.clientY,\n startXPercent: field.xPercent,\n startYPercent: field.yPercent,\n }\n\n event.currentTarget.setPointerCapture(event.pointerId)\n }\n\n function handleDragPointerMove(event: PointerEvent<HTMLDivElement>): void {\n if (!dragStateRef.current) return\n const parentElement = rootRef.current?.parentElement\n if (!parentElement) return\n\n const deltaX = event.clientX - dragStateRef.current.startClientX\n const deltaY = event.clientY - dragStateRef.current.startClientY\n const deltaXPercent = (deltaX / parentElement.clientWidth) * 100\n const deltaYPercent = (deltaY / parentElement.clientHeight) * 100\n const maxX = 100 - field.widthPercent\n const maxY = 100 - field.heightPercent\n\n onUpdateField(field.id, {\n xPercent: clampPercent(Math.min(maxX, dragStateRef.current.startXPercent + deltaXPercent)),\n yPercent: clampPercent(Math.min(maxY, dragStateRef.current.startYPercent + deltaYPercent)),\n })\n }\n\n function handleDragPointerUp(event: PointerEvent<HTMLDivElement>): void {\n dragStateRef.current = null\n if (event.currentTarget.hasPointerCapture(event.pointerId))\n event.currentTarget.releasePointerCapture(event.pointerId)\n }\n\n function handleResizePointerDown(event: PointerEvent<HTMLDivElement>): void {\n event.stopPropagation()\n if (event.button !== 0) return\n\n resizeStateRef.current = {\n startClientX: event.clientX,\n startClientY: event.clientY,\n startWidthPercent: field.widthPercent,\n startHeightPercent: field.heightPercent,\n }\n\n event.currentTarget.setPointerCapture(event.pointerId)\n }\n\n function handleResizePointerMove(event: PointerEvent<HTMLDivElement>): void {\n if (!resizeStateRef.current) return\n const parentElement = rootRef.current?.parentElement\n if (!parentElement) return\n\n const deltaX = event.clientX - resizeStateRef.current.startClientX\n const deltaY = event.clientY - resizeStateRef.current.startClientY\n const deltaWidthPercent = (deltaX / parentElement.clientWidth) * 100\n const deltaHeightPercent = (deltaY / parentElement.clientHeight) * 100\n\n const maxWidth = 100 - field.xPercent\n const maxHeight = 100 - field.yPercent\n const widthPercent = clampPercent(\n Math.min(maxWidth, Math.max(MIN_WIDTH_PERCENT, resizeStateRef.current.startWidthPercent + deltaWidthPercent))\n )\n const heightPercent = clampPercent(\n Math.min(maxHeight, Math.max(MIN_HEIGHT_PERCENT, resizeStateRef.current.startHeightPercent + deltaHeightPercent))\n )\n\n onUpdateField(field.id, { widthPercent, heightPercent })\n }\n\n function handleResizePointerUp(event: PointerEvent<HTMLDivElement>): void {\n resizeStateRef.current = null\n if (event.currentTarget.hasPointerCapture(event.pointerId))\n event.currentTarget.releasePointerCapture(event.pointerId)\n }\n\n const previewText = getFieldPreviewText(field, preview)\n\n return (\n <div\n ref={rootRef}\n data-slot=\"signature-field\"\n data-field-type={field.type}\n className={cn(className)}\n style={{\n position: 'absolute',\n left: `${field.xPercent}%`,\n top: `${field.yPercent}%`,\n width: `${field.widthPercent}%`,\n height: `${field.heightPercent}%`,\n userSelect: 'none',\n }}\n onPointerDown={handleDragPointerDown}\n onPointerMove={handleDragPointerMove}\n onPointerUp={handleDragPointerUp}\n >\n <div\n data-slot=\"signature-field-content\"\n style={{\n display: 'flex',\n height: '100%',\n width: '100%',\n alignItems: 'stretch',\n justifyContent: 'space-between',\n }}\n >\n <div data-slot=\"signature-field-preview\">\n <div data-slot=\"signature-field-label\">{field.type}</div>\n {field.type === 'signature' && preview.signatureDataUrl ? (\n <img\n data-slot=\"signature-field-preview-image\"\n src={preview.signatureDataUrl}\n alt=\"signature preview\"\n draggable={false}\n />\n ) : (\n <div data-slot=\"signature-field-preview-text\">{previewText || '—'}</div>\n )}\n </div>\n <button\n type=\"button\"\n data-slot=\"signature-field-remove\"\n onPointerDown={(event) => event.stopPropagation()}\n onClick={(event) => {\n event.stopPropagation()\n onRemoveField(field.id)\n }}\n aria-label=\"Remove field\"\n >\n ×\n </button>\n </div>\n\n <div\n data-slot=\"signature-field-resize\"\n style={{\n position: 'absolute',\n right: '-0.375rem',\n bottom: '-0.375rem',\n width: '0.75rem',\n height: '0.75rem',\n cursor: 'nwse-resize',\n }}\n onPointerDown={handleResizePointerDown}\n onPointerMove={handleResizePointerMove}\n onPointerUp={handleResizePointerUp}\n />\n </div>\n )\n}\n","import type { FieldPlacement, FieldType, SignatureFieldPreview } from '../types'\nimport { SignatureField } from './signature-field'\nimport type { PointerEvent } from 'react'\nimport { cn } from '../lib/cn'\n\ninterface FieldOverlayProps {\n pageIndex: number\n fields: FieldPlacement[]\n selectedFieldType: FieldType | null\n onAddField: (input: { pageIndex: number; type: FieldType; xPercent: number; yPercent: number }) => void\n onUpdateField: (fieldId: string, partial: Partial<FieldPlacement>) => void\n onRemoveField: (fieldId: string) => void\n preview: SignatureFieldPreview\n className?: string\n}\n\nexport function FieldOverlay({\n pageIndex,\n fields,\n selectedFieldType,\n onAddField,\n onUpdateField,\n onRemoveField,\n preview,\n className,\n}: FieldOverlayProps) {\n function handleOverlayPointerDown(event: PointerEvent<HTMLDivElement>): void {\n if (!selectedFieldType) return\n if (event.button !== 0) return\n if (event.target !== event.currentTarget) return\n const rect = event.currentTarget.getBoundingClientRect()\n const xPercent = ((event.clientX - rect.left) / rect.width) * 100\n const yPercent = ((event.clientY - rect.top) / rect.height) * 100\n onAddField({\n pageIndex,\n type: selectedFieldType,\n xPercent,\n yPercent,\n })\n }\n\n const pageFields = fields.filter((field) => field.pageIndex === pageIndex)\n\n return (\n <div\n data-slot=\"field-overlay\"\n data-state={selectedFieldType ? 'placing' : 'idle'}\n className={cn(className)}\n style={{\n position: 'absolute',\n inset: 0,\n zIndex: 20,\n cursor: selectedFieldType ? 'crosshair' : 'default',\n }}\n onPointerDown={handleOverlayPointerDown}\n aria-label={`Field overlay page ${pageIndex + 1}`}\n >\n {pageFields.map((field) => (\n <SignatureField\n key={field.id}\n field={field}\n onUpdateField={onUpdateField}\n onRemoveField={onRemoveField}\n preview={preview}\n />\n ))}\n </div>\n )\n}\n","import type { FieldType } from '../types'\nimport { cn } from '../lib/cn'\n\ninterface FieldPaletteProps {\n selectedFieldType: FieldType | null\n onSelectFieldType: (fieldType: FieldType | null) => void\n className?: string\n}\n\nconst FIELD_LABELS: Record<FieldType, string> = {\n signature: 'Signature',\n fullName: 'Full Name',\n title: 'Title',\n date: 'Date',\n}\n\nconst FIELD_TYPES: FieldType[] = ['signature', 'fullName', 'title', 'date']\n\nexport function FieldPalette({ selectedFieldType, onSelectFieldType, className }: FieldPaletteProps) {\n return (\n <div data-slot=\"field-palette\" className={cn(className)}>\n {FIELD_TYPES.map((fieldType) => {\n const isSelected = selectedFieldType === fieldType\n return (\n <button\n key={fieldType}\n type=\"button\"\n data-slot=\"field-palette-button\"\n data-state={isSelected ? 'selected' : 'idle'}\n onClick={() => onSelectFieldType(isSelected ? null : fieldType)}\n aria-pressed={isSelected}\n >\n {FIELD_LABELS[fieldType]}\n </button>\n )\n })}\n </div>\n )\n}\n","import type { SignerInfo } from '../types'\nimport { cn } from '../lib/cn'\n\ninterface SignerDetailsPanelProps {\n signerInfo: SignerInfo\n onSignerInfoChange: (nextSignerInfo: SignerInfo) => void\n className?: string\n}\n\nexport function SignerDetailsPanel({ signerInfo, onSignerInfoChange, className }: SignerDetailsPanelProps) {\n function handleInputChange(fieldName: keyof SignerInfo, fieldValue: string): void {\n onSignerInfoChange({\n ...signerInfo,\n [fieldName]: fieldValue,\n })\n }\n\n return (\n <div data-slot=\"signer-panel\" className={cn(className)}>\n <h2 data-slot=\"signer-panel-heading\">Signer Details</h2>\n\n <label data-slot=\"signer-panel-label\">\n First Name\n <input\n data-slot=\"signer-panel-input\"\n value={signerInfo.firstName}\n onChange={(event) => handleInputChange('firstName', event.target.value)}\n />\n </label>\n\n <label data-slot=\"signer-panel-label\">\n Last Name\n <input\n data-slot=\"signer-panel-input\"\n value={signerInfo.lastName}\n onChange={(event) => handleInputChange('lastName', event.target.value)}\n />\n </label>\n\n <label data-slot=\"signer-panel-label\">\n Title\n <input\n data-slot=\"signer-panel-input\"\n value={signerInfo.title}\n onChange={(event) => handleInputChange('title', event.target.value)}\n />\n </label>\n </div>\n )\n}\n","import SignaturePadLibrary from 'signature_pad'\nimport { useEffect, useRef } from 'react'\nimport { cn } from '../lib/cn'\n\ninterface SignaturePadProps {\n onDrawn: (signatureDataUrl: string) => void\n className?: string\n}\n\nexport function SignaturePad({ onDrawn, className }: SignaturePadProps) {\n const canvasRef = useRef<HTMLCanvasElement | null>(null)\n const signaturePadRef = useRef<SignaturePadLibrary | null>(null)\n\n useEffect(() => {\n if (!canvasRef.current) return\n\n const signaturePad = new SignaturePadLibrary(canvasRef.current, {\n minWidth: 1,\n maxWidth: 2.5,\n penColor: '#111827',\n backgroundColor: 'rgba(255,255,255,0)',\n })\n\n signaturePadRef.current = signaturePad\n\n function emitSignatureIfNotEmpty(): void {\n if (signaturePad.isEmpty()) return\n onDrawn(signaturePad.toDataURL('image/png'))\n }\n\n signaturePad.addEventListener('endStroke', emitSignatureIfNotEmpty)\n\n return () => {\n signaturePad.removeEventListener('endStroke', emitSignatureIfNotEmpty)\n signaturePad.off()\n signaturePadRef.current = null\n }\n }, [onDrawn])\n\n function handleClear(): void {\n signaturePadRef.current?.clear()\n onDrawn('')\n }\n\n return (\n <div data-slot=\"signature-pad\" className={cn(className)}>\n <canvas data-slot=\"signature-pad-canvas\" ref={canvasRef} width={420} height={140} />\n <div data-slot=\"signature-pad-actions\">\n <button\n type=\"button\"\n data-slot=\"signature-pad-clear\"\n onClick={handleClear}\n >\n Clear\n </button>\n </div>\n </div>\n )\n}\n","import { useMemo } from 'react'\nimport { SIGNATURE_FONTS } from '../lib/signature-fonts'\nimport type { SignatureStyle } from '../types'\nimport { SignaturePad } from './signature-pad'\nimport { cn } from '../lib/cn'\n\ninterface SignaturePreviewProps {\n signerName: string\n style: SignatureStyle\n signatureDataUrl: string | null\n isRendering: boolean\n onStyleChange: (nextStyle: SignatureStyle) => void\n className?: string\n}\n\nexport function SignaturePreview({\n signerName,\n style,\n signatureDataUrl,\n isRendering,\n onStyleChange,\n className,\n}: SignaturePreviewProps) {\n const canShowPreview = useMemo(() => signerName.trim().length > 0, [signerName])\n\n return (\n <div data-slot=\"signature-preview\" className={cn(className)}>\n <h2 data-slot=\"signature-preview-heading\">Signature</h2>\n\n <div data-slot=\"signature-preview-mode-toggle\">\n <button\n type=\"button\"\n data-slot=\"signature-preview-mode-button\"\n data-mode=\"typed\"\n data-state={style.mode === 'typed' ? 'active' : 'idle'}\n onClick={() => onStyleChange({ mode: 'typed', fontFamily: style.mode === 'typed' ? style.fontFamily : SIGNATURE_FONTS[0] })}\n >\n Typed\n </button>\n <button\n type=\"button\"\n data-slot=\"signature-preview-mode-button\"\n data-mode=\"drawn\"\n data-state={style.mode === 'drawn' ? 'active' : 'idle'}\n onClick={() => onStyleChange({ mode: 'drawn', dataUrl: style.mode === 'drawn' ? style.dataUrl : '' })}\n >\n Drawn\n </button>\n </div>\n\n {style.mode === 'typed' ? (\n <label data-slot=\"signature-preview-font-label\">\n Font\n <select\n data-slot=\"signature-preview-font-select\"\n value={style.fontFamily}\n onChange={(event) => onStyleChange({ mode: 'typed', fontFamily: event.target.value })}\n >\n {SIGNATURE_FONTS.map((fontFamily) => (\n <option key={fontFamily} value={fontFamily}>\n {fontFamily}\n </option>\n ))}\n </select>\n </label>\n ) : (\n <SignaturePad onDrawn={(dataUrl) => onStyleChange({ mode: 'drawn', dataUrl })} />\n )}\n\n <div\n data-slot=\"signature-preview-display\"\n data-state={\n !canShowPreview ? 'empty' : isRendering ? 'rendering' : signatureDataUrl ? 'ready' : 'missing-signature'\n }\n >\n {!canShowPreview ? (\n <p data-slot=\"signature-preview-placeholder\">Enter signer first and last name to render a signature.</p>\n ) : isRendering ? (\n <p data-slot=\"signature-preview-placeholder\">Rendering signature...</p>\n ) : signatureDataUrl ? (\n <img data-slot=\"signature-preview-image\" src={signatureDataUrl} alt=\"Signature preview\" />\n ) : (\n <p data-slot=\"signature-preview-placeholder\">No signature available yet.</p>\n )}\n </div>\n </div>\n )\n}\n","import { cn } from '../lib/cn'\n\ninterface SigningCompleteProps {\n signerName: string\n fieldCount: number\n signedAt: string\n documentHash: string\n downloadUrl: string\n fileName?: string\n onReset: () => void\n className?: string\n}\n\nexport function SigningComplete({\n signerName,\n fieldCount,\n signedAt,\n documentHash,\n downloadUrl,\n fileName = 'signed-document.pdf',\n onReset,\n className,\n}: SigningCompleteProps) {\n return (\n <div data-slot=\"signing-complete\" className={cn(className)}>\n <h2 data-slot=\"signing-complete-heading\">Document Signed</h2>\n <div data-slot=\"signing-complete-details\">\n <p>Signer: {signerName || 'Unknown'}</p>\n <p>Fields applied: {fieldCount}</p>\n <p>Signed at: {signedAt}</p>\n </div>\n\n <div data-slot=\"signing-complete-hash\">\n <p data-slot=\"signing-complete-hash-label\">SHA-256</p>\n <p data-slot=\"signing-complete-hash-value\">{documentHash}</p>\n </div>\n\n <div data-slot=\"signing-complete-actions\">\n <a\n href={downloadUrl}\n download={fileName}\n data-slot=\"signing-complete-download\"\n >\n Download Signed PDF\n </a>\n <button\n type=\"button\"\n data-slot=\"signing-complete-reset\"\n onClick={onReset}\n >\n Sign Another\n </button>\n </div>\n </div>\n )\n}\n","import { useEffect, useMemo, useState } from 'react'\nimport type { PdfPageDimensions } from '../types'\n\nexport type PdfInput = File | Blob | ArrayBuffer | Uint8Array | null\n\nfunction isArrayBuffer(value: unknown): value is ArrayBuffer {\n return value instanceof ArrayBuffer\n}\n\nfunction isUint8Array(value: unknown): value is Uint8Array {\n return value instanceof Uint8Array\n}\n\nasync function convertPdfInputToArrayBuffer(pdfInput: Exclude<PdfInput, null>): Promise<ArrayBuffer> {\n if (isArrayBuffer(pdfInput)) return pdfInput\n if (isUint8Array(pdfInput)) {\n const copy = new Uint8Array(pdfInput.byteLength)\n copy.set(pdfInput)\n return copy.buffer\n }\n return pdfInput.arrayBuffer()\n}\n\nexport function usePdfDocument(pdfInput: PdfInput) {\n const [pdfData, setPdfData] = useState<ArrayBuffer | null>(null)\n const [numPages, setNumPages] = useState(0)\n const [scale, setScale] = useState(1)\n const [pageDimensions, setPageDimensions] = useState<PdfPageDimensions[]>([])\n const [errorMessage, setErrorMessage] = useState<string | null>(null)\n const [isLoading, setIsLoading] = useState(false)\n\n useEffect(() => {\n if (!pdfInput) {\n setPdfData(null)\n setNumPages(0)\n setPageDimensions([])\n setErrorMessage(null)\n return\n }\n\n let isMounted = true\n\n setIsLoading(true)\n setErrorMessage(null)\n convertPdfInputToArrayBuffer(pdfInput)\n .then((arrayBuffer) => {\n if (!isMounted) return\n setPdfData(arrayBuffer)\n })\n .catch((error: unknown) => {\n if (!isMounted) return\n const message = error instanceof Error ? error.message : 'Unable to read PDF data'\n setErrorMessage(message)\n setPdfData(null)\n })\n .finally(() => {\n if (!isMounted) return\n setIsLoading(false)\n })\n\n return () => {\n isMounted = false\n }\n }, [pdfInput])\n\n function handleDocumentLoadSuccess(loadedPages: number): void {\n setNumPages(loadedPages)\n setPageDimensions((previousDimensions) =>\n previousDimensions\n .filter((dimension) => dimension.pageIndex < loadedPages)\n .sort((left, right) => left.pageIndex - right.pageIndex)\n )\n }\n\n function setPageDimension(pageIndex: number, widthPt: number, heightPt: number): void {\n setPageDimensions((previousDimensions) => {\n const nextDimensions = previousDimensions.filter((entry) => entry.pageIndex !== pageIndex)\n nextDimensions.push({ pageIndex, widthPt, heightPt })\n nextDimensions.sort((left, right) => left.pageIndex - right.pageIndex)\n return nextDimensions\n })\n }\n\n const hasPdf = useMemo(() => pdfData !== null, [pdfData])\n\n return {\n pdfData,\n numPages,\n scale,\n setScale,\n pageDimensions,\n setPageDimension,\n handleDocumentLoadSuccess,\n hasPdf,\n isLoading,\n errorMessage,\n }\n}\n","import { useCallback, useMemo, useState } from 'react'\nimport type { FieldPlacement, FieldType } from '../types'\n\ninterface UseFieldPlacementOptions {\n defaultWidthPercent?: number\n defaultHeightPercent?: number\n}\n\ninterface AddFieldInput {\n pageIndex: number\n type: FieldType\n xPercent: number\n yPercent: number\n}\n\nfunction clampPercent(value: number): number {\n if (Number.isNaN(value)) return 0\n if (value < 0) return 0\n if (value > 100) return 100\n return value\n}\n\nfunction buildFieldId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID()\n }\n\n return `field-${Date.now()}-${Math.random().toString(16).slice(2)}`\n}\n\nexport function useFieldPlacement(options: UseFieldPlacementOptions = {}) {\n const defaultWidthPercent = options.defaultWidthPercent ?? 25\n const defaultHeightPercent = options.defaultHeightPercent ?? 5\n const [fields, setFields] = useState<FieldPlacement[]>([])\n\n const addField = useCallback(\n ({ pageIndex, type, xPercent, yPercent }: AddFieldInput) => {\n const field: FieldPlacement = {\n id: buildFieldId(),\n pageIndex,\n type,\n xPercent: clampPercent(xPercent),\n yPercent: clampPercent(yPercent),\n widthPercent: clampPercent(defaultWidthPercent),\n heightPercent: clampPercent(defaultHeightPercent),\n }\n setFields((previousFields) => [...previousFields, field])\n return field\n },\n [defaultHeightPercent, defaultWidthPercent]\n )\n\n const updateField = useCallback((id: string, partial: Partial<FieldPlacement>) => {\n setFields((previousFields) =>\n previousFields.map((field) => {\n if (field.id !== id) return field\n return {\n ...field,\n ...partial,\n xPercent: partial.xPercent === undefined ? field.xPercent : clampPercent(partial.xPercent),\n yPercent: partial.yPercent === undefined ? field.yPercent : clampPercent(partial.yPercent),\n widthPercent:\n partial.widthPercent === undefined ? field.widthPercent : clampPercent(partial.widthPercent),\n heightPercent:\n partial.heightPercent === undefined ? field.heightPercent : clampPercent(partial.heightPercent),\n }\n })\n )\n }, [])\n\n const removeField = useCallback((id: string) => {\n setFields((previousFields) => previousFields.filter((field) => field.id !== id))\n }, [])\n\n const clearFields = useCallback(() => {\n setFields([])\n }, [])\n\n const fieldActions = useMemo(\n () => ({\n addField,\n updateField,\n removeField,\n clearFields,\n }),\n [addField, clearFields, removeField, updateField]\n )\n\n return {\n fields,\n ...fieldActions,\n }\n}\n","import { useEffect, useMemo, useState } from 'react'\nimport { loadSignatureFont } from '../lib/signature-fonts'\nimport type { SignatureStyle } from '../types'\n\ninterface UseSignatureRendererInput {\n signerName: string\n style: SignatureStyle\n}\n\nfunction buildCanvas(): HTMLCanvasElement {\n return document.createElement('canvas')\n}\n\nfunction hashString(s: string): number {\n let h = 2166136261\n for (let i = 0; i < s.length; i++) {\n h ^= s.charCodeAt(i)\n h = Math.imul(h, 16777619)\n }\n return h >>> 0\n}\n\nfunction mulberry32(seed: number): () => number {\n return function () {\n let t = (seed += 0x6d2b79f5)\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\ninterface GlyphLayout {\n char: string\n width: number\n rotation: number\n gapAfter: number\n}\n\nfunction layoutTypedGlyphs({\n signerName,\n fontFamily,\n fontSize,\n context,\n}: {\n signerName: string\n fontFamily: string\n fontSize: number\n context: CanvasRenderingContext2D\n}): GlyphLayout[] {\n const rng = mulberry32(hashString(`${signerName}\\0${fontFamily}`))\n context.font = `${fontSize}px \"${fontFamily}\"`\n const chars = Array.from(signerName)\n const layouts: GlyphLayout[] = []\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i]\n const width = context.measureText(char).width\n const rotation = (rng() * 2 - 1) * 0.07\n const gapAfter = i < chars.length - 1 ? (rng() * 2 - 1) * 1.25 : 0\n layouts.push({ char, width, rotation, gapAfter })\n }\n return layouts\n}\n\nfunction drawTypedSignature({\n signerName,\n fontFamily,\n}: {\n signerName: string\n fontFamily: string\n}): string {\n const canvas = buildCanvas()\n const context = canvas.getContext('2d')\n if (!context) return ''\n\n const padding = 16\n const fontSize = 56\n const baselineY = 50\n\n const glyphs = layoutTypedGlyphs({ signerName, fontFamily, fontSize, context })\n const textWidth = glyphs.reduce((sum, g) => sum + g.width + g.gapAfter, 0)\n\n canvas.width = Math.max(240, Math.ceil(textWidth + padding * 2))\n canvas.height = 100\n\n context.clearRect(0, 0, canvas.width, canvas.height)\n context.font = `${fontSize}px \"${fontFamily}\"`\n context.fillStyle = '#111827'\n context.textAlign = 'center'\n context.textBaseline = 'middle'\n\n let x = padding\n for (const glyph of glyphs) {\n const { char, width, rotation, gapAfter } = glyph\n const cx = x + width / 2\n context.save()\n context.translate(cx, baselineY)\n context.rotate(rotation)\n context.fillText(char, 0, 0)\n context.restore()\n x += width + gapAfter\n }\n\n return canvas.toDataURL('image/png')\n}\n\nexport function useSignatureRenderer({ signerName, style }: UseSignatureRendererInput) {\n const [signatureDataUrl, setSignatureDataUrl] = useState<string | null>(null)\n const [isRendering, setIsRendering] = useState(false)\n\n const normalizedName = useMemo(() => signerName.trim(), [signerName])\n\n useEffect(() => {\n if (!normalizedName) {\n setSignatureDataUrl(null)\n return\n }\n\n if (style.mode === 'drawn') {\n setSignatureDataUrl(style.dataUrl || null)\n return\n }\n\n let isActive = true\n setIsRendering(true)\n\n loadSignatureFont(style.fontFamily)\n .then(() => {\n if (!isActive) return\n const dataUrl = drawTypedSignature({ signerName: normalizedName, fontFamily: style.fontFamily })\n setSignatureDataUrl(dataUrl || null)\n })\n .catch(() => {\n if (!isActive) return\n // Defensive: `loadSignatureFont` should not throw; still render with browser fallback glyphs\n const dataUrl = drawTypedSignature({ signerName: normalizedName, fontFamily: style.fontFamily })\n setSignatureDataUrl(dataUrl || null)\n })\n .finally(() => {\n if (!isActive) return\n setIsRendering(false)\n })\n\n return () => {\n isActive = false\n }\n }, [normalizedName, style])\n\n return {\n signatureDataUrl,\n isRendering,\n }\n}\n","import type { FieldPlacement, PdfPageDimensions, PointRect } from '../types'\n\nfunction clampPercent(value: number): number {\n if (Number.isNaN(value)) return 0\n if (value < 0) return 0\n if (value > 100) return 100\n return value\n}\n\nexport function mapToPoints(field: FieldPlacement, page: PdfPageDimensions): PointRect {\n const xPercent = clampPercent(field.xPercent)\n const yPercent = clampPercent(field.yPercent)\n const widthPercent = clampPercent(field.widthPercent)\n const heightPercent = clampPercent(field.heightPercent)\n\n const width = (widthPercent / 100) * page.widthPt\n const height = (heightPercent / 100) * page.heightPt\n const x = (xPercent / 100) * page.widthPt\n const y = page.heightPt - (yPercent / 100) * page.heightPt - height\n\n return { x, y, width, height }\n}\n\nexport function mapFromPoints(\n rect: PointRect,\n page: PdfPageDimensions\n): Pick<FieldPlacement, 'xPercent' | 'yPercent' | 'widthPercent' | 'heightPercent'> {\n const widthPercent = (rect.width / page.widthPt) * 100\n const heightPercent = (rect.height / page.heightPt) * 100\n const xPercent = (rect.x / page.widthPt) * 100\n const yPercent = ((page.heightPt - rect.y - rect.height) / page.heightPt) * 100\n\n return {\n xPercent: clampPercent(xPercent),\n yPercent: clampPercent(yPercent),\n widthPercent: clampPercent(widthPercent),\n heightPercent: clampPercent(heightPercent),\n }\n}\n","import fontkit from '@pdf-lib/fontkit'\nimport { PDFDocument, StandardFonts } from 'pdf-lib'\nimport { mapToPoints } from './coordinate-mapper'\nimport type { FieldPlacement, PdfPageDimensions, SignerInfo } from '../types'\n\ninterface ModifyPdfInput {\n pdfBytes: Uint8Array\n fields: FieldPlacement[]\n signer: SignerInfo\n signatureDataUrl: string\n pageDimensions: PdfPageDimensions[]\n dateText?: string\n}\n\nfunction fullNameFromSigner(signer: SignerInfo): string {\n return [signer.firstName, signer.lastName].filter(Boolean).join(' ').trim()\n}\n\nfunction dataUrlToBytes(dataUrl: string): Uint8Array {\n const base64 = dataUrl.split(',')[1]\n if (!base64) throw new Error('Invalid signature data URL')\n const binary =\n typeof atob === 'function'\n ? atob(base64)\n : Buffer.from(base64, 'base64').toString('binary')\n const bytes = new Uint8Array(binary.length)\n for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index)\n return bytes\n}\n\nexport async function modifyPdf({\n pdfBytes,\n fields,\n signer,\n signatureDataUrl,\n pageDimensions,\n dateText,\n}: ModifyPdfInput): Promise<Uint8Array> {\n const pdfDocument = await PDFDocument.load(pdfBytes)\n pdfDocument.registerFontkit(fontkit)\n const pages = pdfDocument.getPages()\n const helveticaFont = await pdfDocument.embedFont(StandardFonts.Helvetica)\n\n const signatureImageBytes = signatureDataUrl ? dataUrlToBytes(signatureDataUrl) : null\n const signatureImage = signatureImageBytes ? await pdfDocument.embedPng(signatureImageBytes) : null\n const resolvedDateText = dateText || new Date().toLocaleDateString()\n\n for (const field of fields) {\n const page = pages[field.pageIndex]\n const pageDimension = pageDimensions.find((entry) => entry.pageIndex === field.pageIndex)\n if (!page || !pageDimension) continue\n\n const pointRect = mapToPoints(field, pageDimension)\n if (field.type === 'signature' && signatureImage) {\n page.drawImage(signatureImage, {\n x: pointRect.x,\n y: pointRect.y,\n width: pointRect.width,\n height: pointRect.height,\n })\n continue\n }\n\n const textValue =\n field.type === 'fullName'\n ? fullNameFromSigner(signer)\n : field.type === 'title'\n ? signer.title\n : field.type === 'date'\n ? resolvedDateText\n : ''\n if (!textValue) continue\n\n const textSize = Math.max(9, Math.min(16, pointRect.height * 0.6))\n page.drawText(textValue, {\n x: pointRect.x + 2,\n y: pointRect.y + Math.max(0, (pointRect.height - textSize) / 2),\n size: textSize,\n font: helveticaFont,\n })\n }\n\n return pdfDocument.save()\n}\n","export async function sha256(data: Uint8Array): Promise<string> {\n const dataBuffer = new Uint8Array(data.byteLength)\n dataBuffer.set(data)\n const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer)\n return Array.from(new Uint8Array(hashBuffer))\n .map((byte) => byte.toString(16).padStart(2, '0'))\n .join('')\n}\n","export const SLOTS = {\n pdfViewer: 'pdf-viewer',\n pdfViewerEmpty: 'pdf-viewer-empty',\n pdfViewerToolbar: 'pdf-viewer-toolbar',\n pdfViewerPageCount: 'pdf-viewer-page-count',\n pdfViewerZoom: 'pdf-viewer-zoom',\n pdfViewerZoomButton: 'pdf-viewer-zoom-button',\n pdfViewerZoomValue: 'pdf-viewer-zoom-value',\n pdfViewerPages: 'pdf-viewer-pages',\n pdfViewerPage: 'pdf-viewer-page',\n pdfViewerLoading: 'pdf-viewer-loading',\n pdfViewerError: 'pdf-viewer-error',\n fieldOverlay: 'field-overlay',\n signatureField: 'signature-field',\n signatureFieldContent: 'signature-field-content',\n signatureFieldLabel: 'signature-field-label',\n signatureFieldPreview: 'signature-field-preview',\n signatureFieldPreviewImage: 'signature-field-preview-image',\n signatureFieldPreviewText: 'signature-field-preview-text',\n signatureFieldRemove: 'signature-field-remove',\n signatureFieldResize: 'signature-field-resize',\n fieldPalette: 'field-palette',\n fieldPaletteButton: 'field-palette-button',\n signerPanel: 'signer-panel',\n signerPanelHeading: 'signer-panel-heading',\n signerPanelLabel: 'signer-panel-label',\n signerPanelInput: 'signer-panel-input',\n signaturePreview: 'signature-preview',\n signaturePreviewHeading: 'signature-preview-heading',\n signaturePreviewModeToggle: 'signature-preview-mode-toggle',\n signaturePreviewModeButton: 'signature-preview-mode-button',\n signaturePreviewFontLabel: 'signature-preview-font-label',\n signaturePreviewFontSelect: 'signature-preview-font-select',\n signaturePreviewDisplay: 'signature-preview-display',\n signaturePreviewImage: 'signature-preview-image',\n signaturePreviewPlaceholder: 'signature-preview-placeholder',\n signaturePad: 'signature-pad',\n signaturePadCanvas: 'signature-pad-canvas',\n signaturePadActions: 'signature-pad-actions',\n signaturePadClear: 'signature-pad-clear',\n signingComplete: 'signing-complete',\n signingCompleteHeading: 'signing-complete-heading',\n signingCompleteDetails: 'signing-complete-details',\n signingCompleteHash: 'signing-complete-hash',\n signingCompleteHashLabel: 'signing-complete-hash-label',\n signingCompleteHashValue: 'signing-complete-hash-value',\n signingCompleteActions: 'signing-complete-actions',\n signingCompleteDownload: 'signing-complete-download',\n signingCompleteReset: 'signing-complete-reset',\n} as const\n","import { loadSignatureFont, SIGNATURE_FONTS } from './lib/signature-fonts'\n\nexport { configure } from './lib/config'\nexport type { ESigningConfig, SignatureFontWarning } from './lib/config'\n\nexport { PdfViewer } from './components/pdf-viewer'\nexport { FieldOverlay } from './components/field-overlay'\nexport { SignatureField } from './components/signature-field'\nexport { FieldPalette } from './components/field-palette'\nexport { SignerDetailsPanel } from './components/signer-details-panel'\nexport { SignaturePreview } from './components/signature-preview'\nexport { SignaturePad } from './components/signature-pad'\nexport { SigningComplete } from './components/signing-complete'\n\nexport { usePdfDocument } from './hooks/use-pdf-document'\nexport { useFieldPlacement } from './hooks/use-field-placement'\nexport { useSignatureRenderer } from './hooks/use-signature-renderer'\n\nexport { modifyPdf } from './lib/pdf-modifier'\nexport { mapToPoints, mapFromPoints } from './lib/coordinate-mapper'\nexport { loadSignatureFont, SIGNATURE_FONTS }\nexport { sha256 } from './lib/hash'\nexport { SLOTS } from './lib/slots'\n\nexport type {\n FieldPlacement,\n FieldType,\n SignerInfo,\n SignatureStyle,\n SigningResult,\n PdfPageDimensions,\n SignatureFieldPreview,\n} from './types'\n\nexport const defaults = {\n SIGNATURE_FONTS: [...SIGNATURE_FONTS],\n DEFAULT_FIELD_WIDTH_PERCENT: 25,\n DEFAULT_FIELD_HEIGHT_PERCENT: 5,\n} as const\n"]}
|
package/dist/styles.css
CHANGED
|
@@ -253,6 +253,7 @@
|
|
|
253
253
|
border-radius: 0.375rem;
|
|
254
254
|
background: rgba(239, 246, 255, 0.8);
|
|
255
255
|
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.15);
|
|
256
|
+
overflow: hidden;
|
|
256
257
|
}
|
|
257
258
|
|
|
258
259
|
[data-slot='signature-field-content'] {
|
|
@@ -263,7 +264,11 @@
|
|
|
263
264
|
}
|
|
264
265
|
|
|
265
266
|
[data-slot='signature-field-preview'] {
|
|
267
|
+
display: flex;
|
|
268
|
+
flex-direction: column;
|
|
269
|
+
height: 100%;
|
|
266
270
|
min-width: 0;
|
|
271
|
+
min-height: 0;
|
|
267
272
|
flex: 1;
|
|
268
273
|
overflow: hidden;
|
|
269
274
|
}
|
|
@@ -279,8 +284,9 @@
|
|
|
279
284
|
[data-slot='signature-field-preview-image'] {
|
|
280
285
|
margin-top: 0.25rem;
|
|
281
286
|
display: block;
|
|
282
|
-
|
|
283
|
-
|
|
287
|
+
flex: 1 1 auto;
|
|
288
|
+
min-height: 0;
|
|
289
|
+
height: 100%;
|
|
284
290
|
width: 100%;
|
|
285
291
|
object-fit: contain;
|
|
286
292
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drvillo/react-browser-e-signing",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "React PDF e-signing in the browser — fields, handwriting, pdf-lib",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -24,20 +24,6 @@
|
|
|
24
24
|
"files": [
|
|
25
25
|
"dist"
|
|
26
26
|
],
|
|
27
|
-
"scripts": {
|
|
28
|
-
"postinstall": "pnpm run install:browsers",
|
|
29
|
-
"install:browsers": "playwright install chromium",
|
|
30
|
-
"build": "tsup",
|
|
31
|
-
"dev": "tsup --watch",
|
|
32
|
-
"demo": "vite",
|
|
33
|
-
"demo:build": "vite build",
|
|
34
|
-
"test": "pnpm run test:unit && pnpm run test:browser",
|
|
35
|
-
"test:unit": "vitest run --config vitest.config.ts",
|
|
36
|
-
"test:browser": "vitest run --config vitest.browser.config.ts",
|
|
37
|
-
"typecheck": "tsc --noEmit",
|
|
38
|
-
"prepublishOnly": "npm run build",
|
|
39
|
-
"publish:npm": "npm publish"
|
|
40
|
-
},
|
|
41
27
|
"keywords": [
|
|
42
28
|
"e-signature",
|
|
43
29
|
"pdf",
|
|
@@ -66,6 +52,7 @@
|
|
|
66
52
|
"@vitejs/plugin-react": "^5.0.2",
|
|
67
53
|
"@vitest/browser-playwright": "^4.0.0",
|
|
68
54
|
"happy-dom": "^20.0.0",
|
|
55
|
+
"pdfjs-dist": "4.8.69",
|
|
69
56
|
"playwright": "^1.55.0",
|
|
70
57
|
"react": "^19.1.1",
|
|
71
58
|
"react-dom": "^19.1.1",
|
|
@@ -74,5 +61,18 @@
|
|
|
74
61
|
"typescript": "^5.9.2",
|
|
75
62
|
"vite": "^7.1.5",
|
|
76
63
|
"vitest": "^4.0.0"
|
|
64
|
+
},
|
|
65
|
+
"scripts": {
|
|
66
|
+
"postinstall": "pnpm run install:browsers",
|
|
67
|
+
"install:browsers": "playwright install chromium",
|
|
68
|
+
"build": "tsup",
|
|
69
|
+
"dev": "tsup --watch",
|
|
70
|
+
"demo": "vite",
|
|
71
|
+
"demo:build": "vite build",
|
|
72
|
+
"test": "pnpm run test:unit && pnpm run test:browser",
|
|
73
|
+
"test:unit": "vitest run --config vitest.config.ts",
|
|
74
|
+
"test:browser": "vitest run --config vitest.browser.config.ts",
|
|
75
|
+
"typecheck": "tsc --noEmit",
|
|
76
|
+
"publish:npm": "npm publish"
|
|
77
77
|
}
|
|
78
|
-
}
|
|
78
|
+
}
|