@zerohive/hive-viewer 0.2.5 → 0.2.7
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/index.cjs +185 -245
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +186 -247
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +186 -247
- package/dist/styles.css +200 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -55,222 +55,122 @@ function sanitizeHtml(html) {
|
|
|
55
55
|
// src/editors/RichTextEditor.tsx
|
|
56
56
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
57
57
|
var PAGE_H = 1122;
|
|
58
|
-
var RichTextEditor = (0, import_react.forwardRef)(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
if (props.fileType === "docx") {
|
|
79
|
-
const res = await import_mammoth.default.convertToHtml({
|
|
80
|
-
arrayBuffer: props.arrayBuffer
|
|
81
|
-
});
|
|
82
|
-
if (!cancelled) {
|
|
83
|
-
setHtml(sanitizeHtml(res.value || "<p><br/></p>"));
|
|
58
|
+
var RichTextEditor = (0, import_react.forwardRef)(
|
|
59
|
+
(props, ref) => {
|
|
60
|
+
const readOnly = props.mode === "view";
|
|
61
|
+
const md = (0, import_react.useMemo)(
|
|
62
|
+
() => new import_markdown_it.default({ html: false, linkify: true, breaks: true }),
|
|
63
|
+
[]
|
|
64
|
+
);
|
|
65
|
+
const scrollerRef = (0, import_react.useRef)(null);
|
|
66
|
+
const editorRef = (0, import_react.useRef)(null);
|
|
67
|
+
const captureRef = (0, import_react.useRef)(null);
|
|
68
|
+
const initialized = (0, import_react.useRef)(false);
|
|
69
|
+
(0, import_react.useEffect)(() => {
|
|
70
|
+
if (initialized.current) return;
|
|
71
|
+
(async () => {
|
|
72
|
+
if (props.mode === "create") {
|
|
73
|
+
editorRef.current.innerHTML = "<p><br/></p>";
|
|
74
|
+
initialized.current = true;
|
|
75
|
+
return;
|
|
84
76
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
77
|
+
if (!props.arrayBuffer) return;
|
|
78
|
+
if (props.fileType === "docx") {
|
|
79
|
+
const res = await import_mammoth.default.convertToHtml({
|
|
80
|
+
arrayBuffer: props.arrayBuffer
|
|
81
|
+
});
|
|
82
|
+
editorRef.current.innerHTML = sanitizeHtml(
|
|
83
|
+
res.value || "<p><br/></p>"
|
|
84
|
+
);
|
|
89
85
|
} else {
|
|
90
|
-
|
|
86
|
+
const text = new TextDecoder().decode(props.arrayBuffer);
|
|
87
|
+
editorRef.current.innerHTML = props.fileType === "md" ? sanitizeHtml(md.render(text)) : `<pre>${escapeHtml(text)}</pre>`;
|
|
91
88
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}, [html, props.headerFooterEnabled]);
|
|
109
|
-
function exec(cmd) {
|
|
110
|
-
if (readOnly) {
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
document.execCommand(cmd);
|
|
114
|
-
}
|
|
115
|
-
function onClick(e) {
|
|
116
|
-
if (!props.armedSignatureUrl) {
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
const scroller = scrollerRef.current;
|
|
120
|
-
if (!scroller) {
|
|
121
|
-
return;
|
|
89
|
+
initialized.current = true;
|
|
90
|
+
})();
|
|
91
|
+
}, [props.arrayBuffer, props.fileType, props.mode, md]);
|
|
92
|
+
(0, import_react.useEffect)(() => {
|
|
93
|
+
const el = scrollerRef.current;
|
|
94
|
+
if (!el) return;
|
|
95
|
+
const recompute = () => props.onPageCount(Math.max(1, Math.ceil(el.scrollHeight / PAGE_H)));
|
|
96
|
+
recompute();
|
|
97
|
+
const ro = new ResizeObserver(recompute);
|
|
98
|
+
ro.observe(el);
|
|
99
|
+
return () => ro.disconnect();
|
|
100
|
+
}, [props.headerFooterEnabled]);
|
|
101
|
+
function exec(cmd) {
|
|
102
|
+
if (readOnly) return;
|
|
103
|
+
document.execCommand(cmd);
|
|
104
|
+
editorRef.current?.focus();
|
|
122
105
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
const old = scroller.scrollTop;
|
|
138
|
-
scroller.scrollTop = index * PAGE_H;
|
|
139
|
-
await new Promise((r) => requestAnimationFrame(() => r(null)));
|
|
140
|
-
try {
|
|
141
|
-
const canvas = await (0, import_html2canvas.default)(capture, {
|
|
142
|
-
backgroundColor: null,
|
|
143
|
-
scale: 0.25,
|
|
144
|
-
useCORS: true
|
|
145
|
-
});
|
|
146
|
-
return canvas.toDataURL("image/png");
|
|
147
|
-
} catch {
|
|
148
|
-
return void 0;
|
|
149
|
-
} finally {
|
|
150
|
-
scroller.scrollTop = old;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
async function save(exportPdf) {
|
|
154
|
-
const inner = editorRef.current?.innerHTML ?? html;
|
|
155
|
-
const stitched = `<!doctype html><html><head><meta charset="utf-8" /></head><body>${inner}</body></html>`;
|
|
156
|
-
if (exportPdf) {
|
|
157
|
-
const b642 = btoa(unescape(encodeURIComponent(stitched)));
|
|
158
|
-
props.onSave(b642, {
|
|
159
|
-
fileName: replaceExt(props.fileName, "html"),
|
|
160
|
-
fileType: "txt",
|
|
161
|
-
exportedAsPdf: true,
|
|
162
|
-
annotations: { signaturePlacements: props.signaturePlacements }
|
|
106
|
+
function onClickPage(e) {
|
|
107
|
+
if (!props.armedSignatureUrl) return;
|
|
108
|
+
const scroller = scrollerRef.current;
|
|
109
|
+
if (!scroller) return;
|
|
110
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
111
|
+
const absY = scroller.scrollTop + (e.clientY - rect.top);
|
|
112
|
+
const page = Math.floor(absY / PAGE_H) + 1;
|
|
113
|
+
props.onPlaceSignature({
|
|
114
|
+
page,
|
|
115
|
+
x: (e.clientX - rect.left) / rect.width,
|
|
116
|
+
y: absY % PAGE_H / PAGE_H,
|
|
117
|
+
w: 0.25,
|
|
118
|
+
h: 0.1
|
|
163
119
|
});
|
|
164
|
-
return;
|
|
165
120
|
}
|
|
166
|
-
|
|
121
|
+
async function requestThumbnail(index) {
|
|
122
|
+
const scroller = scrollerRef.current;
|
|
123
|
+
const capture = captureRef.current;
|
|
124
|
+
if (!scroller || !capture) return;
|
|
125
|
+
const old = scroller.scrollTop;
|
|
126
|
+
scroller.scrollTop = index * PAGE_H;
|
|
127
|
+
await new Promise((r) => requestAnimationFrame(r));
|
|
167
128
|
try {
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
body: JSON.stringify({
|
|
172
|
-
html: stitched,
|
|
173
|
-
fileName: replaceExt(props.fileName, "docx")
|
|
174
|
-
})
|
|
129
|
+
const canvas = await (0, import_html2canvas.default)(capture, {
|
|
130
|
+
scale: 0.25,
|
|
131
|
+
useCORS: true
|
|
175
132
|
});
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
const blob = await response.blob();
|
|
180
|
-
const url = window.URL.createObjectURL(blob);
|
|
181
|
-
const a = document.createElement("a");
|
|
182
|
-
a.href = url;
|
|
183
|
-
a.download = replaceExt(props.fileName, "docx");
|
|
184
|
-
document.body.appendChild(a);
|
|
185
|
-
a.click();
|
|
186
|
-
setTimeout(() => {
|
|
187
|
-
window.URL.revokeObjectURL(url);
|
|
188
|
-
a.remove();
|
|
189
|
-
}, 100);
|
|
190
|
-
} catch (err) {
|
|
191
|
-
alert(
|
|
192
|
-
"DOCX export failed: " + (err instanceof Error ? err.message : String(err))
|
|
193
|
-
);
|
|
133
|
+
return canvas.toDataURL("image/png");
|
|
134
|
+
} finally {
|
|
135
|
+
scroller.scrollTop = old;
|
|
194
136
|
}
|
|
195
|
-
return;
|
|
196
137
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
className: "hv-btn",
|
|
221
|
-
onClick: () => exec("italic"),
|
|
222
|
-
disabled: readOnly,
|
|
223
|
-
children: "I"
|
|
224
|
-
}
|
|
225
|
-
),
|
|
226
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
227
|
-
"button",
|
|
228
|
-
{
|
|
229
|
-
className: "hv-btn",
|
|
230
|
-
onClick: () => exec("underline"),
|
|
231
|
-
disabled: readOnly,
|
|
232
|
-
children: "U"
|
|
233
|
-
}
|
|
234
|
-
),
|
|
235
|
-
props.armedSignatureUrl ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hv-hint", children: "Click to place signature" }) : null
|
|
236
|
-
] }),
|
|
237
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hv-scroll", ref: scrollerRef, onClick, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "hv-pageStage", ref: captureRef, children: [
|
|
238
|
-
props.headerFooterEnabled && props.headerComponent ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hv-letterhead", children: props.headerComponent }) : null,
|
|
239
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
138
|
+
async function save(exportPdf) {
|
|
139
|
+
const html = editorRef.current?.innerHTML ?? "";
|
|
140
|
+
const stitched = `<!doctype html><html><body>${html}</body></html>`;
|
|
141
|
+
const b64 = btoa(unescape(encodeURIComponent(stitched)));
|
|
142
|
+
props.onSave(b64, {
|
|
143
|
+
fileName: props.fileName,
|
|
144
|
+
fileType: props.fileType,
|
|
145
|
+
exportedAsPdf: exportPdf,
|
|
146
|
+
annotations: { signaturePlacements: props.signaturePlacements }
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
(0, import_react.useImperativeHandle)(ref, () => ({
|
|
150
|
+
save,
|
|
151
|
+
requestThumbnail
|
|
152
|
+
}));
|
|
153
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "hv-root", children: [
|
|
154
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "hv-toolbar", children: [
|
|
155
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => exec("bold"), disabled: readOnly, children: "B" }),
|
|
156
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => exec("italic"), disabled: readOnly, children: "I" }),
|
|
157
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => exec("underline"), disabled: readOnly, children: "U" }),
|
|
158
|
+
props.armedSignatureUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "hv-hint", children: "Click page to place signature" })
|
|
159
|
+
] }),
|
|
160
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hv-scroll", ref: scrollerRef, onClick: onClickPage, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hv-pageStage", ref: captureRef, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
240
161
|
"div",
|
|
241
162
|
{
|
|
242
163
|
ref: editorRef,
|
|
243
|
-
className: readOnly ? "
|
|
164
|
+
className: `hv-editor ${readOnly ? "ro" : ""}`,
|
|
244
165
|
contentEditable: !readOnly,
|
|
245
|
-
suppressContentEditableWarning: true
|
|
246
|
-
onInput: () => setHtml(editorRef.current?.innerHTML ?? ""),
|
|
247
|
-
dangerouslySetInnerHTML: { __html: html }
|
|
166
|
+
suppressContentEditableWarning: true
|
|
248
167
|
}
|
|
249
|
-
)
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
"img",
|
|
254
|
-
{
|
|
255
|
-
src: s.signatureImageUrl,
|
|
256
|
-
alt: "",
|
|
257
|
-
className: "hv-sign-img"
|
|
258
|
-
}
|
|
259
|
-
),
|
|
260
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
261
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hv-sign-name", children: s.signedBy }),
|
|
262
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hv-sign-date", children: new Date(s.dateSigned).toLocaleString() })
|
|
263
|
-
] })
|
|
264
|
-
] }, i)) }) : null
|
|
265
|
-
] }) })
|
|
266
|
-
] });
|
|
267
|
-
});
|
|
268
|
-
function replaceExt(name, ext) {
|
|
269
|
-
const base = name.includes(".") ? name.slice(0, name.lastIndexOf(".")) : name;
|
|
270
|
-
return `${base}.${ext}`;
|
|
271
|
-
}
|
|
168
|
+
) }) })
|
|
169
|
+
] });
|
|
170
|
+
}
|
|
171
|
+
);
|
|
272
172
|
function escapeHtml(s) {
|
|
273
|
-
return s.replace(/&/g, "&").replace(/</g, "<")
|
|
173
|
+
return s.replace(/&/g, "&").replace(/</g, "<");
|
|
274
174
|
}
|
|
275
175
|
|
|
276
176
|
// src/editors/SpreadsheetEditor.tsx
|
|
@@ -968,49 +868,46 @@ function Toolbar(props) {
|
|
|
968
868
|
role: "toolbar",
|
|
969
869
|
"aria-label": t("a11y.toolbar", "Document toolbar"),
|
|
970
870
|
children: [
|
|
971
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hv-
|
|
871
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hv-toolbar__group", children: [
|
|
972
872
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
973
873
|
"button",
|
|
974
874
|
{
|
|
975
|
-
|
|
976
|
-
className: "hv-btn",
|
|
875
|
+
className: `hv-btn ${props.showThumbnails ? "hv-btn--active" : ""}`,
|
|
977
876
|
onClick: props.onToggleThumbnails,
|
|
978
877
|
"aria-pressed": props.showThumbnails,
|
|
979
|
-
children:
|
|
878
|
+
children: "Thumbnails"
|
|
980
879
|
}
|
|
981
880
|
),
|
|
982
881
|
props.mode !== "create" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
983
882
|
"button",
|
|
984
883
|
{
|
|
985
|
-
|
|
986
|
-
className: "hv-btn",
|
|
884
|
+
className: `hv-btn ${props.showSignatures ? "hv-btn--active" : ""}`,
|
|
987
885
|
onClick: props.onToggleSignatures,
|
|
988
886
|
"aria-pressed": props.showSignatures,
|
|
989
|
-
children:
|
|
887
|
+
children: "Signatures"
|
|
990
888
|
}
|
|
991
|
-
)
|
|
992
|
-
|
|
889
|
+
)
|
|
890
|
+
] }),
|
|
891
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hv-toolbar__group hv-segment", children: [
|
|
993
892
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
994
893
|
"button",
|
|
995
894
|
{
|
|
996
|
-
|
|
997
|
-
className: props.layout === "single" ? "hv-btn hv-btn--active" : "hv-btn",
|
|
895
|
+
className: `hv-btn ${props.layout === "single" ? "hv-btn--active" : ""}`,
|
|
998
896
|
onClick: () => props.onChangeLayout("single"),
|
|
999
|
-
children:
|
|
897
|
+
children: "Single page"
|
|
1000
898
|
}
|
|
1001
899
|
),
|
|
1002
900
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1003
901
|
"button",
|
|
1004
902
|
{
|
|
1005
|
-
|
|
1006
|
-
className: props.layout === "side-by-side" ? "hv-btn hv-btn--active" : "hv-btn",
|
|
903
|
+
className: `hv-btn ${props.layout === "side-by-side" ? "hv-btn--active" : ""}`,
|
|
1007
904
|
onClick: () => props.onChangeLayout("side-by-side"),
|
|
1008
|
-
children:
|
|
905
|
+
children: "Side-by-side"
|
|
1009
906
|
}
|
|
1010
907
|
)
|
|
1011
908
|
] }),
|
|
1012
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hv-
|
|
1013
|
-
props.showHeaderFooterToggle && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "hv-
|
|
909
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hv-toolbar__group hv-toolbar__actions", children: [
|
|
910
|
+
props.showHeaderFooterToggle && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "hv-switch", children: [
|
|
1014
911
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1015
912
|
"input",
|
|
1016
913
|
{
|
|
@@ -1019,28 +916,20 @@ function Toolbar(props) {
|
|
|
1019
916
|
onChange: props.onToggleHeaderFooter
|
|
1020
917
|
}
|
|
1021
918
|
),
|
|
1022
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", {
|
|
919
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hv-switch__slider" }),
|
|
920
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hv-switch__label", children: t("toolbar.letterhead", "Letterhead") })
|
|
1023
921
|
] }),
|
|
1024
922
|
props.allowSigning && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1025
923
|
"button",
|
|
1026
924
|
{
|
|
1027
|
-
type: "button",
|
|
1028
925
|
className: "hv-btn hv-btn--primary",
|
|
1029
926
|
onClick: props.onSign,
|
|
1030
927
|
disabled: props.signingDisabled,
|
|
1031
|
-
children:
|
|
928
|
+
children: "Sign document"
|
|
1032
929
|
}
|
|
1033
930
|
),
|
|
1034
|
-
props.canExportPdf && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", {
|
|
1035
|
-
props.canSave && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1036
|
-
"button",
|
|
1037
|
-
{
|
|
1038
|
-
type: "button",
|
|
1039
|
-
className: "hv-btn hv-btn--primary",
|
|
1040
|
-
onClick: props.onSave,
|
|
1041
|
-
children: t("toolbar.save", "Save")
|
|
1042
|
-
}
|
|
1043
|
-
)
|
|
931
|
+
props.canExportPdf && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { className: "hv-btn", onClick: props.onExportPdf, children: "Export PDF" }),
|
|
932
|
+
props.canSave && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { className: "hv-btn hv-btn--primary", onClick: props.onSave, children: "Save" })
|
|
1044
933
|
] })
|
|
1045
934
|
]
|
|
1046
935
|
}
|
|
@@ -1052,8 +941,13 @@ var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
|
1052
941
|
function DocumentViewer(props) {
|
|
1053
942
|
const mode = props.mode ?? "view";
|
|
1054
943
|
const theme = props.theme ?? "light";
|
|
1055
|
-
const locale = (0, import_react7.useMemo)(
|
|
1056
|
-
|
|
944
|
+
const locale = (0, import_react7.useMemo)(
|
|
945
|
+
() => ({ ...defaultLocale, ...props.locale ?? {} }),
|
|
946
|
+
[props.locale]
|
|
947
|
+
);
|
|
948
|
+
const [layout, setLayout] = (0, import_react7.useState)(
|
|
949
|
+
props.defaultLayout ?? "single"
|
|
950
|
+
);
|
|
1057
951
|
const [showThumbnails, setShowThumbnails] = (0, import_react7.useState)(true);
|
|
1058
952
|
const [showSignatures, setShowSignatures] = (0, import_react7.useState)(true);
|
|
1059
953
|
const [headerFooterEnabled, setHeaderFooterEnabled] = (0, import_react7.useState)(true);
|
|
@@ -1064,10 +958,17 @@ function DocumentViewer(props) {
|
|
|
1064
958
|
const [pageCount, setPageCount] = (0, import_react7.useState)(1);
|
|
1065
959
|
const [currentPage, setCurrentPage] = (0, import_react7.useState)(1);
|
|
1066
960
|
const [thumbs, setThumbs] = (0, import_react7.useState)([]);
|
|
1067
|
-
const [localSignatures, setLocalSignatures] = (0, import_react7.useState)(
|
|
1068
|
-
|
|
961
|
+
const [localSignatures, setLocalSignatures] = (0, import_react7.useState)(
|
|
962
|
+
props.signatures ?? []
|
|
963
|
+
);
|
|
964
|
+
(0, import_react7.useEffect)(
|
|
965
|
+
() => setLocalSignatures(props.signatures ?? []),
|
|
966
|
+
[props.signatures]
|
|
967
|
+
);
|
|
1069
968
|
const [sigPlacements, setSigPlacements] = (0, import_react7.useState)([]);
|
|
1070
|
-
const [armedSignatureUrl, setArmedSignatureUrl] = (0, import_react7.useState)(
|
|
969
|
+
const [armedSignatureUrl, setArmedSignatureUrl] = (0, import_react7.useState)(
|
|
970
|
+
null
|
|
971
|
+
);
|
|
1071
972
|
const editorRef = (0, import_react7.useRef)(null);
|
|
1072
973
|
(0, import_react7.useEffect)(() => {
|
|
1073
974
|
let cancelled = false;
|
|
@@ -1081,7 +982,10 @@ function DocumentViewer(props) {
|
|
|
1081
982
|
setArmedSignatureUrl(null);
|
|
1082
983
|
if (mode === "create") {
|
|
1083
984
|
const ft = props.fileType ?? "docx";
|
|
1084
|
-
setResolved({
|
|
985
|
+
setResolved({
|
|
986
|
+
fileType: ft,
|
|
987
|
+
fileName: props.fileName ?? `Untitled.${ft}`
|
|
988
|
+
});
|
|
1085
989
|
return;
|
|
1086
990
|
}
|
|
1087
991
|
try {
|
|
@@ -1095,7 +999,12 @@ function DocumentViewer(props) {
|
|
|
1095
999
|
if (cancelled) {
|
|
1096
1000
|
return;
|
|
1097
1001
|
}
|
|
1098
|
-
setResolved({
|
|
1002
|
+
setResolved({
|
|
1003
|
+
fileType: res.fileType,
|
|
1004
|
+
fileName: res.fileName,
|
|
1005
|
+
url: res.url,
|
|
1006
|
+
arrayBuffer: res.arrayBuffer
|
|
1007
|
+
});
|
|
1099
1008
|
} catch (e) {
|
|
1100
1009
|
if (cancelled) {
|
|
1101
1010
|
return;
|
|
@@ -1106,7 +1015,14 @@ function DocumentViewer(props) {
|
|
|
1106
1015
|
return () => {
|
|
1107
1016
|
cancelled = true;
|
|
1108
1017
|
};
|
|
1109
|
-
}, [
|
|
1018
|
+
}, [
|
|
1019
|
+
mode,
|
|
1020
|
+
props.fileUrl,
|
|
1021
|
+
props.base64,
|
|
1022
|
+
props.blob,
|
|
1023
|
+
props.fileName,
|
|
1024
|
+
props.fileType
|
|
1025
|
+
]);
|
|
1110
1026
|
const thumbnails = (0, import_react7.useMemo)(() => {
|
|
1111
1027
|
const n = Math.max(1, pageCount);
|
|
1112
1028
|
return Array.from({ length: n }, (_, i) => ({
|
|
@@ -1132,7 +1048,10 @@ function DocumentViewer(props) {
|
|
|
1132
1048
|
if (!armedSignatureUrl) {
|
|
1133
1049
|
return;
|
|
1134
1050
|
}
|
|
1135
|
-
setSigPlacements((prev) => [
|
|
1051
|
+
setSigPlacements((prev) => [
|
|
1052
|
+
...prev,
|
|
1053
|
+
{ ...p, signatureImageUrl: armedSignatureUrl }
|
|
1054
|
+
]);
|
|
1136
1055
|
setArmedSignatureUrl(null);
|
|
1137
1056
|
}
|
|
1138
1057
|
async function handleSave(exportPdf) {
|
|
@@ -1144,7 +1063,11 @@ function DocumentViewer(props) {
|
|
|
1144
1063
|
return;
|
|
1145
1064
|
}
|
|
1146
1065
|
const b64 = arrayBufferToBase642(resolved.arrayBuffer);
|
|
1147
|
-
props.onSave?.(b64, {
|
|
1066
|
+
props.onSave?.(b64, {
|
|
1067
|
+
fileName: resolved.fileName,
|
|
1068
|
+
fileType: resolved.fileType,
|
|
1069
|
+
annotations: { sigPlacements }
|
|
1070
|
+
});
|
|
1148
1071
|
}
|
|
1149
1072
|
const canSave = mode === "edit" || mode === "create";
|
|
1150
1073
|
const canExportPdf = (mode === "edit" || mode === "create") && (resolved?.fileType === "docx" || resolved?.fileType === "md" || resolved?.fileType === "txt" || resolved?.fileType === "xlsx");
|
|
@@ -1201,10 +1124,16 @@ function DocumentViewer(props) {
|
|
|
1201
1124
|
onCurrentPageChange: setCurrentPage,
|
|
1202
1125
|
onPageCount: (n) => {
|
|
1203
1126
|
setPageCount(n);
|
|
1204
|
-
setThumbs(
|
|
1127
|
+
setThumbs(
|
|
1128
|
+
(prev) => prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i])
|
|
1129
|
+
);
|
|
1205
1130
|
},
|
|
1206
1131
|
onThumbs: (t) => setThumbs(t),
|
|
1207
|
-
signatureStamp: armedSignatureUrl ? {
|
|
1132
|
+
signatureStamp: armedSignatureUrl ? {
|
|
1133
|
+
imageUrl: armedSignatureUrl,
|
|
1134
|
+
armed: true,
|
|
1135
|
+
onPlaced: placeSignature
|
|
1136
|
+
} : void 0
|
|
1208
1137
|
}
|
|
1209
1138
|
) : null,
|
|
1210
1139
|
resolved.fileType === "docx" || resolved.fileType === "md" || resolved.fileType === "txt" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
@@ -1223,7 +1152,9 @@ function DocumentViewer(props) {
|
|
|
1223
1152
|
signaturePlacements: sigPlacements,
|
|
1224
1153
|
onPageCount: (n) => {
|
|
1225
1154
|
setPageCount(n);
|
|
1226
|
-
setThumbs(
|
|
1155
|
+
setThumbs(
|
|
1156
|
+
(prev) => prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i])
|
|
1157
|
+
);
|
|
1227
1158
|
},
|
|
1228
1159
|
onSave: (b64, meta) => props.onSave?.(b64, meta),
|
|
1229
1160
|
armedSignatureUrl,
|
|
@@ -1250,12 +1181,21 @@ function DocumentViewer(props) {
|
|
|
1250
1181
|
onCurrentPageChange: setCurrentPage,
|
|
1251
1182
|
onSlideCount: (n) => {
|
|
1252
1183
|
setPageCount(n);
|
|
1253
|
-
setThumbs(
|
|
1184
|
+
setThumbs(
|
|
1185
|
+
(prev) => prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i])
|
|
1186
|
+
);
|
|
1254
1187
|
},
|
|
1255
1188
|
onThumbs: (t) => setThumbs(t)
|
|
1256
1189
|
}
|
|
1257
1190
|
) : null,
|
|
1258
|
-
resolved.fileType === "png" || resolved.fileType === "jpg" || resolved.fileType === "svg" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1191
|
+
resolved.fileType === "png" || resolved.fileType === "jpg" || resolved.fileType === "svg" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1192
|
+
ImageRenderer,
|
|
1193
|
+
{
|
|
1194
|
+
arrayBuffer: resolved.arrayBuffer,
|
|
1195
|
+
fileType: resolved.fileType,
|
|
1196
|
+
fileName: resolved.fileName
|
|
1197
|
+
}
|
|
1198
|
+
) : null
|
|
1259
1199
|
] }),
|
|
1260
1200
|
mode !== "create" && localSignatures.length ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1261
1201
|
SignaturePanel,
|