@sofereditor/react 0.7.0 → 0.10.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.
package/dist/index.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
@@ -23,6 +33,7 @@ __export(index_exports, {
23
33
  A4_PAGE: () => A4_PAGE,
24
34
  Editor: () => Editor,
25
35
  EditorProvider: () => EditorProvider,
36
+ FormulaDialog: () => FormulaDialog,
26
37
  ImageCaptionDialog: () => ImageCaptionDialog,
27
38
  LinkDialog: () => LinkDialog,
28
39
  NodeView: () => NodeView,
@@ -54,8 +65,8 @@ __export(index_exports, {
54
65
  module.exports = __toCommonJS(index_exports);
55
66
 
56
67
  // src/Editor.tsx
57
- var import_react14 = require("react");
58
- var import_core9 = require("@sofereditor/core");
68
+ var import_react15 = require("react");
69
+ var import_core10 = require("@sofereditor/core");
59
70
 
60
71
  // src/dom-bridge.ts
61
72
  function findContainingBlockElement(node, root) {
@@ -128,6 +139,11 @@ function isWrapAnchorImg(n) {
128
139
  function isPhantomEmbed(n) {
129
140
  return n.nodeType === Node.ELEMENT_NODE && n.dataset.embedPhantom === "true";
130
141
  }
142
+ function isCellLineBoundary(n) {
143
+ if (n.nodeType !== Node.ELEMENT_NODE) return false;
144
+ const line = n.dataset.cellLine;
145
+ return line != null && Number(line) > 0;
146
+ }
131
147
  function indexInParent(n) {
132
148
  const parent = n.parentNode;
133
149
  if (!parent) return 0;
@@ -155,6 +171,7 @@ function textOffsetWithin(container, node, offsetInNode) {
155
171
  let done = false;
156
172
  function visit(n) {
157
173
  if (done) return;
174
+ if (isCellLineBoundary(n)) offset += 1;
158
175
  if (n === target) {
159
176
  if (n.nodeType === Node.TEXT_NODE) {
160
177
  offset += targetOff;
@@ -255,6 +272,7 @@ function locatePoint(root, pos) {
255
272
  let remaining = Math.max(0, pos.offset - containerStart);
256
273
  let result = null;
257
274
  let lastImg = null;
275
+ let lastBoundary = null;
258
276
  let lastText = null;
259
277
  function visit(n) {
260
278
  if (result) return;
@@ -266,6 +284,7 @@ function locatePoint(root, pos) {
266
284
  }
267
285
  remaining -= len;
268
286
  lastImg = null;
287
+ lastBoundary = null;
269
288
  lastText = n;
270
289
  return;
271
290
  }
@@ -273,6 +292,25 @@ function locatePoint(root, pos) {
273
292
  const el = n;
274
293
  if (isRejectedSubtree(el, container)) return;
275
294
  if (isImgEmbed(el) && isWrapAnchorImg(el)) return;
295
+ if (isCellLineBoundary(el)) {
296
+ if (remaining === 0) {
297
+ if (lastImg) {
298
+ const parent = lastImg.parentNode;
299
+ if (parent) {
300
+ result = { node: parent, offset: indexInParent(lastImg) + 1 };
301
+ return;
302
+ }
303
+ }
304
+ const prevLine = lastBoundary ?? el.previousElementSibling;
305
+ if (prevLine) {
306
+ result = { node: prevLine, offset: 0 };
307
+ return;
308
+ }
309
+ }
310
+ remaining -= 1;
311
+ lastBoundary = el;
312
+ lastImg = null;
313
+ }
276
314
  if (isImgEmbed(el) || isPhantomEmbed(el)) {
277
315
  if (remaining === 0) {
278
316
  const parent = el.parentNode;
@@ -283,6 +321,7 @@ function locatePoint(root, pos) {
283
321
  }
284
322
  remaining -= 1;
285
323
  lastImg = el;
324
+ lastBoundary = null;
286
325
  return;
287
326
  }
288
327
  for (const child of Array.from(el.childNodes)) {
@@ -292,7 +331,10 @@ function locatePoint(root, pos) {
292
331
  }
293
332
  visit(container);
294
333
  if (result) return result;
295
- if (lastImg && remaining === 0) {
334
+ if (lastBoundary) {
335
+ return { node: lastBoundary, offset: 0 };
336
+ }
337
+ if (lastImg) {
296
338
  const parent = lastImg.parentNode;
297
339
  if (parent) return { node: parent, offset: indexInParent(lastImg) + 1 };
298
340
  }
@@ -1293,7 +1335,7 @@ function LinkHoverTooltip({ href, rect }) {
1293
1335
  }
1294
1336
 
1295
1337
  // src/EditorContext.tsx
1296
- var import_react5 = require("react");
1338
+ var import_react6 = require("react");
1297
1339
 
1298
1340
  // src/LinkDialog.tsx
1299
1341
  var import_react2 = require("react");
@@ -1822,19 +1864,380 @@ function ImageCaptionDialog() {
1822
1864
  );
1823
1865
  }
1824
1866
 
1825
- // src/EditorContext.tsx
1867
+ // src/FormulaDialog.tsx
1868
+ var import_react5 = require("react");
1869
+
1870
+ // src/formulaSnippet.ts
1871
+ var PALETA = [
1872
+ {
1873
+ nome: "Estruturas",
1874
+ colunas: 4,
1875
+ itens: [
1876
+ { label: "Fra\xE7\xE3o", snippet: "\\frac{}{}" },
1877
+ { label: "Expoente", snippet: "^{}" },
1878
+ { label: "\xCDndice", snippet: "_{}" },
1879
+ { label: "Raiz", snippet: "\\sqrt{}" },
1880
+ { label: "Raiz n-\xE9sima", snippet: "\\sqrt[{}]{}" },
1881
+ { label: "Somat\xF3rio", snippet: "\\sum_{}^{}" },
1882
+ { label: "Produt\xF3rio", snippet: "\\prod_{}^{}" },
1883
+ { label: "Integral", snippet: "\\int_{}^{}" },
1884
+ { label: "Limite", snippet: "\\lim_{{} \\to {}}" },
1885
+ { label: "Derivada", snippet: "\\frac{d}{d{}}" },
1886
+ {
1887
+ label: "Matriz 2\xD72",
1888
+ snippet: "\\begin{pmatrix} {} & {} \\\\ {} & {} \\end{pmatrix}"
1889
+ },
1890
+ { label: "Sistema", snippet: "\\begin{cases} {} \\\\ \\end{cases}" },
1891
+ { label: "Par\xEAnteses", snippet: "\\left({}\\right)" },
1892
+ { label: "Binomial", snippet: "\\binom{}{}" },
1893
+ { label: "M\xF3dulo", snippet: "\\left|{}\\right|" }
1894
+ ]
1895
+ },
1896
+ {
1897
+ nome: "S\xEDmbolos",
1898
+ colunas: 6,
1899
+ itens: [
1900
+ { label: "\xB1", snippet: "\\pm", titulo: "mais ou menos" },
1901
+ { label: "\xD7", snippet: "\\times", titulo: "multiplica\xE7\xE3o" },
1902
+ { label: "\xF7", snippet: "\\div", titulo: "divis\xE3o" },
1903
+ { label: "\xB7", snippet: "\\cdot", titulo: "multiplica\xE7\xE3o (ponto)" },
1904
+ { label: "\u221E", snippet: "\\infty", titulo: "infinito" },
1905
+ { label: "\xB0", snippet: "^\\circ", titulo: "grau" },
1906
+ { label: "%", snippet: "\\%", titulo: "por cento" },
1907
+ { label: ",", snippet: "{,}", titulo: "v\xEDrgula decimal" }
1908
+ ]
1909
+ },
1910
+ {
1911
+ nome: "Rela\xE7\xF5es",
1912
+ colunas: 6,
1913
+ itens: [
1914
+ { label: "\u2260", snippet: "\\neq", titulo: "diferente de" },
1915
+ { label: "\u2248", snippet: "\\approx", titulo: "aproximadamente" },
1916
+ { label: "\u2261", snippet: "\\equiv", titulo: "id\xEAntico a" },
1917
+ { label: "\u2264", snippet: "\\leq", titulo: "menor ou igual a" },
1918
+ { label: "\u2265", snippet: "\\geq", titulo: "maior ou igual a" },
1919
+ { label: "\u221D", snippet: "\\propto", titulo: "proporcional a" },
1920
+ { label: "\u22A5", snippet: "\\perp", titulo: "perpendicular a" },
1921
+ { label: "\u2225", snippet: "\\parallel", titulo: "paralelo a" },
1922
+ { label: "\u2245", snippet: "\\cong", titulo: "congruente a" },
1923
+ { label: "\u223C", snippet: "\\sim", titulo: "semelhante a" }
1924
+ ]
1925
+ },
1926
+ {
1927
+ nome: "Gregas",
1928
+ colunas: 6,
1929
+ itens: [
1930
+ { label: "\u03B1", snippet: "\\alpha", titulo: "alfa" },
1931
+ { label: "\u03B2", snippet: "\\beta", titulo: "beta" },
1932
+ { label: "\u03B3", snippet: "\\gamma", titulo: "gama" },
1933
+ { label: "\u03B4", snippet: "\\delta", titulo: "delta" },
1934
+ { label: "\u03B5", snippet: "\\varepsilon", titulo: "\xE9psilon" },
1935
+ { label: "\u03B8", snippet: "\\theta", titulo: "teta" },
1936
+ { label: "\u03BB", snippet: "\\lambda", titulo: "lambda" },
1937
+ { label: "\u03BC", snippet: "\\mu", titulo: "mi" },
1938
+ { label: "\u03C0", snippet: "\\pi", titulo: "pi" },
1939
+ { label: "\u03C1", snippet: "\\rho", titulo: "r\xF4" },
1940
+ { label: "\u03C3", snippet: "\\sigma", titulo: "sigma" },
1941
+ { label: "\u03C6", snippet: "\\varphi", titulo: "fi" },
1942
+ { label: "\u03C9", snippet: "\\omega", titulo: "\xF4mega" },
1943
+ { label: "\u0394", snippet: "\\Delta", titulo: "delta mai\xFAsculo" },
1944
+ {
1945
+ label: "\u03A3",
1946
+ snippet: "\\Sigma",
1947
+ titulo: "sigma mai\xFAsculo \u2014 letra grega; para somat\xF3rio use Estruturas"
1948
+ },
1949
+ {
1950
+ label: "\u03A0",
1951
+ snippet: "\\Pi",
1952
+ titulo: "pi mai\xFAsculo \u2014 letra grega; para produt\xF3rio use Estruturas"
1953
+ },
1954
+ { label: "\u03A9", snippet: "\\Omega", titulo: "\xF4mega mai\xFAsculo" },
1955
+ { label: "\u03A6", snippet: "\\Phi", titulo: "fi mai\xFAsculo" }
1956
+ ]
1957
+ },
1958
+ {
1959
+ nome: "Conjuntos",
1960
+ colunas: 6,
1961
+ itens: [
1962
+ { label: "\u2208", snippet: "\\in", titulo: "pertence a" },
1963
+ { label: "\u2209", snippet: "\\notin", titulo: "n\xE3o pertence a" },
1964
+ { label: "\u2282", snippet: "\\subset", titulo: "contido em" },
1965
+ { label: "\u2286", snippet: "\\subseteq", titulo: "contido ou igual a" },
1966
+ { label: "\u222A", snippet: "\\cup", titulo: "uni\xE3o" },
1967
+ { label: "\u2229", snippet: "\\cap", titulo: "interse\xE7\xE3o" },
1968
+ { label: "\u2205", snippet: "\\varnothing", titulo: "conjunto vazio" },
1969
+ { label: "\u2115", snippet: "\\mathbb{N}", titulo: "conjunto dos naturais" },
1970
+ { label: "\u2124", snippet: "\\mathbb{Z}", titulo: "conjunto dos inteiros" },
1971
+ { label: "\u211A", snippet: "\\mathbb{Q}", titulo: "conjunto dos racionais" },
1972
+ { label: "\u211D", snippet: "\\mathbb{R}", titulo: "conjunto dos reais" },
1973
+ { label: "\u2102", snippet: "\\mathbb{C}", titulo: "conjunto dos complexos" },
1974
+ { label: "\u2200", snippet: "\\forall", titulo: "para todo" },
1975
+ { label: "\u2203", snippet: "\\exists", titulo: "existe" },
1976
+ { label: "{ }", snippet: "\\{{}\\}", titulo: "chaves de conjunto" }
1977
+ ]
1978
+ },
1979
+ {
1980
+ nome: "Fun\xE7\xF5es",
1981
+ colunas: 6,
1982
+ itens: [
1983
+ { label: "sen", snippet: "\\operatorname{sen}", titulo: "seno" },
1984
+ { label: "cos", snippet: "\\cos", titulo: "cosseno" },
1985
+ { label: "tg", snippet: "\\operatorname{tg}", titulo: "tangente" },
1986
+ { label: "cotg", snippet: "\\operatorname{cotg}", titulo: "cotangente" },
1987
+ { label: "log", snippet: "\\log_{}", titulo: "logaritmo" },
1988
+ { label: "ln", snippet: "\\ln", titulo: "logaritmo natural" },
1989
+ { label: "exp", snippet: "\\exp", titulo: "exponencial" }
1990
+ ]
1991
+ },
1992
+ {
1993
+ nome: "Setas",
1994
+ colunas: 6,
1995
+ itens: [
1996
+ { label: "\u2192", snippet: "\\to", titulo: "tende a / vai para" },
1997
+ { label: "\u2190", snippet: "\\leftarrow", titulo: "vem de / sentido inverso" },
1998
+ { label: "\u21D2", snippet: "\\Rightarrow", titulo: "implica em" },
1999
+ { label: "\u21D4", snippet: "\\Leftrightarrow", titulo: "se e somente se" },
2000
+ { label: "\u21CC", snippet: "\\rightleftharpoons", titulo: "equil\xEDbrio qu\xEDmico" },
2001
+ { label: "vetor AB", snippet: "\\overrightarrow{}", titulo: "vetor entre dois pontos (AB)" },
2002
+ { label: "vetor", snippet: "\\vec{}", titulo: "vetor (f\xEDsica)" },
2003
+ { label: "\u2220", snippet: "\\angle", titulo: "\xE2ngulo" },
2004
+ { label: "\u25B3", snippet: "\\triangle", titulo: "tri\xE2ngulo" }
2005
+ ]
2006
+ }
2007
+ ];
2008
+ function paraMathlive(snippet) {
2009
+ return snippet.replaceAll("{}", "{#?}");
2010
+ }
2011
+ function paraMarkup(snippet) {
2012
+ return snippet.replaceAll("{}", "{\u25A1}");
2013
+ }
2014
+ function conteudoDoBotao(markup, snippet, label) {
2015
+ if (!markup) return { children: label };
2016
+ return { dangerouslySetInnerHTML: { __html: markup(paraMarkup(snippet)) } };
2017
+ }
2018
+
2019
+ // src/formulaGuarda.ts
2020
+ var PLACEHOLDER = "\\placeholder{}";
2021
+ var GRUPO_VAZIO = /\{\s*\}/;
2022
+ var CELULA_VAZIA = /(?:\\begin\{[a-zA-Z]+\*?\}|&|\\\\)\s*(?:&|\\\\|\\end\{)/;
2023
+ function podeInserir(latex, preview) {
2024
+ if (motivoBloqueio(latex, preview) !== null) return false;
2025
+ return latex.trim() !== "" && preview?.ok === true;
2026
+ }
2027
+ function motivoBloqueio(latex, preview) {
2028
+ if (latex.includes(PLACEHOLDER) || GRUPO_VAZIO.test(latex) || CELULA_VAZIA.test(latex)) {
2029
+ return "Preencha os campos em branco da f\xF3rmula.";
2030
+ }
2031
+ if (preview && !preview.ok) return preview.error ?? null;
2032
+ return null;
2033
+ }
2034
+
2035
+ // src/FormulaDialog.tsx
1826
2036
  var import_jsx_runtime6 = require("react/jsx-runtime");
1827
- var EditorContext = (0, import_react5.createContext)(null);
1828
- function EditorProvider({ editor, children }) {
1829
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(EditorContext.Provider, { value: editor, children: [
2037
+ var CIRCUNFLEXO_DE_TECLA_MORTA = /* @__PURE__ */ new Set(["\u02C6", "\u0302"]);
2038
+ function FormulaDialog({
2039
+ fontsDirectory
2040
+ }) {
2041
+ const { formulaRequest, resolveFormulaRequest } = useEditorContext();
2042
+ const dialogRef = (0, import_react5.useRef)(null);
2043
+ const hostRef = (0, import_react5.useRef)(null);
2044
+ const fieldRef = (0, import_react5.useRef)(null);
2045
+ const [latex, setLatex] = (0, import_react5.useState)("");
2046
+ const [display, setDisplay] = (0, import_react5.useState)(false);
2047
+ const [abaAtiva, setAbaAtiva] = (0, import_react5.useState)(0);
2048
+ (0, import_react5.useEffect)(() => {
2049
+ const dialog = dialogRef.current;
2050
+ if (!dialog) return;
2051
+ if (formulaRequest) {
2052
+ setLatex(formulaRequest.initialLatex);
2053
+ setDisplay(formulaRequest.initialDisplay);
2054
+ setAbaAtiva(0);
2055
+ if (!dialog.open) dialog.showModal();
2056
+ } else if (dialog.open) {
2057
+ dialog.close();
2058
+ }
2059
+ }, [formulaRequest]);
2060
+ const rendererRef = (0, import_react5.useRef)(null);
2061
+ const mathfieldCtorRef = (0, import_react5.useRef)(null);
2062
+ const markupRef = (0, import_react5.useRef)(null);
2063
+ const [preview, setPreview] = (0, import_react5.useState)(null);
2064
+ const [carregando, setCarregando] = (0, import_react5.useState)(false);
2065
+ const [erroCarregando, setErroCarregando] = (0, import_react5.useState)(null);
2066
+ (0, import_react5.useEffect)(() => {
2067
+ if (!formulaRequest || rendererRef.current) return;
2068
+ setCarregando(true);
2069
+ setErroCarregando(null);
2070
+ void Promise.all([import("@sofereditor/math"), import("mathlive")]).then(([math, mathlive]) => {
2071
+ rendererRef.current = math.renderLatexToSvg;
2072
+ mathfieldCtorRef.current = mathlive.MathfieldElement;
2073
+ markupRef.current = mathlive.convertLatexToMarkup;
2074
+ mathlive.MathfieldElement.soundsDirectory = null;
2075
+ if (fontsDirectory) {
2076
+ mathlive.MathfieldElement.fontsDirectory = fontsDirectory;
2077
+ }
2078
+ setCarregando(false);
2079
+ }).catch(() => {
2080
+ setCarregando(false);
2081
+ setErroCarregando(
2082
+ "N\xE3o foi poss\xEDvel carregar o editor de f\xF3rmulas. Recarregue a p\xE1gina e tente de novo."
2083
+ );
2084
+ });
2085
+ }, [formulaRequest]);
2086
+ (0, import_react5.useEffect)(() => {
2087
+ const render = rendererRef.current;
2088
+ if (!render || !latex.trim()) {
2089
+ setPreview(null);
2090
+ return;
2091
+ }
2092
+ setPreview(render(latex, display));
2093
+ }, [latex, display, carregando]);
2094
+ const onCircunflexoMorto = (0, import_react5.useCallback)((e) => {
2095
+ const ev = e;
2096
+ if (!ev.data || !CIRCUNFLEXO_DE_TECLA_MORTA.has(ev.data)) return;
2097
+ ev.preventDefault();
2098
+ ev.stopPropagation();
2099
+ fieldRef.current?.insert("^{#?}", { focus: true });
2100
+ }, []);
2101
+ (0, import_react5.useEffect)(() => {
2102
+ const Ctor = mathfieldCtorRef.current;
2103
+ const host = hostRef.current;
2104
+ if (!Ctor || !host || !formulaRequest) return;
2105
+ const mf = new Ctor();
2106
+ mf.className = "ed-formula-field";
2107
+ const onInput = () => setLatex(mf.getValue("latex"));
2108
+ mf.addEventListener("input", onInput);
2109
+ mf.addEventListener("beforeinput", onCircunflexoMorto, true);
2110
+ host.appendChild(mf);
2111
+ mf.mathVirtualKeyboardPolicy = "manual";
2112
+ mf.inlineShortcuts = {
2113
+ ...mf.inlineShortcuts,
2114
+ sen: "\\operatorname{sen}",
2115
+ tg: "\\operatorname{tg}",
2116
+ cotg: "\\operatorname{cotg}",
2117
+ // Vírgula decimal. Em modo matemático a vírgula crua é átomo de
2118
+ // pontuação e ganha espaço DEPOIS de si: digitar "3,14" sai impresso
2119
+ // como "3, 14" (medido: 4.4ex contra 4.023ex do agrupado). A paleta
2120
+ // tem um botão `{,}`, mas ninguém clica num botão para uma tecla que
2121
+ // está no teclado — e decimal aparece em toda prova de matemática,
2122
+ // física e química.
2123
+ //
2124
+ // O `after: "digit"` é o que separa os dois usos da vírgula, e foi
2125
+ // verificado no navegador: "3,14" vira `3{,}14` e "f(x,y)" continua
2126
+ // `f\left(x,y\right)`, com a vírgula de lista intacta — que é o
2127
+ // comportamento certo, ali ela É pontuação.
2128
+ ",": { after: "digit", value: "{,}" }
2129
+ };
2130
+ mf.setValue(formulaRequest.initialLatex);
2131
+ setLatex(mf.getValue("latex"));
2132
+ fieldRef.current = mf;
2133
+ queueMicrotask(() => mf.focus());
2134
+ return () => {
2135
+ mf.removeEventListener("input", onInput);
2136
+ mf.removeEventListener("beforeinput", onCircunflexoMorto, true);
2137
+ mf.remove();
2138
+ fieldRef.current = null;
2139
+ };
2140
+ }, [formulaRequest, carregando]);
2141
+ if (!formulaRequest) return null;
2142
+ const markup = markupRef.current;
2143
+ const motivo = motivoBloqueio(latex, preview);
2144
+ const podeSubmeter = podeInserir(latex, preview);
2145
+ const onSubmit = (e) => {
2146
+ e.preventDefault();
2147
+ if (!podeSubmeter) return;
2148
+ resolveFormulaRequest({ latex, display });
2149
+ };
2150
+ const onCancel = () => resolveFormulaRequest(null);
2151
+ const onPaleta = (snippet) => {
2152
+ const mf = fieldRef.current;
2153
+ if (!mf) return;
2154
+ mf.insert(paraMathlive(snippet), { focus: true });
2155
+ setLatex(mf.getValue("latex"));
2156
+ };
2157
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2158
+ "dialog",
2159
+ {
2160
+ ref: dialogRef,
2161
+ className: "ed-formula-dialog ed-link-dialog",
2162
+ style: DIALOG_CENTER_STYLE,
2163
+ onClose: onCancel,
2164
+ onCancel: (e) => {
2165
+ e.preventDefault();
2166
+ onCancel();
2167
+ },
2168
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("form", { onSubmit, className: "ed-formula-form", children: [
2169
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "ed-formula-abas", role: "tablist", children: PALETA.map((cat, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2170
+ "button",
2171
+ {
2172
+ type: "button",
2173
+ role: "tab",
2174
+ "aria-selected": i === abaAtiva,
2175
+ className: "ed-formula-aba",
2176
+ onClick: () => setAbaAtiva(i),
2177
+ children: cat.nome
2178
+ },
2179
+ cat.nome
2180
+ )) }),
2181
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2182
+ "div",
2183
+ {
2184
+ className: "ed-formula-paleta",
2185
+ role: "tabpanel",
2186
+ style: { gridTemplateColumns: `repeat(${PALETA[abaAtiva].colunas}, 1fr)` },
2187
+ children: PALETA[abaAtiva].itens.map((p) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2188
+ "button",
2189
+ {
2190
+ type: "button",
2191
+ className: "ed-formula-paleta-btn",
2192
+ title: p.titulo ?? p.label,
2193
+ "aria-label": p.titulo ?? p.label,
2194
+ onClick: () => onPaleta(p.snippet),
2195
+ ...conteudoDoBotao(markup, p.snippet, p.label)
2196
+ },
2197
+ p.label
2198
+ ))
2199
+ }
2200
+ ),
2201
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { ref: hostRef, className: "ed-formula-host" }),
2202
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "ed-formula-display", children: [
2203
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2204
+ "input",
2205
+ {
2206
+ type: "checkbox",
2207
+ checked: display,
2208
+ onChange: (e) => setDisplay(e.target.checked)
2209
+ }
2210
+ ),
2211
+ "F\xF3rmula em bloco (centralizada, limites acima e abaixo)"
2212
+ ] }),
2213
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "ed-formula-preview", "aria-live": "polite", children: carregando ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ed-formula-vazio", children: "Carregando o editor\u2026" }) : erroCarregando ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ed-formula-erro", role: "alert", children: erroCarregando }) : motivo ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ed-formula-erro", role: "alert", children: motivo }) : null }),
2214
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ed-formula-acoes", children: [
2215
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", onClick: onCancel, children: "Cancelar" }),
2216
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "submit", disabled: !podeSubmeter, children: "Inserir" })
2217
+ ] })
2218
+ ] })
2219
+ }
2220
+ );
2221
+ }
2222
+
2223
+ // src/EditorContext.tsx
2224
+ var import_jsx_runtime7 = require("react/jsx-runtime");
2225
+ var EditorContext = (0, import_react6.createContext)(null);
2226
+ function EditorProvider({
2227
+ editor,
2228
+ children,
2229
+ mathliveFontsDirectory
2230
+ }) {
2231
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(EditorContext.Provider, { value: editor, children: [
1830
2232
  children,
1831
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(LinkDialog, {}),
1832
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PageConfigDialog, {}),
1833
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ImageCaptionDialog, {})
2233
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(LinkDialog, {}),
2234
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PageConfigDialog, {}),
2235
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ImageCaptionDialog, {}),
2236
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FormulaDialog, { fontsDirectory: mathliveFontsDirectory })
1834
2237
  ] });
1835
2238
  }
1836
2239
  function useEditorContext() {
1837
- const ctx = (0, import_react5.useContext)(EditorContext);
2240
+ const ctx = (0, import_react6.useContext)(EditorContext);
1838
2241
  if (!ctx) {
1839
2242
  throw new Error("useEditorContext must be used inside an <EditorProvider>");
1840
2243
  }
@@ -1842,8 +2245,8 @@ function useEditorContext() {
1842
2245
  }
1843
2246
 
1844
2247
  // src/ImageResizeOverlay.tsx
1845
- var import_react6 = require("react");
1846
- var import_jsx_runtime7 = require("react/jsx-runtime");
2248
+ var import_react7 = require("react");
2249
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1847
2250
  function ImageResizeOverlay({
1848
2251
  rootRef,
1849
2252
  blockIndex,
@@ -1854,10 +2257,10 @@ function ImageResizeOverlay({
1854
2257
  onCommitMove,
1855
2258
  onReanchor
1856
2259
  }) {
1857
- const [rect, setRect] = (0, import_react6.useState)(null);
1858
- const [isMoving, setIsMoving] = (0, import_react6.useState)(false);
1859
- const imgRef = (0, import_react6.useRef)(null);
1860
- const locateImage = (0, import_react6.useCallback)(() => {
2260
+ const [rect, setRect] = (0, import_react7.useState)(null);
2261
+ const [isMoving, setIsMoving] = (0, import_react7.useState)(false);
2262
+ const imgRef = (0, import_react7.useRef)(null);
2263
+ const locateImage = (0, import_react7.useCallback)(() => {
1861
2264
  const root = rootRef.current;
1862
2265
  if (!root) return null;
1863
2266
  let container = null;
@@ -1875,7 +2278,7 @@ function ImageResizeOverlay({
1875
2278
  `img[data-embed="image"][data-embed-offset="${localOffset}"]`
1876
2279
  );
1877
2280
  }, [rootRef, blockIndex, offset, cellIndex]);
1878
- const measure = (0, import_react6.useCallback)(() => {
2281
+ const measure = (0, import_react7.useCallback)(() => {
1879
2282
  const img = locateImage();
1880
2283
  if (!img) {
1881
2284
  setRect((prev) => prev === null ? prev : null);
@@ -1896,7 +2299,7 @@ function ImageResizeOverlay({
1896
2299
  (prev) => prev && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
1897
2300
  );
1898
2301
  }, [locateImage, rootRef]);
1899
- (0, import_react6.useLayoutEffect)(() => {
2302
+ (0, import_react7.useLayoutEffect)(() => {
1900
2303
  measure();
1901
2304
  let cancelled = false;
1902
2305
  let frame = 0;
@@ -1926,7 +2329,7 @@ function ImageResizeOverlay({
1926
2329
  embed.offsetX,
1927
2330
  embed.offsetY
1928
2331
  ]);
1929
- (0, import_react6.useEffect)(() => {
2332
+ (0, import_react7.useEffect)(() => {
1930
2333
  const root = rootRef.current;
1931
2334
  if (!root) return;
1932
2335
  const onScroll = () => measure();
@@ -1937,7 +2340,7 @@ function ImageResizeOverlay({
1937
2340
  root.removeEventListener("scroll", onScroll);
1938
2341
  };
1939
2342
  }, [measure, rootRef]);
1940
- (0, import_react6.useEffect)(() => {
2343
+ (0, import_react7.useEffect)(() => {
1941
2344
  if (typeof ResizeObserver === "undefined") return;
1942
2345
  const img = locateImage();
1943
2346
  const root = rootRef.current;
@@ -1950,7 +2353,7 @@ function ImageResizeOverlay({
1950
2353
  if (!rect) return null;
1951
2354
  const layout = embed.layout ?? "inline";
1952
2355
  const movable = layout !== "inline" && onCommitMove !== void 0;
1953
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2356
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1954
2357
  "div",
1955
2358
  {
1956
2359
  className: "ed-image-overlay",
@@ -1961,7 +2364,7 @@ function ImageResizeOverlay({
1961
2364
  // follows the cursor, so the image stays visible while it crosses the
1962
2365
  // page boundary (the real, clipped figure is hidden during the drag).
1963
2366
  // Inline styles only — the package does not ship CSS.
1964
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2367
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1965
2368
  "img",
1966
2369
  {
1967
2370
  src: embed.src,
@@ -1979,7 +2382,7 @@ function ImageResizeOverlay({
1979
2382
  }
1980
2383
  }
1981
2384
  ),
1982
- movable && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2385
+ movable && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1983
2386
  MoveHandle,
1984
2387
  {
1985
2388
  layout,
@@ -1997,7 +2400,7 @@ function ImageResizeOverlay({
1997
2400
  onMoveEnd: () => setIsMoving(false)
1998
2401
  }
1999
2402
  ),
2000
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2403
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2001
2404
  Handle,
2002
2405
  {
2003
2406
  corner: "nw",
@@ -2008,7 +2411,7 @@ function ImageResizeOverlay({
2008
2411
  onLiveChange: measure
2009
2412
  }
2010
2413
  ),
2011
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2414
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2012
2415
  Handle,
2013
2416
  {
2014
2417
  corner: "ne",
@@ -2019,7 +2422,7 @@ function ImageResizeOverlay({
2019
2422
  onLiveChange: measure
2020
2423
  }
2021
2424
  ),
2022
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2425
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2023
2426
  Handle,
2024
2427
  {
2025
2428
  corner: "sw",
@@ -2030,7 +2433,7 @@ function ImageResizeOverlay({
2030
2433
  onLiveChange: measure
2031
2434
  }
2032
2435
  ),
2033
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2436
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2034
2437
  Handle,
2035
2438
  {
2036
2439
  corner: "se",
@@ -2060,7 +2463,7 @@ function MoveHandle({
2060
2463
  onMoveStart,
2061
2464
  onMoveEnd
2062
2465
  }) {
2063
- const dragRef = (0, import_react6.useRef)(null);
2466
+ const dragRef = (0, import_react7.useRef)(null);
2064
2467
  const onPointerDown = (e) => {
2065
2468
  if (e.button !== 0) return;
2066
2469
  if (!imgRef.current) return;
@@ -2210,7 +2613,7 @@ function MoveHandle({
2210
2613
  newOffsetY
2211
2614
  );
2212
2615
  };
2213
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2616
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2214
2617
  "div",
2215
2618
  {
2216
2619
  className: "ed-image-move",
@@ -2230,7 +2633,7 @@ function Handle({
2230
2633
  onCommit,
2231
2634
  onLiveChange
2232
2635
  }) {
2233
- const dragRef = (0, import_react6.useRef)(null);
2636
+ const dragRef = (0, import_react7.useRef)(null);
2234
2637
  const onPointerDown = (e) => {
2235
2638
  if (e.button !== 0) return;
2236
2639
  if (!imgRef.current) return;
@@ -2273,7 +2676,7 @@ function Handle({
2273
2676
  }
2274
2677
  onCommit(Math.round(d.liveW), Math.round(d.liveH));
2275
2678
  };
2276
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2679
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2277
2680
  "div",
2278
2681
  {
2279
2682
  className: `ed-image-handle ${corner}`,
@@ -2286,9 +2689,9 @@ function Handle({
2286
2689
  }
2287
2690
 
2288
2691
  // src/RemoteCursorsOverlay.tsx
2289
- var import_react7 = require("react");
2692
+ var import_react8 = require("react");
2290
2693
  var import_core5 = require("@sofereditor/core");
2291
- var import_jsx_runtime8 = require("react/jsx-runtime");
2694
+ var import_jsx_runtime9 = require("react/jsx-runtime");
2292
2695
  var DEFAULT_COLOR = "#3b82f6";
2293
2696
  function RemoteCursorsOverlay({
2294
2697
  rootRef,
@@ -2296,9 +2699,9 @@ function RemoteCursorsOverlay({
2296
2699
  awareness,
2297
2700
  revision
2298
2701
  }) {
2299
- const [views, setViews] = (0, import_react7.useState)([]);
2300
- const rafRef = (0, import_react7.useRef)(null);
2301
- const measure = (0, import_react7.useCallback)(() => {
2702
+ const [views, setViews] = (0, import_react8.useState)([]);
2703
+ const rafRef = (0, import_react8.useRef)(null);
2704
+ const measure = (0, import_react8.useCallback)(() => {
2302
2705
  const root = rootRef.current;
2303
2706
  if (!root) {
2304
2707
  setViews((prev) => prev.length === 0 ? prev : []);
@@ -2363,7 +2766,7 @@ function RemoteCursorsOverlay({
2363
2766
  });
2364
2767
  setViews(out);
2365
2768
  }, [rootRef, doc, awareness]);
2366
- const scheduleMeasure = (0, import_react7.useCallback)(() => {
2769
+ const scheduleMeasure = (0, import_react8.useCallback)(() => {
2367
2770
  if (rafRef.current != null) return;
2368
2771
  const raf = typeof requestAnimationFrame === "function" ? requestAnimationFrame : (cb) => setTimeout(() => cb(0), 16);
2369
2772
  rafRef.current = raf(() => {
@@ -2371,16 +2774,16 @@ function RemoteCursorsOverlay({
2371
2774
  measure();
2372
2775
  });
2373
2776
  }, [measure]);
2374
- (0, import_react7.useEffect)(() => {
2777
+ (0, import_react8.useEffect)(() => {
2375
2778
  const onChange = () => scheduleMeasure();
2376
2779
  awareness.on("change", onChange);
2377
2780
  scheduleMeasure();
2378
2781
  return () => awareness.off("change", onChange);
2379
2782
  }, [awareness, scheduleMeasure]);
2380
- (0, import_react7.useEffect)(() => {
2783
+ (0, import_react8.useEffect)(() => {
2381
2784
  scheduleMeasure();
2382
2785
  }, [revision, scheduleMeasure]);
2383
- (0, import_react7.useEffect)(() => {
2786
+ (0, import_react8.useEffect)(() => {
2384
2787
  const root = rootRef.current;
2385
2788
  if (!root) return;
2386
2789
  const onScroll = () => scheduleMeasure();
@@ -2402,8 +2805,8 @@ function RemoteCursorsOverlay({
2402
2805
  pointerEvents: "none",
2403
2806
  zIndex: 6
2404
2807
  };
2405
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "ed-remote-cursors", "aria-hidden": true, style: layer, children: views.map((v) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
2406
- v.selection.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2808
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "ed-remote-cursors", "aria-hidden": true, style: layer, children: views.map((v) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
2809
+ v.selection.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2407
2810
  "div",
2408
2811
  {
2409
2812
  style: {
@@ -2419,7 +2822,7 @@ function RemoteCursorsOverlay({
2419
2822
  },
2420
2823
  i
2421
2824
  )),
2422
- v.caret && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2825
+ v.caret && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2423
2826
  "div",
2424
2827
  {
2425
2828
  style: {
@@ -2430,7 +2833,7 @@ function RemoteCursorsOverlay({
2430
2833
  width: 2,
2431
2834
  background: v.color
2432
2835
  },
2433
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2836
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2434
2837
  "span",
2435
2838
  {
2436
2839
  style: {
@@ -2456,18 +2859,18 @@ function RemoteCursorsOverlay({
2456
2859
  }
2457
2860
 
2458
2861
  // src/NodeView.tsx
2459
- var import_react10 = require("react");
2460
- var import_core7 = require("@sofereditor/core");
2862
+ var import_react11 = require("react");
2863
+ var import_core8 = require("@sofereditor/core");
2461
2864
 
2462
2865
  // src/renderInline.tsx
2463
- var import_react8 = require("react");
2866
+ var import_react9 = require("react");
2464
2867
  var import_core6 = require("@sofereditor/core");
2465
- var import_jsx_runtime9 = require("react/jsx-runtime");
2466
- function renderInline(delta, keyPrefix) {
2868
+ var import_jsx_runtime10 = require("react/jsx-runtime");
2869
+ function renderInline(delta, keyPrefix, baseOffset = 0) {
2467
2870
  if (delta.length === 0 || delta.length === 1 && typeof delta[0].insert === "string" && delta[0].insert === "") {
2468
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("br", { "data-empty": "true" });
2871
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("br", { "data-empty": "true" });
2469
2872
  }
2470
- let offset = 0;
2873
+ let offset = baseOffset;
2471
2874
  const wrapAnchors = [];
2472
2875
  const body = [];
2473
2876
  for (const op of delta) {
@@ -2475,7 +2878,7 @@ function renderInline(delta, keyPrefix) {
2475
2878
  const text = op.insert;
2476
2879
  if (text.length === 0) continue;
2477
2880
  const key = `${keyPrefix}-${offset}`;
2478
- body.push(/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react8.Fragment, { children: wrap(text, op.attributes) }, key));
2881
+ body.push(/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react9.Fragment, { children: wrap(text, op.attributes) }, key));
2479
2882
  offset += text.length;
2480
2883
  } else if ((0, import_core6.isImageEmbed)(op.insert)) {
2481
2884
  const key = `${keyPrefix}-${offset}`;
@@ -2483,10 +2886,10 @@ function renderInline(delta, keyPrefix) {
2483
2886
  const commentMarkId = op.attributes?.comment?.markId;
2484
2887
  if (layout === "wrap-left" || layout === "wrap-right") {
2485
2888
  wrapAnchors.push(
2486
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ImageEmbedView, { embed: op.insert, offset, wrapAnchor: true }, `${key}-anchor`)
2889
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ImageEmbedView, { embed: op.insert, offset, wrapAnchor: true }, `${key}-anchor`)
2487
2890
  );
2488
2891
  body.push(
2489
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2892
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2490
2893
  "span",
2491
2894
  {
2492
2895
  "data-embed-phantom": "true",
@@ -2498,10 +2901,10 @@ function renderInline(delta, keyPrefix) {
2498
2901
  )
2499
2902
  );
2500
2903
  } else {
2501
- const imgNode = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ImageEmbedView, { embed: op.insert, offset }, key);
2904
+ const imgNode = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ImageEmbedView, { embed: op.insert, offset }, key);
2502
2905
  if (commentMarkId) {
2503
2906
  body.push(
2504
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "data-comment-id": commentMarkId, className: "ed-comment", children: imgNode }, `${key}-cmt`)
2907
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { "data-comment-id": commentMarkId, className: "ed-comment", children: imgNode }, `${key}-cmt`)
2505
2908
  );
2506
2909
  } else {
2507
2910
  body.push(imgNode);
@@ -2512,7 +2915,7 @@ function renderInline(delta, keyPrefix) {
2512
2915
  offset += 1;
2513
2916
  }
2514
2917
  }
2515
- if (wrapAnchors.length === 0 && body.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("br", { "data-empty": "true" });
2918
+ if (wrapAnchors.length === 0 && body.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("br", { "data-empty": "true" });
2516
2919
  return [...wrapAnchors, ...body];
2517
2920
  }
2518
2921
  var PHANTOM_STYLE = {
@@ -2537,7 +2940,7 @@ function imageEmbedPropsEqual(a, b) {
2537
2940
  // because Y.js stores the embed in its content map and re-exposes it.
2538
2941
  x.src === y.src;
2539
2942
  }
2540
- var ImageEmbedView = (0, import_react8.memo)(ImageEmbedViewImpl, imageEmbedPropsEqual);
2943
+ var ImageEmbedView = (0, import_react9.memo)(ImageEmbedViewImpl, imageEmbedPropsEqual);
2541
2944
  function ImageEmbedViewImpl({
2542
2945
  embed,
2543
2946
  offset,
@@ -2587,7 +2990,9 @@ function ImageEmbedViewImpl({
2587
2990
  marginRight: align === "right" ? 0 : "auto"
2588
2991
  } : {
2589
2992
  display: "inline-block",
2590
- verticalAlign: "text-bottom",
2993
+ // Fórmula inline traz o deslocamento de base que o MathJax mediu;
2994
+ // sem ele a fórmula flutua no topo da linha em vez de sentar nela.
2995
+ verticalAlign: embed.formula?.vAlign ?? "text-bottom",
2591
2996
  width: embed.width
2592
2997
  };
2593
2998
  break;
@@ -2597,7 +3002,7 @@ function ImageEmbedViewImpl({
2597
3002
  height: embed.height,
2598
3003
  display: "block"
2599
3004
  };
2600
- const img = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3005
+ const img = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2601
3006
  "img",
2602
3007
  {
2603
3008
  src: embed.src,
@@ -2617,7 +3022,7 @@ function ImageEmbedViewImpl({
2617
3022
  }
2618
3023
  );
2619
3024
  const captionAlign = embed.captionAlign ?? "center";
2620
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
3025
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2621
3026
  "figure",
2622
3027
  {
2623
3028
  className: "ed-figure",
@@ -2627,7 +3032,7 @@ function ImageEmbedViewImpl({
2627
3032
  style: outerStyle,
2628
3033
  children: [
2629
3034
  img,
2630
- hasCaption && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3035
+ hasCaption && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2631
3036
  "figcaption",
2632
3037
  {
2633
3038
  className: "ed-figcaption",
@@ -2644,26 +3049,26 @@ function decorateBlanks(text) {
2644
3049
  const segs = (0, import_core6.splitUnderscoreRuns)(text);
2645
3050
  if (segs.length === 1 && !segs[0].blank) return text;
2646
3051
  return segs.map(
2647
- (s, i) => s.blank ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "data-blank": "true", style: import_core6.BLANK_STYLE, children: s.text }, i) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react8.Fragment, { children: s.text }, i)
3052
+ (s, i) => s.blank ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { "data-blank": "true", style: import_core6.BLANK_STYLE, children: s.text }, i) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react9.Fragment, { children: s.text }, i)
2648
3053
  );
2649
3054
  }
2650
3055
  function wrap(text, attrs) {
2651
3056
  let node = decorateBlanks(text);
2652
3057
  if (!attrs) return node;
2653
- if (attrs.bold) node = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: node });
2654
- if (attrs.italic) node = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("em", { children: node });
2655
- if (attrs.underline) node = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("u", { children: node });
2656
- if (attrs.strike) node = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("s", { children: node });
3058
+ if (attrs.bold) node = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { children: node });
3059
+ if (attrs.italic) node = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("em", { children: node });
3060
+ if (attrs.underline) node = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("u", { children: node });
3061
+ if (attrs.strike) node = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("s", { children: node });
2657
3062
  const styleParts = {};
2658
3063
  if (attrs.color) styleParts.color = attrs.color;
2659
3064
  if (attrs.highlight) styleParts.backgroundColor = attrs.highlight;
2660
3065
  if (attrs.fontFamily) styleParts.fontFamily = attrs.fontFamily;
2661
3066
  if (attrs.fontSize) styleParts.fontSize = attrs.fontSize;
2662
3067
  if (Object.keys(styleParts).length > 0) {
2663
- node = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: styleParts, children: node });
3068
+ node = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: styleParts, children: node });
2664
3069
  }
2665
3070
  if (attrs.link?.href) {
2666
- node = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3071
+ node = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2667
3072
  "a",
2668
3073
  {
2669
3074
  href: attrs.link.href,
@@ -2682,7 +3087,7 @@ function wrap(text, attrs) {
2682
3087
  );
2683
3088
  }
2684
3089
  if (attrs.comment?.markId) {
2685
- node = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "data-comment-id": attrs.comment.markId, className: "ed-comment", children: node });
3090
+ node = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { "data-comment-id": attrs.comment.markId, className: "ed-comment", children: node });
2686
3091
  }
2687
3092
  return node;
2688
3093
  }
@@ -2726,16 +3131,25 @@ function sliceDelta(delta, start, end) {
2726
3131
  }
2727
3132
 
2728
3133
  // src/TableResizeOverlay.tsx
2729
- var import_react9 = require("react");
2730
- var import_jsx_runtime10 = require("react/jsx-runtime");
2731
- function TableResizeOverlay({ tableRef, blockIndex, cols }) {
3134
+ var import_react10 = require("react");
3135
+ var import_core7 = require("@sofereditor/core");
3136
+ var import_jsx_runtime11 = require("react/jsx-runtime");
3137
+ function deltaPctDoArrasto(dxPx, larguraTabelaPx) {
3138
+ if (!(larguraTabelaPx > 0)) return 0;
3139
+ return dxPx / larguraTabelaPx * 100;
3140
+ }
3141
+ function distribuirAltura(base, deltaPx) {
3142
+ if (base.length === 0) return base;
3143
+ const fatia = deltaPx / base.length;
3144
+ return base.map((h) => Math.max(import_core7.MIN_LINHA_PX, Math.round(h + fatia)));
3145
+ }
3146
+ function TableResizeOverlay({ tableRef, blockIndex, cols, rows }) {
2732
3147
  const editor = useEditorContext();
2733
- const [positions, setPositions] = (0, import_react9.useState)(null);
2734
- const [layout, setLayout] = (0, import_react9.useState)(null);
2735
- const draggingRef = (0, import_react9.useRef)(null);
2736
- const measure = (0, import_react9.useCallback)(() => {
3148
+ const [layout, setLayout] = (0, import_react10.useState)(null);
3149
+ const arrastoRef = (0, import_react10.useRef)(null);
3150
+ const measureNow = (0, import_react10.useCallback)(() => {
2737
3151
  const table = tableRef.current;
2738
- if (!table) return;
3152
+ if (!table) return null;
2739
3153
  const tableRect = table.getBoundingClientRect();
2740
3154
  const cgCols = table.querySelectorAll("colgroup > col");
2741
3155
  let rights = [];
@@ -2758,55 +3172,160 @@ function TableResizeOverlay({ tableRef, blockIndex, cols }) {
2758
3172
  });
2759
3173
  }
2760
3174
  if (rights.length !== cols) {
2761
- setLayout(null);
2762
- return;
3175
+ return null;
2763
3176
  }
2764
- setLayout({ rights, height: tableRect.height });
2765
- }, [cols, tableRef]);
2766
- (0, import_react9.useLayoutEffect)(() => {
3177
+ const trs = table.querySelectorAll("tbody > tr");
3178
+ const bottoms = [];
3179
+ let accY = 0;
3180
+ trs.forEach((tr) => {
3181
+ accY += tr.getBoundingClientRect().height;
3182
+ bottoms.push(accY);
3183
+ });
3184
+ return {
3185
+ rights,
3186
+ bottoms: trs.length === rows ? bottoms : [],
3187
+ width: tableRect.width,
3188
+ height: tableRect.height
3189
+ };
3190
+ }, [cols, rows, tableRef]);
3191
+ const measure = (0, import_react10.useCallback)(() => {
3192
+ setLayout(measureNow());
3193
+ }, [measureNow]);
3194
+ (0, import_react10.useLayoutEffect)(() => {
2767
3195
  measure();
2768
3196
  }, [measure]);
2769
- (0, import_react9.useEffect)(() => {
3197
+ (0, import_react10.useEffect)(() => {
2770
3198
  const table = tableRef.current;
2771
3199
  if (!table) return;
2772
3200
  const ro = new ResizeObserver(() => measure());
2773
3201
  ro.observe(table);
2774
3202
  return () => ro.disconnect();
2775
3203
  }, [measure, tableRef]);
2776
- const onPointerDown = (0, import_react9.useCallback)(
2777
- (col) => (e) => {
3204
+ const onPointerUp = (0, import_react10.useCallback)(
3205
+ (e) => {
3206
+ arrastoRef.current = null;
3207
+ measure();
3208
+ try {
3209
+ e.currentTarget.releasePointerCapture(e.pointerId);
3210
+ } catch {
3211
+ }
3212
+ },
3213
+ [measure]
3214
+ );
3215
+ const onPointerMove = (0, import_react10.useCallback)(
3216
+ (e) => {
3217
+ const d = arrastoRef.current;
3218
+ if (!d) return;
3219
+ switch (d.tipo) {
3220
+ case "coluna": {
3221
+ const dPct = deltaPctDoArrasto(e.clientX - d.startX, d.tableWidthPx);
3222
+ editor.setColumnBoundary(blockIndex, d.boundary, dPct, d.baseWidths);
3223
+ break;
3224
+ }
3225
+ case "larguraTotal": {
3226
+ const dPct = deltaPctDoArrasto(e.clientX - d.startX, d.utilPx);
3227
+ editor.setTableWidth(blockIndex, d.baseWidthPct + dPct);
3228
+ break;
3229
+ }
3230
+ case "linha": {
3231
+ editor.setRowHeight(blockIndex, d.row, d.baseHeightPx + (e.clientY - d.startY));
3232
+ break;
3233
+ }
3234
+ case "alturaTotal": {
3235
+ editor.setRowHeights(blockIndex, distribuirAltura(d.baseHeights, e.clientY - d.startY));
3236
+ break;
3237
+ }
3238
+ case "canto": {
3239
+ const dPct = deltaPctDoArrasto(e.clientX - d.startX, d.utilPx);
3240
+ editor.setTableWidth(blockIndex, d.baseWidthPct + dPct);
3241
+ editor.setRowHeights(blockIndex, distribuirAltura(d.baseHeights, e.clientY - d.startY));
3242
+ break;
3243
+ }
3244
+ }
3245
+ },
3246
+ [blockIndex, editor]
3247
+ );
3248
+ const containerWidthPxOf = (0, import_react10.useCallback)((table, tableWidthPx) => {
3249
+ return table.parentElement?.getBoundingClientRect().width || tableWidthPx;
3250
+ }, []);
3251
+ const onColumnPointerDown = (0, import_react10.useCallback)(
3252
+ (boundary) => (e) => {
2778
3253
  e.preventDefault();
2779
3254
  e.stopPropagation();
2780
3255
  const table = tableRef.current;
2781
3256
  if (!table) return;
2782
- const cgCols = table.querySelectorAll("colgroup > col");
2783
- const startWidth = cgCols[col]?.getBoundingClientRect().width ?? 100;
2784
- draggingRef.current = { col, startX: e.clientX, startWidth };
2785
- setPositions({ x: e.clientX, height: layout?.height ?? 0 });
3257
+ const tableWidthPx = table.getBoundingClientRect().width || 1;
3258
+ const attrs = editor.doc.getBlockAttrs(blockIndex);
3259
+ const baseWidths = (0, import_core7.normalizarLarguras)(attrs.colWidths, cols);
3260
+ arrastoRef.current = { tipo: "coluna", boundary, startX: e.clientX, baseWidths, tableWidthPx };
2786
3261
  e.currentTarget.setPointerCapture(e.pointerId);
2787
3262
  },
2788
- [layout, tableRef]
3263
+ [tableRef, editor, blockIndex, cols]
2789
3264
  );
2790
- const onPointerMove = (0, import_react9.useCallback)(
3265
+ const onTableWidthPointerDown = (0, import_react10.useCallback)(
2791
3266
  (e) => {
2792
- const d = draggingRef.current;
2793
- if (!d) return;
2794
- const dx = e.clientX - d.startX;
2795
- const next = Math.max(40, d.startWidth + dx);
2796
- editor.setColumnWidth(blockIndex, d.col, next);
3267
+ e.preventDefault();
3268
+ e.stopPropagation();
3269
+ const table = tableRef.current;
3270
+ if (!table) return;
3271
+ const tableWidthPx = table.getBoundingClientRect().width || 1;
3272
+ const utilPx = containerWidthPxOf(table, tableWidthPx);
3273
+ const attrs = editor.doc.getBlockAttrs(blockIndex);
3274
+ const baseWidthPct = typeof attrs.tableWidth === "number" ? attrs.tableWidth : 100;
3275
+ arrastoRef.current = { tipo: "larguraTotal", startX: e.clientX, baseWidthPct, utilPx };
3276
+ e.currentTarget.setPointerCapture(e.pointerId);
2797
3277
  },
2798
- [blockIndex, editor]
3278
+ [tableRef, editor, blockIndex, containerWidthPxOf]
3279
+ );
3280
+ const heightsFromBottoms = (bottoms) => bottoms.map((b, i) => b - (i === 0 ? 0 : bottoms[i - 1]));
3281
+ const onRowPointerDown = (0, import_react10.useCallback)(
3282
+ (row) => (e) => {
3283
+ e.preventDefault();
3284
+ e.stopPropagation();
3285
+ const m = measureNow();
3286
+ if (!m || m.bottoms.length === 0) return;
3287
+ const baseHeightPx = m.bottoms[row] - (row === 0 ? 0 : m.bottoms[row - 1]);
3288
+ arrastoRef.current = { tipo: "linha", row, startY: e.clientY, baseHeightPx };
3289
+ e.currentTarget.setPointerCapture(e.pointerId);
3290
+ },
3291
+ [measureNow]
3292
+ );
3293
+ const onTableHeightPointerDown = (0, import_react10.useCallback)(
3294
+ (e) => {
3295
+ e.preventDefault();
3296
+ e.stopPropagation();
3297
+ const m = measureNow();
3298
+ if (!m || m.bottoms.length === 0) return;
3299
+ arrastoRef.current = { tipo: "alturaTotal", startY: e.clientY, baseHeights: heightsFromBottoms(m.bottoms) };
3300
+ e.currentTarget.setPointerCapture(e.pointerId);
3301
+ },
3302
+ [measureNow]
3303
+ );
3304
+ const onCornerPointerDown = (0, import_react10.useCallback)(
3305
+ (e) => {
3306
+ e.preventDefault();
3307
+ e.stopPropagation();
3308
+ const table = tableRef.current;
3309
+ const m = measureNow();
3310
+ if (!table || !m) return;
3311
+ const tableWidthPx = table.getBoundingClientRect().width || 1;
3312
+ const utilPx = containerWidthPxOf(table, tableWidthPx);
3313
+ const attrs = editor.doc.getBlockAttrs(blockIndex);
3314
+ const baseWidthPct = typeof attrs.tableWidth === "number" ? attrs.tableWidth : 100;
3315
+ arrastoRef.current = {
3316
+ tipo: "canto",
3317
+ startX: e.clientX,
3318
+ startY: e.clientY,
3319
+ baseWidthPct,
3320
+ utilPx,
3321
+ baseHeights: heightsFromBottoms(m.bottoms)
3322
+ };
3323
+ e.currentTarget.setPointerCapture(e.pointerId);
3324
+ },
3325
+ [tableRef, editor, blockIndex, measureNow, containerWidthPxOf]
2799
3326
  );
2800
- const onPointerUp = (0, import_react9.useCallback)((e) => {
2801
- draggingRef.current = null;
2802
- setPositions(null);
2803
- try {
2804
- e.currentTarget.releasePointerCapture(e.pointerId);
2805
- } catch {
2806
- }
2807
- }, []);
2808
3327
  if (!layout) return null;
2809
- const handleStyle = (x) => ({
3328
+ const colHandleStyle = (x) => ({
2810
3329
  position: "absolute",
2811
3330
  top: 0,
2812
3331
  left: `${x - 3}px`,
@@ -2815,28 +3334,104 @@ function TableResizeOverlay({ tableRef, blockIndex, cols }) {
2815
3334
  cursor: "col-resize",
2816
3335
  zIndex: 5
2817
3336
  });
2818
- void positions;
2819
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: layout.rights.map((x, c) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2820
- "div",
2821
- {
2822
- contentEditable: false,
2823
- className: "ed-col-resize-handle",
2824
- style: handleStyle(x),
2825
- onPointerDown: onPointerDown(c),
2826
- onPointerMove,
2827
- onPointerUp,
2828
- "aria-label": `Redimensionar coluna ${c + 1}`,
2829
- role: "separator"
2830
- },
2831
- c
2832
- )) });
3337
+ const rowHandleStyle = (y) => ({
3338
+ position: "absolute",
3339
+ left: 0,
3340
+ top: `${y - 3}px`,
3341
+ width: `${layout.width}px`,
3342
+ height: "6px",
3343
+ cursor: "row-resize",
3344
+ zIndex: 5
3345
+ });
3346
+ const cornerHandleStyle = {
3347
+ position: "absolute",
3348
+ left: `${layout.width - 5}px`,
3349
+ top: `${layout.height - 5}px`,
3350
+ width: "10px",
3351
+ height: "10px",
3352
+ cursor: "nwse-resize",
3353
+ zIndex: 6
3354
+ };
3355
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
3356
+ layout.rights.map(
3357
+ (x, c) => c < cols - 1 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3358
+ "div",
3359
+ {
3360
+ contentEditable: false,
3361
+ className: "ed-col-resize-handle",
3362
+ style: colHandleStyle(x),
3363
+ onPointerDown: onColumnPointerDown(c),
3364
+ onPointerMove,
3365
+ onPointerUp,
3366
+ "aria-label": `Redimensionar coluna ${c + 1}`,
3367
+ role: "separator"
3368
+ },
3369
+ `col-${c}`
3370
+ ) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3371
+ "div",
3372
+ {
3373
+ contentEditable: false,
3374
+ className: "ed-col-resize-handle",
3375
+ style: colHandleStyle(x),
3376
+ onPointerDown: onTableWidthPointerDown,
3377
+ onPointerMove,
3378
+ onPointerUp,
3379
+ "aria-label": "Largura da tabela",
3380
+ role: "separator"
3381
+ },
3382
+ "col-total"
3383
+ )
3384
+ ),
3385
+ layout.bottoms.map(
3386
+ (y, r) => r < rows - 1 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3387
+ "div",
3388
+ {
3389
+ contentEditable: false,
3390
+ className: "ed-row-resize-handle",
3391
+ style: rowHandleStyle(y),
3392
+ onPointerDown: onRowPointerDown(r),
3393
+ onPointerMove,
3394
+ onPointerUp,
3395
+ "aria-label": `Redimensionar linha ${r + 1}`,
3396
+ role: "separator"
3397
+ },
3398
+ `row-${r}`
3399
+ ) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3400
+ "div",
3401
+ {
3402
+ contentEditable: false,
3403
+ className: "ed-row-resize-handle",
3404
+ style: rowHandleStyle(y),
3405
+ onPointerDown: onTableHeightPointerDown,
3406
+ onPointerMove,
3407
+ onPointerUp,
3408
+ "aria-label": "Altura da tabela",
3409
+ role: "separator"
3410
+ },
3411
+ "row-total"
3412
+ )
3413
+ ),
3414
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3415
+ "div",
3416
+ {
3417
+ contentEditable: false,
3418
+ className: "ed-table-corner-handle",
3419
+ style: cornerHandleStyle,
3420
+ onPointerDown: onCornerPointerDown,
3421
+ onPointerMove,
3422
+ onPointerUp,
3423
+ "aria-label": "Redimensionar tabela",
3424
+ role: "separator"
3425
+ }
3426
+ )
3427
+ ] });
2833
3428
  }
2834
3429
 
2835
3430
  // src/NodeView.tsx
2836
- var import_jsx_runtime11 = require("react/jsx-runtime");
3431
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2837
3432
  function NodeView({ block, index, children, fragment, tableFragment }) {
2838
3433
  if (block.type === "table") {
2839
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TableView, { block, index, tableFragment });
3434
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TableView, { block, index, tableFragment });
2840
3435
  }
2841
3436
  const inline = fragment ? renderInline(sliceDelta(block.delta, fragment.start, fragment.end), index) : renderInline(block.delta, index);
2842
3437
  const common = commonBlockProps(block.attrs, index, block.type, fragment);
@@ -2844,7 +3439,7 @@ function NodeView({ block, index, children, fragment, tableFragment }) {
2844
3439
  case "heading": {
2845
3440
  const level = clampLevel2(block.attrs.level);
2846
3441
  const Tag = `h${level}`;
2847
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3442
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2848
3443
  Tag,
2849
3444
  {
2850
3445
  ...common,
@@ -2854,7 +3449,7 @@ function NodeView({ block, index, children, fragment, tableFragment }) {
2854
3449
  );
2855
3450
  }
2856
3451
  case "blockquote":
2857
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3452
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2858
3453
  "blockquote",
2859
3454
  {
2860
3455
  ...common,
@@ -2863,18 +3458,18 @@ function NodeView({ block, index, children, fragment, tableFragment }) {
2863
3458
  }
2864
3459
  );
2865
3460
  case "codeBlock":
2866
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3461
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2867
3462
  "pre",
2868
3463
  {
2869
3464
  ...common,
2870
3465
  "data-language": block.attrs.language ?? void 0,
2871
3466
  className: `ed-block ed-codeblock${alignClass(block.attrs.align)}`,
2872
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("code", { children: inline })
3467
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("code", { children: inline })
2873
3468
  }
2874
3469
  );
2875
3470
  case "listItem": {
2876
3471
  const level = clampListLevel(block.attrs.listLevel);
2877
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
3472
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2878
3473
  "li",
2879
3474
  {
2880
3475
  ...common,
@@ -2890,7 +3485,7 @@ function NodeView({ block, index, children, fragment, tableFragment }) {
2890
3485
  }
2891
3486
  case "paragraph":
2892
3487
  default:
2893
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3488
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2894
3489
  "div",
2895
3490
  {
2896
3491
  ...common,
@@ -2903,7 +3498,7 @@ function NodeView({ block, index, children, fragment, tableFragment }) {
2903
3498
  function commonBlockProps(attrs, index, type, fragment) {
2904
3499
  const style = {};
2905
3500
  if (attrs.align) style.textAlign = attrs.align;
2906
- Object.assign(style, (0, import_core7.answerLineStyle)(attrs) ?? {});
3501
+ Object.assign(style, (0, import_core8.answerLineStyle)(attrs) ?? {});
2907
3502
  const base = {
2908
3503
  "data-block-index": index,
2909
3504
  "data-block-type": type,
@@ -2937,84 +3532,107 @@ function clampListLevel(l) {
2937
3532
  if (typeof l !== "number" || !Number.isFinite(l)) return 0;
2938
3533
  return Math.max(0, Math.min(5, Math.trunc(l)));
2939
3534
  }
3535
+ function renderCellContent(attrs, delta, keyPrefix) {
3536
+ const kind = attrs?.listKind;
3537
+ if (!kind) return renderInline(delta, keyPrefix);
3538
+ const linhas = (0, import_core8.splitDeltaByLines)(delta);
3539
+ const Tag = kind === "ordered" ? "ol" : "ul";
3540
+ let baseOffset = 0;
3541
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3542
+ Tag,
3543
+ {
3544
+ className: `ed-list ed-list-${kind}`,
3545
+ "data-list-kind": kind,
3546
+ start: kind === "ordered" && typeof attrs?.listStart === "number" ? attrs.listStart : void 0,
3547
+ style: attrs?.listStyle ? { listStyleType: attrs.listStyle } : void 0,
3548
+ children: linhas.map((linha, i) => {
3549
+ const li = /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("li", { className: "ed-listitem", "data-cell-line": i, children: renderInline(linha, `${keyPrefix}-l${i}`, baseOffset) }, i);
3550
+ baseOffset += (0, import_core8.deltaLength)(linha) + 1;
3551
+ return li;
3552
+ })
3553
+ }
3554
+ );
3555
+ }
2940
3556
  function TableView({ block, index, tableFragment }) {
2941
3557
  const rows = clampPositive(block.attrs.rows);
2942
3558
  const cols = clampPositive(block.attrs.cols);
2943
3559
  const cells = block.cells ?? [];
2944
- const widths = readColWidths(block.attrs.colWidths, cols);
2945
- const tableRef = (0, import_react10.useRef)(null);
3560
+ const widths = (0, import_core8.normalizarLarguras)(block.attrs.colWidths, cols);
3561
+ const tableWidth = block.attrs.tableWidth;
3562
+ const rowHeights = block.attrs.rowHeights;
3563
+ const tableRef = (0, import_react11.useRef)(null);
2946
3564
  const rowStart = tableFragment?.rowStart ?? 0;
2947
3565
  const rowEnd = tableFragment?.rowEnd ?? rows;
2948
3566
  const isFirstFragment = !tableFragment || tableFragment.index === 0;
2949
3567
  const editor = useEditorContext();
2950
- const rect = (0, import_react10.useMemo)(() => {
3568
+ const rect = (0, import_react11.useMemo)(() => {
2951
3569
  if (editor.selection.anchor.blockIndex !== index) return null;
2952
3570
  if (editor.selection.focus.blockIndex !== index) return null;
2953
- return (0, import_core7.tableRectSelection)(editor.doc, editor.selection);
3571
+ return (0, import_core8.tableRectSelection)(editor.doc, editor.selection);
2954
3572
  }, [editor.doc, editor.selection, index]);
2955
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "ed-table-wrap", children: [
2956
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
3573
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "ed-table-wrap", children: [
3574
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2957
3575
  "table",
2958
3576
  {
2959
3577
  ref: tableRef,
2960
3578
  "data-block-index": index,
2961
3579
  "data-block-type": "table",
2962
3580
  className: "ed-block ed-table",
3581
+ style: typeof tableWidth === "number" ? { width: `${tableWidth}%` } : void 0,
2963
3582
  children: [
2964
- widths && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("colgroup", { children: widths.map((w, c) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("col", { style: w != null ? { width: `${w}px` } : void 0 }, c)) }),
2965
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("tbody", { children: Array.from({ length: rowEnd - rowStart }, (_, i) => {
3583
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("colgroup", { children: widths.map((w, c) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("col", { style: { width: `${w}%` } }, c)) }),
3584
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("tbody", { children: Array.from({ length: rowEnd - rowStart }, (_, i) => {
2966
3585
  const r = rowStart + i;
2967
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("tr", { "data-cell-row": r, children: Array.from({ length: cols }, (_2, c) => {
2968
- const flat = r * cols + c;
2969
- const cell = cells[flat];
2970
- if (cell?.attrs.covered === true) return null;
2971
- const rowspan = spanAttr(cell?.attrs.rowspan);
2972
- const colspan = spanAttr(cell?.attrs.colspan);
2973
- const delta = cell?.delta ?? [];
2974
- const inRect = rect !== null && r >= rect.top && r <= rect.bottom && c >= rect.left && c <= rect.right;
2975
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2976
- "td",
2977
- {
2978
- "data-cell-index": flat,
2979
- "data-cell-row": r,
2980
- "data-cell-col": c,
2981
- "data-cell-rowspan": rowspan,
2982
- "data-cell-colspan": colspan,
2983
- rowSpan: rowspan > 1 ? rowspan : void 0,
2984
- colSpan: colspan > 1 ? colspan : void 0,
2985
- style: cellStyle(
2986
- cell?.attrs,
2987
- // rowStart/rowEnd são os limites do FRAGMENTO: numa tabela
2988
- // quebrada entre páginas, cada página fecha a própria caixa.
2989
- (0, import_core7.cellBorderStyle)(
2990
- block.attrs.borderPreset,
2991
- { row: r, col: c, rowspan, colspan, cols, rowStart, rowEnd },
2992
- "screen",
2993
- block.attrs.borderColor
2994
- )
2995
- ),
2996
- className: inRect ? "ed-cell ed-cell--selected" : "ed-cell",
2997
- children: renderInline(delta, `t${index}-c${flat}`)
2998
- },
2999
- c
3000
- );
3001
- }) }, r);
3586
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3587
+ "tr",
3588
+ {
3589
+ "data-cell-row": r,
3590
+ style: typeof rowHeights?.[r] === "number" ? { height: `${rowHeights[r]}px` } : void 0,
3591
+ children: Array.from({ length: cols }, (_2, c) => {
3592
+ const flat = r * cols + c;
3593
+ const cell = cells[flat];
3594
+ if (cell?.attrs.covered === true) return null;
3595
+ const rowspan = spanAttr(cell?.attrs.rowspan);
3596
+ const colspan = spanAttr(cell?.attrs.colspan);
3597
+ const delta = cell?.delta ?? [];
3598
+ const inRect = rect !== null && r >= rect.top && r <= rect.bottom && c >= rect.left && c <= rect.right;
3599
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3600
+ "td",
3601
+ {
3602
+ "data-cell-index": flat,
3603
+ "data-cell-row": r,
3604
+ "data-cell-col": c,
3605
+ "data-cell-rowspan": rowspan,
3606
+ "data-cell-colspan": colspan,
3607
+ rowSpan: rowspan > 1 ? rowspan : void 0,
3608
+ colSpan: colspan > 1 ? colspan : void 0,
3609
+ style: cellStyle(
3610
+ cell?.attrs,
3611
+ // rowStart/rowEnd são os limites do FRAGMENTO: numa tabela
3612
+ // quebrada entre páginas, cada página fecha a própria caixa.
3613
+ (0, import_core8.cellBorderStyle)(
3614
+ block.attrs.borderPreset,
3615
+ { row: r, col: c, rowspan, colspan, cols, rowStart, rowEnd },
3616
+ "screen",
3617
+ block.attrs.borderColor
3618
+ )
3619
+ ),
3620
+ className: inRect ? "ed-cell ed-cell--selected" : "ed-cell",
3621
+ children: renderCellContent(cell?.attrs, delta, `t${index}-c${flat}`)
3622
+ },
3623
+ c
3624
+ );
3625
+ })
3626
+ },
3627
+ r
3628
+ );
3002
3629
  }) })
3003
3630
  ]
3004
3631
  }
3005
3632
  ),
3006
- isFirstFragment && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TableResizeOverlay, { tableRef, blockIndex: index, cols })
3633
+ isFirstFragment && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TableResizeOverlay, { tableRef, blockIndex: index, cols, rows })
3007
3634
  ] });
3008
3635
  }
3009
- function readColWidths(raw, cols) {
3010
- if (!Array.isArray(raw)) return null;
3011
- const out = [];
3012
- for (let i = 0; i < cols; i++) {
3013
- const v = raw[i];
3014
- out.push(typeof v === "number" && Number.isFinite(v) && v > 0 ? v : null);
3015
- }
3016
- return out;
3017
- }
3018
3636
  function spanAttr(v) {
3019
3637
  if (typeof v !== "number" || !Number.isFinite(v) || v < 1) return 1;
3020
3638
  return Math.trunc(v);
@@ -3025,7 +3643,7 @@ function clampPositive(n) {
3025
3643
  }
3026
3644
 
3027
3645
  // src/usePagination.ts
3028
- var import_react11 = require("react");
3646
+ var import_react12 = require("react");
3029
3647
  var A4_PAGE = {
3030
3648
  width: 794,
3031
3649
  height: 1123,
@@ -3051,10 +3669,10 @@ function defaultPageLayout(topLevelCount) {
3051
3669
  };
3052
3670
  }
3053
3671
  function usePageLayout(rootRef, geometry, topLevelCount, deps) {
3054
- const [phase, setPhase] = (0, import_react11.useState)("measure");
3055
- const [layout, setLayout] = (0, import_react11.useState)(() => defaultPageLayout(topLevelCount));
3056
- const lastDepsRef = (0, import_react11.useRef)(null);
3057
- (0, import_react11.useLayoutEffect)(() => {
3672
+ const [phase, setPhase] = (0, import_react12.useState)("measure");
3673
+ const [layout, setLayout] = (0, import_react12.useState)(() => defaultPageLayout(topLevelCount));
3674
+ const lastDepsRef = (0, import_react12.useRef)(null);
3675
+ (0, import_react12.useLayoutEffect)(() => {
3058
3676
  const currentDeps = [...deps, topLevelCount, geometry];
3059
3677
  if (lastDepsRef.current !== null && shallowArrayEqual(lastDepsRef.current, currentDeps)) {
3060
3678
  return;
@@ -3066,7 +3684,7 @@ function usePageLayout(rootRef, geometry, topLevelCount, deps) {
3066
3684
  });
3067
3685
  setPhase("measure");
3068
3686
  });
3069
- (0, import_react11.useLayoutEffect)(() => {
3687
+ (0, import_react12.useLayoutEffect)(() => {
3070
3688
  if (phase !== "measure") return;
3071
3689
  const root = rootRef.current;
3072
3690
  if (!root) return;
@@ -3538,47 +4156,47 @@ function layoutsDeepEqual(a, b) {
3538
4156
  }
3539
4157
 
3540
4158
  // src/useEditor.ts
3541
- var import_react13 = require("react");
4159
+ var import_react14 = require("react");
3542
4160
 
3543
4161
  // src/usePageSettings.ts
3544
- var import_react12 = require("react");
4162
+ var import_react13 = require("react");
3545
4163
  function usePageSettings(doc) {
3546
- const cacheRef = (0, import_react12.useRef)(null);
3547
- const subscribe = (0, import_react12.useCallback)(
4164
+ const cacheRef = (0, import_react13.useRef)(null);
4165
+ const subscribe = (0, import_react13.useCallback)(
3548
4166
  (notify) => doc.observePageSettings(notify),
3549
4167
  [doc]
3550
4168
  );
3551
- const getSnapshot = (0, import_react12.useCallback)(() => {
4169
+ const getSnapshot = (0, import_react13.useCallback)(() => {
3552
4170
  const next = doc.getPageSettings();
3553
4171
  const prev = cacheRef.current;
3554
4172
  if (prev && shallowEqual(prev, next)) return prev;
3555
4173
  cacheRef.current = next;
3556
4174
  return next;
3557
4175
  }, [doc]);
3558
- return (0, import_react12.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
4176
+ return (0, import_react13.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
3559
4177
  }
3560
4178
  function shallowEqual(a, b) {
3561
4179
  return a.width === b.width && a.height === b.height && a.marginTop === b.marginTop && a.marginBottom === b.marginBottom && a.marginLeft === b.marginLeft && a.marginRight === b.marginRight && a.preset === b.preset && a.systemHeaderTitle === b.systemHeaderTitle && a.systemHeaderAuthor === b.systemHeaderAuthor;
3562
4180
  }
3563
4181
 
3564
4182
  // src/useEditor.ts
3565
- var import_core8 = require("@sofereditor/core");
4183
+ var import_core9 = require("@sofereditor/core");
3566
4184
  function useEditor(opts = {}) {
3567
- const doc = (0, import_react13.useMemo)(() => opts.document ?? new import_core8.EditorDocument(), [opts.document]);
3568
- const history = (0, import_react13.useMemo)(() => new import_core8.EditorHistory(doc), [doc]);
3569
- const [snapshot, setSnapshot] = (0, import_react13.useState)(() => doc.toJSON());
3570
- const [selection, setSelectionState] = (0, import_react13.useState)(
3571
- () => (0, import_core8.collapsedSelection)({ blockIndex: 0, offset: 0 })
4185
+ const doc = (0, import_react14.useMemo)(() => opts.document ?? new import_core9.EditorDocument(), [opts.document]);
4186
+ const history = (0, import_react14.useMemo)(() => new import_core9.EditorHistory(doc), [doc]);
4187
+ const [snapshot, setSnapshot] = (0, import_react14.useState)(() => doc.toJSON());
4188
+ const [selection, setSelectionState] = (0, import_react14.useState)(
4189
+ () => (0, import_core9.collapsedSelection)({ blockIndex: 0, offset: 0 })
3572
4190
  );
3573
- const selectionRef = (0, import_react13.useRef)(selection);
4191
+ const selectionRef = (0, import_react14.useRef)(selection);
3574
4192
  selectionRef.current = selection;
3575
- const pendingMarksRef = (0, import_react13.useRef)({});
3576
- const [pendingMarks, setPendingMarksState] = (0, import_react13.useState)({});
3577
- const setPendingMarks = (0, import_react13.useCallback)((next) => {
4193
+ const pendingMarksRef = (0, import_react14.useRef)({});
4194
+ const [pendingMarks, setPendingMarksState] = (0, import_react14.useState)({});
4195
+ const setPendingMarks = (0, import_react14.useCallback)((next) => {
3578
4196
  pendingMarksRef.current = next;
3579
4197
  setPendingMarksState(next);
3580
4198
  }, []);
3581
- (0, import_react13.useEffect)(() => {
4199
+ (0, import_react14.useEffect)(() => {
3582
4200
  let scheduled = false;
3583
4201
  let cancelled = false;
3584
4202
  let frame = 0;
@@ -3605,8 +4223,8 @@ function useEditor(opts = {}) {
3605
4223
  doc.ydoc.off("afterTransaction", schedule);
3606
4224
  };
3607
4225
  }, [doc]);
3608
- const getSelection = (0, import_react13.useCallback)(() => selectionRef.current, []);
3609
- const setSelection = (0, import_react13.useCallback)(
4226
+ const getSelection = (0, import_react14.useCallback)(() => selectionRef.current, []);
4227
+ const setSelection = (0, import_react14.useCallback)(
3610
4228
  (sel) => {
3611
4229
  const prev = selectionRef.current;
3612
4230
  selectionRef.current = sel;
@@ -3621,19 +4239,19 @@ function useEditor(opts = {}) {
3621
4239
  },
3622
4240
  []
3623
4241
  );
3624
- const ctxRef = (0, import_react13.useRef)({ doc, getSelection, setSelection });
4242
+ const ctxRef = (0, import_react14.useRef)({ doc, getSelection, setSelection });
3625
4243
  ctxRef.current = { doc, getSelection, setSelection };
3626
- const consumePendingMarks = (0, import_react13.useCallback)(() => {
4244
+ const consumePendingMarks = (0, import_react14.useCallback)(() => {
3627
4245
  const current = pendingMarksRef.current;
3628
4246
  if (Object.keys(current).length === 0) return void 0;
3629
4247
  pendingMarksRef.current = {};
3630
4248
  setPendingMarksState({});
3631
4249
  return current;
3632
4250
  }, []);
3633
- const isMarkActive = (0, import_react13.useCallback)(
4251
+ const isMarkActive = (0, import_react14.useCallback)(
3634
4252
  (name, value) => {
3635
4253
  const sel = selectionRef.current;
3636
- const { start, end } = (0, import_core8.orderedRange)(sel);
4254
+ const { start, end } = (0, import_core9.orderedRange)(sel);
3637
4255
  if (start.blockIndex === end.blockIndex && start.offset === end.offset) {
3638
4256
  const pending = pendingMarksRef.current[name];
3639
4257
  if (pending !== void 0) {
@@ -3642,7 +4260,7 @@ function useEditor(opts = {}) {
3642
4260
  }
3643
4261
  const yText2 = doc.getBlockText(start.blockIndex);
3644
4262
  if (!yText2 || start.offset === 0) return false;
3645
- return (0, import_core8.isMarkUniformInRange)(yText2, start.offset - 1, start.offset, name, value);
4263
+ return (0, import_core9.isMarkUniformInRange)(yText2, start.offset - 1, start.offset, name, value);
3646
4264
  }
3647
4265
  if (start.blockIndex !== end.blockIndex) {
3648
4266
  for (let i = start.blockIndex; i <= end.blockIndex; i++) {
@@ -3651,19 +4269,19 @@ function useEditor(opts = {}) {
3651
4269
  const s = i === start.blockIndex ? start.offset : 0;
3652
4270
  const e = i === end.blockIndex ? end.offset : yText2.length;
3653
4271
  if (s >= e) continue;
3654
- if (!(0, import_core8.isMarkUniformInRange)(yText2, s, e, name, value)) return false;
4272
+ if (!(0, import_core9.isMarkUniformInRange)(yText2, s, e, name, value)) return false;
3655
4273
  }
3656
4274
  return true;
3657
4275
  }
3658
4276
  const yText = doc.getBlockText(start.blockIndex);
3659
4277
  if (!yText) return false;
3660
- return (0, import_core8.isMarkUniformInRange)(yText, start.offset, end.offset, name, value);
4278
+ return (0, import_core9.isMarkUniformInRange)(yText, start.offset, end.offset, name, value);
3661
4279
  },
3662
4280
  [doc]
3663
4281
  );
3664
- const getActiveMarks = (0, import_react13.useCallback)(() => {
4282
+ const getActiveMarks = (0, import_react14.useCallback)(() => {
3665
4283
  const sel = selectionRef.current;
3666
- const { start, end } = (0, import_core8.orderedRange)(sel);
4284
+ const { start, end } = (0, import_core9.orderedRange)(sel);
3667
4285
  if (start.blockIndex !== end.blockIndex) {
3668
4286
  return {};
3669
4287
  }
@@ -3671,14 +4289,14 @@ function useEditor(opts = {}) {
3671
4289
  if (!yText) return {};
3672
4290
  if (start.offset === end.offset) {
3673
4291
  if (start.offset === 0) return {};
3674
- return (0, import_core8.getMarksInRange)(yText, start.offset - 1, start.offset);
4292
+ return (0, import_core9.getMarksInRange)(yText, start.offset - 1, start.offset);
3675
4293
  }
3676
- return (0, import_core8.getMarksInRange)(yText, start.offset, end.offset);
4294
+ return (0, import_core9.getMarksInRange)(yText, start.offset, end.offset);
3677
4295
  }, [doc]);
3678
- const toggleMark = (0, import_react13.useCallback)(
4296
+ const toggleMark = (0, import_react14.useCallback)(
3679
4297
  (name, value) => {
3680
4298
  const sel = selectionRef.current;
3681
- const { start, end } = (0, import_core8.orderedRange)(sel);
4299
+ const { start, end } = (0, import_core9.orderedRange)(sel);
3682
4300
  const isCollapsed = start.blockIndex === end.blockIndex && start.offset === end.offset;
3683
4301
  if (isCollapsed) {
3684
4302
  const next = { ...pendingMarksRef.current };
@@ -3691,39 +4309,39 @@ function useEditor(opts = {}) {
3691
4309
  setPendingMarks(next);
3692
4310
  return;
3693
4311
  }
3694
- (0, import_core8.toggleMark)(ctxRef.current, name, value);
4312
+ (0, import_core9.toggleMark)(ctxRef.current, name, value);
3695
4313
  },
3696
4314
  [isMarkActive, setPendingMarks]
3697
4315
  );
3698
- const setMark = (0, import_react13.useCallback)(
4316
+ const setMark = (0, import_react14.useCallback)(
3699
4317
  (name, value) => {
3700
4318
  const sel = selectionRef.current;
3701
- const { start, end } = (0, import_core8.orderedRange)(sel);
4319
+ const { start, end } = (0, import_core9.orderedRange)(sel);
3702
4320
  const isCollapsed = start.blockIndex === end.blockIndex && start.offset === end.offset;
3703
4321
  if (isCollapsed) {
3704
4322
  setPendingMarks({ ...pendingMarksRef.current, [name]: value });
3705
4323
  return;
3706
4324
  }
3707
- (0, import_core8.setMark)(ctxRef.current, name, value);
4325
+ (0, import_core9.setMark)(ctxRef.current, name, value);
3708
4326
  },
3709
4327
  [setPendingMarks]
3710
4328
  );
3711
- const removeMark = (0, import_react13.useCallback)(
4329
+ const removeMark = (0, import_react14.useCallback)(
3712
4330
  (name) => {
3713
4331
  const sel = selectionRef.current;
3714
- const { start, end } = (0, import_core8.orderedRange)(sel);
4332
+ const { start, end } = (0, import_core9.orderedRange)(sel);
3715
4333
  const isCollapsed = start.blockIndex === end.blockIndex && start.offset === end.offset;
3716
4334
  if (isCollapsed) {
3717
4335
  setPendingMarks({ ...pendingMarksRef.current, [name]: null });
3718
4336
  return;
3719
4337
  }
3720
- (0, import_core8.removeMark)(ctxRef.current, name);
4338
+ (0, import_core9.removeMark)(ctxRef.current, name);
3721
4339
  },
3722
4340
  [setPendingMarks]
3723
4341
  );
3724
- const getBlockType = (0, import_react13.useCallback)(() => {
4342
+ const getBlockType = (0, import_react14.useCallback)(() => {
3725
4343
  const sel = selectionRef.current;
3726
- const { start, end } = (0, import_core8.orderedRange)(sel);
4344
+ const { start, end } = (0, import_core9.orderedRange)(sel);
3727
4345
  const first = doc.getBlockType(start.blockIndex);
3728
4346
  if (first === void 0) return "paragraph";
3729
4347
  for (let i = start.blockIndex + 1; i <= end.blockIndex; i++) {
@@ -3731,10 +4349,10 @@ function useEditor(opts = {}) {
3731
4349
  }
3732
4350
  return first;
3733
4351
  }, [doc]);
3734
- const getBlockAttr = (0, import_react13.useCallback)(
4352
+ const getBlockAttr = (0, import_react14.useCallback)(
3735
4353
  (key) => {
3736
4354
  const sel = selectionRef.current;
3737
- const { start, end } = (0, import_core8.orderedRange)(sel);
4355
+ const { start, end } = (0, import_core9.orderedRange)(sel);
3738
4356
  const first = doc.getBlockAttrs(start.blockIndex)[key];
3739
4357
  for (let i = start.blockIndex + 1; i <= end.blockIndex; i++) {
3740
4358
  const next = doc.getBlockAttrs(i)[key];
@@ -3744,60 +4362,64 @@ function useEditor(opts = {}) {
3744
4362
  },
3745
4363
  [doc]
3746
4364
  );
3747
- const setBlockType = (0, import_react13.useCallback)((type, attrs) => {
3748
- (0, import_core8.setBlockType)(ctxRef.current, type, attrs);
4365
+ const setBlockType = (0, import_react14.useCallback)((type, attrs) => {
4366
+ (0, import_core9.setBlockType)(ctxRef.current, type, attrs);
3749
4367
  }, []);
3750
- const setBlockAttr = (0, import_react13.useCallback)(
4368
+ const setBlockAttr = (0, import_react14.useCallback)(
3751
4369
  (key, value) => {
3752
- (0, import_core8.setBlockAttr)(ctxRef.current, key, value);
4370
+ (0, import_core9.setBlockAttr)(ctxRef.current, key, value);
3753
4371
  },
3754
4372
  []
3755
4373
  );
3756
- const setAlign = (0, import_react13.useCallback)((value) => {
4374
+ const setAlign = (0, import_react14.useCallback)((value) => {
3757
4375
  const sel = selectionRef.current;
3758
4376
  const inCell = sel.focus.cellIndex != null;
3759
- if (inCell) (0, import_core8.setCellAttr)(ctxRef.current, "align", value);
3760
- else (0, import_core8.setBlockAttr)(ctxRef.current, "align", value);
4377
+ if (inCell) (0, import_core9.setCellAttr)(ctxRef.current, "align", value);
4378
+ else (0, import_core9.setBlockAttr)(ctxRef.current, "align", value);
3761
4379
  }, []);
3762
- const getAlign = (0, import_react13.useCallback)(() => {
4380
+ const getAlign = (0, import_react14.useCallback)(() => {
3763
4381
  const sel = selectionRef.current;
3764
4382
  if (sel.focus.cellIndex != null && doc.isTable(sel.focus.blockIndex)) {
3765
4383
  return doc.getCellAttrs(sel.focus.blockIndex, sel.focus.cellIndex).align;
3766
4384
  }
3767
4385
  return getBlockAttr("align");
3768
4386
  }, [doc, getBlockAttr]);
3769
- const setCellBackground = (0, import_react13.useCallback)((color) => {
3770
- (0, import_core8.setCellAttr)(ctxRef.current, "bgColor", color);
4387
+ const setCellBackground = (0, import_react14.useCallback)((color) => {
4388
+ (0, import_core9.setCellAttr)(ctxRef.current, "bgColor", color);
3771
4389
  }, []);
3772
- const getCellBackground = (0, import_react13.useCallback)(() => {
4390
+ const getCellBackground = (0, import_react14.useCallback)(() => {
3773
4391
  const sel = selectionRef.current;
3774
4392
  if (sel.focus.cellIndex == null || !doc.isTable(sel.focus.blockIndex)) return void 0;
3775
4393
  return doc.getCellAttrs(sel.focus.blockIndex, sel.focus.cellIndex).bgColor;
3776
4394
  }, [doc]);
3777
- const setTableBorderPreset = (0, import_react13.useCallback)((preset) => {
4395
+ const setTableBorderPreset = (0, import_react14.useCallback)((preset) => {
3778
4396
  const sel = selectionRef.current;
3779
4397
  if (!doc.isTable(sel.focus.blockIndex)) return;
3780
- (0, import_core8.setBlockAttrAtIndex)(ctxRef.current, sel.focus.blockIndex, "borderPreset", preset);
4398
+ (0, import_core9.setBlockAttrAtIndex)(ctxRef.current, sel.focus.blockIndex, "borderPreset", preset);
3781
4399
  }, [doc]);
3782
- const getTableBorderPreset = (0, import_react13.useCallback)(() => {
4400
+ const getTableBorderPreset = (0, import_react14.useCallback)(() => {
3783
4401
  const sel = selectionRef.current;
3784
4402
  if (!doc.isTable(sel.focus.blockIndex)) return "all";
3785
4403
  return doc.getBlockAttrs(sel.focus.blockIndex).borderPreset ?? "all";
3786
4404
  }, [doc]);
3787
- const setTableBorderColor = (0, import_react13.useCallback)((color) => {
4405
+ const setTableBorderColor = (0, import_react14.useCallback)((color) => {
3788
4406
  const sel = selectionRef.current;
3789
4407
  if (!doc.isTable(sel.focus.blockIndex)) return;
3790
- (0, import_core8.setBlockAttrAtIndex)(ctxRef.current, sel.focus.blockIndex, "borderColor", color);
4408
+ (0, import_core9.setBlockAttrAtIndex)(ctxRef.current, sel.focus.blockIndex, "borderColor", color);
3791
4409
  }, [doc]);
3792
- const getTableBorderColor = (0, import_react13.useCallback)(() => {
4410
+ const getTableBorderColor = (0, import_react14.useCallback)(() => {
3793
4411
  const sel = selectionRef.current;
3794
4412
  if (!doc.isTable(sel.focus.blockIndex)) return void 0;
3795
4413
  return doc.getBlockAttrs(sel.focus.blockIndex).borderColor;
3796
4414
  }, [doc]);
3797
- const isListActive = (0, import_react13.useCallback)(
4415
+ const isListActive = (0, import_react14.useCallback)(
3798
4416
  (kind) => {
3799
4417
  const sel = selectionRef.current;
3800
- const { start, end } = (0, import_core8.orderedRange)(sel);
4418
+ if (sel.focus.cellIndex != null && doc.isTable(sel.focus.blockIndex)) {
4419
+ const real = doc.realCellIndex(sel.focus.blockIndex, sel.focus.cellIndex);
4420
+ return real != null && doc.getCellAttrs(sel.focus.blockIndex, real).listKind === kind;
4421
+ }
4422
+ const { start, end } = (0, import_core9.orderedRange)(sel);
3801
4423
  for (let i = start.blockIndex; i <= end.blockIndex; i++) {
3802
4424
  if (doc.getBlockType(i) !== "listItem") return false;
3803
4425
  if (doc.getBlockAttrs(i).listKind !== kind) return false;
@@ -3806,119 +4428,128 @@ function useEditor(opts = {}) {
3806
4428
  },
3807
4429
  [doc]
3808
4430
  );
3809
- const toggleList = (0, import_react13.useCallback)((kind) => {
3810
- (0, import_core8.toggleList)(ctxRef.current, kind);
4431
+ const toggleList = (0, import_react14.useCallback)((kind) => {
4432
+ (0, import_core9.toggleList)(ctxRef.current, kind);
3811
4433
  }, []);
3812
- const indentList = (0, import_react13.useCallback)(() => {
3813
- (0, import_core8.indentList)(ctxRef.current);
4434
+ const indentList = (0, import_react14.useCallback)(() => {
4435
+ (0, import_core9.indentList)(ctxRef.current);
3814
4436
  }, []);
3815
- const dedentList = (0, import_react13.useCallback)(() => {
3816
- (0, import_core8.dedentList)(ctxRef.current);
4437
+ const dedentList = (0, import_react14.useCallback)(() => {
4438
+ (0, import_core9.dedentList)(ctxRef.current);
3817
4439
  }, []);
3818
- const splitListItem = (0, import_react13.useCallback)(() => {
3819
- return (0, import_core8.splitListItem)(ctxRef.current);
4440
+ const splitListItem = (0, import_react14.useCallback)(() => {
4441
+ return (0, import_core9.splitListItem)(ctxRef.current);
3820
4442
  }, []);
3821
- const isInTable = (0, import_react13.useCallback)(() => {
4443
+ const isInTable = (0, import_react14.useCallback)(() => {
3822
4444
  return selectionRef.current.focus.cellIndex != null;
3823
4445
  }, []);
3824
- const getTableLocation = (0, import_react13.useCallback)(() => {
3825
- return (0, import_core8.tableLocationOf)(doc, selectionRef.current.focus);
4446
+ const getTableLocation = (0, import_react14.useCallback)(() => {
4447
+ return (0, import_core9.tableLocationOf)(doc, selectionRef.current.focus);
3826
4448
  }, [doc]);
3827
- const insertTable = (0, import_react13.useCallback)((rows, cols) => {
3828
- (0, import_core8.insertTable)(ctxRef.current, rows, cols);
4449
+ const insertTable = (0, import_react14.useCallback)((rows, cols) => {
4450
+ (0, import_core9.insertTable)(ctxRef.current, rows, cols);
3829
4451
  }, []);
3830
- const insertAnswerLines = (0, import_react13.useCallback)((count, spacing) => {
3831
- (0, import_core8.insertAnswerLines)(ctxRef.current, count, spacing);
4452
+ const insertAnswerLines = (0, import_react14.useCallback)((count, spacing) => {
4453
+ (0, import_core9.insertAnswerLines)(ctxRef.current, count, spacing);
3832
4454
  }, []);
3833
- const deleteTable = (0, import_react13.useCallback)((blockIndex) => {
4455
+ const deleteTable = (0, import_react14.useCallback)((blockIndex) => {
3834
4456
  const idx = blockIndex ?? selectionRef.current.focus.blockIndex;
3835
- (0, import_core8.deleteTable)(ctxRef.current, idx);
4457
+ (0, import_core9.deleteTable)(ctxRef.current, idx);
3836
4458
  }, []);
3837
- const insertRowAbove = (0, import_react13.useCallback)(() => {
3838
- const loc = (0, import_core8.tableLocationOf)(doc, selectionRef.current.focus);
4459
+ const insertRowAbove = (0, import_react14.useCallback)(() => {
4460
+ const loc = (0, import_core9.tableLocationOf)(doc, selectionRef.current.focus);
3839
4461
  if (!loc) return;
3840
- (0, import_core8.insertTableRow)(ctxRef.current, loc.blockIndex, loc.row, "before");
4462
+ (0, import_core9.insertTableRow)(ctxRef.current, loc.blockIndex, loc.row, "before");
3841
4463
  }, [doc]);
3842
- const insertRowBelow = (0, import_react13.useCallback)(() => {
3843
- const loc = (0, import_core8.tableLocationOf)(doc, selectionRef.current.focus);
4464
+ const insertRowBelow = (0, import_react14.useCallback)(() => {
4465
+ const loc = (0, import_core9.tableLocationOf)(doc, selectionRef.current.focus);
3844
4466
  if (!loc) return;
3845
- (0, import_core8.insertTableRow)(ctxRef.current, loc.blockIndex, loc.row, "after");
4467
+ (0, import_core9.insertTableRow)(ctxRef.current, loc.blockIndex, loc.row, "after");
3846
4468
  }, [doc]);
3847
- const deleteCurrentRow = (0, import_react13.useCallback)(() => {
3848
- const loc = (0, import_core8.tableLocationOf)(doc, selectionRef.current.focus);
4469
+ const deleteCurrentRow = (0, import_react14.useCallback)(() => {
4470
+ const loc = (0, import_core9.tableLocationOf)(doc, selectionRef.current.focus);
3849
4471
  if (!loc) return;
3850
- (0, import_core8.deleteTableRow)(ctxRef.current, loc.blockIndex, loc.row);
4472
+ (0, import_core9.deleteTableRow)(ctxRef.current, loc.blockIndex, loc.row);
3851
4473
  }, [doc]);
3852
- const insertColumnLeft = (0, import_react13.useCallback)(() => {
3853
- const loc = (0, import_core8.tableLocationOf)(doc, selectionRef.current.focus);
4474
+ const insertColumnLeft = (0, import_react14.useCallback)(() => {
4475
+ const loc = (0, import_core9.tableLocationOf)(doc, selectionRef.current.focus);
3854
4476
  if (!loc) return;
3855
- (0, import_core8.insertTableColumn)(ctxRef.current, loc.blockIndex, loc.col, "before");
4477
+ (0, import_core9.insertTableColumn)(ctxRef.current, loc.blockIndex, loc.col, "before");
3856
4478
  }, [doc]);
3857
- const insertColumnRight = (0, import_react13.useCallback)(() => {
3858
- const loc = (0, import_core8.tableLocationOf)(doc, selectionRef.current.focus);
4479
+ const insertColumnRight = (0, import_react14.useCallback)(() => {
4480
+ const loc = (0, import_core9.tableLocationOf)(doc, selectionRef.current.focus);
3859
4481
  if (!loc) return;
3860
- (0, import_core8.insertTableColumn)(ctxRef.current, loc.blockIndex, loc.col, "after");
4482
+ (0, import_core9.insertTableColumn)(ctxRef.current, loc.blockIndex, loc.col, "after");
3861
4483
  }, [doc]);
3862
- const deleteCurrentColumn = (0, import_react13.useCallback)(() => {
3863
- const loc = (0, import_core8.tableLocationOf)(doc, selectionRef.current.focus);
4484
+ const deleteCurrentColumn = (0, import_react14.useCallback)(() => {
4485
+ const loc = (0, import_core9.tableLocationOf)(doc, selectionRef.current.focus);
3864
4486
  if (!loc) return;
3865
- (0, import_core8.deleteTableColumn)(ctxRef.current, loc.blockIndex, loc.col);
4487
+ (0, import_core9.deleteTableColumn)(ctxRef.current, loc.blockIndex, loc.col);
3866
4488
  }, [doc]);
3867
- const moveToNextCell = (0, import_react13.useCallback)(() => {
3868
- (0, import_core8.moveToNextCell)(ctxRef.current);
4489
+ const moveToNextCell = (0, import_react14.useCallback)(() => {
4490
+ (0, import_core9.moveToNextCell)(ctxRef.current);
3869
4491
  }, []);
3870
- const moveToPrevCell = (0, import_react13.useCallback)(() => {
3871
- (0, import_core8.moveToPrevCell)(ctxRef.current);
4492
+ const moveToPrevCell = (0, import_react14.useCallback)(() => {
4493
+ (0, import_core9.moveToPrevCell)(ctxRef.current);
3872
4494
  }, []);
3873
- const mergeRight = (0, import_react13.useCallback)(() => {
3874
- const loc = (0, import_core8.tableLocationOf)(doc, selectionRef.current.focus);
4495
+ const mergeRight = (0, import_react14.useCallback)(() => {
4496
+ const loc = (0, import_core9.tableLocationOf)(doc, selectionRef.current.focus);
3875
4497
  if (!loc) return false;
3876
- return (0, import_core8.mergeRight)(ctxRef.current, loc.blockIndex, loc.row, loc.col);
4498
+ return (0, import_core9.mergeRight)(ctxRef.current, loc.blockIndex, loc.row, loc.col);
3877
4499
  }, [doc]);
3878
- const mergeDown = (0, import_react13.useCallback)(() => {
3879
- const loc = (0, import_core8.tableLocationOf)(doc, selectionRef.current.focus);
4500
+ const mergeDown = (0, import_react14.useCallback)(() => {
4501
+ const loc = (0, import_core9.tableLocationOf)(doc, selectionRef.current.focus);
3880
4502
  if (!loc) return false;
3881
- return (0, import_core8.mergeDown)(ctxRef.current, loc.blockIndex, loc.row, loc.col);
4503
+ return (0, import_core9.mergeDown)(ctxRef.current, loc.blockIndex, loc.row, loc.col);
3882
4504
  }, [doc]);
3883
- const splitCell = (0, import_react13.useCallback)(() => {
3884
- const loc = (0, import_core8.tableLocationOf)(doc, selectionRef.current.focus);
4505
+ const splitCell = (0, import_react14.useCallback)(() => {
4506
+ const loc = (0, import_core9.tableLocationOf)(doc, selectionRef.current.focus);
3885
4507
  if (!loc) return false;
3886
- return (0, import_core8.splitCell)(ctxRef.current, loc.blockIndex, loc.row, loc.col);
4508
+ return (0, import_core9.splitCell)(ctxRef.current, loc.blockIndex, loc.row, loc.col);
3887
4509
  }, [doc]);
3888
- const setColumnWidth = (0, import_react13.useCallback)(
3889
- (blockIndex, col, widthPx) => {
3890
- (0, import_core8.setColumnWidth)(ctxRef.current, blockIndex, col, widthPx);
4510
+ const setColumnBoundary = (0, import_react14.useCallback)(
4511
+ (blockIndex, boundary, deltaPct, base) => {
4512
+ (0, import_core9.setColumnBoundary)(ctxRef.current, blockIndex, boundary, deltaPct, base);
3891
4513
  },
3892
4514
  []
3893
4515
  );
3894
- const getTableRect = (0, import_react13.useCallback)(
3895
- () => (0, import_core8.tableRectSelection)(doc, selectionRef.current),
4516
+ const setTableWidth = (0, import_react14.useCallback)((blockIndex, pct) => {
4517
+ (0, import_core9.setTableWidth)(ctxRef.current, blockIndex, pct);
4518
+ }, []);
4519
+ const setRowHeight = (0, import_react14.useCallback)((blockIndex, row, px) => {
4520
+ (0, import_core9.setRowHeight)(ctxRef.current, blockIndex, row, px);
4521
+ }, []);
4522
+ const setRowHeights = (0, import_react14.useCallback)((blockIndex, heights) => {
4523
+ (0, import_core9.setRowHeights)(ctxRef.current, blockIndex, heights);
4524
+ }, []);
4525
+ const getTableRect = (0, import_react14.useCallback)(
4526
+ () => (0, import_core9.tableRectSelection)(doc, selectionRef.current),
3896
4527
  [doc]
3897
4528
  );
3898
- const hasTableRectSelection = (0, import_react13.useCallback)(() => {
3899
- return (0, import_core8.tableRectSelection)(doc, selectionRef.current) !== null;
4529
+ const hasTableRectSelection = (0, import_react14.useCallback)(() => {
4530
+ return (0, import_core9.tableRectSelection)(doc, selectionRef.current) !== null;
3900
4531
  }, [doc]);
3901
- const mergeSelection = (0, import_react13.useCallback)(() => {
3902
- return (0, import_core8.mergeSelection)(ctxRef.current);
4532
+ const mergeSelection = (0, import_react14.useCallback)(() => {
4533
+ return (0, import_core9.mergeSelection)(ctxRef.current);
3903
4534
  }, []);
3904
- const insertImage = (0, import_react13.useCallback)((embed) => {
3905
- (0, import_core8.insertImage)(ctxRef.current, embed);
4535
+ const insertImage = (0, import_react14.useCallback)((embed) => {
4536
+ (0, import_core9.insertImage)(ctxRef.current, embed);
3906
4537
  }, []);
3907
- const setImageAttrs = (0, import_react13.useCallback)(
4538
+ const setImageAttrs = (0, import_react14.useCallback)(
3908
4539
  (blockIndex, offset, partial, cellIndex, newOffset) => {
3909
- (0, import_core8.setImageAttrs)(ctxRef.current, blockIndex, offset, partial, cellIndex, newOffset);
4540
+ (0, import_core9.setImageAttrs)(ctxRef.current, blockIndex, offset, partial, cellIndex, newOffset);
3910
4541
  },
3911
4542
  []
3912
4543
  );
3913
- const moveEmbedAnchor = (0, import_react13.useCallback)(
4544
+ const moveEmbedAnchor = (0, import_react14.useCallback)(
3914
4545
  (from, to, newOffsetX, newOffsetY) => {
3915
- (0, import_core8.moveEmbedAnchor)(ctxRef.current, from, to, newOffsetX, newOffsetY);
4546
+ (0, import_core9.moveEmbedAnchor)(ctxRef.current, from, to, newOffsetX, newOffsetY);
3916
4547
  },
3917
4548
  []
3918
4549
  );
3919
- const uploadImageRef = (0, import_react13.useRef)(opts.uploadImage);
4550
+ const uploadImageRef = (0, import_react14.useRef)(opts.uploadImage);
3920
4551
  uploadImageRef.current = opts.uploadImage;
3921
- const insertImageFromFile = (0, import_react13.useCallback)(async (file) => {
4552
+ const insertImageFromFile = (0, import_react14.useCallback)(async (file) => {
3922
4553
  if (!file.type.startsWith("image/")) return;
3923
4554
  const dataUrl = await readAsDataURL(file);
3924
4555
  const dims = await readImageDimensions(dataUrl);
@@ -3930,9 +4561,9 @@ function useEditor(opts = {}) {
3930
4561
  }
3931
4562
  const upload = uploadImageRef.current;
3932
4563
  const src = upload ? await upload(file) : dataUrl;
3933
- (0, import_core8.insertImage)(ctxRef.current, { type: "image", src, width: w, height: h });
4564
+ (0, import_core9.insertImage)(ctxRef.current, { type: "image", src, width: w, height: h });
3934
4565
  }, []);
3935
- const getSelectedEmbed = (0, import_react13.useCallback)(() => {
4566
+ const getSelectedEmbed = (0, import_react14.useCallback)(() => {
3936
4567
  const sel = selectionRef.current;
3937
4568
  if (sel.anchor.blockIndex !== sel.focus.blockIndex) return null;
3938
4569
  if ((sel.anchor.cellIndex ?? -1) !== (sel.focus.cellIndex ?? -1)) return null;
@@ -3949,7 +4580,7 @@ function useEditor(opts = {}) {
3949
4580
  cursor += op.insert.length;
3950
4581
  continue;
3951
4582
  }
3952
- if (cursor === start && (0, import_core8.isImageEmbed)(op.insert)) {
4583
+ if (cursor === start && (0, import_core9.isImageEmbed)(op.insert)) {
3953
4584
  return {
3954
4585
  blockIndex: sel.anchor.blockIndex,
3955
4586
  cellIndex: sel.anchor.cellIndex,
@@ -3961,16 +4592,16 @@ function useEditor(opts = {}) {
3961
4592
  }
3962
4593
  return null;
3963
4594
  }, [doc]);
3964
- const [linkRequest, setLinkRequest] = (0, import_react13.useState)(null);
3965
- const linkRequestRef = (0, import_react13.useRef)(null);
3966
- const requestLink = (0, import_react13.useCallback)((initialHref = "") => {
4595
+ const [linkRequest, setLinkRequest] = (0, import_react14.useState)(null);
4596
+ const linkRequestRef = (0, import_react14.useRef)(null);
4597
+ const requestLink = (0, import_react14.useCallback)((initialHref = "") => {
3967
4598
  return new Promise((resolve) => {
3968
4599
  const req = { initialHref, resolve, selection: selectionRef.current };
3969
4600
  linkRequestRef.current = req;
3970
4601
  setLinkRequest(req);
3971
4602
  });
3972
4603
  }, []);
3973
- const resolveLinkRequest = (0, import_react13.useCallback)(
4604
+ const resolveLinkRequest = (0, import_react14.useCallback)(
3974
4605
  (href) => {
3975
4606
  const req = linkRequestRef.current;
3976
4607
  linkRequestRef.current = null;
@@ -3983,26 +4614,26 @@ function useEditor(opts = {}) {
3983
4614
  [setSelection]
3984
4615
  );
3985
4616
  const pageSettings = usePageSettings(doc);
3986
- const setPageSettings = (0, import_react13.useCallback)(
4617
+ const setPageSettings = (0, import_react14.useCallback)(
3987
4618
  (partial) => {
3988
4619
  doc.setPageSettings(partial);
3989
4620
  },
3990
4621
  [doc]
3991
4622
  );
3992
- const [pageConfigRequest, setPageConfigRequest] = (0, import_react13.useState)(null);
3993
- const requestPageConfig = (0, import_react13.useCallback)(() => {
4623
+ const [pageConfigRequest, setPageConfigRequest] = (0, import_react14.useState)(null);
4624
+ const requestPageConfig = (0, import_react14.useCallback)(() => {
3994
4625
  return new Promise((resolve) => {
3995
4626
  setPageConfigRequest({ initial: doc.getPageSettings(), resolve });
3996
4627
  });
3997
4628
  }, [doc]);
3998
- const resolvePageConfigRequest = (0, import_react13.useCallback)((applied) => {
4629
+ const resolvePageConfigRequest = (0, import_react14.useCallback)((applied) => {
3999
4630
  setPageConfigRequest((prev) => {
4000
4631
  if (prev) prev.resolve(applied);
4001
4632
  return null;
4002
4633
  });
4003
4634
  }, []);
4004
- const [imageCaptionRequest, setImageCaptionRequest] = (0, import_react13.useState)(null);
4005
- const requestImageCaption = (0, import_react13.useCallback)(
4635
+ const [imageCaptionRequest, setImageCaptionRequest] = (0, import_react14.useState)(null);
4636
+ const requestImageCaption = (0, import_react14.useCallback)(
4006
4637
  (initialCaption = "", initialAlign = "center") => {
4007
4638
  return new Promise((resolve) => {
4008
4639
  setImageCaptionRequest({ initialCaption, initialAlign, resolve });
@@ -4010,12 +4641,82 @@ function useEditor(opts = {}) {
4010
4641
  },
4011
4642
  []
4012
4643
  );
4013
- const resolveImageCaptionRequest = (0, import_react13.useCallback)((result) => {
4644
+ const resolveImageCaptionRequest = (0, import_react14.useCallback)((result) => {
4014
4645
  setImageCaptionRequest((prev) => {
4015
4646
  if (prev) prev.resolve(result);
4016
4647
  return null;
4017
4648
  });
4018
4649
  }, []);
4650
+ const [formulaRequest, setFormulaRequest] = (0, import_react14.useState)(null);
4651
+ const requestFormula = (0, import_react14.useCallback)(
4652
+ (initialLatex = "", initialDisplay = false) => {
4653
+ return new Promise((resolve) => {
4654
+ setFormulaRequest({ initialLatex, initialDisplay, resolve });
4655
+ });
4656
+ },
4657
+ []
4658
+ );
4659
+ const resolveFormulaRequest = (0, import_react14.useCallback)((result) => {
4660
+ setFormulaRequest((prev) => {
4661
+ if (prev) prev.resolve(result);
4662
+ return null;
4663
+ });
4664
+ }, []);
4665
+ const insertFormula = (0, import_react14.useCallback)(
4666
+ async (latex, display) => {
4667
+ const selectionAtCall = ctxRef.current.getSelection();
4668
+ const embedAtCall = getSelectedEmbed();
4669
+ let mathModule;
4670
+ try {
4671
+ mathModule = await import("@sofereditor/math");
4672
+ } catch {
4673
+ return;
4674
+ }
4675
+ const { renderLatexToSvg, measureExInPx, svgToDataUrl, svgToPngDataUrl } = mathModule;
4676
+ const r = renderLatexToSvg(latex, display);
4677
+ if (!r.ok) return;
4678
+ const root = document.querySelector(".ed-root");
4679
+ const exPx = root ? measureExInPx(root) : 8;
4680
+ let w = Math.round(r.widthEx * exPx);
4681
+ let h = Math.round(r.heightEx * exPx);
4682
+ let vAlignScale = 1;
4683
+ if (w > MAX_INSERT_WIDTH) {
4684
+ vAlignScale = MAX_INSERT_WIDTH / w;
4685
+ h = Math.round(h * MAX_INSERT_WIDTH / w);
4686
+ w = MAX_INSERT_WIDTH;
4687
+ }
4688
+ const src = svgToDataUrl(r.svg);
4689
+ let svgFallback;
4690
+ try {
4691
+ svgFallback = await svgToPngDataUrl(r.svg, w, h);
4692
+ } catch {
4693
+ svgFallback = void 0;
4694
+ }
4695
+ ctxRef.current.setSelection(selectionAtCall);
4696
+ const inheritedLayout = {};
4697
+ if ((0, import_core9.isFormulaEmbed)(embedAtCall?.embed)) {
4698
+ const prev = embedAtCall.embed;
4699
+ if (prev.layout !== void 0) inheritedLayout.layout = prev.layout;
4700
+ if (prev.offsetX !== void 0) inheritedLayout.offsetX = prev.offsetX;
4701
+ if (prev.offsetY !== void 0) inheritedLayout.offsetY = prev.offsetY;
4702
+ }
4703
+ (0, import_core9.insertImage)(ctxRef.current, {
4704
+ type: "image",
4705
+ src,
4706
+ width: w,
4707
+ height: h,
4708
+ ...inheritedLayout,
4709
+ ...display ? { align: "center" } : {},
4710
+ formula: {
4711
+ latex,
4712
+ display,
4713
+ ...display ? {} : { vAlign: `${r.vAlignEx * vAlignScale}ex` }
4714
+ },
4715
+ ...svgFallback ? { svgFallback } : {}
4716
+ });
4717
+ },
4718
+ [getSelectedEmbed]
4719
+ );
4019
4720
  return {
4020
4721
  doc,
4021
4722
  history,
@@ -4066,7 +4767,10 @@ function useEditor(opts = {}) {
4066
4767
  mergeRight,
4067
4768
  mergeDown,
4068
4769
  splitCell,
4069
- setColumnWidth,
4770
+ setColumnBoundary,
4771
+ setTableWidth,
4772
+ setRowHeight,
4773
+ setRowHeights,
4070
4774
  getTableRect,
4071
4775
  hasTableRectSelection,
4072
4776
  mergeSelection,
@@ -4083,6 +4787,10 @@ function useEditor(opts = {}) {
4083
4787
  imageCaptionRequest,
4084
4788
  requestImageCaption,
4085
4789
  resolveImageCaptionRequest,
4790
+ formulaRequest,
4791
+ requestFormula,
4792
+ resolveFormulaRequest,
4793
+ insertFormula,
4086
4794
  uploadImage: opts.uploadImage
4087
4795
  };
4088
4796
  }
@@ -4115,7 +4823,7 @@ function sameValue(a, b) {
4115
4823
  }
4116
4824
 
4117
4825
  // src/Editor.tsx
4118
- var import_jsx_runtime12 = require("react/jsx-runtime");
4826
+ var import_jsx_runtime13 = require("react/jsx-runtime");
4119
4827
  var defaultFooter = ({ pageNumber, pageCount }) => `${pageNumber} / ${pageCount}`;
4120
4828
  function Editor({
4121
4829
  editor: providedEditor,
@@ -4128,15 +4836,15 @@ function Editor({
4128
4836
  const internal = useEditor();
4129
4837
  const editor = providedEditor ?? internal;
4130
4838
  const { doc, history, snapshot, getSelection, setSelection } = editor;
4131
- const rootRef = (0, import_react14.useRef)(null);
4132
- const isComposingRef = (0, import_react14.useRef)(false);
4133
- const pasteInFlightRef = (0, import_react14.useRef)(false);
4134
- const [hoveredBehind, setHoveredBehind] = (0, import_react14.useState)(null);
4135
- const hoveredBehindRef = (0, import_react14.useRef)(null);
4136
- const [hoveredLink, setHoveredLink] = (0, import_react14.useState)(null);
4137
- const hoveredLinkElRef = (0, import_react14.useRef)(null);
4138
- const suppressSelectionSyncRef = (0, import_react14.useRef)(false);
4139
- (0, import_react14.useEffect)(() => {
4839
+ const rootRef = (0, import_react15.useRef)(null);
4840
+ const isComposingRef = (0, import_react15.useRef)(false);
4841
+ const pasteInFlightRef = (0, import_react15.useRef)(false);
4842
+ const [hoveredBehind, setHoveredBehind] = (0, import_react15.useState)(null);
4843
+ const hoveredBehindRef = (0, import_react15.useRef)(null);
4844
+ const [hoveredLink, setHoveredLink] = (0, import_react15.useState)(null);
4845
+ const hoveredLinkElRef = (0, import_react15.useRef)(null);
4846
+ const suppressSelectionSyncRef = (0, import_react15.useRef)(false);
4847
+ (0, import_react15.useEffect)(() => {
4140
4848
  if (!awareness) return;
4141
4849
  const root = rootRef.current;
4142
4850
  if (!root) return;
@@ -4146,7 +4854,7 @@ function Editor({
4146
4854
  const sel = readDomSelection(root);
4147
4855
  awareness.setLocalStateField(
4148
4856
  "cursor",
4149
- sel ? (0, import_core9.encodeSelection)(doc, sel) ?? null : null
4857
+ sel ? (0, import_core10.encodeSelection)(doc, sel) ?? null : null
4150
4858
  );
4151
4859
  };
4152
4860
  const onSelChange = () => {
@@ -4166,13 +4874,13 @@ function Editor({
4166
4874
  awareness.setLocalStateField("cursor", null);
4167
4875
  };
4168
4876
  }, [awareness, doc]);
4169
- const ctxRef = (0, import_react14.useRef)({ doc, getSelection, setSelection });
4877
+ const ctxRef = (0, import_react15.useRef)({ doc, getSelection, setSelection });
4170
4878
  ctxRef.current = { doc, getSelection, setSelection };
4171
- const historyRef = (0, import_react14.useRef)(history);
4879
+ const historyRef = (0, import_react15.useRef)(history);
4172
4880
  historyRef.current = history;
4173
- const editorRef = (0, import_react14.useRef)(editor);
4881
+ const editorRef = (0, import_react15.useRef)(editor);
4174
4882
  editorRef.current = editor;
4175
- (0, import_react14.useLayoutEffect)(() => {
4883
+ (0, import_react15.useLayoutEffect)(() => {
4176
4884
  const root = rootRef.current;
4177
4885
  if (!root) return;
4178
4886
  if (isComposingRef.current) return;
@@ -4187,7 +4895,7 @@ function Editor({
4187
4895
  suppressSelectionSyncRef.current = true;
4188
4896
  applyDomSelection(root, editor.selection);
4189
4897
  });
4190
- (0, import_react14.useEffect)(() => {
4898
+ (0, import_react15.useEffect)(() => {
4191
4899
  const root = rootRef.current;
4192
4900
  if (!root) return;
4193
4901
  const handler = () => {
@@ -4208,7 +4916,7 @@ function Editor({
4208
4916
  document.addEventListener("selectionchange", handler);
4209
4917
  return () => document.removeEventListener("selectionchange", handler);
4210
4918
  }, [setSelection]);
4211
- (0, import_react14.useEffect)(() => {
4919
+ (0, import_react15.useEffect)(() => {
4212
4920
  const root = rootRef.current;
4213
4921
  if (!root) return;
4214
4922
  let drag = null;
@@ -4279,7 +4987,7 @@ function Editor({
4279
4987
  document.removeEventListener("pointerup", onPointerUp);
4280
4988
  };
4281
4989
  }, []);
4282
- (0, import_react14.useEffect)(() => {
4990
+ (0, import_react15.useEffect)(() => {
4283
4991
  const root = rootRef.current;
4284
4992
  if (!root) return;
4285
4993
  const onDragOver = (e) => {
@@ -4317,7 +5025,7 @@ function Editor({
4317
5025
  root.removeEventListener("drop", onDrop);
4318
5026
  };
4319
5027
  }, []);
4320
- (0, import_react14.useEffect)(() => {
5028
+ (0, import_react15.useEffect)(() => {
4321
5029
  const root = rootRef.current;
4322
5030
  if (!root) return;
4323
5031
  const onPointerDown = (e) => {
@@ -4345,7 +5053,27 @@ function Editor({
4345
5053
  root.addEventListener("pointerdown", onPointerDown);
4346
5054
  return () => root.removeEventListener("pointerdown", onPointerDown);
4347
5055
  }, []);
4348
- (0, import_react14.useEffect)(() => {
5056
+ (0, import_react15.useEffect)(() => {
5057
+ const root = rootRef.current;
5058
+ if (!root) return;
5059
+ const onDoubleClick = (e) => {
5060
+ const target = e.target;
5061
+ if (!(target instanceof Element)) return;
5062
+ if (!target.closest('img[data-embed="image"]')) return;
5063
+ const ed = editorRef.current;
5064
+ const sel = ed.getSelectedEmbed();
5065
+ if (!sel || !(0, import_core10.isFormulaEmbed)(sel.embed)) return;
5066
+ e.preventDefault();
5067
+ const { latex, display } = sel.embed.formula;
5068
+ void ed.requestFormula(latex, display).then((r) => {
5069
+ if (!r) return;
5070
+ void ed.insertFormula(r.latex, r.display);
5071
+ });
5072
+ };
5073
+ root.addEventListener("dblclick", onDoubleClick);
5074
+ return () => root.removeEventListener("dblclick", onDoubleClick);
5075
+ }, []);
5076
+ (0, import_react15.useEffect)(() => {
4349
5077
  const root = rootRef.current;
4350
5078
  if (!root) return;
4351
5079
  const same = (a, b) => a === b || !!a && !!b && a.blockIndex === b.blockIndex && a.offset === b.offset && (a.cellIndex ?? -1) === (b.cellIndex ?? -1);
@@ -4398,7 +5126,7 @@ function Editor({
4398
5126
  if (raf) cancelAnimationFrame(raf);
4399
5127
  };
4400
5128
  }, []);
4401
- (0, import_react14.useEffect)(() => {
5129
+ (0, import_react15.useEffect)(() => {
4402
5130
  const root = rootRef.current;
4403
5131
  if (!root) return;
4404
5132
  const clear = () => {
@@ -4433,7 +5161,7 @@ function Editor({
4433
5161
  window.removeEventListener("scroll", clear, true);
4434
5162
  };
4435
5163
  }, []);
4436
- (0, import_react14.useEffect)(() => {
5164
+ (0, import_react15.useEffect)(() => {
4437
5165
  const root = rootRef.current;
4438
5166
  if (!root) return;
4439
5167
  const handler = (e) => {
@@ -4447,14 +5175,14 @@ function Editor({
4447
5175
  const data = e.data ?? "";
4448
5176
  if (data.length > 0) {
4449
5177
  e.preventDefault();
4450
- (0, import_core9.insertText)(ctx, data, ed.consumePendingMarks());
5178
+ (0, import_core10.insertText)(ctx, data, ed.consumePendingMarks());
4451
5179
  }
4452
5180
  return;
4453
5181
  }
4454
5182
  case "insertLineBreak": {
4455
5183
  e.preventDefault();
4456
5184
  if (ed.getBlockType() === "listItem") {
4457
- (0, import_core9.insertText)(ctx, "\n", ed.consumePendingMarks());
5185
+ (0, import_core10.insertText)(ctx, "\n", ed.consumePendingMarks());
4458
5186
  return;
4459
5187
  }
4460
5188
  const selEmbed = ed.getSelectedEmbed();
@@ -4474,7 +5202,7 @@ function Editor({
4474
5202
  });
4475
5203
  }
4476
5204
  if (ed.splitListItem()) return;
4477
- (0, import_core9.insertParagraph)(ctx);
5205
+ (0, import_core10.insertParagraph)(ctx);
4478
5206
  return;
4479
5207
  }
4480
5208
  case "insertParagraph": {
@@ -4496,14 +5224,14 @@ function Editor({
4496
5224
  });
4497
5225
  }
4498
5226
  if (ed.splitListItem()) return;
4499
- (0, import_core9.insertParagraph)(ctx);
5227
+ (0, import_core10.insertParagraph)(ctx);
4500
5228
  return;
4501
5229
  }
4502
5230
  case "insertReplacementText": {
4503
5231
  const text = e.data ?? e.dataTransfer?.getData("text/plain") ?? "";
4504
5232
  if (text.length > 0) {
4505
5233
  e.preventDefault();
4506
- (0, import_core9.insertText)(ctx, text, ed.consumePendingMarks());
5234
+ (0, import_core10.insertText)(ctx, text, ed.consumePendingMarks());
4507
5235
  }
4508
5236
  return;
4509
5237
  }
@@ -4516,7 +5244,7 @@ function Editor({
4516
5244
  case "deleteSoftLineBackward":
4517
5245
  case "deleteHardLineBackward": {
4518
5246
  e.preventDefault();
4519
- (0, import_core9.deleteBackward)(ctx);
5247
+ (0, import_core10.deleteBackward)(ctx);
4520
5248
  return;
4521
5249
  }
4522
5250
  case "deleteContentForward":
@@ -4524,7 +5252,7 @@ function Editor({
4524
5252
  case "deleteSoftLineForward":
4525
5253
  case "deleteHardLineForward": {
4526
5254
  e.preventDefault();
4527
- (0, import_core9.deleteForward)(ctx);
5255
+ (0, import_core10.deleteForward)(ctx);
4528
5256
  return;
4529
5257
  }
4530
5258
  case "historyUndo": {
@@ -4546,15 +5274,15 @@ function Editor({
4546
5274
  root.addEventListener("beforeinput", handler);
4547
5275
  return () => root.removeEventListener("beforeinput", handler);
4548
5276
  }, []);
4549
- (0, import_react14.useEffect)(() => {
5277
+ (0, import_react15.useEffect)(() => {
4550
5278
  const root = rootRef.current;
4551
5279
  if (!root) return;
4552
5280
  const writeSlice = (e) => {
4553
5281
  const ctx = ctxRef.current;
4554
- const slice = (0, import_core9.serializeSelection)(ctx.doc, ctx.getSelection());
5282
+ const slice = (0, import_core10.serializeSelection)(ctx.doc, ctx.getSelection());
4555
5283
  if (!slice || !e.clipboardData) return false;
4556
- e.clipboardData.setData(import_core9.SOFER_MIME, JSON.stringify(slice));
4557
- e.clipboardData.setData("text/plain", (0, import_core9.sliceToText)(slice));
5284
+ e.clipboardData.setData(import_core10.SOFER_MIME, JSON.stringify(slice));
5285
+ e.clipboardData.setData("text/plain", (0, import_core10.sliceToText)(slice));
4558
5286
  return true;
4559
5287
  };
4560
5288
  const onCopy = (e) => {
@@ -4562,7 +5290,7 @@ function Editor({
4562
5290
  };
4563
5291
  const onCut = (e) => {
4564
5292
  e.preventDefault();
4565
- if (writeSlice(e)) (0, import_core9.deleteSelection)(ctxRef.current);
5293
+ if (writeSlice(e)) (0, import_core10.deleteSelection)(ctxRef.current);
4566
5294
  };
4567
5295
  const onPaste = (e) => {
4568
5296
  const ctx = ctxRef.current;
@@ -4573,11 +5301,11 @@ function Editor({
4573
5301
  e.preventDefault();
4574
5302
  switch (plan.kind) {
4575
5303
  case "sofer":
4576
- (0, import_core9.insertSlice)(ctx, plan.slice);
5304
+ (0, import_core10.insertSlice)(ctx, plan.slice);
4577
5305
  return;
4578
5306
  case "html": {
4579
5307
  if (!sliceHasDataImageEmbeds(plan.slice)) {
4580
- (0, import_core9.insertSlice)(ctx, plan.slice);
5308
+ (0, import_core10.insertSlice)(ctx, plan.slice);
4581
5309
  return;
4582
5310
  }
4583
5311
  if (pasteInFlightRef.current) {
@@ -4602,10 +5330,10 @@ function Editor({
4602
5330
  );
4603
5331
  const lastIndex = Math.max(0, ctxRef.current.doc.blockCount() - 1);
4604
5332
  const lastText = ctxRef.current.doc.getBlockText(lastIndex);
4605
- insertAt = (0, import_core9.collapsedSelection)({ blockIndex: lastIndex, offset: lastText ? lastText.length : 0 });
5333
+ insertAt = (0, import_core10.collapsedSelection)({ blockIndex: lastIndex, offset: lastText ? lastText.length : 0 });
4606
5334
  }
4607
5335
  ctxRef.current.setSelection(insertAt);
4608
- (0, import_core9.insertSlice)(ctxRef.current, resolved);
5336
+ (0, import_core10.insertSlice)(ctxRef.current, resolved);
4609
5337
  if (userMovedAway) {
4610
5338
  ctxRef.current.setSelection(liveSelection);
4611
5339
  }
@@ -4623,8 +5351,8 @@ function Editor({
4623
5351
  case "text": {
4624
5352
  const lines = plan.text.split(/\r\n|\r|\n/);
4625
5353
  lines.forEach((line, i) => {
4626
- if (i > 0) (0, import_core9.insertParagraph)(ctx);
4627
- if (line.length > 0) (0, import_core9.insertText)(ctx, line);
5354
+ if (i > 0) (0, import_core10.insertParagraph)(ctx);
5355
+ if (line.length > 0) (0, import_core10.insertText)(ctx, line);
4628
5356
  });
4629
5357
  return;
4630
5358
  }
@@ -4639,7 +5367,7 @@ function Editor({
4639
5367
  root.removeEventListener("paste", onPaste);
4640
5368
  };
4641
5369
  }, []);
4642
- const onKeyDown = (0, import_react14.useCallback)((e) => {
5370
+ const onKeyDown = (0, import_react15.useCallback)((e) => {
4643
5371
  const ed = editorRef.current;
4644
5372
  const mod = e.metaKey || e.ctrlKey;
4645
5373
  if (e.key === "Tab") {
@@ -4670,11 +5398,11 @@ function Editor({
4670
5398
  if (!mod && (e.key === "Backspace" || e.key === "Delete")) {
4671
5399
  if (isComposingRef.current) return;
4672
5400
  const direction = e.key === "Backspace" ? "backward" : "forward";
4673
- const shouldIntercept = ed.getSelectedEmbed() != null || (0, import_core9.isEmbedAdjacentToCaret)(ctxRef.current, direction);
5401
+ const shouldIntercept = ed.getSelectedEmbed() != null || (0, import_core10.isEmbedAdjacentToCaret)(ctxRef.current, direction);
4674
5402
  if (shouldIntercept) {
4675
5403
  e.preventDefault();
4676
- if (direction === "backward") (0, import_core9.deleteBackward)(ctxRef.current);
4677
- else (0, import_core9.deleteForward)(ctxRef.current);
5404
+ if (direction === "backward") (0, import_core10.deleteBackward)(ctxRef.current);
5405
+ else (0, import_core10.deleteForward)(ctxRef.current);
4678
5406
  }
4679
5407
  return;
4680
5408
  }
@@ -4724,17 +5452,17 @@ function Editor({
4724
5452
  });
4725
5453
  }
4726
5454
  }, []);
4727
- const onCompositionStart = (0, import_react14.useCallback)(() => {
5455
+ const onCompositionStart = (0, import_react15.useCallback)(() => {
4728
5456
  isComposingRef.current = true;
4729
5457
  }, []);
4730
- const onCompositionEnd = (0, import_react14.useCallback)((e) => {
5458
+ const onCompositionEnd = (0, import_react15.useCallback)((e) => {
4731
5459
  isComposingRef.current = false;
4732
5460
  if (e.data && e.data.length > 0) {
4733
- (0, import_core9.insertText)(ctxRef.current, e.data);
5461
+ (0, import_core10.insertText)(ctxRef.current, e.data);
4734
5462
  }
4735
5463
  }, []);
4736
- const topLevels = (0, import_react14.useMemo)(() => groupTopLevels(snapshot.blocks), [snapshot]);
4737
- const topLevelsStructuralKey = (0, import_react14.useMemo)(
5464
+ const topLevels = (0, import_react15.useMemo)(() => groupTopLevels(snapshot.blocks), [snapshot]);
5465
+ const topLevelsStructuralKey = (0, import_react15.useMemo)(
4738
5466
  () => topLevels.map(
4739
5467
  (t) => t.kind === "list" ? `L:${t.listKind}:${t.items.length}:${t.ordinalStart}` : `B:${t.block.type}:${t.block.attrs.level ?? ""}`
4740
5468
  ).join("|"),
@@ -4756,7 +5484,7 @@ function Editor({
4756
5484
  [topLevelsStructuralKey, pageGeometry]
4757
5485
  );
4758
5486
  const effectiveLayout = paginated ? layout : defaultPageLayout(topLevels.length);
4759
- const pageStyle = (0, import_react14.useMemo)(
5487
+ const pageStyle = (0, import_react15.useMemo)(
4760
5488
  () => paginated ? {
4761
5489
  "--ed-page-width": `${geom.width}px`,
4762
5490
  "--ed-page-height": `${geom.height}px`,
@@ -4775,7 +5503,7 @@ function Editor({
4775
5503
  geom.marginRight
4776
5504
  ]
4777
5505
  );
4778
- const body = /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
5506
+ const body = /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
4779
5507
  "div",
4780
5508
  {
4781
5509
  ref: rootRef,
@@ -4801,7 +5529,7 @@ function Editor({
4801
5529
  const pageInlineStyle = pi === 0 && geom.firstPageExtraTop ? {
4802
5530
  "--ed-page-margin-top": `${geom.marginTop + geom.firstPageExtraTop}px`
4803
5531
  } : void 0;
4804
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
5532
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
4805
5533
  "div",
4806
5534
  {
4807
5535
  className: "ed-page",
@@ -4809,15 +5537,15 @@ function Editor({
4809
5537
  "data-page-total": ctx.pageCount,
4810
5538
  style: pageInlineStyle,
4811
5539
  children: [
4812
- renderPageHeader && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ed-page-header", contentEditable: false, children: renderPageHeader(ctx) }),
4813
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ed-page-content", children: page.slots.map((slot) => renderSlot(slot, topLevels)) }),
4814
- renderPageFooter && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ed-page-footer", contentEditable: false, children: renderPageFooter(ctx) })
5540
+ renderPageHeader && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "ed-page-header", contentEditable: false, children: renderPageHeader(ctx) }),
5541
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "ed-page-content", children: page.slots.map((slot) => renderSlot(slot, topLevels)) }),
5542
+ renderPageFooter && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "ed-page-footer", contentEditable: false, children: renderPageFooter(ctx) })
4815
5543
  ]
4816
5544
  },
4817
5545
  `page-${pi}`
4818
5546
  );
4819
5547
  }) : topLevels.map((t) => renderTopLevel(t)),
4820
- selectedEmbed && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5548
+ selectedEmbed && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4821
5549
  ImageResizeOverlay,
4822
5550
  {
4823
5551
  rootRef,
@@ -4849,7 +5577,7 @@ function Editor({
4849
5577
  )
4850
5578
  }
4851
5579
  ),
4852
- hoveredBehind && !(selectedEmbed && selectedEmbed.blockIndex === hoveredBehind.blockIndex && selectedEmbed.offset === hoveredBehind.offset && (selectedEmbed.cellIndex ?? -1) === (hoveredBehind.cellIndex ?? -1)) && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5580
+ hoveredBehind && !(selectedEmbed && selectedEmbed.blockIndex === hoveredBehind.blockIndex && selectedEmbed.offset === hoveredBehind.offset && (selectedEmbed.cellIndex ?? -1) === (hoveredBehind.cellIndex ?? -1)) && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4853
5581
  BehindImageSelectAffordance,
4854
5582
  {
4855
5583
  rootRef,
@@ -4870,8 +5598,8 @@ function Editor({
4870
5598
  })
4871
5599
  }
4872
5600
  ),
4873
- hoveredLink && hoveredLink.href && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(LinkHoverTooltip, { href: hoveredLink.href, rect: hoveredLink.rect }),
4874
- awareness && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5601
+ hoveredLink && hoveredLink.href && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(LinkHoverTooltip, { href: hoveredLink.href, rect: hoveredLink.rect }),
5602
+ awareness && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4875
5603
  RemoteCursorsOverlay,
4876
5604
  {
4877
5605
  rootRef,
@@ -4883,7 +5611,7 @@ function Editor({
4883
5611
  ]
4884
5612
  }
4885
5613
  );
4886
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(EditorProvider, { editor, children: body });
5614
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(EditorProvider, { editor, children: body });
4887
5615
  }
4888
5616
  function groupTopLevels(snapshot) {
4889
5617
  const out = [];
@@ -4937,7 +5665,7 @@ function renderSlot(slot, topLevels) {
4937
5665
  start: slot.fragment.start,
4938
5666
  end: slot.fragment.end
4939
5667
  };
4940
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5668
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4941
5669
  NodeView,
4942
5670
  {
4943
5671
  block: top.block,
@@ -4948,7 +5676,7 @@ function renderSlot(slot, topLevels) {
4948
5676
  );
4949
5677
  }
4950
5678
  if (slot.tableFragment && top.kind === "block" && top.block.type === "table") {
4951
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5679
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4952
5680
  NodeView,
4953
5681
  {
4954
5682
  block: top.block,
@@ -4968,7 +5696,7 @@ function renderTopLevel(top) {
4968
5696
  const tree = buildListTree(top.items);
4969
5697
  return renderListTree(tree, top, top.ordinalStart, `list-${top.key}`);
4970
5698
  }
4971
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(NodeView, { block: top.block, index: top.blockIndex }, top.key);
5699
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(NodeView, { block: top.block, index: top.blockIndex }, top.key);
4972
5700
  }
4973
5701
  function renderListFragment(top, frag) {
4974
5702
  const ranges = topLevelItemRanges(top.items);
@@ -5010,9 +5738,9 @@ function buildListTree(items) {
5010
5738
  function renderListTree(tree, top, start, key) {
5011
5739
  const className = `ed-list ed-list-${top.listKind}`;
5012
5740
  const style = top.listStyle ? { listStyleType: top.listStyle } : void 0;
5013
- const items = tree.map((node) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(NodeView, { block: node.entry.block, index: node.entry.index, children: node.children.length > 0 ? renderNestedListTree(node.children, `nested-${node.entry.index}`) : null }, node.entry.index));
5741
+ const items = tree.map((node) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(NodeView, { block: node.entry.block, index: node.entry.index, children: node.children.length > 0 ? renderNestedListTree(node.children, `nested-${node.entry.index}`) : null }, node.entry.index));
5014
5742
  if (top.listKind === "ordered") {
5015
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5743
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5016
5744
  "ol",
5017
5745
  {
5018
5746
  className,
@@ -5024,12 +5752,12 @@ function renderListTree(tree, top, start, key) {
5024
5752
  key
5025
5753
  );
5026
5754
  }
5027
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("ul", { className, "data-list-kind": "bullet", style, children: items }, key);
5755
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("ul", { className, "data-list-kind": "bullet", style, children: items }, key);
5028
5756
  }
5029
5757
  function renderNestedListTree(tree, key) {
5030
5758
  const kind = tree[0]?.entry.block.attrs.listKind === "ordered" ? "ordered" : "bullet";
5031
5759
  const Tag = kind === "ordered" ? "ol" : "ul";
5032
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Tag, { className: `ed-list ed-list-${kind}`, "data-list-kind": kind, children: tree.map((node) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(NodeView, { block: node.entry.block, index: node.entry.index, children: node.children.length > 0 ? renderNestedListTree(node.children, `nested-${node.entry.index}`) : null }, node.entry.index)) }, key);
5760
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Tag, { className: `ed-list ed-list-${kind}`, "data-list-kind": kind, children: tree.map((node) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(NodeView, { block: node.entry.block, index: node.entry.index, children: node.children.length > 0 ? renderNestedListTree(node.children, `nested-${node.entry.index}`) : null }, node.entry.index)) }, key);
5033
5761
  }
5034
5762
  function clampListLevel2(l) {
5035
5763
  if (typeof l !== "number" || !Number.isFinite(l)) return 0;
@@ -5057,10 +5785,76 @@ function caretRangeFromPoint(x, y) {
5057
5785
  }
5058
5786
 
5059
5787
  // src/Toolbar.tsx
5060
- var import_react15 = require("react");
5061
- var import_core10 = require("@sofereditor/core");
5062
- var import_jsx_runtime13 = require("react/jsx-runtime");
5063
- var FONT_FAMILIES = ["Arial"];
5788
+ var import_react16 = require("react");
5789
+ var import_core11 = require("@sofereditor/core");
5790
+
5791
+ // src/TableBorderPanel.tsx
5792
+ var import_jsx_runtime14 = require("react/jsx-runtime");
5793
+ var BORDER_PRESETS = [
5794
+ { key: "all", label: "Todas", glyph: "\u229E" },
5795
+ { key: "outer", label: "S\xF3 externas", glyph: "\u25A1" },
5796
+ { key: "horizontal", label: "S\xF3 horizontais", glyph: "\u25A4" },
5797
+ { key: "vertical", label: "S\xF3 verticais", glyph: "\u25A5" },
5798
+ { key: "none", label: "Nenhuma", glyph: "\u2B1A" }
5799
+ ];
5800
+ var BORDER_MENU_GLYPH = "\u229E";
5801
+ function TableBorderPanel({
5802
+ preset,
5803
+ color,
5804
+ onPreset,
5805
+ onColor,
5806
+ onResetColor
5807
+ }) {
5808
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "ed-border-panel", children: [
5809
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "ed-border-presets", children: BORDER_PRESETS.map((p) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
5810
+ "button",
5811
+ {
5812
+ type: "button",
5813
+ className: "ed-border-preset",
5814
+ "aria-pressed": preset === p.key,
5815
+ title: p.label,
5816
+ onClick: (e) => {
5817
+ e.preventDefault();
5818
+ onPreset(p.key);
5819
+ },
5820
+ children: [
5821
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ed-border-glyph", "aria-hidden": true, children: p.glyph }),
5822
+ p.label
5823
+ ]
5824
+ },
5825
+ p.key
5826
+ )) }),
5827
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("hr", {}),
5828
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "ed-toolbar-label ed-border-color", children: [
5829
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ed-toolbar-swatch", "aria-hidden": true, style: { background: color } }),
5830
+ "Cor da linha",
5831
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5832
+ "input",
5833
+ {
5834
+ type: "color",
5835
+ value: color,
5836
+ onChange: (e) => onColor(e.target.value),
5837
+ "aria-label": "Cor da linha da borda"
5838
+ }
5839
+ )
5840
+ ] }),
5841
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5842
+ "button",
5843
+ {
5844
+ type: "button",
5845
+ className: "ed-border-reset",
5846
+ onClick: (e) => {
5847
+ e.preventDefault();
5848
+ onResetColor();
5849
+ },
5850
+ children: "Padr\xE3o"
5851
+ }
5852
+ )
5853
+ ] });
5854
+ }
5855
+
5856
+ // src/Toolbar.tsx
5857
+ var import_jsx_runtime15 = require("react/jsx-runtime");
5064
5858
  var FONT_SIZES = ["8pt", "10pt", "11pt", "12pt", "14pt", "16pt", "18pt", "24pt", "32pt", "48pt"];
5065
5859
  var BLOCK_OPTIONS = [
5066
5860
  { value: "paragraph", label: "Par\xE1grafo", type: "paragraph" },
@@ -5134,11 +5928,6 @@ function Toolbar({ className }) {
5134
5928
  const onHighlightChange = (e) => {
5135
5929
  setMark("highlight", e.target.value);
5136
5930
  };
5137
- const onFontFamilyChange = (e) => {
5138
- const v = e.target.value;
5139
- if (v === "") removeMark("fontFamily");
5140
- else setMark("fontFamily", v);
5141
- };
5142
5931
  const onFontSizeChange = (e) => {
5143
5932
  const v = e.target.value;
5144
5933
  if (v === "") removeMark("fontSize");
@@ -5163,14 +5952,14 @@ function Toolbar({ className }) {
5163
5952
  }
5164
5953
  setAlign(value);
5165
5954
  };
5166
- const onInsertImageClick = (0, import_react15.useCallback)(
5955
+ const onInsertImageClick = (0, import_react16.useCallback)(
5167
5956
  (e) => {
5168
5957
  e.preventDefault();
5169
5958
  imageInputRef.current?.click();
5170
5959
  },
5171
5960
  []
5172
5961
  );
5173
- const onImageInputChange = (0, import_react15.useCallback)(
5962
+ const onImageInputChange = (0, import_react16.useCallback)(
5174
5963
  (e) => {
5175
5964
  const file = e.target.files?.[0];
5176
5965
  if (file) void editor.insertImageFromFile(file);
@@ -5178,14 +5967,14 @@ function Toolbar({ className }) {
5178
5967
  },
5179
5968
  [editor]
5180
5969
  );
5181
- const imageInputRef = (0, import_react15.useRef)(null);
5970
+ const imageInputRef = (0, import_react16.useRef)(null);
5182
5971
  const onToggleDir = (e) => {
5183
5972
  e.preventDefault();
5184
5973
  const next = blockDir === "rtl" ? "ltr" : "rtl";
5185
5974
  setBlockAttr("dir", next);
5186
5975
  };
5187
5976
  const linkActive = isMarkActive("link");
5188
- const onLinkClick = (0, import_react15.useCallback)(
5977
+ const onLinkClick = (0, import_react16.useCallback)(
5189
5978
  (e) => {
5190
5979
  e.preventDefault();
5191
5980
  const currentHref = active.link && typeof active.link === "object" && "href" in active.link ? active.link.href : "";
@@ -5199,7 +5988,6 @@ function Toolbar({ className }) {
5199
5988
  );
5200
5989
  const colorValue = typeof active.color === "string" ? active.color : "#000000";
5201
5990
  const highlightValue = typeof active.highlight === "string" ? active.highlight : "#fff176";
5202
- const fontFamilyValue = typeof active.fontFamily === "string" ? active.fontFamily : "";
5203
5991
  const fontSizeValue = typeof active.fontSize === "string" ? active.fontSize : "";
5204
5992
  const blockValue = blockSelectValue(blockType, blockLevel);
5205
5993
  const selectedEmbed = editor.getSelectedEmbed();
@@ -5216,7 +6004,7 @@ function Toolbar({ className }) {
5216
6004
  sel.cellIndex
5217
6005
  );
5218
6006
  };
5219
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
6007
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
5220
6008
  "div",
5221
6009
  {
5222
6010
  className: className ?? "ed-toolbar",
@@ -5224,7 +6012,7 @@ function Toolbar({ className }) {
5224
6012
  "aria-label": "Editor toolbar",
5225
6013
  onMouseDown: stop,
5226
6014
  children: [
5227
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Group, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
6015
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Group, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
5228
6016
  "select",
5229
6017
  {
5230
6018
  className: "ed-toolbar-select",
@@ -5233,23 +6021,23 @@ function Toolbar({ className }) {
5233
6021
  onMouseDown: stop,
5234
6022
  "aria-label": "Tipo de bloco",
5235
6023
  children: [
5236
- blockValue === "" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "", children: "\u2014 (misto)" }),
5237
- BLOCK_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: o.value, children: o.label }, o.value))
6024
+ blockValue === "" && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: "", children: "\u2014 (misto)" }),
6025
+ BLOCK_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: o.value, children: o.label }, o.value))
5238
6026
  ]
5239
6027
  }
5240
6028
  ) }),
5241
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Group, { children: [
5242
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MarkButton, { title: "Negrito (\u2318B)", pressed: isMarkActive("bold"), onClick: onToggle("bold"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("strong", { children: "B" }) }),
5243
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MarkButton, { title: "It\xE1lico (\u2318I)", pressed: isMarkActive("italic"), onClick: onToggle("italic"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("em", { children: "I" }) }),
5244
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MarkButton, { title: "Sublinhado (\u2318U)", pressed: isMarkActive("underline"), onClick: onToggle("underline"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("u", { children: "U" }) }),
5245
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MarkButton, { title: "Tachado (\u2318\u21E7X)", pressed: isMarkActive("strike"), onClick: onToggle("strike"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("s", { children: "S" }) })
6029
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Group, { children: [
6030
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(MarkButton, { title: "Negrito (\u2318B)", pressed: isMarkActive("bold"), onClick: onToggle("bold"), children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("strong", { children: "B" }) }),
6031
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(MarkButton, { title: "It\xE1lico (\u2318I)", pressed: isMarkActive("italic"), onClick: onToggle("italic"), children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("em", { children: "I" }) }),
6032
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(MarkButton, { title: "Sublinhado (\u2318U)", pressed: isMarkActive("underline"), onClick: onToggle("underline"), children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("u", { children: "U" }) }),
6033
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(MarkButton, { title: "Tachado (\u2318\u21E7X)", pressed: isMarkActive("strike"), onClick: onToggle("strike"), children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("s", { children: "S" }) })
5246
6034
  ] }),
5247
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Group, { children: [
5248
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "ed-toolbar-label", children: [
5249
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ed-toolbar-swatch", "aria-hidden": true, style: { background: colorValue } }),
5250
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("input", { type: "color", value: colorValue, onChange: onColorChange, onMouseDown: stop, "aria-label": "Cor do texto" })
6035
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Group, { children: [
6036
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "ed-toolbar-label", children: [
6037
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "ed-toolbar-swatch", "aria-hidden": true, style: { background: colorValue } }),
6038
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("input", { type: "color", value: colorValue, onChange: onColorChange, onMouseDown: stop, "aria-label": "Cor do texto" })
5251
6039
  ] }),
5252
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6040
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5253
6041
  "button",
5254
6042
  {
5255
6043
  type: "button",
@@ -5263,8 +6051,8 @@ function Toolbar({ className }) {
5263
6051
  children: "\u232B"
5264
6052
  }
5265
6053
  ),
5266
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "ed-toolbar-label", title: "Marca-texto", children: [
5267
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6054
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "ed-toolbar-label", title: "Marca-texto", children: [
6055
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5268
6056
  "span",
5269
6057
  {
5270
6058
  className: "ed-toolbar-swatch ed-toolbar-swatch--highlight",
@@ -5272,7 +6060,7 @@ function Toolbar({ className }) {
5272
6060
  style: { background: highlightValue }
5273
6061
  }
5274
6062
  ),
5275
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6063
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5276
6064
  "input",
5277
6065
  {
5278
6066
  type: "color",
@@ -5283,7 +6071,7 @@ function Toolbar({ className }) {
5283
6071
  }
5284
6072
  )
5285
6073
  ] }),
5286
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6074
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5287
6075
  "button",
5288
6076
  {
5289
6077
  type: "button",
@@ -5298,37 +6086,21 @@ function Toolbar({ className }) {
5298
6086
  }
5299
6087
  )
5300
6088
  ] }),
5301
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Group, { children: [
5302
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
5303
- "select",
5304
- {
5305
- className: "ed-toolbar-select",
5306
- value: fontFamilyValue,
5307
- onChange: onFontFamilyChange,
5308
- onMouseDown: stop,
5309
- "aria-label": "Fam\xEDlia da fonte",
5310
- children: [
5311
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "", children: "Fonte\u2026" }),
5312
- FONT_FAMILIES.map((f) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: f, children: f }, f))
5313
- ]
5314
- }
5315
- ),
5316
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
5317
- "select",
5318
- {
5319
- className: "ed-toolbar-select",
5320
- value: fontSizeValue,
5321
- onChange: onFontSizeChange,
5322
- onMouseDown: stop,
5323
- "aria-label": "Tamanho da fonte",
5324
- children: [
5325
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "", children: "Tamanho\u2026" }),
5326
- FONT_SIZES.map((s) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: s, children: s }, s))
5327
- ]
5328
- }
5329
- )
5330
- ] }),
5331
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Group, { children: ALIGN_OPTIONS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6089
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Group, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
6090
+ "select",
6091
+ {
6092
+ className: "ed-toolbar-select",
6093
+ value: fontSizeValue,
6094
+ onChange: onFontSizeChange,
6095
+ onMouseDown: stop,
6096
+ "aria-label": "Tamanho da fonte",
6097
+ children: [
6098
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: "", children: "Tamanho\u2026" }),
6099
+ FONT_SIZES.map((s) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: s, children: s }, s))
6100
+ ]
6101
+ }
6102
+ ) }),
6103
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Group, { children: ALIGN_OPTIONS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5332
6104
  "button",
5333
6105
  {
5334
6106
  type: "button",
@@ -5341,7 +6113,7 @@ function Toolbar({ className }) {
5341
6113
  },
5342
6114
  a.value
5343
6115
  )) }),
5344
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Group, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6116
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Group, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5345
6117
  "button",
5346
6118
  {
5347
6119
  type: "button",
@@ -5353,8 +6125,8 @@ function Toolbar({ className }) {
5353
6125
  children: blockDir === "rtl" ? "RTL" : "LTR"
5354
6126
  }
5355
6127
  ) }),
5356
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Group, { children: [
5357
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6128
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Group, { children: [
6129
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5358
6130
  "button",
5359
6131
  {
5360
6132
  type: "button",
@@ -5369,7 +6141,7 @@ function Toolbar({ className }) {
5369
6141
  children: "\u2022"
5370
6142
  }
5371
6143
  ),
5372
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6144
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5373
6145
  "button",
5374
6146
  {
5375
6147
  type: "button",
@@ -5384,7 +6156,7 @@ function Toolbar({ className }) {
5384
6156
  children: "1."
5385
6157
  }
5386
6158
  ),
5387
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6159
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5388
6160
  "button",
5389
6161
  {
5390
6162
  type: "button",
@@ -5398,7 +6170,7 @@ function Toolbar({ className }) {
5398
6170
  children: "\u21E4"
5399
6171
  }
5400
6172
  ),
5401
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6173
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5402
6174
  "button",
5403
6175
  {
5404
6176
  type: "button",
@@ -5413,7 +6185,7 @@ function Toolbar({ className }) {
5413
6185
  }
5414
6186
  )
5415
6187
  ] }),
5416
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Group, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6188
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Group, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5417
6189
  "button",
5418
6190
  {
5419
6191
  type: "button",
@@ -5425,12 +6197,12 @@ function Toolbar({ className }) {
5425
6197
  children: "\u{1F517}"
5426
6198
  }
5427
6199
  ) }),
5428
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Group, { children: [
5429
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TableMenu, {}),
5430
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(AnswerLinesMenu, {})
6200
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Group, { children: [
6201
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TableMenu, {}),
6202
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AnswerLinesMenu, {})
5431
6203
  ] }),
5432
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Group, { children: [
5433
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6204
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Group, { children: [
6205
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5434
6206
  "button",
5435
6207
  {
5436
6208
  type: "button",
@@ -5441,7 +6213,7 @@ function Toolbar({ className }) {
5441
6213
  children: "\u{1F5BC}"
5442
6214
  }
5443
6215
  ),
5444
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6216
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5445
6217
  "input",
5446
6218
  {
5447
6219
  ref: imageInputRef,
@@ -5450,10 +6222,26 @@ function Toolbar({ className }) {
5450
6222
  hidden: true,
5451
6223
  onChange: onImageInputChange
5452
6224
  }
6225
+ ),
6226
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6227
+ "button",
6228
+ {
6229
+ type: "button",
6230
+ className: "ed-toolbar-btn",
6231
+ title: "Inserir f\xF3rmula",
6232
+ onMouseDown: stop,
6233
+ onClick: (e) => {
6234
+ e.preventDefault();
6235
+ void editor.requestFormula().then((r) => r ? editor.insertFormula(r.latex, r.display) : void 0).catch((err) => {
6236
+ console.error("Falha ao inserir f\xF3rmula:", err);
6237
+ });
6238
+ },
6239
+ children: "\u221Ax"
6240
+ }
5453
6241
  )
5454
6242
  ] }),
5455
- selectedEmbed && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Group, { children: [
5456
- IMAGE_LAYOUT_OPTIONS.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6243
+ selectedEmbed && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Group, { children: [
6244
+ IMAGE_LAYOUT_OPTIONS.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5457
6245
  "button",
5458
6246
  {
5459
6247
  type: "button",
@@ -5466,7 +6254,25 @@ function Toolbar({ className }) {
5466
6254
  },
5467
6255
  opt.value
5468
6256
  )),
5469
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6257
+ (0, import_core11.isFormulaEmbed)(selectedEmbed.embed) ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6258
+ "button",
6259
+ {
6260
+ type: "button",
6261
+ className: "ed-toolbar-btn",
6262
+ title: "Editar f\xF3rmula",
6263
+ onMouseDown: stop,
6264
+ onClick: (e) => {
6265
+ e.preventDefault();
6266
+ if (!(0, import_core11.isFormulaEmbed)(selectedEmbed.embed)) return;
6267
+ const f = selectedEmbed.embed.formula;
6268
+ void editor.requestFormula(f.latex, f.display).then((r) => {
6269
+ if (!r) return;
6270
+ void editor.insertFormula(r.latex, r.display);
6271
+ });
6272
+ },
6273
+ children: "Editar f\xF3rmula"
6274
+ }
6275
+ ) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5470
6276
  "button",
5471
6277
  {
5472
6278
  type: "button",
@@ -5496,7 +6302,7 @@ function Toolbar({ className }) {
5496
6302
  }
5497
6303
  )
5498
6304
  ] }),
5499
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Group, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6305
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Group, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5500
6306
  "button",
5501
6307
  {
5502
6308
  type: "button",
@@ -5516,11 +6322,11 @@ function Toolbar({ className }) {
5516
6322
  }
5517
6323
  function AnswerLinesMenu() {
5518
6324
  const editor = useEditorContext();
5519
- const [open, setOpen] = (0, import_react15.useState)(false);
5520
- const [count, setCount] = (0, import_react15.useState)(5);
5521
- const [spacing, setSpacing] = (0, import_react15.useState)(1.5);
5522
- const rootRef = (0, import_react15.useRef)(null);
5523
- (0, import_react15.useEffect)(() => {
6325
+ const [open, setOpen] = (0, import_react16.useState)(false);
6326
+ const [count, setCount] = (0, import_react16.useState)(5);
6327
+ const [spacing, setSpacing] = (0, import_react16.useState)(1.5);
6328
+ const rootRef = (0, import_react16.useRef)(null);
6329
+ (0, import_react16.useEffect)(() => {
5524
6330
  if (!open) return;
5525
6331
  const onDown = (e) => {
5526
6332
  if (!rootRef.current) return;
@@ -5530,9 +6336,9 @@ function AnswerLinesMenu() {
5530
6336
  document.addEventListener("mousedown", onDown);
5531
6337
  return () => document.removeEventListener("mousedown", onDown);
5532
6338
  }, [open]);
5533
- const clamped = Math.max(1, Math.min(import_core10.ANSWER_LINE_MAX, Math.trunc(count) || 1));
5534
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { ref: rootRef, className: "ed-toolbar-tablemenu", children: [
5535
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6339
+ const clamped = Math.max(1, Math.min(import_core11.ANSWER_LINE_MAX, Math.trunc(count) || 1));
6340
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { ref: rootRef, className: "ed-toolbar-tablemenu", children: [
6341
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5536
6342
  "button",
5537
6343
  {
5538
6344
  type: "button",
@@ -5547,7 +6353,7 @@ function AnswerLinesMenu() {
5547
6353
  children: "\u2630"
5548
6354
  }
5549
6355
  ),
5550
- open && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
6356
+ open && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
5551
6357
  "div",
5552
6358
  {
5553
6359
  className: "ed-table-popover ed-answerlines-popover",
@@ -5556,37 +6362,37 @@ function AnswerLinesMenu() {
5556
6362
  if (!keepsOwnMouseDown(e.target)) e.preventDefault();
5557
6363
  },
5558
6364
  children: [
5559
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "ed-toolbar-label", children: [
6365
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "ed-toolbar-label", children: [
5560
6366
  "Quantidade",
5561
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6367
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5562
6368
  "input",
5563
6369
  {
5564
6370
  type: "number",
5565
6371
  min: 1,
5566
- max: import_core10.ANSWER_LINE_MAX,
6372
+ max: import_core11.ANSWER_LINE_MAX,
5567
6373
  value: count,
5568
6374
  onChange: (e) => setCount(Number(e.target.value)),
5569
6375
  "aria-label": "Quantidade de linhas"
5570
6376
  }
5571
6377
  )
5572
6378
  ] }),
5573
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "ed-toolbar-label", children: [
6379
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "ed-toolbar-label", children: [
5574
6380
  "Entrelinha",
5575
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
6381
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
5576
6382
  "select",
5577
6383
  {
5578
6384
  value: String(spacing),
5579
6385
  onChange: (e) => setSpacing(Number(e.target.value)),
5580
6386
  "aria-label": "Entrelinha",
5581
6387
  children: [
5582
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "1", children: "Simples" }),
5583
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "1.5", children: "1,5" }),
5584
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "2", children: "Duplo" })
6388
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: "1", children: "Simples" }),
6389
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: "1.5", children: "1,5" }),
6390
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: "2", children: "Duplo" })
5585
6391
  ]
5586
6392
  }
5587
6393
  )
5588
6394
  ] }),
5589
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
6395
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
5590
6396
  "button",
5591
6397
  {
5592
6398
  type: "button",
@@ -5610,9 +6416,10 @@ function AnswerLinesMenu() {
5610
6416
  function TableMenu() {
5611
6417
  const editor = useEditorContext();
5612
6418
  const inTable = editor.isInTable();
5613
- const [open, setOpen] = (0, import_react15.useState)(false);
5614
- const rootRef = (0, import_react15.useRef)(null);
5615
- (0, import_react15.useEffect)(() => {
6419
+ const [open, setOpen] = (0, import_react16.useState)(false);
6420
+ const [bordersOpen, setBordersOpen] = (0, import_react16.useState)(false);
6421
+ const rootRef = (0, import_react16.useRef)(null);
6422
+ (0, import_react16.useEffect)(() => {
5616
6423
  if (!open) return;
5617
6424
  const onDown = (e) => {
5618
6425
  if (!rootRef.current) return;
@@ -5622,8 +6429,11 @@ function TableMenu() {
5622
6429
  document.addEventListener("mousedown", onDown);
5623
6430
  return () => document.removeEventListener("mousedown", onDown);
5624
6431
  }, [open]);
5625
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { ref: rootRef, className: "ed-toolbar-tablemenu", children: [
5626
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6432
+ (0, import_react16.useEffect)(() => {
6433
+ if (!open) setBordersOpen(false);
6434
+ }, [open]);
6435
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { ref: rootRef, className: "ed-toolbar-tablemenu", children: [
6436
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5627
6437
  "button",
5628
6438
  {
5629
6439
  type: "button",
@@ -5638,7 +6448,7 @@ function TableMenu() {
5638
6448
  children: "\u25A6"
5639
6449
  }
5640
6450
  ),
5641
- open && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
6451
+ open && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
5642
6452
  "div",
5643
6453
  {
5644
6454
  className: "ed-table-popover",
@@ -5647,7 +6457,7 @@ function TableMenu() {
5647
6457
  if (!keepsOwnMouseDown(e.target)) e.preventDefault();
5648
6458
  },
5649
6459
  children: [
5650
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6460
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5651
6461
  TableSizePicker,
5652
6462
  {
5653
6463
  onPick: (rows, cols) => {
@@ -5656,34 +6466,34 @@ function TableMenu() {
5656
6466
  }
5657
6467
  }
5658
6468
  ),
5659
- inTable && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "ed-table-actions", children: [
5660
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("hr", {}),
5661
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
6469
+ inTable && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "ed-table-actions", children: [
6470
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("hr", {}),
6471
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", onClick: () => {
5662
6472
  setOpen(false);
5663
6473
  editor.insertRowAbove();
5664
6474
  }, children: "Inserir linha acima" }),
5665
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
6475
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", onClick: () => {
5666
6476
  setOpen(false);
5667
6477
  editor.insertRowBelow();
5668
6478
  }, children: "Inserir linha abaixo" }),
5669
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
6479
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", onClick: () => {
5670
6480
  setOpen(false);
5671
6481
  editor.insertColumnLeft();
5672
6482
  }, children: "Inserir coluna \xE0 esquerda" }),
5673
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
6483
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", onClick: () => {
5674
6484
  setOpen(false);
5675
6485
  editor.insertColumnRight();
5676
6486
  }, children: "Inserir coluna \xE0 direita" }),
5677
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
6487
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", onClick: () => {
5678
6488
  setOpen(false);
5679
6489
  editor.deleteCurrentRow();
5680
6490
  }, children: "Excluir linha" }),
5681
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
6491
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", onClick: () => {
5682
6492
  setOpen(false);
5683
6493
  editor.deleteCurrentColumn();
5684
6494
  }, children: "Excluir coluna" }),
5685
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("hr", {}),
5686
- editor.hasTableRectSelection() && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6495
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("hr", {}),
6496
+ editor.hasTableRectSelection() && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5687
6497
  "button",
5688
6498
  {
5689
6499
  type: "button",
@@ -5694,21 +6504,21 @@ function TableMenu() {
5694
6504
  children: "Mesclar c\xE9lulas selecionadas"
5695
6505
  }
5696
6506
  ),
5697
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
6507
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", onClick: () => {
5698
6508
  setOpen(false);
5699
6509
  editor.mergeRight();
5700
6510
  }, children: "Mesclar com c\xE9lula \xE0 direita" }),
5701
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
6511
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", onClick: () => {
5702
6512
  setOpen(false);
5703
6513
  editor.mergeDown();
5704
6514
  }, children: "Mesclar com c\xE9lula abaixo" }),
5705
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
6515
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", onClick: () => {
5706
6516
  setOpen(false);
5707
6517
  editor.splitCell();
5708
6518
  }, children: "Dividir c\xE9lulas mescladas" }),
5709
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("hr", {}),
5710
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "ed-toolbar-label ed-table-bgcolor", children: [
5711
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6519
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("hr", {}),
6520
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "ed-toolbar-label ed-table-bgcolor", children: [
6521
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5712
6522
  "span",
5713
6523
  {
5714
6524
  className: "ed-toolbar-swatch",
@@ -5717,7 +6527,7 @@ function TableMenu() {
5717
6527
  }
5718
6528
  ),
5719
6529
  "Cor de fundo da c\xE9lula",
5720
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6530
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5721
6531
  "input",
5722
6532
  {
5723
6533
  type: "color",
@@ -5727,62 +6537,39 @@ function TableMenu() {
5727
6537
  }
5728
6538
  )
5729
6539
  ] }),
5730
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
6540
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", onClick: () => {
5731
6541
  setOpen(false);
5732
6542
  editor.setCellBackground(null);
5733
6543
  }, children: "Remover cor de fundo" }),
5734
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("hr", {}),
5735
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "ed-toolbar-label", children: [
5736
- "Bordas",
5737
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
5738
- "select",
5739
- {
5740
- value: editor.getTableBorderPreset(),
5741
- onChange: (e) => editor.setTableBorderPreset(e.target.value),
5742
- "aria-label": "Bordas da tabela",
5743
- children: [
5744
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "all", children: "Todas" }),
5745
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "outer", children: "S\xF3 externas" }),
5746
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "horizontal", children: "S\xF3 horizontais" }),
5747
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "vertical", children: "S\xF3 verticais" }),
5748
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "none", children: "Nenhuma" })
5749
- ]
5750
- }
5751
- )
5752
- ] }),
5753
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "ed-toolbar-label ed-table-bgcolor", children: [
5754
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5755
- "span",
5756
- {
5757
- className: "ed-toolbar-swatch",
5758
- "aria-hidden": true,
5759
- style: { background: editor.getTableBorderColor() ?? import_core10.TABLE_BORDER_COLOR }
5760
- }
5761
- ),
5762
- "Cor da borda",
5763
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5764
- "input",
5765
- {
5766
- type: "color",
5767
- value: editor.getTableBorderColor() ?? import_core10.TABLE_BORDER_COLOR,
5768
- onChange: (e) => editor.setTableBorderColor(e.target.value),
5769
- "aria-label": "Cor da borda"
5770
- }
5771
- )
5772
- ] }),
5773
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6544
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("hr", {}),
6545
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5774
6546
  "button",
5775
6547
  {
5776
6548
  type: "button",
5777
- onClick: () => {
5778
- setOpen(false);
5779
- editor.setTableBorderColor(null);
6549
+ className: "ed-border-toggle",
6550
+ "aria-pressed": bordersOpen,
6551
+ "aria-expanded": bordersOpen,
6552
+ title: "Bordas da tabela",
6553
+ "aria-label": "Bordas da tabela",
6554
+ onClick: (e) => {
6555
+ e.preventDefault();
6556
+ setBordersOpen((v) => !v);
5780
6557
  },
5781
- children: "Restaurar cor padr\xE3o"
6558
+ children: BORDER_MENU_GLYPH
6559
+ }
6560
+ ),
6561
+ bordersOpen && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6562
+ TableBorderPanel,
6563
+ {
6564
+ preset: editor.getTableBorderPreset(),
6565
+ color: editor.getTableBorderColor() ?? import_core11.TABLE_BORDER_COLOR,
6566
+ onPreset: (p) => editor.setTableBorderPreset(p),
6567
+ onColor: (c) => editor.setTableBorderColor(c),
6568
+ onResetColor: () => editor.setTableBorderColor(null)
5782
6569
  }
5783
6570
  ),
5784
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("hr", {}),
5785
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6571
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("hr", {}),
6572
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5786
6573
  "button",
5787
6574
  {
5788
6575
  type: "button",
@@ -5803,11 +6590,11 @@ function TableMenu() {
5803
6590
  var PICKER_MAX_ROWS = 8;
5804
6591
  var PICKER_MAX_COLS = 10;
5805
6592
  function TableSizePicker({ onPick }) {
5806
- const [hover, setHover] = (0, import_react15.useState)(null);
6593
+ const [hover, setHover] = (0, import_react16.useState)(null);
5807
6594
  const label = hover ? `${hover.r + 1} \xD7 ${hover.c + 1}` : "Inserir tabela";
5808
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "ed-table-picker", children: [
5809
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "ed-table-picker-label", children: label }),
5810
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6595
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "ed-table-picker", children: [
6596
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "ed-table-picker-label", children: label }),
6597
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5811
6598
  "div",
5812
6599
  {
5813
6600
  className: "ed-table-picker-grid",
@@ -5820,7 +6607,7 @@ function TableSizePicker({ onPick }) {
5820
6607
  { length: PICKER_MAX_ROWS },
5821
6608
  (_, r) => Array.from({ length: PICKER_MAX_COLS }, (_2, c) => {
5822
6609
  const filled = hover != null && r <= hover.r && c <= hover.c;
5823
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6610
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5824
6611
  "button",
5825
6612
  {
5826
6613
  type: "button",
@@ -5850,10 +6637,10 @@ function blockSelectValue(type, level) {
5850
6637
  return type;
5851
6638
  }
5852
6639
  function Group({ children }) {
5853
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "ed-toolbar-group", children });
6640
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "ed-toolbar-group", children });
5854
6641
  }
5855
6642
  function MarkButton({ title, pressed, onClick, children }) {
5856
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6643
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5857
6644
  "button",
5858
6645
  {
5859
6646
  type: "button",
@@ -5871,6 +6658,7 @@ function MarkButton({ title, pressed, onClick, children }) {
5871
6658
  A4_PAGE,
5872
6659
  Editor,
5873
6660
  EditorProvider,
6661
+ FormulaDialog,
5874
6662
  ImageCaptionDialog,
5875
6663
  LinkDialog,
5876
6664
  NodeView,