@w100n/documents 0.15.1 → 0.16.0

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.
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-QDH7EZAF.js";
5
5
  import {
6
6
  useLive
7
- } from "./chunk-XR42B3F5.js";
7
+ } from "./chunk-3OLRFIHQ.js";
8
8
  import {
9
9
  a4,
10
10
  align,
@@ -13,7 +13,6 @@ import {
13
13
  clear,
14
14
  decide,
15
15
  entries,
16
- fromMarkdown,
17
16
  indent,
18
17
  kit,
19
18
  letter,
@@ -23,19 +22,23 @@ import {
23
22
  replace,
24
23
  searching,
25
24
  spacing,
26
- suggesting,
25
+ suggesting
26
+ } from "./chunk-2L3TK7UF.js";
27
+ import {
28
+ fromMarkdown,
27
29
  toMarkdown,
28
30
  track
29
- } from "./chunk-BGH36LAR.js";
31
+ } from "./chunk-EQLBYW42.js";
30
32
  import {
31
33
  rove,
32
34
  useRestore
33
35
  } from "./chunk-TDP6OJET.js";
36
+ import "./chunk-RKV3N6OS.js";
34
37
  import {
35
38
  mathml,
36
39
  readDocx,
37
40
  writeDocx
38
- } from "./chunk-CAPICJ6B.js";
41
+ } from "./chunk-ZAVXCH7V.js";
39
42
  import "./chunk-ISOOUYLI.js";
40
43
 
41
44
  // src/editor/TextEditor.tsx
@@ -234,12 +237,17 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
234
237
  const scroller = useRef2(null);
235
238
  const root = useRef2(null);
236
239
  const [pop, setPop] = useState2(null);
240
+ const [spot, setSpot] = useState2({ x: 0, y: 0 });
241
+ const touch = useRef2(false);
242
+ const [spell, setSpell] = useState2(() => typeof localStorage === "undefined" || localStorage.getItem("w100n-docs-spell") !== "0");
237
243
  const [dialog, setDialog] = useState2(null);
238
244
  const field = useRef2(null);
239
245
  const [more, setMore] = useState2(() => typeof localStorage !== "undefined" && localStorage.getItem("w100n-docs-more") === "1");
240
246
  const [zoom, setZoom] = useState2(null);
241
247
  const [layout, setLayout] = useState2(null);
242
248
  const [room, setRoom] = useState2(0);
249
+ const [printed, setPrinted] = useState2(null);
250
+ const flow = docx && !(printed ?? !(room > 0 && room < 640));
243
251
  const [saving, setSaving] = useState2("idle");
244
252
  const [href, setHref] = useState2("");
245
253
  const [grid, setGrid] = useState2({ rows: 0, cols: 0 });
@@ -270,7 +278,7 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
270
278
  editable: can.edit && (!live || !!shared),
271
279
  immediatelyRender: true,
272
280
  shouldRerenderOnTransaction: false,
273
- editorProps: { attributes: { class: "w100n-docs-prose w100n-text-body", "aria-label": t.documentText }, transformPastedHTML: cleanPaste },
281
+ editorProps: { attributes: { class: "w100n-docs-prose w100n-text-body", "aria-label": t.documentText, spellcheck: String(spell), lang: language }, transformPastedHTML: cleanPaste },
274
282
  onCreate: ({ editor: made }) => {
275
283
  if (source.data && !live) baseline.current = { bytes, doc: made.state.doc, base: source.data.md && track(source.data.md, made.state.doc) };
276
284
  }
@@ -346,8 +354,8 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
346
354
  };
347
355
  const marginal = marg ?? (source.data && "marginal" in source.data ? source.data.marginal : null) ?? { header: "", footer: "", numbers: false };
348
356
  useEffect(() => {
349
- if (editor && docx && source.data) editor.view.dispatch(editor.state.tr.setMeta(paging, { page, marks: { header: marginal.header, footer: marginal.footer } }));
350
- }, [editor, source.data, page, marginal.header, marginal.footer]);
357
+ if (editor && docx && source.data) editor.view.dispatch(editor.state.tr.setMeta(paging, { page, marks: { header: marginal.header, footer: marginal.footer }, flow }));
358
+ }, [editor, source.data, page, marginal.header, marginal.footer, flow]);
351
359
  useEffect(() => {
352
360
  if (!shared || !docx) return;
353
361
  const map = shared.doc.getMap("setup");
@@ -461,6 +469,18 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
461
469
  watch.observe(el);
462
470
  return () => watch.disconnect();
463
471
  }, [editor, source.data]);
472
+ useEffect(() => {
473
+ const view = window.visualViewport;
474
+ const el = root.current;
475
+ if (!view || !el) return;
476
+ const lift = () => el.style.setProperty("--kb", `${Math.max(0, innerHeight - view.height - view.offsetTop)}px`);
477
+ view.addEventListener("resize", lift);
478
+ view.addEventListener("scroll", lift);
479
+ return () => {
480
+ view.removeEventListener("resize", lift);
481
+ view.removeEventListener("scroll", lift);
482
+ };
483
+ }, [editor, source.data]);
464
484
  useEffect(() => {
465
485
  const el = root.current;
466
486
  if (!el) return;
@@ -490,8 +510,17 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
490
510
  const close = (e) => {
491
511
  if (!e.target.closest(".w100n-text-pop, [data-pop]")) setPop(null);
492
512
  };
513
+ const off = (e) => {
514
+ if (pop === "context" && (e.type === "scroll" || e.key === "Escape")) setPop(null);
515
+ };
493
516
  document.addEventListener("pointerdown", close);
494
- return () => document.removeEventListener("pointerdown", close);
517
+ window.addEventListener("keydown", off);
518
+ window.addEventListener("scroll", off, true);
519
+ return () => {
520
+ document.removeEventListener("pointerdown", close);
521
+ window.removeEventListener("keydown", off);
522
+ window.removeEventListener("scroll", off, true);
523
+ };
495
524
  }, [pop]);
496
525
  if (source.error) return docx ? /* @__PURE__ */ jsx2("div", { className: "w100n-docs-scroll", children: /* @__PURE__ */ jsx2(DocxView, { bytes, onOutline, failed: t.failed }) }) : /* @__PURE__ */ jsx2("div", { className: "w100n-docs-empty", children: t.failed });
497
526
  if (!source.data || !editor || !state || live && !live.ready && !live.late && !live.denied) return /* @__PURE__ */ jsx2("div", { className: "w100n-docs-empty", children: t.loading });
@@ -624,9 +653,9 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
624
653
  const drops = (c) => mine(c) || c.author.id.startsWith("guest:") && !!rights?.edit;
625
654
  const show = (c) => {
626
655
  setActive(c.id);
627
- const spot = notes.getState(editor.state).spots.find((s) => s.id === c.id);
628
- if (!spot) return;
629
- const at = editor.view.domAtPos(spot.from).node;
656
+ const spot2 = notes.getState(editor.state).spots.find((s) => s.id === c.id);
657
+ if (!spot2) return;
658
+ const at = editor.view.domAtPos(spot2.from).node;
630
659
  (at instanceof HTMLElement ? at : at.parentElement)?.scrollIntoView({ behavior: "smooth", block: "center" });
631
660
  };
632
661
  const suggested = [...state.revs.reduce((all2, c) => {
@@ -639,7 +668,7 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
639
668
  const dom = editor.view.domAtPos(at).node;
640
669
  (dom instanceof HTMLElement ? dom : dom.parentElement)?.scrollIntoView({ behavior: "smooth", block: "center" });
641
670
  };
642
- const percent = zoom ?? (docx && room ? Math.max(10, Math.min(100, Math.floor((room - 24) / page.width * 100))) : 100);
671
+ const percent = zoom ?? (docx && room && !flow ? Math.max(10, Math.min(100, Math.floor((room - 24) / page.width * 100))) : 100);
643
672
  const zoomBy = (d) => setZoom(Math.min(200, Math.max(30, percent + d)));
644
673
  const keys = (e) => {
645
674
  if (e.defaultPrevented) return;
@@ -665,7 +694,7 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
665
694
  else if (key === "]" || key === "[") act(() => indent(editor, key === "]" ? 1 : -1));
666
695
  else if (key === "\\") act(() => clear(editor));
667
696
  else if (key === "enter" && docx) act(() => editor.chain().focus().insertContent({ type: "pageBreak" }).run());
668
- else if (e.shiftKey && docx && ["l", "e", "r", "j"].includes(key)) act(() => align(editor, { l: "left", e: "center", r: "right", j: "justify" }[key]));
697
+ else if (e.shiftKey && ["l", "e", "r", "j"].includes(key)) act(() => align(editor, { l: "left", e: "center", r: "right", j: "justify" }[key]));
669
698
  };
670
699
  const tool = (icon, label, run, pressed, disabled) => {
671
700
  const Icon = icon;
@@ -783,9 +812,13 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
783
812
  item(t.clearFormat, () => clear(editor), { keys: `${mod}\\` })
784
813
  ] : []],
785
814
  ["view", t.viewTab, [
815
+ docx && item(t.printLayout, () => {
816
+ setPrinted(flow);
817
+ setZoom(null);
818
+ }, { on: !flow }),
786
819
  item(t.zoomIn, () => zoomBy(10)),
787
820
  item(t.zoomOut, () => zoomBy(-10)),
788
- docx && item(t.fitWidth, () => setZoom(null), { on: zoom === null }),
821
+ docx && !flow && item(t.fitWidth, () => setZoom(null), { on: zoom === null }),
789
822
  item(t.fit, () => setZoom(100)),
790
823
  "-",
791
824
  item(t.outline, () => onPanel?.("outline")),
@@ -807,8 +840,8 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
807
840
  can.comment && item(t.addComment, begin, { off: state.empty, keys: `${mod}\u2325M` }),
808
841
  "-",
809
842
  item(t.symbols, () => setDialog({ kind: "symbol", query: "" })),
810
- docx && item(t.formula, () => setDialog({ kind: "formula", latex: "", at: null })),
811
- docx && item(t.footnote, () => setDialog({ kind: "note", text: "", at: null }))
843
+ item(t.formula, () => setDialog({ kind: "formula", latex: "", at: null })),
844
+ item(t.footnote, () => setDialog({ kind: "note", text: "", at: null }))
812
845
  ] : []],
813
846
  ["format", t.menuFormat, can.edit ? [
814
847
  ...styles.map(([key, label, run]) => item(label, run, { on: state.style === key })),
@@ -819,12 +852,9 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
819
852
  item(t.strike, () => editor.chain().focus().toggleStrike().run(), { on: state.strike }),
820
853
  docx && item(t.superscript, () => editor.chain().focus().toggleMark("superscript").run(), { on: state.sup, keys: `${mod}.` }),
821
854
  docx && item(t.subscript, () => editor.chain().focus().toggleMark("subscript").run(), { on: state.sub, keys: `${mod},` }),
822
- ...docx ? [
823
- "-",
824
- ...aligns.map(([, label, value]) => item(label, () => align(editor, value), { on: state.align === value })),
825
- "-",
826
- ...lines.map(([v, label]) => item(`${t.lineSpacing}: ${label}`, () => spacing(editor, { line: v }), { on: state.line === v }))
827
- ] : [],
855
+ "-",
856
+ ...aligns.map(([, label, value]) => item(label, () => align(editor, value), { on: state.align === value })),
857
+ ...docx ? ["-", ...lines.map(([v, label]) => item(`${t.lineSpacing}: ${label}`, () => spacing(editor, { line: v }), { on: state.line === v }))] : [],
828
858
  "-",
829
859
  item(t.bullets, () => editor.chain().focus().toggleBulletList().run(), { on: state.bullets }),
830
860
  item(t.numbers, () => editor.chain().focus().toggleOrderedList().run(), { on: state.numbers }),
@@ -837,19 +867,55 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
837
867
  docx && can.edit && item(t.suggest, suggest, { on: state.suggest }),
838
868
  docx && can.edit && state.revs.length > 0 && item(t.acceptAll, () => decide(editor, true)),
839
869
  docx && can.edit && state.revs.length > 0 && item(t.rejectAll, () => decide(editor, false)),
840
- !!host?.comments && (can.comment || open.length > 0) && item(t.comments, () => onPanel?.("comments"))
870
+ !!host?.comments && (can.comment || open.length > 0) && item(t.comments, () => onPanel?.("comments")),
871
+ can.edit && item(t.spellCheck, () => {
872
+ editor.view.dom.spellcheck = !spell;
873
+ localStorage.setItem("w100n-docs-spell", spell ? "0" : "1");
874
+ setSpell(!spell);
875
+ }, { on: spell })
841
876
  ]]
842
877
  ];
878
+ const clip = (kind2) => {
879
+ editor.view.focus();
880
+ document.execCommand(kind2);
881
+ };
882
+ const paste = async () => {
883
+ const found2 = await navigator.clipboard.read().catch(() => []);
884
+ const html = found2.find((c) => c.types.includes("text/html"));
885
+ if (html) return editor.view.pasteHTML(await (await html.getType("text/html")).text());
886
+ const plain = found2.find((c) => c.types.includes("text/plain"));
887
+ if (plain) editor.view.pasteText(await (await plain.getType("text/plain")).text());
888
+ };
889
+ const table = editor.isActive("table");
890
+ const near = [
891
+ can.edit && item(t.cut, () => clip("cut"), { off: state.empty, keys: `${mod}X` }),
892
+ item(t.copy, () => clip("copy"), { off: state.empty, keys: `${mod}C` }),
893
+ can.edit && !!navigator.clipboard?.read && item(t.paste, () => void paste(), { keys: `${mod}V` }),
894
+ "-",
895
+ can.comment && item(t.addComment, begin, { off: state.empty, keys: `${mod}\u2325M` }),
896
+ can.edit && item(t.link, linkUp, { keys: `${mod}K` }),
897
+ can.edit && item(t.clearFormat, () => clear(editor), { keys: `${mod}\\` }),
898
+ ...can.edit && table ? [
899
+ "-",
900
+ item(t.rowAbove, () => editor.chain().focus().addRowBefore().run()),
901
+ item(t.rowBelow, () => editor.chain().focus().addRowAfter().run()),
902
+ item(t.columnLeft, () => editor.chain().focus().addColumnBefore().run()),
903
+ item(t.columnRight, () => editor.chain().focus().addColumnAfter().run()),
904
+ item(t.deleteRow, () => editor.chain().focus().deleteRow().run()),
905
+ item(t.deleteColumn, () => editor.chain().focus().deleteColumn().run())
906
+ ] : []
907
+ ];
908
+ const rows = (list) => list.filter((x) => x !== false).filter((x, i, all2) => x !== "-" || i > 0 && all2[i - 1] !== "-" && i < all2.length - 1).map((x, i) => x === "-" ? /* @__PURE__ */ jsx2("hr", {}, i) : /* @__PURE__ */ jsxs2("button", { type: "button", role: x.on === void 0 ? "menuitem" : "menuitemcheckbox", "aria-checked": x.on, disabled: x.off, onClick: () => {
909
+ setPop(null);
910
+ x.run();
911
+ }, children: [
912
+ /* @__PURE__ */ jsx2(Check, { "aria-hidden": true }),
913
+ /* @__PURE__ */ jsx2("span", { children: x.label }),
914
+ x.keys && /* @__PURE__ */ jsx2("kbd", { children: x.keys })
915
+ ] }, i));
843
916
  const menu = ([key, label, list]) => /* @__PURE__ */ jsxs2("span", { className: "w100n-text-anchor", children: [
844
917
  /* @__PURE__ */ jsx2("button", { type: "button", className: "w100n-text-menu-button", "data-pop": true, "aria-haspopup": "menu", "aria-expanded": pop === key, onClick: () => pick(key), children: label }),
845
- pop === key && /* @__PURE__ */ jsx2("span", { className: "w100n-text-pop w100n-text-menu", role: "menu", "aria-label": label, children: list.filter((x) => x !== false).map((x, i) => x === "-" ? /* @__PURE__ */ jsx2("hr", {}, i) : /* @__PURE__ */ jsxs2("button", { type: "button", role: x.on === void 0 ? "menuitem" : "menuitemcheckbox", "aria-checked": x.on, disabled: x.off, onClick: () => {
846
- setPop(null);
847
- x.run();
848
- }, children: [
849
- /* @__PURE__ */ jsx2(Check, { "aria-hidden": true }),
850
- /* @__PURE__ */ jsx2("span", { children: x.label }),
851
- x.keys && /* @__PURE__ */ jsx2("kbd", { children: x.keys })
852
- ] }, i)) })
918
+ pop === key && /* @__PURE__ */ jsx2("span", { className: "w100n-text-pop w100n-text-menu", role: "menu", "aria-label": label, children: rows(list) })
853
919
  ] }, key);
854
920
  const seek = (next) => {
855
921
  editor.view.dispatch(editor.state.tr.setMeta(searching, next));
@@ -1056,7 +1122,7 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
1056
1122
  pop === "color" && swatches(inks, state.color, (c) => c ? editor.chain().focus().setColor(c).run() : editor.chain().focus().unsetColor().run(), t.automatic)
1057
1123
  ] }),
1058
1124
  gap,
1059
- docx && aligner,
1125
+ aligner,
1060
1126
  tool(List, t.bullets, () => editor.chain().focus().toggleBulletList().run(), state.bullets),
1061
1127
  tool(ListOrdered, t.numbers, () => editor.chain().focus().toggleOrderedList().run(), state.numbers),
1062
1128
  !docx && tool(ListChecks, t.tasks, () => editor.chain().focus().toggleTaskList().run(), state.tasks),
@@ -1133,17 +1199,17 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
1133
1199
  /* @__PURE__ */ jsx2("button", { type: "button", "data-pop": true, "aria-expanded": pop === "table", "aria-label": t.table, title: t.table, onClick: () => pick("table"), children: /* @__PURE__ */ jsx2(Table, { "aria-hidden": true }) }),
1134
1200
  pop === "table" && /* @__PURE__ */ jsxs2("span", { className: "w100n-text-pop w100n-text-grid", role: "group", "aria-label": t.table, onPointerLeave: () => setGrid({ rows: 0, cols: 0 }), children: [
1135
1201
  /* @__PURE__ */ jsx2("span", { children: Array.from({ length: 48 }, (_, i) => {
1136
- const rows = Math.floor(i / 8) + 1;
1202
+ const rows2 = Math.floor(i / 8) + 1;
1137
1203
  const cols = i % 8 + 1;
1138
1204
  return /* @__PURE__ */ jsx2(
1139
1205
  "button",
1140
1206
  {
1141
1207
  type: "button",
1142
- "aria-label": `${rows} \xD7 ${cols}`,
1143
- "data-on": rows <= grid.rows && cols <= grid.cols,
1144
- onPointerEnter: () => setGrid({ rows, cols }),
1208
+ "aria-label": `${rows2} \xD7 ${cols}`,
1209
+ "data-on": rows2 <= grid.rows && cols <= grid.cols,
1210
+ onPointerEnter: () => setGrid({ rows: rows2, cols }),
1145
1211
  onClick: () => {
1146
- editor.chain().focus().insertTable({ rows, cols, withHeaderRow: true }).run();
1212
+ editor.chain().focus().insertTable({ rows: rows2, cols, withHeaderRow: true }).run();
1147
1213
  setPop(null);
1148
1214
  }
1149
1215
  },
@@ -1245,7 +1311,17 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
1245
1311
  menubar,
1246
1312
  status
1247
1313
  ] }),
1248
- /* @__PURE__ */ jsx2("div", { ref: scroller, className: "w100n-text-scroll", "data-paint": !!paint, onMouseUp: lay, onClick: (e) => {
1314
+ /* @__PURE__ */ jsx2("div", { ref: scroller, className: "w100n-text-scroll", "data-paint": !!paint, onMouseUp: lay, onPointerDown: (e) => {
1315
+ touch.current = e.pointerType === "touch";
1316
+ }, onContextMenu: (e) => {
1317
+ if (touch.current || e.shiftKey || pop === "context" || !e.target.closest(".ProseMirror")) return setPop(null);
1318
+ e.preventDefault();
1319
+ const at = editor.view.posAtCoords({ left: e.clientX, top: e.clientY });
1320
+ const { from, to } = editor.state.selection;
1321
+ if (at && (at.pos < from || at.pos > to)) editor.commands.setTextSelection(at.pos);
1322
+ setSpot({ x: Math.min(e.clientX, innerWidth - 260), y: Math.min(e.clientY, innerHeight - 360) });
1323
+ setPop("context");
1324
+ }, onClick: (e) => {
1249
1325
  const atom = can.edit ? e.target.closest(".w100n-math, sup[data-footnote]") : null;
1250
1326
  if (atom) {
1251
1327
  const at = editor.view.posAtDOM(atom, 0);
@@ -1258,7 +1334,11 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
1258
1334
  if (!id) return;
1259
1335
  setActive(id);
1260
1336
  onPanel?.("comments");
1261
- }, children: /* @__PURE__ */ jsx2("div", { className: "w100n-text-zoomed", style: { zoom: percent / 100 }, children: /* @__PURE__ */ jsx2("div", { className: docx ? "w100n-text-sheet" : "w100n-docs-page w100n-text-column", style: sheet, children: /* @__PURE__ */ jsx2(EditorContent, { editor }) }) }) }),
1337
+ }, children: /* @__PURE__ */ jsx2("div", { className: "w100n-text-zoomed", style: { zoom: percent / 100 }, children: /* @__PURE__ */ jsx2("div", { className: docx ? `w100n-text-sheet${flow ? " is-flow" : ""}` : "w100n-docs-page w100n-text-column", style: sheet, children: /* @__PURE__ */ jsx2(EditorContent, { editor }) }) }) }),
1338
+ pop === "context" && /* @__PURE__ */ jsxs2("span", { className: "w100n-text-pop w100n-text-menu w100n-text-context", role: "menu", "aria-label": t.textTools, style: { left: spot.x, top: spot.y }, onPointerDown: keep, children: [
1339
+ rows(near),
1340
+ spell && /* @__PURE__ */ jsx2("small", { className: "w100n-text-hint", children: t.spellHint })
1341
+ ] }),
1262
1342
  /* @__PURE__ */ jsx2("div", { className: "w100n-text-ribbon w100n-text-corner", "data-side": "left", onPointerDown: keep, children: /* @__PURE__ */ jsxs2("div", { className: "w100n-text-tools", role: "group", "aria-label": t.zoom, children: [
1263
1343
  tool(Minus, t.zoomOut, () => zoomBy(-10)),
1264
1344
  zoomer,
@@ -1310,7 +1390,6 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
1310
1390
  /* @__PURE__ */ jsxs2("div", { className: "w100n-new-head", children: [
1311
1391
  /* @__PURE__ */ jsx2("span", { className: "w100n-new-tile", "data-tone": "blue", children: /* @__PURE__ */ jsx2(Sigma, { "aria-hidden": true }) }),
1312
1392
  /* @__PURE__ */ jsx2("b", { className: "w100n-pdf-dialog-title", children: t.formula }),
1313
- /* @__PURE__ */ jsx2("span", { className: "w100n-docs-badge", children: t.formulaHint }),
1314
1393
  /* @__PURE__ */ jsx2("button", { type: "button", className: "w100n-docs-close", onClick: () => setDialog(null), "aria-label": t.close, title: t.close, children: /* @__PURE__ */ jsx2(X, { "aria-hidden": true }) })
1315
1394
  ] }),
1316
1395
  /* @__PURE__ */ jsx2("input", { ref: field, autoFocus: true, className: "w100n-insert-latex", value: dialog.latex, "aria-label": t.formula, placeholder: "F = 900 + 12 \\\\cdot n", onChange: (e) => setDialog({ ...dialog, latex: e.target.value }) }),
@@ -1341,7 +1420,13 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
1341
1420
  tr.setNodeAttribute(dialog.at, "text", text);
1342
1421
  return true;
1343
1422
  }).run();
1344
- else editor.chain().focus().insertContent({ type: "footnote", attrs: { id: null, text } }).run();
1423
+ else {
1424
+ let id = 0;
1425
+ editor.state.doc.descendants((n) => {
1426
+ if (n.type.name === "footnote") id = Math.max(id, Number(n.attrs.id) || 0);
1427
+ });
1428
+ editor.chain().focus().insertContent({ type: "footnote", attrs: { id: docx ? null : String(id + 1), text } }).run();
1429
+ }
1345
1430
  setDialog(null);
1346
1431
  }, children: [
1347
1432
  /* @__PURE__ */ jsxs2("div", { className: "w100n-new-head", children: [
@@ -1559,4 +1644,4 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
1559
1644
  export {
1560
1645
  TextEditor as default
1561
1646
  };
1562
- //# sourceMappingURL=TextEditor-D6QH2B7O.js.map
1647
+ //# sourceMappingURL=TextEditor-MGCSGGGA.js.map