@zerohive/hive-viewer 0.2.4 → 0.2.6

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 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)((props, ref) => {
59
- const readOnly = props.mode === "view";
60
- const md = (0, import_react.useMemo)(
61
- () => new import_markdown_it.default({ html: false, linkify: true, breaks: true }),
62
- []
63
- );
64
- const scrollerRef = (0, import_react.useRef)(null);
65
- const editorRef = (0, import_react.useRef)(null);
66
- const captureRef = (0, import_react.useRef)(null);
67
- const [html, setHtml] = (0, import_react.useState)("<p><br/></p>");
68
- (0, import_react.useEffect)(() => {
69
- let cancelled = false;
70
- (async () => {
71
- if (props.mode === "create") {
72
- setHtml("<p><br/></p>");
73
- return;
74
- }
75
- if (!props.arrayBuffer) {
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
- } else {
86
- const text = new TextDecoder().decode(props.arrayBuffer);
87
- if (props.fileType === "md") {
88
- setHtml(sanitizeHtml(md.render(text)));
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
- setHtml(`<pre>${escapeHtml(text)}</pre>`);
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
- return () => {
95
- cancelled = true;
96
- };
97
- }, [props.arrayBuffer, props.fileType, props.mode, md]);
98
- (0, import_react.useEffect)(() => {
99
- const el = scrollerRef.current;
100
- if (!el) {
101
- return;
102
- }
103
- const recompute = () => props.onPageCount(Math.max(1, Math.ceil(el.scrollHeight / PAGE_H)));
104
- recompute();
105
- const ro = new ResizeObserver(recompute);
106
- ro.observe(el);
107
- return () => ro.disconnect();
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;
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();
118
105
  }
119
- const scroller = scrollerRef.current;
120
- if (!scroller) {
121
- return;
122
- }
123
- const rect = e.currentTarget.getBoundingClientRect();
124
- const absY = scroller.scrollTop + (e.clientY - rect.top);
125
- const page = Math.max(1, Math.floor(absY / PAGE_H) + 1);
126
- const pageTop = (page - 1) * PAGE_H;
127
- const x = (e.clientX - rect.left) / rect.width;
128
- const y = (absY - pageTop) / PAGE_H;
129
- props.onPlaceSignature({ page, x, y, w: 0.25, h: 0.1 });
130
- }
131
- async function requestThumbnail(index) {
132
- const scroller = scrollerRef.current;
133
- const capture = captureRef.current;
134
- if (!scroller || !capture) {
135
- return void 0;
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
- if (props.fileType === "docx") {
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 response = await fetch("/api/export-docx", {
169
- method: "POST",
170
- headers: { "Content-Type": "application/json" },
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
- if (!response.ok) {
177
- throw new Error("Failed to generate DOCX");
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
- const text = editorRef.current?.innerText ?? "";
198
- const b64 = btoa(unescape(encodeURIComponent(text)));
199
- props.onSave(b64, {
200
- fileName: replaceExt(props.fileName, props.fileType),
201
- fileType: props.fileType,
202
- annotations: { signaturePlacements: props.signaturePlacements }
203
- });
204
- }
205
- (0, import_react.useImperativeHandle)(ref, () => ({ save, requestThumbnail }));
206
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "hv-doc", children: [
207
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "hv-ribbon", role: "toolbar", children: [
208
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
209
- "button",
210
- {
211
- className: "hv-btn",
212
- onClick: () => exec("bold"),
213
- disabled: readOnly,
214
- children: "B"
215
- }
216
- ),
217
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
218
- "button",
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 ? "hv-editor hv-editor--ro" : "hv-editor",
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
- props.headerFooterEnabled && props.footerComponent ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hv-letterhead hv-letterhead--footer", children: props.footerComponent }) : null,
251
- props.mode === "create" && props.signatures.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hv-signatures-inline", children: props.signatures.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "hv-sign-inline", children: [
252
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
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, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
173
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;");
274
174
  }
275
175
 
276
176
  // src/editors/SpreadsheetEditor.tsx
@@ -968,12 +868,12 @@ 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-toolbar__left gap-2", children: [
871
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hv-toolbar__left space-x-1", children: [
972
872
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
973
873
  "button",
974
874
  {
975
875
  type: "button",
976
- className: "hv-btn",
876
+ className: "hv-btn text-sm",
977
877
  onClick: props.onToggleThumbnails,
978
878
  "aria-pressed": props.showThumbnails,
979
879
  children: t("toolbar.thumbs", "Thumbnails")
@@ -983,7 +883,7 @@ function Toolbar(props) {
983
883
  "button",
984
884
  {
985
885
  type: "button",
986
- className: "hv-btn",
886
+ className: "hv-btn text-sm",
987
887
  onClick: props.onToggleSignatures,
988
888
  "aria-pressed": props.showSignatures,
989
889
  children: t("toolbar.signatures", "Signatures")
@@ -994,7 +894,7 @@ function Toolbar(props) {
994
894
  "button",
995
895
  {
996
896
  type: "button",
997
- className: props.layout === "single" ? "hv-btn hv-btn--active" : "hv-btn",
897
+ className: props.layout === "single" ? "hv-btn hv-btn--active text-sm" : "hv-btn text-sm",
998
898
  onClick: () => props.onChangeLayout("single"),
999
899
  children: t("toolbar.layout.single", "Single")
1000
900
  }
@@ -1003,7 +903,7 @@ function Toolbar(props) {
1003
903
  "button",
1004
904
  {
1005
905
  type: "button",
1006
- className: props.layout === "side-by-side" ? "hv-btn hv-btn--active" : "hv-btn",
906
+ className: props.layout === "side-by-side" ? "hv-btn hv-btn--active text-sm" : "hv-btn text-sm",
1007
907
  onClick: () => props.onChangeLayout("side-by-side"),
1008
908
  children: t("toolbar.layout.two", "Two")
1009
909
  }
@@ -1025,18 +925,26 @@ function Toolbar(props) {
1025
925
  "button",
1026
926
  {
1027
927
  type: "button",
1028
- className: "hv-btn hv-btn--primary",
928
+ className: "hv-btn hv-btn--primary text-sm",
1029
929
  onClick: props.onSign,
1030
930
  disabled: props.signingDisabled,
1031
931
  children: t("toolbar.sign", "Sign Document")
1032
932
  }
1033
933
  ),
1034
- props.canExportPdf && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "hv-btn", onClick: props.onExportPdf, children: t("toolbar.exportPdf", "Export as PDF") }),
934
+ props.canExportPdf && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
935
+ "button",
936
+ {
937
+ type: "button",
938
+ className: "hv-btn text-sm",
939
+ onClick: props.onExportPdf,
940
+ children: t("toolbar.exportPdf", "Export as PDF")
941
+ }
942
+ ),
1035
943
  props.canSave && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1036
944
  "button",
1037
945
  {
1038
946
  type: "button",
1039
- className: "hv-btn hv-btn--primary",
947
+ className: "hv-btn hv-btn--primary text-sm",
1040
948
  onClick: props.onSave,
1041
949
  children: t("toolbar.save", "Save")
1042
950
  }
@@ -1052,8 +960,13 @@ var import_jsx_runtime9 = require("react/jsx-runtime");
1052
960
  function DocumentViewer(props) {
1053
961
  const mode = props.mode ?? "view";
1054
962
  const theme = props.theme ?? "light";
1055
- const locale = (0, import_react7.useMemo)(() => ({ ...defaultLocale, ...props.locale ?? {} }), [props.locale]);
1056
- const [layout, setLayout] = (0, import_react7.useState)(props.defaultLayout ?? "single");
963
+ const locale = (0, import_react7.useMemo)(
964
+ () => ({ ...defaultLocale, ...props.locale ?? {} }),
965
+ [props.locale]
966
+ );
967
+ const [layout, setLayout] = (0, import_react7.useState)(
968
+ props.defaultLayout ?? "single"
969
+ );
1057
970
  const [showThumbnails, setShowThumbnails] = (0, import_react7.useState)(true);
1058
971
  const [showSignatures, setShowSignatures] = (0, import_react7.useState)(true);
1059
972
  const [headerFooterEnabled, setHeaderFooterEnabled] = (0, import_react7.useState)(true);
@@ -1064,10 +977,17 @@ function DocumentViewer(props) {
1064
977
  const [pageCount, setPageCount] = (0, import_react7.useState)(1);
1065
978
  const [currentPage, setCurrentPage] = (0, import_react7.useState)(1);
1066
979
  const [thumbs, setThumbs] = (0, import_react7.useState)([]);
1067
- const [localSignatures, setLocalSignatures] = (0, import_react7.useState)(props.signatures ?? []);
1068
- (0, import_react7.useEffect)(() => setLocalSignatures(props.signatures ?? []), [props.signatures]);
980
+ const [localSignatures, setLocalSignatures] = (0, import_react7.useState)(
981
+ props.signatures ?? []
982
+ );
983
+ (0, import_react7.useEffect)(
984
+ () => setLocalSignatures(props.signatures ?? []),
985
+ [props.signatures]
986
+ );
1069
987
  const [sigPlacements, setSigPlacements] = (0, import_react7.useState)([]);
1070
- const [armedSignatureUrl, setArmedSignatureUrl] = (0, import_react7.useState)(null);
988
+ const [armedSignatureUrl, setArmedSignatureUrl] = (0, import_react7.useState)(
989
+ null
990
+ );
1071
991
  const editorRef = (0, import_react7.useRef)(null);
1072
992
  (0, import_react7.useEffect)(() => {
1073
993
  let cancelled = false;
@@ -1081,7 +1001,10 @@ function DocumentViewer(props) {
1081
1001
  setArmedSignatureUrl(null);
1082
1002
  if (mode === "create") {
1083
1003
  const ft = props.fileType ?? "docx";
1084
- setResolved({ fileType: ft, fileName: props.fileName ?? `Untitled.${ft}` });
1004
+ setResolved({
1005
+ fileType: ft,
1006
+ fileName: props.fileName ?? `Untitled.${ft}`
1007
+ });
1085
1008
  return;
1086
1009
  }
1087
1010
  try {
@@ -1095,7 +1018,12 @@ function DocumentViewer(props) {
1095
1018
  if (cancelled) {
1096
1019
  return;
1097
1020
  }
1098
- setResolved({ fileType: res.fileType, fileName: res.fileName, url: res.url, arrayBuffer: res.arrayBuffer });
1021
+ setResolved({
1022
+ fileType: res.fileType,
1023
+ fileName: res.fileName,
1024
+ url: res.url,
1025
+ arrayBuffer: res.arrayBuffer
1026
+ });
1099
1027
  } catch (e) {
1100
1028
  if (cancelled) {
1101
1029
  return;
@@ -1106,7 +1034,14 @@ function DocumentViewer(props) {
1106
1034
  return () => {
1107
1035
  cancelled = true;
1108
1036
  };
1109
- }, [mode, props.fileUrl, props.base64, props.blob, props.fileName, props.fileType]);
1037
+ }, [
1038
+ mode,
1039
+ props.fileUrl,
1040
+ props.base64,
1041
+ props.blob,
1042
+ props.fileName,
1043
+ props.fileType
1044
+ ]);
1110
1045
  const thumbnails = (0, import_react7.useMemo)(() => {
1111
1046
  const n = Math.max(1, pageCount);
1112
1047
  return Array.from({ length: n }, (_, i) => ({
@@ -1132,7 +1067,10 @@ function DocumentViewer(props) {
1132
1067
  if (!armedSignatureUrl) {
1133
1068
  return;
1134
1069
  }
1135
- setSigPlacements((prev) => [...prev, { ...p, signatureImageUrl: armedSignatureUrl }]);
1070
+ setSigPlacements((prev) => [
1071
+ ...prev,
1072
+ { ...p, signatureImageUrl: armedSignatureUrl }
1073
+ ]);
1136
1074
  setArmedSignatureUrl(null);
1137
1075
  }
1138
1076
  async function handleSave(exportPdf) {
@@ -1144,7 +1082,11 @@ function DocumentViewer(props) {
1144
1082
  return;
1145
1083
  }
1146
1084
  const b64 = arrayBufferToBase642(resolved.arrayBuffer);
1147
- props.onSave?.(b64, { fileName: resolved.fileName, fileType: resolved.fileType, annotations: { sigPlacements } });
1085
+ props.onSave?.(b64, {
1086
+ fileName: resolved.fileName,
1087
+ fileType: resolved.fileType,
1088
+ annotations: { sigPlacements }
1089
+ });
1148
1090
  }
1149
1091
  const canSave = mode === "edit" || mode === "create";
1150
1092
  const canExportPdf = (mode === "edit" || mode === "create") && (resolved?.fileType === "docx" || resolved?.fileType === "md" || resolved?.fileType === "txt" || resolved?.fileType === "xlsx");
@@ -1201,10 +1143,16 @@ function DocumentViewer(props) {
1201
1143
  onCurrentPageChange: setCurrentPage,
1202
1144
  onPageCount: (n) => {
1203
1145
  setPageCount(n);
1204
- setThumbs((prev) => prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i]));
1146
+ setThumbs(
1147
+ (prev) => prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i])
1148
+ );
1205
1149
  },
1206
1150
  onThumbs: (t) => setThumbs(t),
1207
- signatureStamp: armedSignatureUrl ? { imageUrl: armedSignatureUrl, armed: true, onPlaced: placeSignature } : void 0
1151
+ signatureStamp: armedSignatureUrl ? {
1152
+ imageUrl: armedSignatureUrl,
1153
+ armed: true,
1154
+ onPlaced: placeSignature
1155
+ } : void 0
1208
1156
  }
1209
1157
  ) : null,
1210
1158
  resolved.fileType === "docx" || resolved.fileType === "md" || resolved.fileType === "txt" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
@@ -1223,7 +1171,9 @@ function DocumentViewer(props) {
1223
1171
  signaturePlacements: sigPlacements,
1224
1172
  onPageCount: (n) => {
1225
1173
  setPageCount(n);
1226
- setThumbs((prev) => prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i]));
1174
+ setThumbs(
1175
+ (prev) => prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i])
1176
+ );
1227
1177
  },
1228
1178
  onSave: (b64, meta) => props.onSave?.(b64, meta),
1229
1179
  armedSignatureUrl,
@@ -1250,12 +1200,21 @@ function DocumentViewer(props) {
1250
1200
  onCurrentPageChange: setCurrentPage,
1251
1201
  onSlideCount: (n) => {
1252
1202
  setPageCount(n);
1253
- setThumbs((prev) => prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i]));
1203
+ setThumbs(
1204
+ (prev) => prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i])
1205
+ );
1254
1206
  },
1255
1207
  onThumbs: (t) => setThumbs(t)
1256
1208
  }
1257
1209
  ) : null,
1258
- resolved.fileType === "png" || resolved.fileType === "jpg" || resolved.fileType === "svg" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ImageRenderer, { arrayBuffer: resolved.arrayBuffer, fileType: resolved.fileType, fileName: resolved.fileName }) : null
1210
+ resolved.fileType === "png" || resolved.fileType === "jpg" || resolved.fileType === "svg" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1211
+ ImageRenderer,
1212
+ {
1213
+ arrayBuffer: resolved.arrayBuffer,
1214
+ fileType: resolved.fileType,
1215
+ fileName: resolved.fileName
1216
+ }
1217
+ ) : null
1259
1218
  ] }),
1260
1219
  mode !== "create" && localSignatures.length ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1261
1220
  SignaturePanel,