@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.
- package/api-reference.json +1 -1
- package/dist/index.cjs +346 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +346 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -3619,6 +3619,9 @@ declare const underverseMessages: {
|
|
|
3619
3619
|
borderColor: string;
|
|
3620
3620
|
clearBorder: string;
|
|
3621
3621
|
formula: string;
|
|
3622
|
+
numberFormat: string;
|
|
3623
|
+
formatText: string;
|
|
3624
|
+
formatDate: string;
|
|
3622
3625
|
apply: string;
|
|
3623
3626
|
clear: string;
|
|
3624
3627
|
recalculate: string;
|
|
@@ -3997,6 +4000,9 @@ declare const underverseMessages: {
|
|
|
3997
4000
|
borderColor: string;
|
|
3998
4001
|
clearBorder: string;
|
|
3999
4002
|
formula: string;
|
|
4003
|
+
numberFormat: string;
|
|
4004
|
+
formatText: string;
|
|
4005
|
+
formatDate: string;
|
|
4000
4006
|
apply: string;
|
|
4001
4007
|
clear: string;
|
|
4002
4008
|
recalculate: string;
|
|
@@ -5124,6 +5130,9 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
|
|
|
5124
5130
|
borderColor: string;
|
|
5125
5131
|
clearBorder: string;
|
|
5126
5132
|
formula: string;
|
|
5133
|
+
numberFormat: string;
|
|
5134
|
+
formatText: string;
|
|
5135
|
+
formatDate: string;
|
|
5127
5136
|
apply: string;
|
|
5128
5137
|
clear: string;
|
|
5129
5138
|
recalculate: string;
|
|
@@ -5501,6 +5510,9 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
|
|
|
5501
5510
|
borderColor: string;
|
|
5502
5511
|
clearBorder: string;
|
|
5503
5512
|
formula: string;
|
|
5513
|
+
numberFormat: string;
|
|
5514
|
+
formatText: string;
|
|
5515
|
+
formatDate: string;
|
|
5504
5516
|
apply: string;
|
|
5505
5517
|
clear: string;
|
|
5506
5518
|
recalculate: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -3619,6 +3619,9 @@ declare const underverseMessages: {
|
|
|
3619
3619
|
borderColor: string;
|
|
3620
3620
|
clearBorder: string;
|
|
3621
3621
|
formula: string;
|
|
3622
|
+
numberFormat: string;
|
|
3623
|
+
formatText: string;
|
|
3624
|
+
formatDate: string;
|
|
3622
3625
|
apply: string;
|
|
3623
3626
|
clear: string;
|
|
3624
3627
|
recalculate: string;
|
|
@@ -3997,6 +4000,9 @@ declare const underverseMessages: {
|
|
|
3997
4000
|
borderColor: string;
|
|
3998
4001
|
clearBorder: string;
|
|
3999
4002
|
formula: string;
|
|
4003
|
+
numberFormat: string;
|
|
4004
|
+
formatText: string;
|
|
4005
|
+
formatDate: string;
|
|
4000
4006
|
apply: string;
|
|
4001
4007
|
clear: string;
|
|
4002
4008
|
recalculate: string;
|
|
@@ -5124,6 +5130,9 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
|
|
|
5124
5130
|
borderColor: string;
|
|
5125
5131
|
clearBorder: string;
|
|
5126
5132
|
formula: string;
|
|
5133
|
+
numberFormat: string;
|
|
5134
|
+
formatText: string;
|
|
5135
|
+
formatDate: string;
|
|
5127
5136
|
apply: string;
|
|
5128
5137
|
clear: string;
|
|
5129
5138
|
recalculate: string;
|
|
@@ -5501,6 +5510,9 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
|
|
|
5501
5510
|
borderColor: string;
|
|
5502
5511
|
clearBorder: string;
|
|
5503
5512
|
formula: string;
|
|
5513
|
+
numberFormat: string;
|
|
5514
|
+
formatText: string;
|
|
5515
|
+
formatDate: string;
|
|
5504
5516
|
apply: string;
|
|
5505
5517
|
clear: string;
|
|
5506
5518
|
recalculate: string;
|
package/dist/index.js
CHANGED
|
@@ -844,6 +844,9 @@ var en_default = {
|
|
|
844
844
|
borderColor: "Border Color",
|
|
845
845
|
clearBorder: "Clear Border",
|
|
846
846
|
formula: "Formula",
|
|
847
|
+
numberFormat: "Number Format",
|
|
848
|
+
formatText: "Text",
|
|
849
|
+
formatDate: "Date",
|
|
847
850
|
apply: "Apply",
|
|
848
851
|
clear: "Clear",
|
|
849
852
|
recalculate: "Recalculate",
|
|
@@ -1224,6 +1227,9 @@ var vi_default = {
|
|
|
1224
1227
|
borderColor: "M\xE0u vi\u1EC1n",
|
|
1225
1228
|
clearBorder: "X\xF3a vi\u1EC1n",
|
|
1226
1229
|
formula: "C\xF4ng th\u1EE9c",
|
|
1230
|
+
numberFormat: "\u0110\u1ECBnh d\u1EA1ng s\u1ED1",
|
|
1231
|
+
formatText: "Ch\u1EEF",
|
|
1232
|
+
formatDate: "Ng\xE0y",
|
|
1227
1233
|
apply: "\xC1p d\u1EE5ng",
|
|
1228
1234
|
clear: "X\xF3a",
|
|
1229
1235
|
recalculate: "T\xEDnh l\u1EA1i",
|
|
@@ -25993,6 +25999,10 @@ function getTableCellAttrs(cell, styles, defaultBackgroundColor) {
|
|
|
25993
25999
|
if (borderAttrs.borderColor) attrs.borderColor = borderAttrs.borderColor;
|
|
25994
26000
|
if (borderAttrs.borderStyle) attrs.borderStyle = borderAttrs.borderStyle;
|
|
25995
26001
|
if (borderAttrs.borderWidth) attrs.borderWidth = borderAttrs.borderWidth;
|
|
26002
|
+
if (cell.getAttribute("data-cell-id")) attrs.cellId = cell.getAttribute("data-cell-id") ?? void 0;
|
|
26003
|
+
if (cell.getAttribute("data-number-format")) attrs.numberFormat = cell.getAttribute("data-number-format") ?? void 0;
|
|
26004
|
+
if (cell.getAttribute("data-formula")) attrs.formula = cell.getAttribute("data-formula") ?? void 0;
|
|
26005
|
+
if (cell.getAttribute("data-computed-value")) attrs.computedValue = cell.getAttribute("data-computed-value") ?? void 0;
|
|
25996
26006
|
if (colspan > 1) attrs.colspan = colspan;
|
|
25997
26007
|
if (rowspan > 1) attrs.rowspan = rowspan;
|
|
25998
26008
|
if (colwidth) attrs.colwidth = colwidth;
|
|
@@ -27620,6 +27630,16 @@ var CodeBlockView = ({
|
|
|
27620
27630
|
};
|
|
27621
27631
|
|
|
27622
27632
|
// src/components/UEditor/extensions.ts
|
|
27633
|
+
function getFormulaStateAttributes(attributes) {
|
|
27634
|
+
const formula = attributes["data-formula"];
|
|
27635
|
+
if (!formula) {
|
|
27636
|
+
return {};
|
|
27637
|
+
}
|
|
27638
|
+
const computedValue = String(attributes["data-computed-value"] ?? "");
|
|
27639
|
+
return {
|
|
27640
|
+
"data-formula-state": computedValue.startsWith("#") ? "error" : "computed"
|
|
27641
|
+
};
|
|
27642
|
+
}
|
|
27623
27643
|
var CustomTableCell = TableCell2.extend({
|
|
27624
27644
|
addAttributes() {
|
|
27625
27645
|
return {
|
|
@@ -27722,7 +27742,7 @@ var CustomTableCell = TableCell2.extend({
|
|
|
27722
27742
|
mergedStyle = mergedStyle.replace(/^;/, "").trim();
|
|
27723
27743
|
return [
|
|
27724
27744
|
"td",
|
|
27725
|
-
mergeAttributes5(this.options.HTMLAttributes, HTMLAttributes, mergedStyle ? { style: mergedStyle } : {}),
|
|
27745
|
+
mergeAttributes5(this.options.HTMLAttributes, HTMLAttributes, getFormulaStateAttributes(HTMLAttributes), mergedStyle ? { style: mergedStyle } : {}),
|
|
27726
27746
|
0
|
|
27727
27747
|
];
|
|
27728
27748
|
}
|
|
@@ -27829,7 +27849,7 @@ var CustomTableHeader = TableHeader2.extend({
|
|
|
27829
27849
|
mergedStyle = mergedStyle.replace(/^;/, "").trim();
|
|
27830
27850
|
return [
|
|
27831
27851
|
"th",
|
|
27832
|
-
mergeAttributes5(this.options.HTMLAttributes, HTMLAttributes, mergedStyle ? { style: mergedStyle } : {}),
|
|
27852
|
+
mergeAttributes5(this.options.HTMLAttributes, HTMLAttributes, getFormulaStateAttributes(HTMLAttributes), mergedStyle ? { style: mergedStyle } : {}),
|
|
27833
27853
|
0
|
|
27834
27854
|
];
|
|
27835
27855
|
}
|
|
@@ -29910,6 +29930,143 @@ function getTableCellRangeLabels(range) {
|
|
|
29910
29930
|
function normalizeTableFormula(formula) {
|
|
29911
29931
|
return formula.trim().replace(/^=/, "").trim();
|
|
29912
29932
|
}
|
|
29933
|
+
function formatFormulaError(error) {
|
|
29934
|
+
return `#${error.toUpperCase()}`;
|
|
29935
|
+
}
|
|
29936
|
+
function normalizeTableNumberFormat(format) {
|
|
29937
|
+
return format === "text" || format === "number" || format === "currency" || format === "percent" || format === "date" ? format : "text";
|
|
29938
|
+
}
|
|
29939
|
+
function formatTableFormulaDisplayValue(value, numberFormat) {
|
|
29940
|
+
const stringValue = String(value);
|
|
29941
|
+
if (stringValue.startsWith("#")) {
|
|
29942
|
+
return stringValue;
|
|
29943
|
+
}
|
|
29944
|
+
const normalizedFormat = normalizeTableNumberFormat(numberFormat);
|
|
29945
|
+
if (normalizedFormat === "text") {
|
|
29946
|
+
return stringValue;
|
|
29947
|
+
}
|
|
29948
|
+
const numericValue = typeof value === "number" ? value : Number.parseFloat(stringValue.replace(/,/g, ""));
|
|
29949
|
+
if (!Number.isFinite(numericValue)) {
|
|
29950
|
+
return stringValue;
|
|
29951
|
+
}
|
|
29952
|
+
if (normalizedFormat === "number") {
|
|
29953
|
+
return new Intl.NumberFormat("en-US", { maximumFractionDigits: 6 }).format(numericValue);
|
|
29954
|
+
}
|
|
29955
|
+
if (normalizedFormat === "currency") {
|
|
29956
|
+
return new Intl.NumberFormat("en-US", {
|
|
29957
|
+
style: "currency",
|
|
29958
|
+
currency: "USD",
|
|
29959
|
+
maximumFractionDigits: 2
|
|
29960
|
+
}).format(numericValue);
|
|
29961
|
+
}
|
|
29962
|
+
if (normalizedFormat === "percent") {
|
|
29963
|
+
return new Intl.NumberFormat("en-US", {
|
|
29964
|
+
style: "percent",
|
|
29965
|
+
maximumFractionDigits: 2
|
|
29966
|
+
}).format(numericValue);
|
|
29967
|
+
}
|
|
29968
|
+
const excelEpochMs = Date.UTC(1899, 11, 30);
|
|
29969
|
+
const date = new Date(excelEpochMs + numericValue * 24 * 60 * 60 * 1e3);
|
|
29970
|
+
if (Number.isNaN(date.getTime())) {
|
|
29971
|
+
return stringValue;
|
|
29972
|
+
}
|
|
29973
|
+
return new Intl.DateTimeFormat("en-US", {
|
|
29974
|
+
year: "numeric",
|
|
29975
|
+
month: "2-digit",
|
|
29976
|
+
day: "2-digit",
|
|
29977
|
+
timeZone: "UTC"
|
|
29978
|
+
}).format(date);
|
|
29979
|
+
}
|
|
29980
|
+
function getTableFormulaReferences(formula) {
|
|
29981
|
+
const normalized = normalizeTableFormula(formula);
|
|
29982
|
+
if (!normalized) return [];
|
|
29983
|
+
const tokens = tokenizeFormula(normalized);
|
|
29984
|
+
if (!tokens) return [];
|
|
29985
|
+
const references = /* @__PURE__ */ new Set();
|
|
29986
|
+
for (const token of tokens) {
|
|
29987
|
+
if (token.type === "cell") {
|
|
29988
|
+
references.add(token.value);
|
|
29989
|
+
} else if (token.type === "range") {
|
|
29990
|
+
const range = parseTableCellRange(token.value);
|
|
29991
|
+
if (!range) continue;
|
|
29992
|
+
for (const label of getTableCellRangeLabels(range)) {
|
|
29993
|
+
references.add(label);
|
|
29994
|
+
}
|
|
29995
|
+
}
|
|
29996
|
+
}
|
|
29997
|
+
return Array.from(references);
|
|
29998
|
+
}
|
|
29999
|
+
function buildTableFormulaDependencyGraph(cells) {
|
|
30000
|
+
const dependencies = /* @__PURE__ */ new Map();
|
|
30001
|
+
const dependents = /* @__PURE__ */ new Map();
|
|
30002
|
+
const formulas = /* @__PURE__ */ new Map();
|
|
30003
|
+
for (const cell of cells) {
|
|
30004
|
+
const label = cell.label.toUpperCase();
|
|
30005
|
+
formulas.set(label, cell.formula);
|
|
30006
|
+
dependencies.set(label, new Set(getTableFormulaReferences(cell.formula)));
|
|
30007
|
+
if (!dependents.has(label)) {
|
|
30008
|
+
dependents.set(label, /* @__PURE__ */ new Set());
|
|
30009
|
+
}
|
|
30010
|
+
}
|
|
30011
|
+
for (const [label, refs] of dependencies) {
|
|
30012
|
+
for (const ref of refs) {
|
|
30013
|
+
if (!dependents.has(ref)) {
|
|
30014
|
+
dependents.set(ref, /* @__PURE__ */ new Set());
|
|
30015
|
+
}
|
|
30016
|
+
dependents.get(ref)?.add(label);
|
|
30017
|
+
}
|
|
30018
|
+
}
|
|
30019
|
+
return { dependencies, dependents, formulas };
|
|
30020
|
+
}
|
|
30021
|
+
function getTableFormulaCircularReferences(graph) {
|
|
30022
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
30023
|
+
const visited = /* @__PURE__ */ new Set();
|
|
30024
|
+
const circular = /* @__PURE__ */ new Set();
|
|
30025
|
+
const stack = [];
|
|
30026
|
+
const visit = (label) => {
|
|
30027
|
+
if (visiting.has(label)) {
|
|
30028
|
+
const start = stack.indexOf(label);
|
|
30029
|
+
for (const cycleLabel of start >= 0 ? stack.slice(start) : [label]) {
|
|
30030
|
+
circular.add(cycleLabel);
|
|
30031
|
+
}
|
|
30032
|
+
return;
|
|
30033
|
+
}
|
|
30034
|
+
if (visited.has(label)) return;
|
|
30035
|
+
visiting.add(label);
|
|
30036
|
+
stack.push(label);
|
|
30037
|
+
for (const ref of graph.dependencies.get(label) ?? []) {
|
|
30038
|
+
if (graph.formulas.has(ref)) {
|
|
30039
|
+
visit(ref);
|
|
30040
|
+
}
|
|
30041
|
+
}
|
|
30042
|
+
stack.pop();
|
|
30043
|
+
visiting.delete(label);
|
|
30044
|
+
visited.add(label);
|
|
30045
|
+
};
|
|
30046
|
+
for (const label of graph.formulas.keys()) {
|
|
30047
|
+
visit(label);
|
|
30048
|
+
}
|
|
30049
|
+
return circular;
|
|
30050
|
+
}
|
|
30051
|
+
function getTableFormulaRecalculationOrder(graph) {
|
|
30052
|
+
const circular = getTableFormulaCircularReferences(graph);
|
|
30053
|
+
const visited = /* @__PURE__ */ new Set();
|
|
30054
|
+
const order = [];
|
|
30055
|
+
const visit = (label) => {
|
|
30056
|
+
if (visited.has(label) || circular.has(label)) return;
|
|
30057
|
+
visited.add(label);
|
|
30058
|
+
for (const ref of graph.dependencies.get(label) ?? []) {
|
|
30059
|
+
if (graph.formulas.has(ref)) {
|
|
30060
|
+
visit(ref);
|
|
30061
|
+
}
|
|
30062
|
+
}
|
|
30063
|
+
order.push(label);
|
|
30064
|
+
};
|
|
30065
|
+
for (const label of graph.formulas.keys()) {
|
|
30066
|
+
visit(label);
|
|
30067
|
+
}
|
|
30068
|
+
return { order, circular };
|
|
30069
|
+
}
|
|
29913
30070
|
function evaluateBasicTableFormula(formula, getCellValue) {
|
|
29914
30071
|
const normalized = normalizeTableFormula(formula);
|
|
29915
30072
|
if (!normalized) {
|
|
@@ -30114,6 +30271,7 @@ var FormulaParser = class {
|
|
|
30114
30271
|
};
|
|
30115
30272
|
|
|
30116
30273
|
// src/components/UEditor/table-formula-commands.ts
|
|
30274
|
+
var UEDITOR_TABLE_FORMULA_RECALCULATE_META = "ueditorTableFormulaRecalculate";
|
|
30117
30275
|
function collectChildren2(node) {
|
|
30118
30276
|
const children = [];
|
|
30119
30277
|
node.forEach((child) => children.push(child));
|
|
@@ -30144,6 +30302,13 @@ function safeFindCell2(map, relativePos) {
|
|
|
30144
30302
|
function getCellText(cellNode) {
|
|
30145
30303
|
return cellNode.textBetween(0, cellNode.content.size, "\n").trim();
|
|
30146
30304
|
}
|
|
30305
|
+
function createCellDisplayContent(cellNode, displayValue) {
|
|
30306
|
+
const paragraphType = cellNode.type.schema.nodes.paragraph;
|
|
30307
|
+
if (!paragraphType || !displayValue) {
|
|
30308
|
+
return paragraphType ? [paragraphType.create()] : cellNode.content;
|
|
30309
|
+
}
|
|
30310
|
+
return [paragraphType.create(null, cellNode.type.schema.text(displayValue))];
|
|
30311
|
+
}
|
|
30147
30312
|
function buildTableValueGetter(tableNode) {
|
|
30148
30313
|
const map = TableMap2.get(tableNode);
|
|
30149
30314
|
const values = /* @__PURE__ */ new Map();
|
|
@@ -30158,6 +30323,20 @@ function buildTableValueGetter(tableNode) {
|
|
|
30158
30323
|
}
|
|
30159
30324
|
return (label) => values.get(label.toUpperCase());
|
|
30160
30325
|
}
|
|
30326
|
+
function buildTableValueMap(tableNode) {
|
|
30327
|
+
const map = TableMap2.get(tableNode);
|
|
30328
|
+
const values = /* @__PURE__ */ new Map();
|
|
30329
|
+
for (const rowInfo of getTableRows2(tableNode)) {
|
|
30330
|
+
for (const entry of rowInfo.cells) {
|
|
30331
|
+
const rect = safeFindCell2(map, entry.relativePos);
|
|
30332
|
+
if (!rect) continue;
|
|
30333
|
+
const label = `${indexToColumnName(rect.left)}${rect.top + 1}`;
|
|
30334
|
+
const computedValue = entry.node.attrs.computedValue;
|
|
30335
|
+
values.set(label, typeof computedValue === "string" && computedValue.trim() ? computedValue : getCellText(entry.node));
|
|
30336
|
+
}
|
|
30337
|
+
}
|
|
30338
|
+
return values;
|
|
30339
|
+
}
|
|
30161
30340
|
function getFormulaComputedValue(formula, tableNode) {
|
|
30162
30341
|
const result = evaluateBasicTableFormula(formula, buildTableValueGetter(tableNode));
|
|
30163
30342
|
return result.error ? `#${result.error.toUpperCase()}` : String(result.value);
|
|
@@ -30194,37 +30373,143 @@ function setSelectedTableCellFormula(editor, formula) {
|
|
|
30194
30373
|
function clearSelectedTableCellFormula(editor) {
|
|
30195
30374
|
return setSelectedTableCellFormula(editor, "");
|
|
30196
30375
|
}
|
|
30197
|
-
function
|
|
30198
|
-
const
|
|
30199
|
-
const
|
|
30200
|
-
const
|
|
30201
|
-
|
|
30376
|
+
function setSelectedTableCellNumberFormat(editor, numberFormat) {
|
|
30377
|
+
const value = numberFormat && numberFormat !== "text" ? numberFormat : null;
|
|
30378
|
+
const { state, view } = editor;
|
|
30379
|
+
const applied = setCellAttr("numberFormat", value)(state, view.dispatch.bind(view));
|
|
30380
|
+
if (!applied) return false;
|
|
30381
|
+
recalculateSelectedTable(editor);
|
|
30382
|
+
view.focus();
|
|
30383
|
+
dispatchTableLayoutChange(editor);
|
|
30384
|
+
return true;
|
|
30385
|
+
}
|
|
30386
|
+
function promoteFormulaTextInTableNode(tableNode) {
|
|
30202
30387
|
let changed = false;
|
|
30203
30388
|
const rows = getTableRows2(tableNode).map((rowInfo) => {
|
|
30204
30389
|
const cells = collectChildren2(rowInfo.node);
|
|
30390
|
+
for (const entry of rowInfo.cells) {
|
|
30391
|
+
const text = getCellText(entry.node);
|
|
30392
|
+
const formula = text.startsWith("=") ? normalizeFormulaInput(text) : "";
|
|
30393
|
+
if (!formula || entry.node.attrs.formula === formula) continue;
|
|
30394
|
+
cells[entry.index] = entry.node.type.create(
|
|
30395
|
+
{
|
|
30396
|
+
...entry.node.attrs,
|
|
30397
|
+
formula,
|
|
30398
|
+
computedValue: null
|
|
30399
|
+
},
|
|
30400
|
+
entry.node.content,
|
|
30401
|
+
entry.node.marks
|
|
30402
|
+
);
|
|
30403
|
+
changed = true;
|
|
30404
|
+
}
|
|
30405
|
+
return rowInfo.node.type.create(rowInfo.node.attrs, cells);
|
|
30406
|
+
});
|
|
30407
|
+
return {
|
|
30408
|
+
tableNode: changed ? tableNode.type.create(tableNode.attrs, rows) : tableNode,
|
|
30409
|
+
changed
|
|
30410
|
+
};
|
|
30411
|
+
}
|
|
30412
|
+
function recalculateTableNode(tableNode) {
|
|
30413
|
+
const promoted = promoteFormulaTextInTableNode(tableNode);
|
|
30414
|
+
tableNode = promoted.tableNode;
|
|
30415
|
+
const map = TableMap2.get(tableNode);
|
|
30416
|
+
const values = buildTableValueMap(tableNode);
|
|
30417
|
+
const formulaEntries = /* @__PURE__ */ new Map();
|
|
30418
|
+
let changed = false;
|
|
30419
|
+
const rowInfos = getTableRows2(tableNode);
|
|
30420
|
+
for (const [rowIndex, rowInfo] of rowInfos.entries()) {
|
|
30205
30421
|
for (const entry of rowInfo.cells) {
|
|
30206
30422
|
const formula = typeof entry.node.attrs.formula === "string" ? entry.node.attrs.formula.trim() : "";
|
|
30207
30423
|
if (!formula) continue;
|
|
30208
30424
|
const rectForCell = safeFindCell2(map, entry.relativePos);
|
|
30209
30425
|
if (!rectForCell) continue;
|
|
30210
|
-
const
|
|
30211
|
-
|
|
30212
|
-
|
|
30426
|
+
const label = `${indexToColumnName(rectForCell.left)}${rectForCell.top + 1}`;
|
|
30427
|
+
formulaEntries.set(label, {
|
|
30428
|
+
rowIndex,
|
|
30429
|
+
cellIndex: entry.index,
|
|
30430
|
+
node: entry.node,
|
|
30431
|
+
formula
|
|
30432
|
+
});
|
|
30433
|
+
}
|
|
30434
|
+
}
|
|
30435
|
+
const graph = buildTableFormulaDependencyGraph(
|
|
30436
|
+
Array.from(formulaEntries, ([label, entry]) => ({
|
|
30437
|
+
label,
|
|
30438
|
+
formula: entry.formula
|
|
30439
|
+
}))
|
|
30440
|
+
);
|
|
30441
|
+
const { order, circular } = getTableFormulaRecalculationOrder(graph);
|
|
30442
|
+
const computedValues = /* @__PURE__ */ new Map();
|
|
30443
|
+
const getCellValue = (label) => values.get(label.toUpperCase());
|
|
30444
|
+
for (const label of circular) {
|
|
30445
|
+
computedValues.set(label, formatFormulaError("circular-reference"));
|
|
30446
|
+
values.set(label, formatFormulaError("circular-reference"));
|
|
30447
|
+
}
|
|
30448
|
+
for (const label of order) {
|
|
30449
|
+
const entry = formulaEntries.get(label);
|
|
30450
|
+
if (!entry) continue;
|
|
30451
|
+
const result = evaluateBasicTableFormula(entry.formula, getCellValue);
|
|
30452
|
+
const computedValue = result.error ? formatFormulaError(result.error) : String(result.value);
|
|
30453
|
+
computedValues.set(label, computedValue);
|
|
30454
|
+
values.set(label, computedValue);
|
|
30455
|
+
}
|
|
30456
|
+
const rows = rowInfos.map((rowInfo) => {
|
|
30457
|
+
const cells = collectChildren2(rowInfo.node);
|
|
30458
|
+
for (const entry of rowInfo.cells) {
|
|
30459
|
+
const rectForCell = safeFindCell2(map, entry.relativePos);
|
|
30460
|
+
if (!rectForCell) continue;
|
|
30461
|
+
const label = `${indexToColumnName(rectForCell.left)}${rectForCell.top + 1}`;
|
|
30462
|
+
const computedValue = computedValues.get(label);
|
|
30463
|
+
if (computedValue == null) continue;
|
|
30464
|
+
const displayValue = formatTableFormulaDisplayValue(computedValue, entry.node.attrs.numberFormat);
|
|
30465
|
+
const contentMatchesComputedValue = getCellText(entry.node) === displayValue;
|
|
30466
|
+
if (entry.node.attrs.computedValue === computedValue && contentMatchesComputedValue) continue;
|
|
30213
30467
|
cells[entry.index] = entry.node.type.create(
|
|
30214
30468
|
{
|
|
30215
30469
|
...entry.node.attrs,
|
|
30216
30470
|
computedValue
|
|
30217
30471
|
},
|
|
30218
|
-
entry.node
|
|
30472
|
+
createCellDisplayContent(entry.node, displayValue),
|
|
30219
30473
|
entry.node.marks
|
|
30220
30474
|
);
|
|
30221
30475
|
changed = true;
|
|
30222
30476
|
}
|
|
30223
30477
|
return rowInfo.node.type.create(rowInfo.node.attrs, cells);
|
|
30224
30478
|
});
|
|
30225
|
-
if (!changed) return
|
|
30226
|
-
|
|
30227
|
-
|
|
30479
|
+
if (!changed) return promoted.changed ? tableNode : null;
|
|
30480
|
+
return tableNode.type.create(tableNode.attrs, rows);
|
|
30481
|
+
}
|
|
30482
|
+
function recalculateSelectedTable(editor) {
|
|
30483
|
+
const rect = selectedRect2(editor.state);
|
|
30484
|
+
const tableNode = rect.table;
|
|
30485
|
+
const nextTable = recalculateTableNode(tableNode);
|
|
30486
|
+
if (!nextTable) return false;
|
|
30487
|
+
editor.view.dispatch(
|
|
30488
|
+
editor.state.tr.replaceWith(rect.tableStart - 1, rect.tableStart - 1 + tableNode.nodeSize, nextTable).setMeta(UEDITOR_TABLE_FORMULA_RECALCULATE_META, true)
|
|
30489
|
+
);
|
|
30490
|
+
dispatchTableLayoutChange(editor);
|
|
30491
|
+
return true;
|
|
30492
|
+
}
|
|
30493
|
+
function recalculateAllTableFormulas(editor) {
|
|
30494
|
+
const replacements = [];
|
|
30495
|
+
editor.state.doc.descendants((node, pos) => {
|
|
30496
|
+
if (node.type.name !== "table") return true;
|
|
30497
|
+
const nextTable = recalculateTableNode(node);
|
|
30498
|
+
if (nextTable) {
|
|
30499
|
+
replacements.push({
|
|
30500
|
+
from: pos,
|
|
30501
|
+
to: pos + node.nodeSize,
|
|
30502
|
+
node: nextTable
|
|
30503
|
+
});
|
|
30504
|
+
}
|
|
30505
|
+
return false;
|
|
30506
|
+
});
|
|
30507
|
+
if (replacements.length === 0) return false;
|
|
30508
|
+
let tr = editor.state.tr;
|
|
30509
|
+
for (const replacement of replacements.reverse()) {
|
|
30510
|
+
tr = tr.replaceWith(replacement.from, replacement.to, replacement.node);
|
|
30511
|
+
}
|
|
30512
|
+
editor.view.dispatch(tr.setMeta(UEDITOR_TABLE_FORMULA_RECALCULATE_META, true));
|
|
30228
30513
|
dispatchTableLayoutChange(editor);
|
|
30229
30514
|
return true;
|
|
30230
30515
|
}
|
|
@@ -30273,6 +30558,7 @@ var BubbleMenuContent = ({
|
|
|
30273
30558
|
const currentHighlightColor = normalizeStyleValue(editor.getAttributes("highlight").color) || "";
|
|
30274
30559
|
const currentCellBgColor = normalizeStyleValue(editor.getAttributes("tableCell").backgroundColor || editor.getAttributes("tableHeader").backgroundColor) || "";
|
|
30275
30560
|
const currentCellFormula = normalizeStyleValue(editor.getAttributes("tableCell").formula || editor.getAttributes("tableHeader").formula) || "";
|
|
30561
|
+
const currentCellNumberFormat = normalizeStyleValue(editor.getAttributes("tableCell").numberFormat || editor.getAttributes("tableHeader").numberFormat) || "text";
|
|
30276
30562
|
const isInTable2 = isSelectionInTable(editor.state);
|
|
30277
30563
|
const canMergeCells = isInTable2 && editor.can().mergeCells();
|
|
30278
30564
|
const canSplitCell = isInTable2 && editor.can().splitCell();
|
|
@@ -30532,6 +30818,28 @@ var BubbleMenuContent = ({
|
|
|
30532
30818
|
className: "h-full min-w-0 flex-1 bg-transparent px-2 text-sm font-medium text-foreground outline-none"
|
|
30533
30819
|
}
|
|
30534
30820
|
) }),
|
|
30821
|
+
/* @__PURE__ */ jsxs72("div", { className: "mt-2", children: [
|
|
30822
|
+
/* @__PURE__ */ jsx86("div", { className: "mb-1 px-1 text-[11px] font-medium text-muted-foreground", children: t("tableMenu.numberFormat") || "Number format" }),
|
|
30823
|
+
/* @__PURE__ */ jsx86("div", { className: "grid grid-cols-5 gap-1", children: [
|
|
30824
|
+
["text", "Text"],
|
|
30825
|
+
["number", "123"],
|
|
30826
|
+
["currency", "$"],
|
|
30827
|
+
["percent", "%"],
|
|
30828
|
+
["date", "Date"]
|
|
30829
|
+
].map(([format, label]) => /* @__PURE__ */ jsx86(
|
|
30830
|
+
"button",
|
|
30831
|
+
{
|
|
30832
|
+
type: "button",
|
|
30833
|
+
onClick: () => setSelectedTableCellNumberFormat(editor, format),
|
|
30834
|
+
className: cn(
|
|
30835
|
+
"h-8 rounded-md text-[11px] font-semibold transition-colors hover:bg-muted",
|
|
30836
|
+
currentCellNumberFormat === format || format === "text" && !currentCellNumberFormat ? "bg-primary/10 text-primary" : "bg-muted/40 text-foreground"
|
|
30837
|
+
),
|
|
30838
|
+
children: format === "text" ? t("tableMenu.formatText") || label : format === "date" ? t("tableMenu.formatDate") || label : label
|
|
30839
|
+
},
|
|
30840
|
+
format
|
|
30841
|
+
)) })
|
|
30842
|
+
] }),
|
|
30535
30843
|
/* @__PURE__ */ jsxs72("div", { className: "mt-2 grid grid-cols-3 gap-1", children: [
|
|
30536
30844
|
/* @__PURE__ */ jsx86(
|
|
30537
30845
|
"button",
|
|
@@ -38261,6 +38569,7 @@ var UEditor = React82.forwardRef(({
|
|
|
38261
38569
|
const effectivePlaceholder = placeholder ?? t("placeholder");
|
|
38262
38570
|
const inFlightPrepareRef = useRef37(null);
|
|
38263
38571
|
const lastAppliedContentRef = useRef37(content ?? "");
|
|
38572
|
+
const scheduledFormulaRecalculateRef = useRef37(false);
|
|
38264
38573
|
const resolvedUploadFile = useMemo24(() => {
|
|
38265
38574
|
if (uploadFile) return uploadFile;
|
|
38266
38575
|
if (uploadFileForSave) {
|
|
@@ -38324,7 +38633,16 @@ var UEditor = React82.forwardRef(({
|
|
|
38324
38633
|
class: UEDITOR_PROSEMIRROR_CLASS_NAME
|
|
38325
38634
|
}
|
|
38326
38635
|
},
|
|
38327
|
-
onUpdate: ({ editor: editor2 }) => {
|
|
38636
|
+
onUpdate: ({ editor: editor2, transaction }) => {
|
|
38637
|
+
if (!transaction.getMeta(UEDITOR_TABLE_FORMULA_RECALCULATE_META) && !scheduledFormulaRecalculateRef.current) {
|
|
38638
|
+
scheduledFormulaRecalculateRef.current = true;
|
|
38639
|
+
queueMicrotask(() => {
|
|
38640
|
+
scheduledFormulaRecalculateRef.current = false;
|
|
38641
|
+
if (!editor2.isDestroyed) {
|
|
38642
|
+
recalculateAllTableFormulas(editor2);
|
|
38643
|
+
}
|
|
38644
|
+
});
|
|
38645
|
+
}
|
|
38328
38646
|
const html = editor2.getHTML();
|
|
38329
38647
|
onChange?.(html);
|
|
38330
38648
|
onHtmlChange?.(html);
|
|
@@ -38362,6 +38680,14 @@ var UEditor = React82.forwardRef(({
|
|
|
38362
38680
|
}),
|
|
38363
38681
|
[content, editor, uploadImageForSave, uploadFileForSave, uploadImageConcurrency]
|
|
38364
38682
|
);
|
|
38683
|
+
useEffect38(() => {
|
|
38684
|
+
if (!editor) return;
|
|
38685
|
+
queueMicrotask(() => {
|
|
38686
|
+
if (!editor.isDestroyed) {
|
|
38687
|
+
recalculateAllTableFormulas(editor);
|
|
38688
|
+
}
|
|
38689
|
+
});
|
|
38690
|
+
}, [editor]);
|
|
38365
38691
|
useEffect38(() => {
|
|
38366
38692
|
if (!editor) return;
|
|
38367
38693
|
const nextContent = content ?? "";
|
|
@@ -38371,6 +38697,11 @@ var UEditor = React82.forwardRef(({
|
|
|
38371
38697
|
Promise.resolve().then(() => {
|
|
38372
38698
|
if (!editor.isDestroyed) {
|
|
38373
38699
|
editor.commands.setContent(nextContent, { emitUpdate: false });
|
|
38700
|
+
queueMicrotask(() => {
|
|
38701
|
+
if (!editor.isDestroyed) {
|
|
38702
|
+
recalculateAllTableFormulas(editor);
|
|
38703
|
+
}
|
|
38704
|
+
});
|
|
38374
38705
|
}
|
|
38375
38706
|
});
|
|
38376
38707
|
}
|