@underverse-ui/underverse 1.0.151 → 1.0.153

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "@underverse-ui/underverse",
3
- "version": "1.0.151",
3
+ "version": "1.0.153",
4
4
  "sourceEntry": "src/index.ts",
5
5
  "totalExports": 232,
6
6
  "exports": [
package/dist/index.cjs CHANGED
@@ -1030,6 +1030,9 @@ var en_default = {
1030
1030
  borderColor: "Border Color",
1031
1031
  clearBorder: "Clear Border",
1032
1032
  formula: "Formula",
1033
+ numberFormat: "Number Format",
1034
+ formatText: "Text",
1035
+ formatDate: "Date",
1033
1036
  apply: "Apply",
1034
1037
  clear: "Clear",
1035
1038
  recalculate: "Recalculate",
@@ -1410,6 +1413,9 @@ var vi_default = {
1410
1413
  borderColor: "M\xE0u vi\u1EC1n",
1411
1414
  clearBorder: "X\xF3a vi\u1EC1n",
1412
1415
  formula: "C\xF4ng th\u1EE9c",
1416
+ numberFormat: "\u0110\u1ECBnh d\u1EA1ng s\u1ED1",
1417
+ formatText: "Ch\u1EEF",
1418
+ formatDate: "Ng\xE0y",
1413
1419
  apply: "\xC1p d\u1EE5ng",
1414
1420
  clear: "X\xF3a",
1415
1421
  recalculate: "T\xEDnh l\u1EA1i",
@@ -26148,6 +26154,10 @@ function getTableCellAttrs(cell, styles, defaultBackgroundColor) {
26148
26154
  if (borderAttrs.borderColor) attrs.borderColor = borderAttrs.borderColor;
26149
26155
  if (borderAttrs.borderStyle) attrs.borderStyle = borderAttrs.borderStyle;
26150
26156
  if (borderAttrs.borderWidth) attrs.borderWidth = borderAttrs.borderWidth;
26157
+ if (cell.getAttribute("data-cell-id")) attrs.cellId = cell.getAttribute("data-cell-id") ?? void 0;
26158
+ if (cell.getAttribute("data-number-format")) attrs.numberFormat = cell.getAttribute("data-number-format") ?? void 0;
26159
+ if (cell.getAttribute("data-formula")) attrs.formula = cell.getAttribute("data-formula") ?? void 0;
26160
+ if (cell.getAttribute("data-computed-value")) attrs.computedValue = cell.getAttribute("data-computed-value") ?? void 0;
26151
26161
  if (colspan > 1) attrs.colspan = colspan;
26152
26162
  if (rowspan > 1) attrs.rowspan = rowspan;
26153
26163
  if (colwidth) attrs.colwidth = colwidth;
@@ -27775,6 +27785,16 @@ var CodeBlockView = ({
27775
27785
  };
27776
27786
 
27777
27787
  // src/components/UEditor/extensions.ts
27788
+ function getFormulaStateAttributes(attributes) {
27789
+ const formula = attributes["data-formula"];
27790
+ if (!formula) {
27791
+ return {};
27792
+ }
27793
+ const computedValue = String(attributes["data-computed-value"] ?? "");
27794
+ return {
27795
+ "data-formula-state": computedValue.startsWith("#") ? "error" : "computed"
27796
+ };
27797
+ }
27778
27798
  var CustomTableCell = import_extension_table_cell.default.extend({
27779
27799
  addAttributes() {
27780
27800
  return {
@@ -27877,7 +27897,7 @@ var CustomTableCell = import_extension_table_cell.default.extend({
27877
27897
  mergedStyle = mergedStyle.replace(/^;/, "").trim();
27878
27898
  return [
27879
27899
  "td",
27880
- (0, import_core13.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, mergedStyle ? { style: mergedStyle } : {}),
27900
+ (0, import_core13.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, getFormulaStateAttributes(HTMLAttributes), mergedStyle ? { style: mergedStyle } : {}),
27881
27901
  0
27882
27902
  ];
27883
27903
  }
@@ -27984,7 +28004,7 @@ var CustomTableHeader = import_extension_table_header.default.extend({
27984
28004
  mergedStyle = mergedStyle.replace(/^;/, "").trim();
27985
28005
  return [
27986
28006
  "th",
27987
- (0, import_core13.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, mergedStyle ? { style: mergedStyle } : {}),
28007
+ (0, import_core13.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, getFormulaStateAttributes(HTMLAttributes), mergedStyle ? { style: mergedStyle } : {}),
27988
28008
  0
27989
28009
  ];
27990
28010
  }
@@ -30005,6 +30025,143 @@ function getTableCellRangeLabels(range) {
30005
30025
  function normalizeTableFormula(formula) {
30006
30026
  return formula.trim().replace(/^=/, "").trim();
30007
30027
  }
30028
+ function formatFormulaError(error) {
30029
+ return `#${error.toUpperCase()}`;
30030
+ }
30031
+ function normalizeTableNumberFormat(format) {
30032
+ return format === "text" || format === "number" || format === "currency" || format === "percent" || format === "date" ? format : "text";
30033
+ }
30034
+ function formatTableFormulaDisplayValue(value, numberFormat) {
30035
+ const stringValue = String(value);
30036
+ if (stringValue.startsWith("#")) {
30037
+ return stringValue;
30038
+ }
30039
+ const normalizedFormat = normalizeTableNumberFormat(numberFormat);
30040
+ if (normalizedFormat === "text") {
30041
+ return stringValue;
30042
+ }
30043
+ const numericValue = typeof value === "number" ? value : Number.parseFloat(stringValue.replace(/,/g, ""));
30044
+ if (!Number.isFinite(numericValue)) {
30045
+ return stringValue;
30046
+ }
30047
+ if (normalizedFormat === "number") {
30048
+ return new Intl.NumberFormat("en-US", { maximumFractionDigits: 6 }).format(numericValue);
30049
+ }
30050
+ if (normalizedFormat === "currency") {
30051
+ return new Intl.NumberFormat("en-US", {
30052
+ style: "currency",
30053
+ currency: "USD",
30054
+ maximumFractionDigits: 2
30055
+ }).format(numericValue);
30056
+ }
30057
+ if (normalizedFormat === "percent") {
30058
+ return new Intl.NumberFormat("en-US", {
30059
+ style: "percent",
30060
+ maximumFractionDigits: 2
30061
+ }).format(numericValue);
30062
+ }
30063
+ const excelEpochMs = Date.UTC(1899, 11, 30);
30064
+ const date = new Date(excelEpochMs + numericValue * 24 * 60 * 60 * 1e3);
30065
+ if (Number.isNaN(date.getTime())) {
30066
+ return stringValue;
30067
+ }
30068
+ return new Intl.DateTimeFormat("en-US", {
30069
+ year: "numeric",
30070
+ month: "2-digit",
30071
+ day: "2-digit",
30072
+ timeZone: "UTC"
30073
+ }).format(date);
30074
+ }
30075
+ function getTableFormulaReferences(formula) {
30076
+ const normalized = normalizeTableFormula(formula);
30077
+ if (!normalized) return [];
30078
+ const tokens = tokenizeFormula(normalized);
30079
+ if (!tokens) return [];
30080
+ const references = /* @__PURE__ */ new Set();
30081
+ for (const token of tokens) {
30082
+ if (token.type === "cell") {
30083
+ references.add(token.value);
30084
+ } else if (token.type === "range") {
30085
+ const range = parseTableCellRange(token.value);
30086
+ if (!range) continue;
30087
+ for (const label of getTableCellRangeLabels(range)) {
30088
+ references.add(label);
30089
+ }
30090
+ }
30091
+ }
30092
+ return Array.from(references);
30093
+ }
30094
+ function buildTableFormulaDependencyGraph(cells) {
30095
+ const dependencies = /* @__PURE__ */ new Map();
30096
+ const dependents = /* @__PURE__ */ new Map();
30097
+ const formulas = /* @__PURE__ */ new Map();
30098
+ for (const cell of cells) {
30099
+ const label = cell.label.toUpperCase();
30100
+ formulas.set(label, cell.formula);
30101
+ dependencies.set(label, new Set(getTableFormulaReferences(cell.formula)));
30102
+ if (!dependents.has(label)) {
30103
+ dependents.set(label, /* @__PURE__ */ new Set());
30104
+ }
30105
+ }
30106
+ for (const [label, refs] of dependencies) {
30107
+ for (const ref of refs) {
30108
+ if (!dependents.has(ref)) {
30109
+ dependents.set(ref, /* @__PURE__ */ new Set());
30110
+ }
30111
+ dependents.get(ref)?.add(label);
30112
+ }
30113
+ }
30114
+ return { dependencies, dependents, formulas };
30115
+ }
30116
+ function getTableFormulaCircularReferences(graph) {
30117
+ const visiting = /* @__PURE__ */ new Set();
30118
+ const visited = /* @__PURE__ */ new Set();
30119
+ const circular = /* @__PURE__ */ new Set();
30120
+ const stack = [];
30121
+ const visit = (label) => {
30122
+ if (visiting.has(label)) {
30123
+ const start = stack.indexOf(label);
30124
+ for (const cycleLabel of start >= 0 ? stack.slice(start) : [label]) {
30125
+ circular.add(cycleLabel);
30126
+ }
30127
+ return;
30128
+ }
30129
+ if (visited.has(label)) return;
30130
+ visiting.add(label);
30131
+ stack.push(label);
30132
+ for (const ref of graph.dependencies.get(label) ?? []) {
30133
+ if (graph.formulas.has(ref)) {
30134
+ visit(ref);
30135
+ }
30136
+ }
30137
+ stack.pop();
30138
+ visiting.delete(label);
30139
+ visited.add(label);
30140
+ };
30141
+ for (const label of graph.formulas.keys()) {
30142
+ visit(label);
30143
+ }
30144
+ return circular;
30145
+ }
30146
+ function getTableFormulaRecalculationOrder(graph) {
30147
+ const circular = getTableFormulaCircularReferences(graph);
30148
+ const visited = /* @__PURE__ */ new Set();
30149
+ const order = [];
30150
+ const visit = (label) => {
30151
+ if (visited.has(label) || circular.has(label)) return;
30152
+ visited.add(label);
30153
+ for (const ref of graph.dependencies.get(label) ?? []) {
30154
+ if (graph.formulas.has(ref)) {
30155
+ visit(ref);
30156
+ }
30157
+ }
30158
+ order.push(label);
30159
+ };
30160
+ for (const label of graph.formulas.keys()) {
30161
+ visit(label);
30162
+ }
30163
+ return { order, circular };
30164
+ }
30008
30165
  function evaluateBasicTableFormula(formula, getCellValue) {
30009
30166
  const normalized = normalizeTableFormula(formula);
30010
30167
  if (!normalized) {
@@ -30209,6 +30366,7 @@ var FormulaParser = class {
30209
30366
  };
30210
30367
 
30211
30368
  // src/components/UEditor/table-formula-commands.ts
30369
+ var UEDITOR_TABLE_FORMULA_RECALCULATE_META = "ueditorTableFormulaRecalculate";
30212
30370
  function collectChildren2(node) {
30213
30371
  const children = [];
30214
30372
  node.forEach((child) => children.push(child));
@@ -30239,6 +30397,13 @@ function safeFindCell2(map, relativePos) {
30239
30397
  function getCellText(cellNode) {
30240
30398
  return cellNode.textBetween(0, cellNode.content.size, "\n").trim();
30241
30399
  }
30400
+ function createCellDisplayContent(cellNode, displayValue) {
30401
+ const paragraphType = cellNode.type.schema.nodes.paragraph;
30402
+ if (!paragraphType || !displayValue) {
30403
+ return paragraphType ? [paragraphType.create()] : cellNode.content;
30404
+ }
30405
+ return [paragraphType.create(null, cellNode.type.schema.text(displayValue))];
30406
+ }
30242
30407
  function buildTableValueGetter(tableNode) {
30243
30408
  const map = import_tables2.TableMap.get(tableNode);
30244
30409
  const values = /* @__PURE__ */ new Map();
@@ -30253,6 +30418,20 @@ function buildTableValueGetter(tableNode) {
30253
30418
  }
30254
30419
  return (label) => values.get(label.toUpperCase());
30255
30420
  }
30421
+ function buildTableValueMap(tableNode) {
30422
+ const map = import_tables2.TableMap.get(tableNode);
30423
+ const values = /* @__PURE__ */ new Map();
30424
+ for (const rowInfo of getTableRows2(tableNode)) {
30425
+ for (const entry of rowInfo.cells) {
30426
+ const rect = safeFindCell2(map, entry.relativePos);
30427
+ if (!rect) continue;
30428
+ const label = `${indexToColumnName(rect.left)}${rect.top + 1}`;
30429
+ const computedValue = entry.node.attrs.computedValue;
30430
+ values.set(label, typeof computedValue === "string" && computedValue.trim() ? computedValue : getCellText(entry.node));
30431
+ }
30432
+ }
30433
+ return values;
30434
+ }
30256
30435
  function getFormulaComputedValue(formula, tableNode) {
30257
30436
  const result = evaluateBasicTableFormula(formula, buildTableValueGetter(tableNode));
30258
30437
  return result.error ? `#${result.error.toUpperCase()}` : String(result.value);
@@ -30289,37 +30468,143 @@ function setSelectedTableCellFormula(editor, formula) {
30289
30468
  function clearSelectedTableCellFormula(editor) {
30290
30469
  return setSelectedTableCellFormula(editor, "");
30291
30470
  }
30292
- function recalculateSelectedTable(editor) {
30293
- const rect = (0, import_tables2.selectedRect)(editor.state);
30294
- const tableNode = rect.table;
30295
- const map = import_tables2.TableMap.get(tableNode);
30296
- const getCellValue = buildTableValueGetter(tableNode);
30471
+ function setSelectedTableCellNumberFormat(editor, numberFormat) {
30472
+ const value = numberFormat && numberFormat !== "text" ? numberFormat : null;
30473
+ const { state, view } = editor;
30474
+ const applied = (0, import_tables2.setCellAttr)("numberFormat", value)(state, view.dispatch.bind(view));
30475
+ if (!applied) return false;
30476
+ recalculateSelectedTable(editor);
30477
+ view.focus();
30478
+ dispatchTableLayoutChange(editor);
30479
+ return true;
30480
+ }
30481
+ function promoteFormulaTextInTableNode(tableNode) {
30297
30482
  let changed = false;
30298
30483
  const rows = getTableRows2(tableNode).map((rowInfo) => {
30299
30484
  const cells = collectChildren2(rowInfo.node);
30485
+ for (const entry of rowInfo.cells) {
30486
+ const text = getCellText(entry.node);
30487
+ const formula = text.startsWith("=") ? normalizeFormulaInput(text) : "";
30488
+ if (!formula || entry.node.attrs.formula === formula) continue;
30489
+ cells[entry.index] = entry.node.type.create(
30490
+ {
30491
+ ...entry.node.attrs,
30492
+ formula,
30493
+ computedValue: null
30494
+ },
30495
+ entry.node.content,
30496
+ entry.node.marks
30497
+ );
30498
+ changed = true;
30499
+ }
30500
+ return rowInfo.node.type.create(rowInfo.node.attrs, cells);
30501
+ });
30502
+ return {
30503
+ tableNode: changed ? tableNode.type.create(tableNode.attrs, rows) : tableNode,
30504
+ changed
30505
+ };
30506
+ }
30507
+ function recalculateTableNode(tableNode) {
30508
+ const promoted = promoteFormulaTextInTableNode(tableNode);
30509
+ tableNode = promoted.tableNode;
30510
+ const map = import_tables2.TableMap.get(tableNode);
30511
+ const values = buildTableValueMap(tableNode);
30512
+ const formulaEntries = /* @__PURE__ */ new Map();
30513
+ let changed = false;
30514
+ const rowInfos = getTableRows2(tableNode);
30515
+ for (const [rowIndex, rowInfo] of rowInfos.entries()) {
30300
30516
  for (const entry of rowInfo.cells) {
30301
30517
  const formula = typeof entry.node.attrs.formula === "string" ? entry.node.attrs.formula.trim() : "";
30302
30518
  if (!formula) continue;
30303
30519
  const rectForCell = safeFindCell2(map, entry.relativePos);
30304
30520
  if (!rectForCell) continue;
30305
- const result = evaluateBasicTableFormula(formula, getCellValue);
30306
- const computedValue = result.error ? `#${result.error.toUpperCase()}` : String(result.value);
30307
- if (entry.node.attrs.computedValue === computedValue) continue;
30521
+ const label = `${indexToColumnName(rectForCell.left)}${rectForCell.top + 1}`;
30522
+ formulaEntries.set(label, {
30523
+ rowIndex,
30524
+ cellIndex: entry.index,
30525
+ node: entry.node,
30526
+ formula
30527
+ });
30528
+ }
30529
+ }
30530
+ const graph = buildTableFormulaDependencyGraph(
30531
+ Array.from(formulaEntries, ([label, entry]) => ({
30532
+ label,
30533
+ formula: entry.formula
30534
+ }))
30535
+ );
30536
+ const { order, circular } = getTableFormulaRecalculationOrder(graph);
30537
+ const computedValues = /* @__PURE__ */ new Map();
30538
+ const getCellValue = (label) => values.get(label.toUpperCase());
30539
+ for (const label of circular) {
30540
+ computedValues.set(label, formatFormulaError("circular-reference"));
30541
+ values.set(label, formatFormulaError("circular-reference"));
30542
+ }
30543
+ for (const label of order) {
30544
+ const entry = formulaEntries.get(label);
30545
+ if (!entry) continue;
30546
+ const result = evaluateBasicTableFormula(entry.formula, getCellValue);
30547
+ const computedValue = result.error ? formatFormulaError(result.error) : String(result.value);
30548
+ computedValues.set(label, computedValue);
30549
+ values.set(label, computedValue);
30550
+ }
30551
+ const rows = rowInfos.map((rowInfo) => {
30552
+ const cells = collectChildren2(rowInfo.node);
30553
+ for (const entry of rowInfo.cells) {
30554
+ const rectForCell = safeFindCell2(map, entry.relativePos);
30555
+ if (!rectForCell) continue;
30556
+ const label = `${indexToColumnName(rectForCell.left)}${rectForCell.top + 1}`;
30557
+ const computedValue = computedValues.get(label);
30558
+ if (computedValue == null) continue;
30559
+ const displayValue = formatTableFormulaDisplayValue(computedValue, entry.node.attrs.numberFormat);
30560
+ const contentMatchesComputedValue = getCellText(entry.node) === displayValue;
30561
+ if (entry.node.attrs.computedValue === computedValue && contentMatchesComputedValue) continue;
30308
30562
  cells[entry.index] = entry.node.type.create(
30309
30563
  {
30310
30564
  ...entry.node.attrs,
30311
30565
  computedValue
30312
30566
  },
30313
- entry.node.content,
30567
+ createCellDisplayContent(entry.node, displayValue),
30314
30568
  entry.node.marks
30315
30569
  );
30316
30570
  changed = true;
30317
30571
  }
30318
30572
  return rowInfo.node.type.create(rowInfo.node.attrs, cells);
30319
30573
  });
30320
- if (!changed) return false;
30321
- const nextTable = tableNode.type.create(tableNode.attrs, rows);
30322
- editor.view.dispatch(editor.state.tr.replaceWith(rect.tableStart - 1, rect.tableStart - 1 + tableNode.nodeSize, nextTable));
30574
+ if (!changed) return promoted.changed ? tableNode : null;
30575
+ return tableNode.type.create(tableNode.attrs, rows);
30576
+ }
30577
+ function recalculateSelectedTable(editor) {
30578
+ const rect = (0, import_tables2.selectedRect)(editor.state);
30579
+ const tableNode = rect.table;
30580
+ const nextTable = recalculateTableNode(tableNode);
30581
+ if (!nextTable) return false;
30582
+ editor.view.dispatch(
30583
+ editor.state.tr.replaceWith(rect.tableStart - 1, rect.tableStart - 1 + tableNode.nodeSize, nextTable).setMeta(UEDITOR_TABLE_FORMULA_RECALCULATE_META, true)
30584
+ );
30585
+ dispatchTableLayoutChange(editor);
30586
+ return true;
30587
+ }
30588
+ function recalculateAllTableFormulas(editor) {
30589
+ const replacements = [];
30590
+ editor.state.doc.descendants((node, pos) => {
30591
+ if (node.type.name !== "table") return true;
30592
+ const nextTable = recalculateTableNode(node);
30593
+ if (nextTable) {
30594
+ replacements.push({
30595
+ from: pos,
30596
+ to: pos + node.nodeSize,
30597
+ node: nextTable
30598
+ });
30599
+ }
30600
+ return false;
30601
+ });
30602
+ if (replacements.length === 0) return false;
30603
+ let tr = editor.state.tr;
30604
+ for (const replacement of replacements.reverse()) {
30605
+ tr = tr.replaceWith(replacement.from, replacement.to, replacement.node);
30606
+ }
30607
+ editor.view.dispatch(tr.setMeta(UEDITOR_TABLE_FORMULA_RECALCULATE_META, true));
30323
30608
  dispatchTableLayoutChange(editor);
30324
30609
  return true;
30325
30610
  }
@@ -30368,6 +30653,7 @@ var BubbleMenuContent = ({
30368
30653
  const currentHighlightColor = normalizeStyleValue(editor.getAttributes("highlight").color) || "";
30369
30654
  const currentCellBgColor = normalizeStyleValue(editor.getAttributes("tableCell").backgroundColor || editor.getAttributes("tableHeader").backgroundColor) || "";
30370
30655
  const currentCellFormula = normalizeStyleValue(editor.getAttributes("tableCell").formula || editor.getAttributes("tableHeader").formula) || "";
30656
+ const currentCellNumberFormat = normalizeStyleValue(editor.getAttributes("tableCell").numberFormat || editor.getAttributes("tableHeader").numberFormat) || "text";
30371
30657
  const isInTable2 = (0, import_tables3.isInTable)(editor.state);
30372
30658
  const canMergeCells = isInTable2 && editor.can().mergeCells();
30373
30659
  const canSplitCell = isInTable2 && editor.can().splitCell();
@@ -30627,6 +30913,28 @@ var BubbleMenuContent = ({
30627
30913
  className: "h-full min-w-0 flex-1 bg-transparent px-2 text-sm font-medium text-foreground outline-none"
30628
30914
  }
30629
30915
  ) }),
30916
+ /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "mt-2", children: [
30917
+ /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: "mb-1 px-1 text-[11px] font-medium text-muted-foreground", children: t("tableMenu.numberFormat") || "Number format" }),
30918
+ /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: "grid grid-cols-5 gap-1", children: [
30919
+ ["text", "Text"],
30920
+ ["number", "123"],
30921
+ ["currency", "$"],
30922
+ ["percent", "%"],
30923
+ ["date", "Date"]
30924
+ ].map(([format, label]) => /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
30925
+ "button",
30926
+ {
30927
+ type: "button",
30928
+ onClick: () => setSelectedTableCellNumberFormat(editor, format),
30929
+ className: cn(
30930
+ "h-8 rounded-md text-[11px] font-semibold transition-colors hover:bg-muted",
30931
+ currentCellNumberFormat === format || format === "text" && !currentCellNumberFormat ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
30932
+ ),
30933
+ children: format === "text" ? t("tableMenu.formatText") || label : format === "date" ? t("tableMenu.formatDate") || label : label
30934
+ },
30935
+ format
30936
+ )) })
30937
+ ] }),
30630
30938
  /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "mt-2 grid grid-cols-3 gap-1", children: [
30631
30939
  /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
30632
30940
  "button",
@@ -38317,6 +38625,7 @@ var UEditor = import_react69.default.forwardRef(({
38317
38625
  const effectivePlaceholder = placeholder ?? t("placeholder");
38318
38626
  const inFlightPrepareRef = (0, import_react69.useRef)(null);
38319
38627
  const lastAppliedContentRef = (0, import_react69.useRef)(content ?? "");
38628
+ const scheduledFormulaRecalculateRef = (0, import_react69.useRef)(false);
38320
38629
  const resolvedUploadFile = (0, import_react69.useMemo)(() => {
38321
38630
  if (uploadFile) return uploadFile;
38322
38631
  if (uploadFileForSave) {
@@ -38380,7 +38689,16 @@ var UEditor = import_react69.default.forwardRef(({
38380
38689
  class: UEDITOR_PROSEMIRROR_CLASS_NAME
38381
38690
  }
38382
38691
  },
38383
- onUpdate: ({ editor: editor2 }) => {
38692
+ onUpdate: ({ editor: editor2, transaction }) => {
38693
+ if (!transaction.getMeta(UEDITOR_TABLE_FORMULA_RECALCULATE_META) && !scheduledFormulaRecalculateRef.current) {
38694
+ scheduledFormulaRecalculateRef.current = true;
38695
+ queueMicrotask(() => {
38696
+ scheduledFormulaRecalculateRef.current = false;
38697
+ if (!editor2.isDestroyed) {
38698
+ recalculateAllTableFormulas(editor2);
38699
+ }
38700
+ });
38701
+ }
38384
38702
  const html = editor2.getHTML();
38385
38703
  onChange?.(html);
38386
38704
  onHtmlChange?.(html);
@@ -38418,6 +38736,14 @@ var UEditor = import_react69.default.forwardRef(({
38418
38736
  }),
38419
38737
  [content, editor, uploadImageForSave, uploadFileForSave, uploadImageConcurrency]
38420
38738
  );
38739
+ (0, import_react69.useEffect)(() => {
38740
+ if (!editor) return;
38741
+ queueMicrotask(() => {
38742
+ if (!editor.isDestroyed) {
38743
+ recalculateAllTableFormulas(editor);
38744
+ }
38745
+ });
38746
+ }, [editor]);
38421
38747
  (0, import_react69.useEffect)(() => {
38422
38748
  if (!editor) return;
38423
38749
  const nextContent = content ?? "";
@@ -38427,6 +38753,11 @@ var UEditor = import_react69.default.forwardRef(({
38427
38753
  Promise.resolve().then(() => {
38428
38754
  if (!editor.isDestroyed) {
38429
38755
  editor.commands.setContent(nextContent, { emitUpdate: false });
38756
+ queueMicrotask(() => {
38757
+ if (!editor.isDestroyed) {
38758
+ recalculateAllTableFormulas(editor);
38759
+ }
38760
+ });
38430
38761
  }
38431
38762
  });
38432
38763
  }