@arbidocs/blocks 0.4.157 → 0.4.159
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ConnectedNativeDocxComparison-S25BPUH5.cjs → ConnectedNativeDocxComparison-R6RU5TZE.cjs} +8 -7
- package/dist/{ConnectedNativeDocxComparison-S25BPUH5.cjs.map → ConnectedNativeDocxComparison-R6RU5TZE.cjs.map} +1 -1
- package/dist/{ConnectedNativeDocxComparison-2PLOOXSH.js → ConnectedNativeDocxComparison-XMZ5KLD4.js} +7 -6
- package/dist/{ConnectedNativeDocxComparison-2PLOOXSH.js.map → ConnectedNativeDocxComparison-XMZ5KLD4.js.map} +1 -1
- package/dist/{ConnectedNativeDocxEditor-YA4HWLY4.cjs → ConnectedNativeDocxEditor-LBATSM3M.cjs} +7 -6
- package/dist/{ConnectedNativeDocxEditor-YA4HWLY4.cjs.map → ConnectedNativeDocxEditor-LBATSM3M.cjs.map} +1 -1
- package/dist/{ConnectedNativeDocxEditor-JJAGMHZC.js → ConnectedNativeDocxEditor-NGUK2AX6.js} +5 -4
- package/dist/{ConnectedNativeDocxEditor-JJAGMHZC.js.map → ConnectedNativeDocxEditor-NGUK2AX6.js.map} +1 -1
- package/dist/{ConnectedStreamedWordArtifact-EXYZAU4Y.cjs → ConnectedStreamedWordArtifact-CWFR6A37.cjs} +8 -7
- package/dist/ConnectedStreamedWordArtifact-CWFR6A37.cjs.map +1 -0
- package/dist/{ConnectedStreamedWordArtifact-YAAXY5KY.js → ConnectedStreamedWordArtifact-IXRJ7MUE.js} +7 -6
- package/dist/{ConnectedStreamedWordArtifact-YAAXY5KY.js.map → ConnectedStreamedWordArtifact-IXRJ7MUE.js.map} +1 -1
- package/dist/{NativeDocxEditor-M3I776GD.cjs → NativeDocxEditor-T2PJIZMU.cjs} +9 -7
- package/dist/{NativeDocxEditor-M3I776GD.cjs.map → NativeDocxEditor-T2PJIZMU.cjs.map} +1 -1
- package/dist/{NativeDocxEditor-JBQMH3MP.js → NativeDocxEditor-TBTBD6TC.js} +5 -3
- package/dist/{NativeDocxEditor-JBQMH3MP.js.map → NativeDocxEditor-TBTBD6TC.js.map} +1 -1
- package/dist/{WorkspaceTableView-5OWX53R5.js → WorkspaceTableView-DWUE4VQF.js} +19 -9
- package/dist/WorkspaceTableView-DWUE4VQF.js.map +1 -0
- package/dist/{WorkspaceTableView-ZFMAYHUD.cjs → WorkspaceTableView-EYLEUZZT.cjs} +21 -11
- package/dist/WorkspaceTableView-EYLEUZZT.cjs.map +1 -0
- package/dist/{chunk-IJEISII2.cjs → chunk-2BHDRVVL.cjs} +17 -7
- package/dist/chunk-2BHDRVVL.cjs.map +1 -0
- package/dist/chunk-2R3GGNPA.js +151 -0
- package/dist/chunk-2R3GGNPA.js.map +1 -0
- package/dist/{chunk-F3EZDBDJ.js → chunk-3OCNUKGX.js} +4 -4
- package/dist/{chunk-F3EZDBDJ.js.map → chunk-3OCNUKGX.js.map} +1 -1
- package/dist/{chunk-D3WFIFRY.cjs → chunk-3VW7ZXQ6.cjs} +211 -5
- package/dist/chunk-3VW7ZXQ6.cjs.map +1 -0
- package/dist/{chunk-JSQEAPTC.cjs → chunk-4GITK3Q5.cjs} +398 -75
- package/dist/chunk-4GITK3Q5.cjs.map +1 -0
- package/dist/{chunk-2CWM2CFZ.js → chunk-7UENVUA6.js} +4 -4
- package/dist/{chunk-2CWM2CFZ.js.map → chunk-7UENVUA6.js.map} +1 -1
- package/dist/{chunk-EWCJXUBP.js → chunk-AVXRXPII.js} +3 -3
- package/dist/{chunk-EWCJXUBP.js.map → chunk-AVXRXPII.js.map} +1 -1
- package/dist/{chunk-7IRSCMNK.js → chunk-BGXWPVHR.js} +3 -3
- package/dist/{chunk-7IRSCMNK.js.map → chunk-BGXWPVHR.js.map} +1 -1
- package/dist/chunk-DAN7EJ4O.js +482 -0
- package/dist/chunk-DAN7EJ4O.js.map +1 -0
- package/dist/chunk-E4H5H2C3.cjs +18 -0
- package/dist/{chunk-OTU5KGQ6.cjs.map → chunk-E4H5H2C3.cjs.map} +1 -1
- package/dist/{chunk-VY4UFXTM.cjs → chunk-ETJFC6MO.cjs} +4 -4
- package/dist/{chunk-VY4UFXTM.cjs.map → chunk-ETJFC6MO.cjs.map} +1 -1
- package/dist/{chunk-TQIY2SVY.cjs → chunk-GFVIFXWT.cjs} +5 -5
- package/dist/{chunk-TQIY2SVY.cjs.map → chunk-GFVIFXWT.cjs.map} +1 -1
- package/dist/chunk-JPWPR6QU.cjs +485 -0
- package/dist/chunk-JPWPR6QU.cjs.map +1 -0
- package/dist/{chunk-KQYPP72K.js → chunk-JTJCCL2E.js} +212 -9
- package/dist/chunk-JTJCCL2E.js.map +1 -0
- package/dist/{chunk-PGOSIJ2I.js → chunk-KFMRBZQK.js} +15 -5
- package/dist/chunk-KFMRBZQK.js.map +1 -0
- package/dist/chunk-NMZI3K6R.cjs +159 -0
- package/dist/chunk-NMZI3K6R.cjs.map +1 -0
- package/dist/{chunk-53RCZPMR.cjs → chunk-P2YM67Y5.cjs} +5 -5
- package/dist/{chunk-53RCZPMR.cjs.map → chunk-P2YM67Y5.cjs.map} +1 -1
- package/dist/chunk-Q2XGM372.cjs +18 -0
- package/dist/{chunk-S74QMZVZ.cjs.map → chunk-Q2XGM372.cjs.map} +1 -1
- package/dist/{chunk-7HHYMDPE.js → chunk-RATEAOKT.js} +3 -3
- package/dist/{chunk-7HHYMDPE.js.map → chunk-RATEAOKT.js.map} +1 -1
- package/dist/{chunk-SN2GZ4ZM.cjs → chunk-TQUYWUEE.cjs} +10 -156
- package/dist/chunk-TQUYWUEE.cjs.map +1 -0
- package/dist/{chunk-ONTUMV74.js → chunk-XER3JLC7.js} +398 -78
- package/dist/chunk-XER3JLC7.js.map +1 -0
- package/dist/{chunk-HP2C4MD3.js → chunk-ZDOKJD44.js} +4 -143
- package/dist/chunk-ZDOKJD44.js.map +1 -0
- package/dist/connect/docx.cjs +11 -10
- package/dist/connect/docx.js +7 -6
- package/dist/connect/index.cjs +406 -384
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.js +69 -47
- package/dist/connect/index.js.map +1 -1
- package/dist/connect/viewer.cjs +41 -20
- package/dist/connect/viewer.cjs.map +1 -1
- package/dist/connect/viewer.js +29 -8
- package/dist/connect/viewer.js.map +1 -1
- package/dist/connection/viewer/ViewerPdfPane.d.ts +7 -1
- package/dist/connection/workspace-list/ConnectedWorkspaceList.d.ts +4 -2
- package/dist/connection/workspace-list/WorkspaceCardsView.d.ts +3 -2
- package/dist/connection/workspace-list/WorkspaceTableView.d.ts +3 -2
- package/dist/connection/workspace-list/index.d.ts +1 -1
- package/dist/connection/workspace-list/useConnectedWorkspaceList.d.ts +19 -0
- package/dist/connection/workspace-list/workspaceTable.d.ts +3 -1
- package/dist/connection/workspace-settings/ConnectedWorkspaceSettings.d.ts +3 -1
- package/dist/document-tools/AdoptSignatureDialog.d.ts +39 -4
- package/dist/document-tools/PlaceMySignatureButton.d.ts +16 -0
- package/dist/document-tools/SavedSignatureSettings.d.ts +10 -0
- package/dist/document-tools/index.cjs +37 -22
- package/dist/document-tools/index.d.ts +2 -0
- package/dist/document-tools/index.js +5 -2
- package/dist/document-tools/viewer/AnnotatedPdfViewer.d.ts +10 -1
- package/dist/document-tools/viewer/SignatureRequestEditor.d.ts +7 -4
- package/dist/document-tools/viewer/index.cjs +184 -18
- package/dist/document-tools/viewer/index.cjs.map +1 -1
- package/dist/document-tools/viewer/index.js +184 -18
- package/dist/document-tools/viewer/index.js.map +1 -1
- package/dist/docx/NativeDocxEditor.d.ts +5 -0
- package/dist/docx/index.cjs +61 -47
- package/dist/docx/index.d.ts +1 -0
- package/dist/docx/index.js +5 -3
- package/dist/docx/signatures/SignatureFields.d.ts +50 -0
- package/dist/settings/index.cjs +183 -182
- package/dist/settings/index.js +2 -1
- package/node_modules/@arbidocs/coedit/dist/commands.cjs +109 -16
- package/node_modules/@arbidocs/coedit/dist/commands.cjs.map +1 -1
- package/node_modules/@arbidocs/coedit/dist/commands.d.cts +84 -1
- package/node_modules/@arbidocs/coedit/dist/commands.d.ts +84 -1
- package/node_modules/@arbidocs/coedit/dist/commands.js +99 -17
- package/node_modules/@arbidocs/coedit/dist/commands.js.map +1 -1
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +5 -5
- package/src/docx/styles.css +50 -0
- package/dist/ConnectedStreamedWordArtifact-EXYZAU4Y.cjs.map +0 -1
- package/dist/WorkspaceTableView-5OWX53R5.js.map +0 -1
- package/dist/WorkspaceTableView-ZFMAYHUD.cjs.map +0 -1
- package/dist/chunk-6MG62I5B.cjs +0 -272
- package/dist/chunk-6MG62I5B.cjs.map +0 -1
- package/dist/chunk-D3WFIFRY.cjs.map +0 -1
- package/dist/chunk-EQB3WELX.js +0 -269
- package/dist/chunk-EQB3WELX.js.map +0 -1
- package/dist/chunk-HP2C4MD3.js.map +0 -1
- package/dist/chunk-IJEISII2.cjs.map +0 -1
- package/dist/chunk-JSQEAPTC.cjs.map +0 -1
- package/dist/chunk-KQYPP72K.js.map +0 -1
- package/dist/chunk-ONTUMV74.js.map +0 -1
- package/dist/chunk-OTU5KGQ6.cjs +0 -18
- package/dist/chunk-PGOSIJ2I.js.map +0 -1
- package/dist/chunk-S74QMZVZ.cjs +0 -18
- package/dist/chunk-SN2GZ4ZM.cjs.map +0 -1
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var chunkULWRNGGE_cjs = require('./chunk-ULWRNGGE.cjs');
|
|
5
|
+
var react = require('react');
|
|
6
|
+
var documentTools = require('@arbidocs/react/document-tools');
|
|
7
|
+
var ui = require('@arbidocs/react/ui');
|
|
8
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
9
|
+
|
|
10
|
+
var TYPED_SIGNATURE_STYLE = {
|
|
11
|
+
fontFamily: '"Times New Roman", Times, serif',
|
|
12
|
+
fontStyle: "italic",
|
|
13
|
+
color: "#0d1a59"
|
|
14
|
+
};
|
|
15
|
+
var SignaturePad = react.forwardRef(function SignaturePad2({ label, className, onInk, testId }, ref) {
|
|
16
|
+
const canvas = react.useRef(null);
|
|
17
|
+
const strokes = react.useRef([]);
|
|
18
|
+
const drawing = react.useRef(null);
|
|
19
|
+
const paint = react.useCallback(() => {
|
|
20
|
+
const c = canvas.current;
|
|
21
|
+
const ctx = c?.getContext("2d");
|
|
22
|
+
if (!c || !ctx) return;
|
|
23
|
+
const ratio = window.devicePixelRatio || 1;
|
|
24
|
+
const width = c.width / ratio;
|
|
25
|
+
const height = c.height / ratio;
|
|
26
|
+
ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
|
|
27
|
+
ctx.clearRect(0, 0, width, height);
|
|
28
|
+
ctx.lineWidth = Math.min(4, Math.max(2, height * 0.018));
|
|
29
|
+
ctx.lineCap = "round";
|
|
30
|
+
ctx.lineJoin = "round";
|
|
31
|
+
ctx.strokeStyle = TYPED_SIGNATURE_STYLE.color;
|
|
32
|
+
for (const stroke of strokes.current) {
|
|
33
|
+
if (!stroke.length) continue;
|
|
34
|
+
ctx.beginPath();
|
|
35
|
+
ctx.moveTo(stroke[0].x * width, stroke[0].y * height);
|
|
36
|
+
if (stroke.length === 1) ctx.lineTo(stroke[0].x * width + 0.1, stroke[0].y * height);
|
|
37
|
+
for (const p of stroke.slice(1)) ctx.lineTo(p.x * width, p.y * height);
|
|
38
|
+
ctx.stroke();
|
|
39
|
+
}
|
|
40
|
+
}, []);
|
|
41
|
+
react.useEffect(() => {
|
|
42
|
+
const c = canvas.current;
|
|
43
|
+
if (!c) return;
|
|
44
|
+
const fit = () => {
|
|
45
|
+
const rect = c.getBoundingClientRect();
|
|
46
|
+
const ratio = window.devicePixelRatio || 1;
|
|
47
|
+
const width = Math.max(1, Math.round(rect.width * ratio));
|
|
48
|
+
const height = Math.max(1, Math.round(rect.height * ratio));
|
|
49
|
+
if (c.width !== width || c.height !== height) {
|
|
50
|
+
c.width = width;
|
|
51
|
+
c.height = height;
|
|
52
|
+
}
|
|
53
|
+
paint();
|
|
54
|
+
};
|
|
55
|
+
fit();
|
|
56
|
+
const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(fit);
|
|
57
|
+
observer?.observe(c);
|
|
58
|
+
return () => observer?.disconnect();
|
|
59
|
+
}, [paint]);
|
|
60
|
+
react.useImperativeHandle(
|
|
61
|
+
ref,
|
|
62
|
+
() => ({
|
|
63
|
+
isBlank: () => strokes.current.every((s) => s.length === 0),
|
|
64
|
+
toDataUrl: () => strokes.current.some((s) => s.length) ? canvas.current?.toDataURL("image/png") ?? null : null,
|
|
65
|
+
clear: () => {
|
|
66
|
+
strokes.current = [];
|
|
67
|
+
paint();
|
|
68
|
+
onInk(false);
|
|
69
|
+
}
|
|
70
|
+
}),
|
|
71
|
+
[paint, onInk]
|
|
72
|
+
);
|
|
73
|
+
const at = (e) => {
|
|
74
|
+
const r = e.currentTarget.getBoundingClientRect();
|
|
75
|
+
return {
|
|
76
|
+
x: Math.min(1, Math.max(0, (e.clientX - r.left) / (r.width || 1))),
|
|
77
|
+
y: Math.min(1, Math.max(0, (e.clientY - r.top) / (r.height || 1)))
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
81
|
+
"canvas",
|
|
82
|
+
{
|
|
83
|
+
ref: canvas,
|
|
84
|
+
className: ui.cn(
|
|
85
|
+
"block touch-none rounded-md border bg-white select-none [overscroll-behavior:contain]",
|
|
86
|
+
className
|
|
87
|
+
),
|
|
88
|
+
style: { touchAction: "none" },
|
|
89
|
+
"aria-label": label,
|
|
90
|
+
role: "img",
|
|
91
|
+
onPointerDown: (e) => {
|
|
92
|
+
e.preventDefault();
|
|
93
|
+
e.currentTarget.setPointerCapture?.(e.pointerId);
|
|
94
|
+
drawing.current = [at(e)];
|
|
95
|
+
strokes.current.push(drawing.current);
|
|
96
|
+
paint();
|
|
97
|
+
onInk(true);
|
|
98
|
+
},
|
|
99
|
+
onPointerMove: (e) => {
|
|
100
|
+
if (!drawing.current) return;
|
|
101
|
+
e.preventDefault();
|
|
102
|
+
const native = e.nativeEvent;
|
|
103
|
+
const samples = native.getCoalescedEvents?.() ?? [];
|
|
104
|
+
if (samples.length) {
|
|
105
|
+
const r = e.currentTarget.getBoundingClientRect();
|
|
106
|
+
for (const s of samples)
|
|
107
|
+
drawing.current.push({
|
|
108
|
+
x: Math.min(1, Math.max(0, (s.clientX - r.left) / (r.width || 1))),
|
|
109
|
+
y: Math.min(1, Math.max(0, (s.clientY - r.top) / (r.height || 1)))
|
|
110
|
+
});
|
|
111
|
+
} else drawing.current.push(at(e));
|
|
112
|
+
paint();
|
|
113
|
+
},
|
|
114
|
+
onPointerUp: () => drawing.current = null,
|
|
115
|
+
onPointerCancel: () => drawing.current = null,
|
|
116
|
+
"data-testid": testId
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
});
|
|
120
|
+
async function uploadedPng(file) {
|
|
121
|
+
const url = URL.createObjectURL(file);
|
|
122
|
+
try {
|
|
123
|
+
const img = new Image();
|
|
124
|
+
await new Promise((resolve, reject) => {
|
|
125
|
+
img.onload = () => resolve();
|
|
126
|
+
img.onerror = () => reject(new Error("That file is not an image"));
|
|
127
|
+
img.src = url;
|
|
128
|
+
});
|
|
129
|
+
const canvas = document.createElement("canvas");
|
|
130
|
+
canvas.width = 900;
|
|
131
|
+
canvas.height = 300;
|
|
132
|
+
const ctx = canvas.getContext("2d");
|
|
133
|
+
const scale = Math.min(canvas.width / img.width, canvas.height / img.height);
|
|
134
|
+
const w = img.width * scale;
|
|
135
|
+
const h = img.height * scale;
|
|
136
|
+
ctx.drawImage(img, (canvas.width - w) / 2, (canvas.height - h) / 2, w, h);
|
|
137
|
+
const pixels = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
138
|
+
for (let i = 0; i < pixels.data.length; i += 4) {
|
|
139
|
+
const [r, g, b] = [pixels.data[i], pixels.data[i + 1], pixels.data[i + 2]];
|
|
140
|
+
if (r > 225 && g > 225 && b > 225) pixels.data[i + 3] = 0;
|
|
141
|
+
}
|
|
142
|
+
ctx.putImageData(pixels, 0, 0);
|
|
143
|
+
return canvas.toDataURL("image/png");
|
|
144
|
+
} finally {
|
|
145
|
+
URL.revokeObjectURL(url);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
var base64Of = (dataUrl) => dataUrl.slice(dataUrl.indexOf(",") + 1);
|
|
149
|
+
var dataUrlOf = (png) => `data:image/png;base64,${png}`;
|
|
150
|
+
function typedPng(text, height = 120) {
|
|
151
|
+
const canvas = document.createElement("canvas");
|
|
152
|
+
const ctx = canvas.getContext("2d");
|
|
153
|
+
if (!ctx) return "";
|
|
154
|
+
const font = `italic ${Math.round(height * 0.6)}px ${TYPED_SIGNATURE_STYLE.fontFamily}`;
|
|
155
|
+
ctx.font = font;
|
|
156
|
+
const width = Math.max(height, Math.ceil(ctx.measureText(text).width + height * 0.4));
|
|
157
|
+
canvas.width = width;
|
|
158
|
+
canvas.height = height;
|
|
159
|
+
ctx.font = font;
|
|
160
|
+
ctx.fillStyle = TYPED_SIGNATURE_STYLE.color;
|
|
161
|
+
ctx.textBaseline = "middle";
|
|
162
|
+
ctx.fillText(text, height * 0.2, height / 2);
|
|
163
|
+
return base64Of(canvas.toDataURL("image/png"));
|
|
164
|
+
}
|
|
165
|
+
var PAD_SIGNATURE = "-mx-6 w-[calc(100%+3rem)] h-[44vw] min-h-36 sm:mx-0 sm:w-full sm:h-56";
|
|
166
|
+
var PAD_INITIALS = "-mx-6 w-[calc(100%+3rem)] h-[34vw] min-h-28 sm:mx-0 sm:w-80 sm:h-40";
|
|
167
|
+
function AdoptSignatureDialog({
|
|
168
|
+
open,
|
|
169
|
+
onOpenChange,
|
|
170
|
+
defaultName,
|
|
171
|
+
onAdopt,
|
|
172
|
+
saved = null,
|
|
173
|
+
onSave,
|
|
174
|
+
mode = "adopt"
|
|
175
|
+
}) {
|
|
176
|
+
const saving = mode === "save";
|
|
177
|
+
const [saveToAccount, setSaveToAccount] = react.useState(false);
|
|
178
|
+
const [busy, setBusy] = react.useState(false);
|
|
179
|
+
const [savedDrawing, setSavedDrawing] = react.useState(null);
|
|
180
|
+
const [savedInitials, setSavedInitials] = react.useState(null);
|
|
181
|
+
const [name, setName] = react.useState(defaultName);
|
|
182
|
+
const [initials, setInitials] = react.useState(() => documentTools.initialsOf(defaultName));
|
|
183
|
+
const [style, setStyle] = react.useState("typed");
|
|
184
|
+
const [initialsStyle, setInitialsStyle] = react.useState("typed");
|
|
185
|
+
const [hasInk, setHasInk] = react.useState(false);
|
|
186
|
+
const [hasInitialsInk, setHasInitialsInk] = react.useState(false);
|
|
187
|
+
const [upload, setUpload] = react.useState(null);
|
|
188
|
+
const [error, setError] = react.useState(null);
|
|
189
|
+
const signaturePad = react.useRef(null);
|
|
190
|
+
const initialsPad = react.useRef(null);
|
|
191
|
+
react.useEffect(() => {
|
|
192
|
+
if (!open) return;
|
|
193
|
+
setSaveToAccount(false);
|
|
194
|
+
setError(null);
|
|
195
|
+
if (saved) {
|
|
196
|
+
setName(saved.name);
|
|
197
|
+
setInitials(saved.initials);
|
|
198
|
+
setStyle(saved.style);
|
|
199
|
+
setInitialsStyle(saved.initials_style);
|
|
200
|
+
setSavedDrawing(saved.style === "drawn" ? dataUrlOf(saved.signature_png) : null);
|
|
201
|
+
setUpload(saved.style === "uploaded" ? dataUrlOf(saved.signature_png) : null);
|
|
202
|
+
setSavedInitials(saved.initials_style === "drawn" ? dataUrlOf(saved.initials_png) : null);
|
|
203
|
+
} else {
|
|
204
|
+
setName(defaultName);
|
|
205
|
+
setInitials(documentTools.initialsOf(defaultName));
|
|
206
|
+
}
|
|
207
|
+
}, [open, defaultName, saved]);
|
|
208
|
+
const adopt = async () => {
|
|
209
|
+
setError(null);
|
|
210
|
+
if (!name.trim() || !initials.trim()) return;
|
|
211
|
+
let signatureUrl = null;
|
|
212
|
+
if (style === "drawn") {
|
|
213
|
+
signatureUrl = signaturePad.current?.toDataUrl() ?? (hasInk ? null : savedDrawing);
|
|
214
|
+
if (!signatureUrl) return setError("Draw your signature first.");
|
|
215
|
+
} else if (style === "uploaded") {
|
|
216
|
+
signatureUrl = upload;
|
|
217
|
+
if (!signatureUrl) return setError("Choose an image first.");
|
|
218
|
+
}
|
|
219
|
+
let initialsUrl = null;
|
|
220
|
+
if (initialsStyle === "drawn") {
|
|
221
|
+
initialsUrl = initialsPad.current?.toDataUrl() ?? (hasInitialsInk ? null : savedInitials);
|
|
222
|
+
if (!initialsUrl) return setError("Draw your initials first.");
|
|
223
|
+
}
|
|
224
|
+
if (onSave && (saving || saveToAccount)) {
|
|
225
|
+
setBusy(true);
|
|
226
|
+
try {
|
|
227
|
+
await onSave({
|
|
228
|
+
name: name.trim(),
|
|
229
|
+
initials: initials.trim(),
|
|
230
|
+
style,
|
|
231
|
+
initials_style: initialsStyle,
|
|
232
|
+
signature_png: signatureUrl ? base64Of(signatureUrl) : typedPng(name.trim()),
|
|
233
|
+
initials_png: initialsUrl ? base64Of(initialsUrl) : typedPng(initials.trim())
|
|
234
|
+
});
|
|
235
|
+
} catch (err) {
|
|
236
|
+
setError(err instanceof Error ? err.message : "Your signature could not be saved");
|
|
237
|
+
return;
|
|
238
|
+
} finally {
|
|
239
|
+
setBusy(false);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
onAdopt({
|
|
243
|
+
adopted: {
|
|
244
|
+
name: name.trim(),
|
|
245
|
+
initials: initials.trim(),
|
|
246
|
+
style,
|
|
247
|
+
...signatureUrl ? { signature_image: base64Of(signatureUrl) } : {},
|
|
248
|
+
...initialsUrl ? { initials_image: base64Of(initialsUrl) } : {}
|
|
249
|
+
},
|
|
250
|
+
signatureUrl,
|
|
251
|
+
initialsUrl
|
|
252
|
+
});
|
|
253
|
+
};
|
|
254
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
255
|
+
chunkULWRNGGE_cjs.ModalScaffold,
|
|
256
|
+
{
|
|
257
|
+
open,
|
|
258
|
+
onOpenChange,
|
|
259
|
+
title: saving ? "Your signature" : "Adopt your signature",
|
|
260
|
+
description: saving ? "Saved to your account, sealed with your own key, for placing in documents yourself." : "You adopt it once and apply it at each place you are asked to sign.",
|
|
261
|
+
showDescription: true,
|
|
262
|
+
size: "lg",
|
|
263
|
+
testId: "adopt-signature-dialog",
|
|
264
|
+
children: [
|
|
265
|
+
/* @__PURE__ */ jsxRuntime.jsxs(chunkULWRNGGE_cjs.ModalScaffold.Body, { children: [
|
|
266
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_7rem] gap-3", children: [
|
|
267
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
268
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "adopt-name", children: "Full name" }),
|
|
269
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
270
|
+
ui.Input,
|
|
271
|
+
{
|
|
272
|
+
id: "adopt-name",
|
|
273
|
+
value: name,
|
|
274
|
+
onChange: (e) => {
|
|
275
|
+
setName(e.target.value);
|
|
276
|
+
setInitials(documentTools.initialsOf(e.target.value));
|
|
277
|
+
},
|
|
278
|
+
"data-testid": "adopt-signature-name"
|
|
279
|
+
}
|
|
280
|
+
)
|
|
281
|
+
] }),
|
|
282
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
283
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "adopt-initials", children: "Initials" }),
|
|
284
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
285
|
+
ui.Input,
|
|
286
|
+
{
|
|
287
|
+
id: "adopt-initials",
|
|
288
|
+
value: initials,
|
|
289
|
+
maxLength: 12,
|
|
290
|
+
onChange: (e) => setInitials(e.target.value),
|
|
291
|
+
"data-testid": "adopt-signature-initials"
|
|
292
|
+
}
|
|
293
|
+
)
|
|
294
|
+
] })
|
|
295
|
+
] }),
|
|
296
|
+
/* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-1.5", "aria-label": "Signature", children: [
|
|
297
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium", children: "Signature" }),
|
|
298
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
299
|
+
ui.Tabs,
|
|
300
|
+
{
|
|
301
|
+
value: style,
|
|
302
|
+
onValueChange: (v) => {
|
|
303
|
+
setStyle(v);
|
|
304
|
+
setError(null);
|
|
305
|
+
},
|
|
306
|
+
children: [
|
|
307
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.TabsList, { className: "grid w-full grid-cols-3", children: [
|
|
308
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.TabsTrigger, { value: "typed", "data-testid": "adopt-tab-typed", children: "Type" }),
|
|
309
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.TabsTrigger, { value: "drawn", "data-testid": "adopt-tab-drawn", children: "Draw" }),
|
|
310
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.TabsTrigger, { value: "uploaded", "data-testid": "adopt-tab-uploaded", children: "Upload" })
|
|
311
|
+
] }),
|
|
312
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.TabsContent, { value: "typed", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
313
|
+
"div",
|
|
314
|
+
{
|
|
315
|
+
className: "flex h-28 items-center justify-center overflow-hidden rounded-md border bg-white px-4 text-4xl whitespace-nowrap",
|
|
316
|
+
style: TYPED_SIGNATURE_STYLE,
|
|
317
|
+
"data-testid": "adopt-signature-typed-preview",
|
|
318
|
+
children: name.trim() || "Your name"
|
|
319
|
+
}
|
|
320
|
+
) }),
|
|
321
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.TabsContent, { value: "drawn", forceMount: true, hidden: style !== "drawn", children: [
|
|
322
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
323
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
324
|
+
SignaturePad,
|
|
325
|
+
{
|
|
326
|
+
ref: signaturePad,
|
|
327
|
+
label: "Draw your signature",
|
|
328
|
+
className: PAD_SIGNATURE,
|
|
329
|
+
onInk: setHasInk,
|
|
330
|
+
testId: "adopt-signature-canvas"
|
|
331
|
+
}
|
|
332
|
+
),
|
|
333
|
+
savedDrawing && !hasInk && /* @__PURE__ */ jsxRuntime.jsx(
|
|
334
|
+
"img",
|
|
335
|
+
{
|
|
336
|
+
src: savedDrawing,
|
|
337
|
+
alt: "Your saved signature",
|
|
338
|
+
className: "pointer-events-none absolute inset-0 h-full w-full object-contain p-2",
|
|
339
|
+
"data-testid": "adopt-signature-saved"
|
|
340
|
+
}
|
|
341
|
+
)
|
|
342
|
+
] }),
|
|
343
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between pt-1 text-xs text-muted-foreground", children: [
|
|
344
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Sign with your finger, a pen or the mouse." }),
|
|
345
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
346
|
+
ui.Button,
|
|
347
|
+
{
|
|
348
|
+
type: "button",
|
|
349
|
+
variant: "ghost",
|
|
350
|
+
size: "sm",
|
|
351
|
+
onClick: () => signaturePad.current?.clear(),
|
|
352
|
+
disabled: !hasInk,
|
|
353
|
+
"data-testid": "adopt-signature-clear",
|
|
354
|
+
children: "Clear"
|
|
355
|
+
}
|
|
356
|
+
)
|
|
357
|
+
] })
|
|
358
|
+
] }),
|
|
359
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.TabsContent, { value: "uploaded", forceMount: true, hidden: style !== "uploaded", children: [
|
|
360
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-28 items-center justify-center rounded-md border bg-white", children: upload ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: upload, alt: "Uploaded signature", className: "h-full object-contain" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "No image chosen" }) }),
|
|
361
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
362
|
+
ui.Input,
|
|
363
|
+
{
|
|
364
|
+
type: "file",
|
|
365
|
+
accept: "image/png,image/jpeg,image/webp",
|
|
366
|
+
className: "mt-2",
|
|
367
|
+
onChange: async (e) => {
|
|
368
|
+
const file = e.target.files?.[0];
|
|
369
|
+
if (!file) return;
|
|
370
|
+
try {
|
|
371
|
+
setUpload(await uploadedPng(file));
|
|
372
|
+
setError(null);
|
|
373
|
+
} catch (err) {
|
|
374
|
+
setError(err instanceof Error ? err.message : "The image could not be read");
|
|
375
|
+
}
|
|
376
|
+
},
|
|
377
|
+
"data-testid": "adopt-signature-upload"
|
|
378
|
+
}
|
|
379
|
+
)
|
|
380
|
+
] })
|
|
381
|
+
]
|
|
382
|
+
}
|
|
383
|
+
)
|
|
384
|
+
] }),
|
|
385
|
+
/* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-1.5", "aria-label": "Initials", children: [
|
|
386
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium", children: "Initials" }),
|
|
387
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
388
|
+
ui.Tabs,
|
|
389
|
+
{
|
|
390
|
+
value: initialsStyle,
|
|
391
|
+
onValueChange: (v) => {
|
|
392
|
+
setInitialsStyle(v);
|
|
393
|
+
setError(null);
|
|
394
|
+
},
|
|
395
|
+
children: [
|
|
396
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.TabsList, { className: "grid w-full grid-cols-2 sm:w-80", children: [
|
|
397
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.TabsTrigger, { value: "typed", "data-testid": "adopt-initials-tab-typed", children: "Type" }),
|
|
398
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.TabsTrigger, { value: "drawn", "data-testid": "adopt-initials-tab-drawn", children: "Draw" })
|
|
399
|
+
] }),
|
|
400
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.TabsContent, { value: "typed", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
401
|
+
"div",
|
|
402
|
+
{
|
|
403
|
+
className: "flex h-20 items-center justify-center rounded-md border bg-white px-4 text-3xl sm:w-80",
|
|
404
|
+
style: TYPED_SIGNATURE_STYLE,
|
|
405
|
+
"data-testid": "adopt-initials-typed-preview",
|
|
406
|
+
children: initials.trim() || "AB"
|
|
407
|
+
}
|
|
408
|
+
) }),
|
|
409
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.TabsContent, { value: "drawn", forceMount: true, hidden: initialsStyle !== "drawn", children: [
|
|
410
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative sm:w-80", children: [
|
|
411
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
412
|
+
SignaturePad,
|
|
413
|
+
{
|
|
414
|
+
ref: initialsPad,
|
|
415
|
+
label: "Draw your initials",
|
|
416
|
+
className: PAD_INITIALS,
|
|
417
|
+
onInk: setHasInitialsInk,
|
|
418
|
+
testId: "adopt-initials-canvas"
|
|
419
|
+
}
|
|
420
|
+
),
|
|
421
|
+
savedInitials && !hasInitialsInk && /* @__PURE__ */ jsxRuntime.jsx(
|
|
422
|
+
"img",
|
|
423
|
+
{
|
|
424
|
+
src: savedInitials,
|
|
425
|
+
alt: "Your saved initials",
|
|
426
|
+
className: "pointer-events-none absolute inset-0 h-full w-full object-contain p-2"
|
|
427
|
+
}
|
|
428
|
+
)
|
|
429
|
+
] }),
|
|
430
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
431
|
+
ui.Button,
|
|
432
|
+
{
|
|
433
|
+
type: "button",
|
|
434
|
+
variant: "ghost",
|
|
435
|
+
size: "sm",
|
|
436
|
+
onClick: () => initialsPad.current?.clear(),
|
|
437
|
+
disabled: !hasInitialsInk,
|
|
438
|
+
children: "Clear"
|
|
439
|
+
}
|
|
440
|
+
)
|
|
441
|
+
] })
|
|
442
|
+
]
|
|
443
|
+
}
|
|
444
|
+
)
|
|
445
|
+
] }),
|
|
446
|
+
onSave && !saving && /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-sm", children: [
|
|
447
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
448
|
+
ui.Checkbox,
|
|
449
|
+
{
|
|
450
|
+
checked: saveToAccount,
|
|
451
|
+
onCheckedChange: (c) => setSaveToAccount(c === true),
|
|
452
|
+
"data-testid": "adopt-signature-save"
|
|
453
|
+
}
|
|
454
|
+
),
|
|
455
|
+
"Save to my account for future use"
|
|
456
|
+
] }),
|
|
457
|
+
name.trim() && !saving && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
458
|
+
"By adopting it you agree to sign electronically: \u201C",
|
|
459
|
+
documentTools.intentText({ name }),
|
|
460
|
+
"\u201D"
|
|
461
|
+
] }),
|
|
462
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-red-text", role: "alert", children: error })
|
|
463
|
+
] }),
|
|
464
|
+
/* @__PURE__ */ jsxRuntime.jsxs(chunkULWRNGGE_cjs.ModalScaffold.Footer, { children: [
|
|
465
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), children: "Cancel" }),
|
|
466
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
467
|
+
ui.Button,
|
|
468
|
+
{
|
|
469
|
+
type: "button",
|
|
470
|
+
onClick: () => void adopt(),
|
|
471
|
+
disabled: busy || !name.trim() || !initials.trim(),
|
|
472
|
+
"data-testid": "adopt-signature-submit",
|
|
473
|
+
children: saving ? "Save" : "Adopt and sign"
|
|
474
|
+
}
|
|
475
|
+
)
|
|
476
|
+
] })
|
|
477
|
+
]
|
|
478
|
+
}
|
|
479
|
+
);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
exports.AdoptSignatureDialog = AdoptSignatureDialog;
|
|
483
|
+
exports.TYPED_SIGNATURE_STYLE = TYPED_SIGNATURE_STYLE;
|
|
484
|
+
//# sourceMappingURL=chunk-JPWPR6QU.cjs.map
|
|
485
|
+
//# sourceMappingURL=chunk-JPWPR6QU.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/document-tools/AdoptSignatureDialog.tsx"],"names":["forwardRef","SignaturePad","useRef","useCallback","useEffect","useImperativeHandle","jsx","cn","useState","initialsOf","jsxs","ModalScaffold","Label","Input","Tabs","TabsList","TabsTrigger","TabsContent","Button","Checkbox","intentText"],"mappings":"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","file":"chunk-JPWPR6QU.cjs","sourcesContent":["/**\n * Adopt a signature once, before applying it at each field: type it (the name in a signature\n * face, as the signed PDF draws it), draw it, or upload an image of it; initials likewise typed or\n * drawn. A drawn or uploaded mark is handed on as a PNG (white made transparent); the server\n * re-encodes it.\n *\n * The drawing pad spans the screen's width on a phone and is a generous box on a tablet or desktop.\n * Its canvas is backed at the device's pixel ratio (crisp strokes on a retina screen), and it takes\n * every touch for itself (`touch-action: none`): drawing with a finger never scrolls or zooms the\n * page. Strokes are kept as points, so a resize (turning the phone) redraws them at the new size.\n *\n * With `onSave`, the person may also tick \"Save to my account for future use\": the signature and\n * initials are then sealed to their own key and kept for next time (`saved` prefills the dialog).\n * In `mode=\"save\"` (account settings) the dialog only saves.\n */\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n type PointerEvent,\n type ReactElement,\n} from 'react'\nimport {\n initialsOf,\n intentText,\n type AdoptedSignature,\n type SavedSignature,\n} from '@arbidocs/react/document-tools'\nimport {\n Button,\n Checkbox,\n Input,\n Label,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n cn,\n} from '@arbidocs/react/ui'\nimport { ModalScaffold } from '../settings/ModalScaffold'\n\nexport interface AdoptedMark {\n adopted: AdoptedSignature\n /** A data URL of the drawn/uploaded signature, for showing it at each field; null when typed. */\n signatureUrl: string | null\n /** A data URL of the drawn initials; null when typed. */\n initialsUrl?: string | null\n}\n\nexport interface AdoptSignatureDialogProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n defaultName: string\n onAdopt: (mark: AdoptedMark) => void\n /** The signature saved to the account: the dialog starts from it. */\n saved?: SavedSignature | null\n /** Present: offer \"Save to my account for future use\" (and save when ticked). */\n onSave?: (signature: SavedSignature) => Promise<void>\n /** `save`: account settings, the dialog only saves the signature (no signing). */\n mode?: 'adopt' | 'save'\n}\n\n/** Typed signatures look like the PDF will: an italic serif in ink blue. */\nexport const TYPED_SIGNATURE_STYLE = {\n fontFamily: '\"Times New Roman\", Times, serif',\n fontStyle: 'italic',\n color: '#0d1a59',\n} as const\n\ntype Style = AdoptedSignature['style']\ntype InitialsStyle = 'typed' | 'drawn'\ntype Point = { x: number; y: number }\n\nexport interface SignaturePadHandle {\n isBlank: () => boolean\n toDataUrl: () => string | null\n clear: () => void\n}\n\n/**\n * A drawing pad: strokes in fractions of the pad, painted on a canvas at the device's pixel ratio.\n * `onInk` fires when the first stroke lands or the pad is cleared.\n */\nexport const SignaturePad = forwardRef<\n SignaturePadHandle,\n { label: string; className?: string; onInk: (has: boolean) => void; testId?: string }\n>(function SignaturePad({ label, className, onInk, testId }, ref) {\n const canvas = useRef<HTMLCanvasElement>(null)\n const strokes = useRef<Point[][]>([])\n const drawing = useRef<Point[] | null>(null)\n\n const paint = useCallback(() => {\n const c = canvas.current\n const ctx = c?.getContext('2d')\n if (!c || !ctx) return\n const ratio = window.devicePixelRatio || 1\n const width = c.width / ratio\n const height = c.height / ratio\n ctx.setTransform(ratio, 0, 0, ratio, 0, 0)\n ctx.clearRect(0, 0, width, height)\n ctx.lineWidth = Math.min(4, Math.max(2, height * 0.018))\n ctx.lineCap = 'round'\n ctx.lineJoin = 'round'\n ctx.strokeStyle = TYPED_SIGNATURE_STYLE.color\n for (const stroke of strokes.current) {\n if (!stroke.length) continue\n ctx.beginPath()\n ctx.moveTo(stroke[0]!.x * width, stroke[0]!.y * height)\n // A dot is a stroke too.\n if (stroke.length === 1) ctx.lineTo(stroke[0]!.x * width + 0.1, stroke[0]!.y * height)\n for (const p of stroke.slice(1)) ctx.lineTo(p.x * width, p.y * height)\n ctx.stroke()\n }\n }, [])\n\n // Back the canvas at the device's pixel ratio, and redraw on every resize.\n useEffect(() => {\n const c = canvas.current\n if (!c) return\n const fit = () => {\n const rect = c.getBoundingClientRect()\n const ratio = window.devicePixelRatio || 1\n const width = Math.max(1, Math.round(rect.width * ratio))\n const height = Math.max(1, Math.round(rect.height * ratio))\n if (c.width !== width || c.height !== height) {\n c.width = width\n c.height = height\n }\n paint()\n }\n fit()\n const observer = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(fit)\n observer?.observe(c)\n return () => observer?.disconnect()\n }, [paint])\n\n useImperativeHandle(\n ref,\n () => ({\n isBlank: () => strokes.current.every((s) => s.length === 0),\n toDataUrl: () =>\n strokes.current.some((s) => s.length)\n ? (canvas.current?.toDataURL('image/png') ?? null)\n : null,\n clear: () => {\n strokes.current = []\n paint()\n onInk(false)\n },\n }),\n [paint, onInk]\n )\n\n const at = (e: PointerEvent<HTMLCanvasElement>): Point => {\n const r = e.currentTarget.getBoundingClientRect()\n return {\n x: Math.min(1, Math.max(0, (e.clientX - r.left) / (r.width || 1))),\n y: Math.min(1, Math.max(0, (e.clientY - r.top) / (r.height || 1))),\n }\n }\n\n return (\n <canvas\n ref={canvas}\n className={cn(\n 'block touch-none rounded-md border bg-white select-none [overscroll-behavior:contain]',\n className\n )}\n style={{ touchAction: 'none' }}\n aria-label={label}\n role=\"img\"\n onPointerDown={(e) => {\n e.preventDefault()\n e.currentTarget.setPointerCapture?.(e.pointerId)\n drawing.current = [at(e)]\n strokes.current.push(drawing.current)\n paint()\n onInk(true)\n }}\n onPointerMove={(e) => {\n if (!drawing.current) return\n e.preventDefault()\n // Every sample the browser coalesced, for a smooth line from a fast finger or pen.\n const native = e.nativeEvent as globalThis.PointerEvent\n const samples = native.getCoalescedEvents?.() ?? []\n if (samples.length) {\n const r = e.currentTarget.getBoundingClientRect()\n for (const s of samples)\n drawing.current.push({\n x: Math.min(1, Math.max(0, (s.clientX - r.left) / (r.width || 1))),\n y: Math.min(1, Math.max(0, (s.clientY - r.top) / (r.height || 1))),\n })\n } else drawing.current.push(at(e))\n paint()\n }}\n onPointerUp={() => (drawing.current = null)}\n onPointerCancel={() => (drawing.current = null)}\n data-testid={testId}\n />\n )\n})\n\n/** Draw an uploaded image onto a fresh canvas, fitted, with near-white made transparent. */\nasync function uploadedPng(file: File): Promise<string> {\n const url = URL.createObjectURL(file)\n try {\n const img = new Image()\n await new Promise<void>((resolve, reject) => {\n img.onload = () => resolve()\n img.onerror = () => reject(new Error('That file is not an image'))\n img.src = url\n })\n const canvas = document.createElement('canvas')\n canvas.width = 900\n canvas.height = 300\n const ctx = canvas.getContext('2d')!\n const scale = Math.min(canvas.width / img.width, canvas.height / img.height)\n const w = img.width * scale\n const h = img.height * scale\n ctx.drawImage(img, (canvas.width - w) / 2, (canvas.height - h) / 2, w, h)\n const pixels = ctx.getImageData(0, 0, canvas.width, canvas.height)\n for (let i = 0; i < pixels.data.length; i += 4) {\n const [r, g, b] = [pixels.data[i]!, pixels.data[i + 1]!, pixels.data[i + 2]!]\n if (r > 225 && g > 225 && b > 225) pixels.data[i + 3] = 0\n }\n ctx.putImageData(pixels, 0, 0)\n return canvas.toDataURL('image/png')\n } finally {\n URL.revokeObjectURL(url)\n }\n}\n\nconst base64Of = (dataUrl: string) => dataUrl.slice(dataUrl.indexOf(',') + 1)\nconst dataUrlOf = (png: string) => `data:image/png;base64,${png}`\n\n/** A typed mark as a picture (transparent, ink blue, the signature face): what is saved for it. */\nexport function typedPng(text: string, height = 120): string {\n const canvas = document.createElement('canvas')\n const ctx = canvas.getContext('2d')\n if (!ctx) return ''\n const font = `italic ${Math.round(height * 0.6)}px ${TYPED_SIGNATURE_STYLE.fontFamily}`\n ctx.font = font\n const width = Math.max(height, Math.ceil(ctx.measureText(text).width + height * 0.4))\n canvas.width = width\n canvas.height = height\n ctx.font = font\n ctx.fillStyle = TYPED_SIGNATURE_STYLE.color\n ctx.textBaseline = 'middle'\n ctx.fillText(text, height * 0.2, height / 2)\n return base64Of(canvas.toDataURL('image/png'))\n}\n\n/** Full width of the screen on a phone (past the dialog's padding), a large box on wider screens. */\nconst PAD_SIGNATURE = '-mx-6 w-[calc(100%+3rem)] h-[44vw] min-h-36 sm:mx-0 sm:w-full sm:h-56'\nconst PAD_INITIALS = '-mx-6 w-[calc(100%+3rem)] h-[34vw] min-h-28 sm:mx-0 sm:w-80 sm:h-40'\n\nexport function AdoptSignatureDialog({\n open,\n onOpenChange,\n defaultName,\n onAdopt,\n saved = null,\n onSave,\n mode = 'adopt',\n}: AdoptSignatureDialogProps): ReactElement {\n const saving = mode === 'save'\n const [saveToAccount, setSaveToAccount] = useState(false)\n const [busy, setBusy] = useState(false)\n /** The saved drawing, shown on the pad until the person draws a new one. */\n const [savedDrawing, setSavedDrawing] = useState<string | null>(null)\n const [savedInitials, setSavedInitials] = useState<string | null>(null)\n const [name, setName] = useState(defaultName)\n const [initials, setInitials] = useState(() => initialsOf(defaultName))\n const [style, setStyle] = useState<Style>('typed')\n const [initialsStyle, setInitialsStyle] = useState<InitialsStyle>('typed')\n const [hasInk, setHasInk] = useState(false)\n const [hasInitialsInk, setHasInitialsInk] = useState(false)\n const [upload, setUpload] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const signaturePad = useRef<SignaturePadHandle>(null)\n const initialsPad = useRef<SignaturePadHandle>(null)\n\n useEffect(() => {\n if (!open) return\n setSaveToAccount(false)\n setError(null)\n if (saved) {\n setName(saved.name)\n setInitials(saved.initials)\n setStyle(saved.style)\n setInitialsStyle(saved.initials_style)\n setSavedDrawing(saved.style === 'drawn' ? dataUrlOf(saved.signature_png) : null)\n setUpload(saved.style === 'uploaded' ? dataUrlOf(saved.signature_png) : null)\n setSavedInitials(saved.initials_style === 'drawn' ? dataUrlOf(saved.initials_png) : null)\n } else {\n setName(defaultName)\n setInitials(initialsOf(defaultName))\n }\n }, [open, defaultName, saved])\n\n const adopt = async () => {\n setError(null)\n if (!name.trim() || !initials.trim()) return\n let signatureUrl: string | null = null\n if (style === 'drawn') {\n signatureUrl = signaturePad.current?.toDataUrl() ?? (hasInk ? null : savedDrawing)\n if (!signatureUrl) return setError('Draw your signature first.')\n } else if (style === 'uploaded') {\n signatureUrl = upload\n if (!signatureUrl) return setError('Choose an image first.')\n }\n let initialsUrl: string | null = null\n if (initialsStyle === 'drawn') {\n initialsUrl = initialsPad.current?.toDataUrl() ?? (hasInitialsInk ? null : savedInitials)\n if (!initialsUrl) return setError('Draw your initials first.')\n }\n if (onSave && (saving || saveToAccount)) {\n setBusy(true)\n try {\n await onSave({\n name: name.trim(),\n initials: initials.trim(),\n style,\n initials_style: initialsStyle,\n signature_png: signatureUrl ? base64Of(signatureUrl) : typedPng(name.trim()),\n initials_png: initialsUrl ? base64Of(initialsUrl) : typedPng(initials.trim()),\n })\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Your signature could not be saved')\n return\n } finally {\n setBusy(false)\n }\n }\n onAdopt({\n adopted: {\n name: name.trim(),\n initials: initials.trim(),\n style,\n ...(signatureUrl ? { signature_image: base64Of(signatureUrl) } : {}),\n ...(initialsUrl ? { initials_image: base64Of(initialsUrl) } : {}),\n },\n signatureUrl,\n initialsUrl,\n })\n }\n\n return (\n <ModalScaffold\n open={open}\n onOpenChange={onOpenChange}\n title={saving ? 'Your signature' : 'Adopt your signature'}\n description={\n saving\n ? 'Saved to your account, sealed with your own key, for placing in documents yourself.'\n : 'You adopt it once and apply it at each place you are asked to sign.'\n }\n showDescription\n size=\"lg\"\n testId=\"adopt-signature-dialog\"\n >\n <ModalScaffold.Body>\n <div className=\"grid grid-cols-[1fr_7rem] gap-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"adopt-name\">Full name</Label>\n <Input\n id=\"adopt-name\"\n value={name}\n onChange={(e) => {\n setName(e.target.value)\n setInitials(initialsOf(e.target.value))\n }}\n data-testid=\"adopt-signature-name\"\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"adopt-initials\">Initials</Label>\n <Input\n id=\"adopt-initials\"\n value={initials}\n maxLength={12}\n onChange={(e) => setInitials(e.target.value)}\n data-testid=\"adopt-signature-initials\"\n />\n </div>\n </div>\n <section className=\"space-y-1.5\" aria-label=\"Signature\">\n <h3 className=\"text-sm font-medium\">Signature</h3>\n <Tabs\n value={style}\n onValueChange={(v) => {\n setStyle(v as Style)\n setError(null)\n }}\n >\n <TabsList className=\"grid w-full grid-cols-3\">\n <TabsTrigger value=\"typed\" data-testid=\"adopt-tab-typed\">\n Type\n </TabsTrigger>\n <TabsTrigger value=\"drawn\" data-testid=\"adopt-tab-drawn\">\n Draw\n </TabsTrigger>\n <TabsTrigger value=\"uploaded\" data-testid=\"adopt-tab-uploaded\">\n Upload\n </TabsTrigger>\n </TabsList>\n <TabsContent value=\"typed\">\n <div\n className=\"flex h-28 items-center justify-center overflow-hidden rounded-md border bg-white px-4 text-4xl whitespace-nowrap\"\n style={TYPED_SIGNATURE_STYLE}\n data-testid=\"adopt-signature-typed-preview\"\n >\n {name.trim() || 'Your name'}\n </div>\n </TabsContent>\n <TabsContent value=\"drawn\" forceMount hidden={style !== 'drawn'}>\n <div className=\"relative\">\n <SignaturePad\n ref={signaturePad}\n label=\"Draw your signature\"\n className={PAD_SIGNATURE}\n onInk={setHasInk}\n testId=\"adopt-signature-canvas\"\n />\n {savedDrawing && !hasInk && (\n <img\n src={savedDrawing}\n alt=\"Your saved signature\"\n className=\"pointer-events-none absolute inset-0 h-full w-full object-contain p-2\"\n data-testid=\"adopt-signature-saved\"\n />\n )}\n </div>\n <div className=\"flex items-center justify-between pt-1 text-xs text-muted-foreground\">\n <span>Sign with your finger, a pen or the mouse.</span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => signaturePad.current?.clear()}\n disabled={!hasInk}\n data-testid=\"adopt-signature-clear\"\n >\n Clear\n </Button>\n </div>\n </TabsContent>\n <TabsContent value=\"uploaded\" forceMount hidden={style !== 'uploaded'}>\n <div className=\"flex h-28 items-center justify-center rounded-md border bg-white\">\n {upload ? (\n <img src={upload} alt=\"Uploaded signature\" className=\"h-full object-contain\" />\n ) : (\n <span className=\"text-sm text-muted-foreground\">No image chosen</span>\n )}\n </div>\n <Input\n type=\"file\"\n accept=\"image/png,image/jpeg,image/webp\"\n className=\"mt-2\"\n onChange={async (e) => {\n const file = e.target.files?.[0]\n if (!file) return\n try {\n setUpload(await uploadedPng(file))\n setError(null)\n } catch (err) {\n setError(err instanceof Error ? err.message : 'The image could not be read')\n }\n }}\n data-testid=\"adopt-signature-upload\"\n />\n </TabsContent>\n </Tabs>\n </section>\n <section className=\"space-y-1.5\" aria-label=\"Initials\">\n <h3 className=\"text-sm font-medium\">Initials</h3>\n <Tabs\n value={initialsStyle}\n onValueChange={(v) => {\n setInitialsStyle(v as InitialsStyle)\n setError(null)\n }}\n >\n <TabsList className=\"grid w-full grid-cols-2 sm:w-80\">\n <TabsTrigger value=\"typed\" data-testid=\"adopt-initials-tab-typed\">\n Type\n </TabsTrigger>\n <TabsTrigger value=\"drawn\" data-testid=\"adopt-initials-tab-drawn\">\n Draw\n </TabsTrigger>\n </TabsList>\n <TabsContent value=\"typed\">\n <div\n className=\"flex h-20 items-center justify-center rounded-md border bg-white px-4 text-3xl sm:w-80\"\n style={TYPED_SIGNATURE_STYLE}\n data-testid=\"adopt-initials-typed-preview\"\n >\n {initials.trim() || 'AB'}\n </div>\n </TabsContent>\n <TabsContent value=\"drawn\" forceMount hidden={initialsStyle !== 'drawn'}>\n <div className=\"relative sm:w-80\">\n <SignaturePad\n ref={initialsPad}\n label=\"Draw your initials\"\n className={PAD_INITIALS}\n onInk={setHasInitialsInk}\n testId=\"adopt-initials-canvas\"\n />\n {savedInitials && !hasInitialsInk && (\n <img\n src={savedInitials}\n alt=\"Your saved initials\"\n className=\"pointer-events-none absolute inset-0 h-full w-full object-contain p-2\"\n />\n )}\n </div>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => initialsPad.current?.clear()}\n disabled={!hasInitialsInk}\n >\n Clear\n </Button>\n </TabsContent>\n </Tabs>\n </section>\n {onSave && !saving && (\n <label className=\"flex items-center gap-2 text-sm\">\n <Checkbox\n checked={saveToAccount}\n onCheckedChange={(c) => setSaveToAccount(c === true)}\n data-testid=\"adopt-signature-save\"\n />\n Save to my account for future use\n </label>\n )}\n {name.trim() && !saving && (\n <p className=\"text-xs text-muted-foreground\">\n By adopting it you agree to sign electronically: “{intentText({ name })}”\n </p>\n )}\n {error && (\n <p className=\"text-sm text-red-text\" role=\"alert\">\n {error}\n </p>\n )}\n </ModalScaffold.Body>\n <ModalScaffold.Footer>\n <Button type=\"button\" variant=\"outline\" onClick={() => onOpenChange(false)}>\n Cancel\n </Button>\n <Button\n type=\"button\"\n onClick={() => void adopt()}\n disabled={busy || !name.trim() || !initials.trim()}\n data-testid=\"adopt-signature-submit\"\n >\n {saving ? 'Save' : 'Adopt and sign'}\n </Button>\n </ModalScaffold.Footer>\n </ModalScaffold>\n )\n}\n"]}
|