@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.js CHANGED
@@ -10,8 +10,7 @@ import {
10
10
  useEffect,
11
11
  useImperativeHandle,
12
12
  useMemo,
13
- useRef,
14
- useState
13
+ useRef
15
14
  } from "react";
16
15
 
17
16
  // src/utils/sanitize.ts
@@ -26,222 +25,122 @@ function sanitizeHtml(html) {
26
25
  // src/editors/RichTextEditor.tsx
27
26
  import { jsx, jsxs } from "react/jsx-runtime";
28
27
  var PAGE_H = 1122;
29
- var RichTextEditor = forwardRef((props, ref) => {
30
- const readOnly = props.mode === "view";
31
- const md = useMemo(
32
- () => new MarkdownIt({ html: false, linkify: true, breaks: true }),
33
- []
34
- );
35
- const scrollerRef = useRef(null);
36
- const editorRef = useRef(null);
37
- const captureRef = useRef(null);
38
- const [html, setHtml] = useState("<p><br/></p>");
39
- useEffect(() => {
40
- let cancelled = false;
41
- (async () => {
42
- if (props.mode === "create") {
43
- setHtml("<p><br/></p>");
44
- return;
45
- }
46
- if (!props.arrayBuffer) {
47
- return;
48
- }
49
- if (props.fileType === "docx") {
50
- const res = await mammoth.convertToHtml({
51
- arrayBuffer: props.arrayBuffer
52
- });
53
- if (!cancelled) {
54
- setHtml(sanitizeHtml(res.value || "<p><br/></p>"));
28
+ var RichTextEditor = forwardRef(
29
+ (props, ref) => {
30
+ const readOnly = props.mode === "view";
31
+ const md = useMemo(
32
+ () => new MarkdownIt({ html: false, linkify: true, breaks: true }),
33
+ []
34
+ );
35
+ const scrollerRef = useRef(null);
36
+ const editorRef = useRef(null);
37
+ const captureRef = useRef(null);
38
+ const initialized = useRef(false);
39
+ useEffect(() => {
40
+ if (initialized.current) return;
41
+ (async () => {
42
+ if (props.mode === "create") {
43
+ editorRef.current.innerHTML = "<p><br/></p>";
44
+ initialized.current = true;
45
+ return;
55
46
  }
56
- } else {
57
- const text = new TextDecoder().decode(props.arrayBuffer);
58
- if (props.fileType === "md") {
59
- setHtml(sanitizeHtml(md.render(text)));
47
+ if (!props.arrayBuffer) return;
48
+ if (props.fileType === "docx") {
49
+ const res = await mammoth.convertToHtml({
50
+ arrayBuffer: props.arrayBuffer
51
+ });
52
+ editorRef.current.innerHTML = sanitizeHtml(
53
+ res.value || "<p><br/></p>"
54
+ );
60
55
  } else {
61
- setHtml(`<pre>${escapeHtml(text)}</pre>`);
56
+ const text = new TextDecoder().decode(props.arrayBuffer);
57
+ editorRef.current.innerHTML = props.fileType === "md" ? sanitizeHtml(md.render(text)) : `<pre>${escapeHtml(text)}</pre>`;
62
58
  }
63
- }
64
- })();
65
- return () => {
66
- cancelled = true;
67
- };
68
- }, [props.arrayBuffer, props.fileType, props.mode, md]);
69
- useEffect(() => {
70
- const el = scrollerRef.current;
71
- if (!el) {
72
- return;
73
- }
74
- const recompute = () => props.onPageCount(Math.max(1, Math.ceil(el.scrollHeight / PAGE_H)));
75
- recompute();
76
- const ro = new ResizeObserver(recompute);
77
- ro.observe(el);
78
- return () => ro.disconnect();
79
- }, [html, props.headerFooterEnabled]);
80
- function exec(cmd) {
81
- if (readOnly) {
82
- return;
83
- }
84
- document.execCommand(cmd);
85
- }
86
- function onClick(e) {
87
- if (!props.armedSignatureUrl) {
88
- return;
89
- }
90
- const scroller = scrollerRef.current;
91
- if (!scroller) {
92
- return;
59
+ initialized.current = true;
60
+ })();
61
+ }, [props.arrayBuffer, props.fileType, props.mode, md]);
62
+ useEffect(() => {
63
+ const el = scrollerRef.current;
64
+ if (!el) return;
65
+ const recompute = () => props.onPageCount(Math.max(1, Math.ceil(el.scrollHeight / PAGE_H)));
66
+ recompute();
67
+ const ro = new ResizeObserver(recompute);
68
+ ro.observe(el);
69
+ return () => ro.disconnect();
70
+ }, [props.headerFooterEnabled]);
71
+ function exec(cmd) {
72
+ if (readOnly) return;
73
+ document.execCommand(cmd);
74
+ editorRef.current?.focus();
93
75
  }
94
- const rect = e.currentTarget.getBoundingClientRect();
95
- const absY = scroller.scrollTop + (e.clientY - rect.top);
96
- const page = Math.max(1, Math.floor(absY / PAGE_H) + 1);
97
- const pageTop = (page - 1) * PAGE_H;
98
- const x = (e.clientX - rect.left) / rect.width;
99
- const y = (absY - pageTop) / PAGE_H;
100
- props.onPlaceSignature({ page, x, y, w: 0.25, h: 0.1 });
101
- }
102
- async function requestThumbnail(index) {
103
- const scroller = scrollerRef.current;
104
- const capture = captureRef.current;
105
- if (!scroller || !capture) {
106
- return void 0;
107
- }
108
- const old = scroller.scrollTop;
109
- scroller.scrollTop = index * PAGE_H;
110
- await new Promise((r) => requestAnimationFrame(() => r(null)));
111
- try {
112
- const canvas = await html2canvas(capture, {
113
- backgroundColor: null,
114
- scale: 0.25,
115
- useCORS: true
116
- });
117
- return canvas.toDataURL("image/png");
118
- } catch {
119
- return void 0;
120
- } finally {
121
- scroller.scrollTop = old;
122
- }
123
- }
124
- async function save(exportPdf) {
125
- const inner = editorRef.current?.innerHTML ?? html;
126
- const stitched = `<!doctype html><html><head><meta charset="utf-8" /></head><body>${inner}</body></html>`;
127
- if (exportPdf) {
128
- const b642 = btoa(unescape(encodeURIComponent(stitched)));
129
- props.onSave(b642, {
130
- fileName: replaceExt(props.fileName, "html"),
131
- fileType: "txt",
132
- exportedAsPdf: true,
133
- annotations: { signaturePlacements: props.signaturePlacements }
76
+ function onClickPage(e) {
77
+ if (!props.armedSignatureUrl) return;
78
+ const scroller = scrollerRef.current;
79
+ if (!scroller) return;
80
+ const rect = e.currentTarget.getBoundingClientRect();
81
+ const absY = scroller.scrollTop + (e.clientY - rect.top);
82
+ const page = Math.floor(absY / PAGE_H) + 1;
83
+ props.onPlaceSignature({
84
+ page,
85
+ x: (e.clientX - rect.left) / rect.width,
86
+ y: absY % PAGE_H / PAGE_H,
87
+ w: 0.25,
88
+ h: 0.1
134
89
  });
135
- return;
136
90
  }
137
- if (props.fileType === "docx") {
91
+ async function requestThumbnail(index) {
92
+ const scroller = scrollerRef.current;
93
+ const capture = captureRef.current;
94
+ if (!scroller || !capture) return;
95
+ const old = scroller.scrollTop;
96
+ scroller.scrollTop = index * PAGE_H;
97
+ await new Promise((r) => requestAnimationFrame(r));
138
98
  try {
139
- const response = await fetch("/api/export-docx", {
140
- method: "POST",
141
- headers: { "Content-Type": "application/json" },
142
- body: JSON.stringify({
143
- html: stitched,
144
- fileName: replaceExt(props.fileName, "docx")
145
- })
99
+ const canvas = await html2canvas(capture, {
100
+ scale: 0.25,
101
+ useCORS: true
146
102
  });
147
- if (!response.ok) {
148
- throw new Error("Failed to generate DOCX");
149
- }
150
- const blob = await response.blob();
151
- const url = window.URL.createObjectURL(blob);
152
- const a = document.createElement("a");
153
- a.href = url;
154
- a.download = replaceExt(props.fileName, "docx");
155
- document.body.appendChild(a);
156
- a.click();
157
- setTimeout(() => {
158
- window.URL.revokeObjectURL(url);
159
- a.remove();
160
- }, 100);
161
- } catch (err) {
162
- alert(
163
- "DOCX export failed: " + (err instanceof Error ? err.message : String(err))
164
- );
103
+ return canvas.toDataURL("image/png");
104
+ } finally {
105
+ scroller.scrollTop = old;
165
106
  }
166
- return;
167
107
  }
168
- const text = editorRef.current?.innerText ?? "";
169
- const b64 = btoa(unescape(encodeURIComponent(text)));
170
- props.onSave(b64, {
171
- fileName: replaceExt(props.fileName, props.fileType),
172
- fileType: props.fileType,
173
- annotations: { signaturePlacements: props.signaturePlacements }
174
- });
175
- }
176
- useImperativeHandle(ref, () => ({ save, requestThumbnail }));
177
- return /* @__PURE__ */ jsxs("div", { className: "hv-doc", children: [
178
- /* @__PURE__ */ jsxs("div", { className: "hv-ribbon", role: "toolbar", children: [
179
- /* @__PURE__ */ jsx(
180
- "button",
181
- {
182
- className: "hv-btn",
183
- onClick: () => exec("bold"),
184
- disabled: readOnly,
185
- children: "B"
186
- }
187
- ),
188
- /* @__PURE__ */ jsx(
189
- "button",
190
- {
191
- className: "hv-btn",
192
- onClick: () => exec("italic"),
193
- disabled: readOnly,
194
- children: "I"
195
- }
196
- ),
197
- /* @__PURE__ */ jsx(
198
- "button",
199
- {
200
- className: "hv-btn",
201
- onClick: () => exec("underline"),
202
- disabled: readOnly,
203
- children: "U"
204
- }
205
- ),
206
- props.armedSignatureUrl ? /* @__PURE__ */ jsx("div", { className: "hv-hint", children: "Click to place signature" }) : null
207
- ] }),
208
- /* @__PURE__ */ jsx("div", { className: "hv-scroll", ref: scrollerRef, onClick, children: /* @__PURE__ */ jsxs("div", { className: "hv-pageStage", ref: captureRef, children: [
209
- props.headerFooterEnabled && props.headerComponent ? /* @__PURE__ */ jsx("div", { className: "hv-letterhead", children: props.headerComponent }) : null,
210
- /* @__PURE__ */ jsx(
108
+ async function save(exportPdf) {
109
+ const html = editorRef.current?.innerHTML ?? "";
110
+ const stitched = `<!doctype html><html><body>${html}</body></html>`;
111
+ const b64 = btoa(unescape(encodeURIComponent(stitched)));
112
+ props.onSave(b64, {
113
+ fileName: props.fileName,
114
+ fileType: props.fileType,
115
+ exportedAsPdf: exportPdf,
116
+ annotations: { signaturePlacements: props.signaturePlacements }
117
+ });
118
+ }
119
+ useImperativeHandle(ref, () => ({
120
+ save,
121
+ requestThumbnail
122
+ }));
123
+ return /* @__PURE__ */ jsxs("div", { className: "hv-root", children: [
124
+ /* @__PURE__ */ jsxs("div", { className: "hv-toolbar", children: [
125
+ /* @__PURE__ */ jsx("button", { onClick: () => exec("bold"), disabled: readOnly, children: "B" }),
126
+ /* @__PURE__ */ jsx("button", { onClick: () => exec("italic"), disabled: readOnly, children: "I" }),
127
+ /* @__PURE__ */ jsx("button", { onClick: () => exec("underline"), disabled: readOnly, children: "U" }),
128
+ props.armedSignatureUrl && /* @__PURE__ */ jsx("span", { className: "hv-hint", children: "Click page to place signature" })
129
+ ] }),
130
+ /* @__PURE__ */ jsx("div", { className: "hv-scroll", ref: scrollerRef, onClick: onClickPage, children: /* @__PURE__ */ jsx("div", { className: "hv-pageStage", ref: captureRef, children: /* @__PURE__ */ jsx(
211
131
  "div",
212
132
  {
213
133
  ref: editorRef,
214
- className: readOnly ? "hv-editor hv-editor--ro" : "hv-editor",
134
+ className: `hv-editor ${readOnly ? "ro" : ""}`,
215
135
  contentEditable: !readOnly,
216
- suppressContentEditableWarning: true,
217
- onInput: () => setHtml(editorRef.current?.innerHTML ?? ""),
218
- dangerouslySetInnerHTML: { __html: html }
136
+ suppressContentEditableWarning: true
219
137
  }
220
- ),
221
- props.headerFooterEnabled && props.footerComponent ? /* @__PURE__ */ jsx("div", { className: "hv-letterhead hv-letterhead--footer", children: props.footerComponent }) : null,
222
- props.mode === "create" && props.signatures.length ? /* @__PURE__ */ jsx("div", { className: "hv-signatures-inline", children: props.signatures.map((s, i) => /* @__PURE__ */ jsxs("div", { className: "hv-sign-inline", children: [
223
- /* @__PURE__ */ jsx(
224
- "img",
225
- {
226
- src: s.signatureImageUrl,
227
- alt: "",
228
- className: "hv-sign-img"
229
- }
230
- ),
231
- /* @__PURE__ */ jsxs("div", { children: [
232
- /* @__PURE__ */ jsx("div", { className: "hv-sign-name", children: s.signedBy }),
233
- /* @__PURE__ */ jsx("div", { className: "hv-sign-date", children: new Date(s.dateSigned).toLocaleString() })
234
- ] })
235
- ] }, i)) }) : null
236
- ] }) })
237
- ] });
238
- });
239
- function replaceExt(name, ext) {
240
- const base = name.includes(".") ? name.slice(0, name.lastIndexOf(".")) : name;
241
- return `${base}.${ext}`;
242
- }
138
+ ) }) })
139
+ ] });
140
+ }
141
+ );
243
142
  function escapeHtml(s) {
244
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
143
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;");
245
144
  }
246
145
 
247
146
  // src/editors/SpreadsheetEditor.tsx
@@ -941,49 +840,46 @@ function Toolbar(props) {
941
840
  role: "toolbar",
942
841
  "aria-label": t("a11y.toolbar", "Document toolbar"),
943
842
  children: [
944
- /* @__PURE__ */ jsxs8("div", { className: "hv-toolbar__left gap-2", children: [
843
+ /* @__PURE__ */ jsxs8("div", { className: "hv-toolbar__group", children: [
945
844
  /* @__PURE__ */ jsx8(
946
845
  "button",
947
846
  {
948
- type: "button",
949
- className: "hv-btn",
847
+ className: `hv-btn ${props.showThumbnails ? "hv-btn--active" : ""}`,
950
848
  onClick: props.onToggleThumbnails,
951
849
  "aria-pressed": props.showThumbnails,
952
- children: t("toolbar.thumbs", "Thumbnails")
850
+ children: "Thumbnails"
953
851
  }
954
852
  ),
955
853
  props.mode !== "create" && /* @__PURE__ */ jsx8(
956
854
  "button",
957
855
  {
958
- type: "button",
959
- className: "hv-btn",
856
+ className: `hv-btn ${props.showSignatures ? "hv-btn--active" : ""}`,
960
857
  onClick: props.onToggleSignatures,
961
858
  "aria-pressed": props.showSignatures,
962
- children: t("toolbar.signatures", "Signatures")
859
+ children: "Signatures"
963
860
  }
964
- ),
965
- /* @__PURE__ */ jsx8("span", { className: "hv-sep" }),
861
+ )
862
+ ] }),
863
+ /* @__PURE__ */ jsxs8("div", { className: "hv-toolbar__group hv-segment", children: [
966
864
  /* @__PURE__ */ jsx8(
967
865
  "button",
968
866
  {
969
- type: "button",
970
- className: props.layout === "single" ? "hv-btn hv-btn--active" : "hv-btn",
867
+ className: `hv-btn ${props.layout === "single" ? "hv-btn--active" : ""}`,
971
868
  onClick: () => props.onChangeLayout("single"),
972
- children: t("toolbar.layout.single", "Single")
869
+ children: "Single page"
973
870
  }
974
871
  ),
975
872
  /* @__PURE__ */ jsx8(
976
873
  "button",
977
874
  {
978
- type: "button",
979
- className: props.layout === "side-by-side" ? "hv-btn hv-btn--active" : "hv-btn",
875
+ className: `hv-btn ${props.layout === "side-by-side" ? "hv-btn--active" : ""}`,
980
876
  onClick: () => props.onChangeLayout("side-by-side"),
981
- children: t("toolbar.layout.two", "Two")
877
+ children: "Side-by-side"
982
878
  }
983
879
  )
984
880
  ] }),
985
- /* @__PURE__ */ jsxs8("div", { className: "hv-toolbar__right", children: [
986
- props.showHeaderFooterToggle && /* @__PURE__ */ jsxs8("label", { className: "hv-toggle", children: [
881
+ /* @__PURE__ */ jsxs8("div", { className: "hv-toolbar__group hv-toolbar__actions", children: [
882
+ props.showHeaderFooterToggle && /* @__PURE__ */ jsxs8("label", { className: "hv-switch", children: [
987
883
  /* @__PURE__ */ jsx8(
988
884
  "input",
989
885
  {
@@ -992,28 +888,20 @@ function Toolbar(props) {
992
888
  onChange: props.onToggleHeaderFooter
993
889
  }
994
890
  ),
995
- /* @__PURE__ */ jsx8("span", { children: t("toolbar.letterhead", "Letterhead") })
891
+ /* @__PURE__ */ jsx8("span", { className: "hv-switch__slider" }),
892
+ /* @__PURE__ */ jsx8("span", { className: "hv-switch__label", children: t("toolbar.letterhead", "Letterhead") })
996
893
  ] }),
997
894
  props.allowSigning && /* @__PURE__ */ jsx8(
998
895
  "button",
999
896
  {
1000
- type: "button",
1001
897
  className: "hv-btn hv-btn--primary",
1002
898
  onClick: props.onSign,
1003
899
  disabled: props.signingDisabled,
1004
- children: t("toolbar.sign", "Sign Document")
900
+ children: "Sign document"
1005
901
  }
1006
902
  ),
1007
- props.canExportPdf && /* @__PURE__ */ jsx8("button", { type: "button", className: "hv-btn", onClick: props.onExportPdf, children: t("toolbar.exportPdf", "Export as PDF") }),
1008
- props.canSave && /* @__PURE__ */ jsx8(
1009
- "button",
1010
- {
1011
- type: "button",
1012
- className: "hv-btn hv-btn--primary",
1013
- onClick: props.onSave,
1014
- children: t("toolbar.save", "Save")
1015
- }
1016
- )
903
+ props.canExportPdf && /* @__PURE__ */ jsx8("button", { className: "hv-btn", onClick: props.onExportPdf, children: "Export PDF" }),
904
+ props.canSave && /* @__PURE__ */ jsx8("button", { className: "hv-btn hv-btn--primary", onClick: props.onSave, children: "Save" })
1017
905
  ] })
1018
906
  ]
1019
907
  }
@@ -1025,8 +913,13 @@ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1025
913
  function DocumentViewer(props) {
1026
914
  const mode = props.mode ?? "view";
1027
915
  const theme = props.theme ?? "light";
1028
- const locale = useMemo6(() => ({ ...defaultLocale, ...props.locale ?? {} }), [props.locale]);
1029
- const [layout, setLayout] = useState6(props.defaultLayout ?? "single");
916
+ const locale = useMemo6(
917
+ () => ({ ...defaultLocale, ...props.locale ?? {} }),
918
+ [props.locale]
919
+ );
920
+ const [layout, setLayout] = useState6(
921
+ props.defaultLayout ?? "single"
922
+ );
1030
923
  const [showThumbnails, setShowThumbnails] = useState6(true);
1031
924
  const [showSignatures, setShowSignatures] = useState6(true);
1032
925
  const [headerFooterEnabled, setHeaderFooterEnabled] = useState6(true);
@@ -1037,10 +930,17 @@ function DocumentViewer(props) {
1037
930
  const [pageCount, setPageCount] = useState6(1);
1038
931
  const [currentPage, setCurrentPage] = useState6(1);
1039
932
  const [thumbs, setThumbs] = useState6([]);
1040
- const [localSignatures, setLocalSignatures] = useState6(props.signatures ?? []);
1041
- useEffect6(() => setLocalSignatures(props.signatures ?? []), [props.signatures]);
933
+ const [localSignatures, setLocalSignatures] = useState6(
934
+ props.signatures ?? []
935
+ );
936
+ useEffect6(
937
+ () => setLocalSignatures(props.signatures ?? []),
938
+ [props.signatures]
939
+ );
1042
940
  const [sigPlacements, setSigPlacements] = useState6([]);
1043
- const [armedSignatureUrl, setArmedSignatureUrl] = useState6(null);
941
+ const [armedSignatureUrl, setArmedSignatureUrl] = useState6(
942
+ null
943
+ );
1044
944
  const editorRef = useRef3(null);
1045
945
  useEffect6(() => {
1046
946
  let cancelled = false;
@@ -1054,7 +954,10 @@ function DocumentViewer(props) {
1054
954
  setArmedSignatureUrl(null);
1055
955
  if (mode === "create") {
1056
956
  const ft = props.fileType ?? "docx";
1057
- setResolved({ fileType: ft, fileName: props.fileName ?? `Untitled.${ft}` });
957
+ setResolved({
958
+ fileType: ft,
959
+ fileName: props.fileName ?? `Untitled.${ft}`
960
+ });
1058
961
  return;
1059
962
  }
1060
963
  try {
@@ -1068,7 +971,12 @@ function DocumentViewer(props) {
1068
971
  if (cancelled) {
1069
972
  return;
1070
973
  }
1071
- setResolved({ fileType: res.fileType, fileName: res.fileName, url: res.url, arrayBuffer: res.arrayBuffer });
974
+ setResolved({
975
+ fileType: res.fileType,
976
+ fileName: res.fileName,
977
+ url: res.url,
978
+ arrayBuffer: res.arrayBuffer
979
+ });
1072
980
  } catch (e) {
1073
981
  if (cancelled) {
1074
982
  return;
@@ -1079,7 +987,14 @@ function DocumentViewer(props) {
1079
987
  return () => {
1080
988
  cancelled = true;
1081
989
  };
1082
- }, [mode, props.fileUrl, props.base64, props.blob, props.fileName, props.fileType]);
990
+ }, [
991
+ mode,
992
+ props.fileUrl,
993
+ props.base64,
994
+ props.blob,
995
+ props.fileName,
996
+ props.fileType
997
+ ]);
1083
998
  const thumbnails = useMemo6(() => {
1084
999
  const n = Math.max(1, pageCount);
1085
1000
  return Array.from({ length: n }, (_, i) => ({
@@ -1105,7 +1020,10 @@ function DocumentViewer(props) {
1105
1020
  if (!armedSignatureUrl) {
1106
1021
  return;
1107
1022
  }
1108
- setSigPlacements((prev) => [...prev, { ...p, signatureImageUrl: armedSignatureUrl }]);
1023
+ setSigPlacements((prev) => [
1024
+ ...prev,
1025
+ { ...p, signatureImageUrl: armedSignatureUrl }
1026
+ ]);
1109
1027
  setArmedSignatureUrl(null);
1110
1028
  }
1111
1029
  async function handleSave(exportPdf) {
@@ -1117,7 +1035,11 @@ function DocumentViewer(props) {
1117
1035
  return;
1118
1036
  }
1119
1037
  const b64 = arrayBufferToBase642(resolved.arrayBuffer);
1120
- props.onSave?.(b64, { fileName: resolved.fileName, fileType: resolved.fileType, annotations: { sigPlacements } });
1038
+ props.onSave?.(b64, {
1039
+ fileName: resolved.fileName,
1040
+ fileType: resolved.fileType,
1041
+ annotations: { sigPlacements }
1042
+ });
1121
1043
  }
1122
1044
  const canSave = mode === "edit" || mode === "create";
1123
1045
  const canExportPdf = (mode === "edit" || mode === "create") && (resolved?.fileType === "docx" || resolved?.fileType === "md" || resolved?.fileType === "txt" || resolved?.fileType === "xlsx");
@@ -1174,10 +1096,16 @@ function DocumentViewer(props) {
1174
1096
  onCurrentPageChange: setCurrentPage,
1175
1097
  onPageCount: (n) => {
1176
1098
  setPageCount(n);
1177
- setThumbs((prev) => prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i]));
1099
+ setThumbs(
1100
+ (prev) => prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i])
1101
+ );
1178
1102
  },
1179
1103
  onThumbs: (t) => setThumbs(t),
1180
- signatureStamp: armedSignatureUrl ? { imageUrl: armedSignatureUrl, armed: true, onPlaced: placeSignature } : void 0
1104
+ signatureStamp: armedSignatureUrl ? {
1105
+ imageUrl: armedSignatureUrl,
1106
+ armed: true,
1107
+ onPlaced: placeSignature
1108
+ } : void 0
1181
1109
  }
1182
1110
  ) : null,
1183
1111
  resolved.fileType === "docx" || resolved.fileType === "md" || resolved.fileType === "txt" ? /* @__PURE__ */ jsx9(
@@ -1196,7 +1124,9 @@ function DocumentViewer(props) {
1196
1124
  signaturePlacements: sigPlacements,
1197
1125
  onPageCount: (n) => {
1198
1126
  setPageCount(n);
1199
- setThumbs((prev) => prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i]));
1127
+ setThumbs(
1128
+ (prev) => prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i])
1129
+ );
1200
1130
  },
1201
1131
  onSave: (b64, meta) => props.onSave?.(b64, meta),
1202
1132
  armedSignatureUrl,
@@ -1223,12 +1153,21 @@ function DocumentViewer(props) {
1223
1153
  onCurrentPageChange: setCurrentPage,
1224
1154
  onSlideCount: (n) => {
1225
1155
  setPageCount(n);
1226
- setThumbs((prev) => prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i]));
1156
+ setThumbs(
1157
+ (prev) => prev.length === n ? prev : Array.from({ length: n }, (_, i) => prev[i])
1158
+ );
1227
1159
  },
1228
1160
  onThumbs: (t) => setThumbs(t)
1229
1161
  }
1230
1162
  ) : null,
1231
- resolved.fileType === "png" || resolved.fileType === "jpg" || resolved.fileType === "svg" ? /* @__PURE__ */ jsx9(ImageRenderer, { arrayBuffer: resolved.arrayBuffer, fileType: resolved.fileType, fileName: resolved.fileName }) : null
1163
+ resolved.fileType === "png" || resolved.fileType === "jpg" || resolved.fileType === "svg" ? /* @__PURE__ */ jsx9(
1164
+ ImageRenderer,
1165
+ {
1166
+ arrayBuffer: resolved.arrayBuffer,
1167
+ fileType: resolved.fileType,
1168
+ fileName: resolved.fileName
1169
+ }
1170
+ ) : null
1232
1171
  ] }),
1233
1172
  mode !== "create" && localSignatures.length ? /* @__PURE__ */ jsx9(
1234
1173
  SignaturePanel,