@drvillo/react-browser-e-signing 0.1.2 → 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 +20 -2
- package/dist/index.js +62 -15
- package/dist/index.js.map +1 -1
- 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
|
@@ -5,6 +5,22 @@ import { ReactNode } from 'react';
|
|
|
5
5
|
declare const SIGNATURE_FONTS: readonly ["Caveat", "Homemade Apple", "Reenie Beanie", "Mr Dafoe", "Pacifico", "Qwitcher Grypen"];
|
|
6
6
|
declare function loadSignatureFont(fontFamily: string): Promise<void>;
|
|
7
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
|
+
|
|
8
24
|
interface PdfViewerProps {
|
|
9
25
|
pdfData: ArrayBuffer | null;
|
|
10
26
|
numPages: number;
|
|
@@ -18,8 +34,10 @@ interface PdfViewerProps {
|
|
|
18
34
|
}) => void;
|
|
19
35
|
renderOverlay?: (pageIndex: number) => ReactNode;
|
|
20
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;
|
|
21
39
|
}
|
|
22
|
-
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;
|
|
23
41
|
|
|
24
42
|
type FieldType = 'signature' | 'fullName' | 'title' | 'date';
|
|
25
43
|
interface FieldPlacement {
|
|
@@ -248,4 +266,4 @@ declare const defaults: {
|
|
|
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,10 +1,19 @@
|
|
|
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/lib/config.ts
|
|
9
|
+
var _config = {};
|
|
10
|
+
function configure(options) {
|
|
11
|
+
_config = { ..._config, ...options };
|
|
12
|
+
}
|
|
13
|
+
function getConfig() {
|
|
14
|
+
return _config;
|
|
15
|
+
}
|
|
16
|
+
|
|
8
17
|
// src/lib/signature-fonts.ts
|
|
9
18
|
var loadedFonts = /* @__PURE__ */ new Set();
|
|
10
19
|
var SIGNATURE_FONTS = [
|
|
@@ -29,18 +38,51 @@ function extractFontSource(cssText) {
|
|
|
29
38
|
if (!sourceMatch) return null;
|
|
30
39
|
return sourceMatch[1].replace(/['"]/g, "");
|
|
31
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
|
+
}
|
|
32
54
|
async function loadSignatureFont(fontFamily) {
|
|
33
55
|
if (loadedFonts.has(fontFamily)) return;
|
|
34
56
|
if (typeof document === "undefined") return;
|
|
35
57
|
if (typeof FontFace === "undefined") return;
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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();
|
|
44
86
|
loadedFonts.add(fontFamily);
|
|
45
87
|
}
|
|
46
88
|
|
|
@@ -48,9 +90,6 @@ async function loadSignatureFont(fontFamily) {
|
|
|
48
90
|
function cn(...values) {
|
|
49
91
|
return values.filter(Boolean).join(" ");
|
|
50
92
|
}
|
|
51
|
-
if (typeof window !== "undefined") {
|
|
52
|
-
pdfjs.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`;
|
|
53
|
-
}
|
|
54
93
|
var MIN_SCALE = 0.5;
|
|
55
94
|
var MAX_SCALE = 2;
|
|
56
95
|
var SCALE_STEP = 0.1;
|
|
@@ -62,8 +101,15 @@ function PdfViewer({
|
|
|
62
101
|
onDocumentLoadSuccess,
|
|
63
102
|
onPageDimensions,
|
|
64
103
|
renderOverlay,
|
|
65
|
-
className
|
|
104
|
+
className,
|
|
105
|
+
workerSrc
|
|
66
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]);
|
|
67
113
|
if (!pdfData)
|
|
68
114
|
return /* @__PURE__ */ jsx("div", { "data-slot": "pdf-viewer-empty", className: cn(className), children: "Upload a PDF to begin" });
|
|
69
115
|
return /* @__PURE__ */ jsxs("div", { "data-slot": "pdf-viewer", className: cn(className), children: [
|
|
@@ -802,7 +848,8 @@ function useSignatureRenderer({ signerName, style }) {
|
|
|
802
848
|
setSignatureDataUrl(dataUrl || null);
|
|
803
849
|
}).catch(() => {
|
|
804
850
|
if (!isActive) return;
|
|
805
|
-
|
|
851
|
+
const dataUrl = drawTypedSignature({ signerName: normalizedName, fontFamily: style.fontFamily });
|
|
852
|
+
setSignatureDataUrl(dataUrl || null);
|
|
806
853
|
}).finally(() => {
|
|
807
854
|
if (!isActive) return;
|
|
808
855
|
setIsRendering(false);
|
|
@@ -969,6 +1016,6 @@ var defaults = {
|
|
|
969
1016
|
DEFAULT_FIELD_HEIGHT_PERCENT: 5
|
|
970
1017
|
};
|
|
971
1018
|
|
|
972
|
-
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 };
|
|
973
1020
|
//# sourceMappingURL=index.js.map
|
|
974
1021
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../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":["const 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\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","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: '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 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","import { loadSignatureFont, SIGNATURE_FONTS } from './lib/signature-fonts'\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"]}
|
|
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/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
|
+
}
|