@underverse-ui/underverse 1.0.156 → 1.0.157
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 +311 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +311 -28
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/api-reference.json
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -28978,6 +28978,20 @@ function createEmptyCellNode(cellNode) {
|
|
|
28978
28978
|
function createCellCopyForColumnDuplicate(cellNode) {
|
|
28979
28979
|
return cellNode.type.create(cellNode.attrs, cellNode.content);
|
|
28980
28980
|
}
|
|
28981
|
+
function createCellWithDuplicatedLogicalColumn(cellNode, widthIndex) {
|
|
28982
|
+
const colspan = Math.max(1, Number(cellNode.attrs.colspan) || 1);
|
|
28983
|
+
let nextColwidth = null;
|
|
28984
|
+
if (Array.isArray(cellNode.attrs.colwidth)) {
|
|
28985
|
+
nextColwidth = [...cellNode.attrs.colwidth];
|
|
28986
|
+
const duplicateWidth = nextColwidth[widthIndex];
|
|
28987
|
+
nextColwidth.splice(widthIndex + 1, 0, typeof duplicateWidth === "number" ? duplicateWidth : 0);
|
|
28988
|
+
}
|
|
28989
|
+
return cellNode.type.create({
|
|
28990
|
+
...cellNode.attrs,
|
|
28991
|
+
colspan: colspan + 1,
|
|
28992
|
+
...nextColwidth ? { colwidth: nextColwidth } : null
|
|
28993
|
+
}, cellNode.content);
|
|
28994
|
+
}
|
|
28981
28995
|
function getTableRows(tableNode) {
|
|
28982
28996
|
const rows = [];
|
|
28983
28997
|
tableNode.forEach((rowNode, rowOffset) => {
|
|
@@ -29153,6 +29167,11 @@ function duplicateTableColumnAt(editor, columnIndex, cellPos) {
|
|
|
29153
29167
|
return rect && rect.top === rowIndex && rect.left <= columnIndex && columnIndex < rect.right;
|
|
29154
29168
|
});
|
|
29155
29169
|
if (!sourceCell) return rowInfo.node;
|
|
29170
|
+
const sourceRect = safeFindCell(map, sourceCell.relativePos);
|
|
29171
|
+
if (sourceRect && (sourceRect.left < columnIndex || sourceRect.right > columnIndex + 1)) {
|
|
29172
|
+
cells[sourceCell.index] = createCellWithDuplicatedLogicalColumn(sourceCell.node, columnIndex - sourceRect.left);
|
|
29173
|
+
return rowInfo.node.type.create(rowInfo.node.attrs, cells);
|
|
29174
|
+
}
|
|
29156
29175
|
cells.splice(sourceCell.index + 1, 0, createCellCopyForColumnDuplicate(sourceCell.node));
|
|
29157
29176
|
return rowInfo.node.type.create(rowInfo.node.attrs, cells);
|
|
29158
29177
|
});
|
|
@@ -30452,6 +30471,25 @@ function getTableFormulaRecalculationOrder(graph) {
|
|
|
30452
30471
|
}
|
|
30453
30472
|
return { order, circular };
|
|
30454
30473
|
}
|
|
30474
|
+
function getAffectedTableFormulaLabels(graph, changedLabels) {
|
|
30475
|
+
const affected = /* @__PURE__ */ new Set();
|
|
30476
|
+
const queue = Array.from(changedLabels, (label) => label.toUpperCase());
|
|
30477
|
+
for (const label of queue) {
|
|
30478
|
+
if (graph.formulas.has(label)) {
|
|
30479
|
+
affected.add(label);
|
|
30480
|
+
}
|
|
30481
|
+
}
|
|
30482
|
+
for (let index = 0; index < queue.length; index += 1) {
|
|
30483
|
+
const label = queue[index];
|
|
30484
|
+
if (!label) continue;
|
|
30485
|
+
for (const dependent of graph.dependents.get(label) ?? []) {
|
|
30486
|
+
if (affected.has(dependent)) continue;
|
|
30487
|
+
affected.add(dependent);
|
|
30488
|
+
queue.push(dependent);
|
|
30489
|
+
}
|
|
30490
|
+
}
|
|
30491
|
+
return affected;
|
|
30492
|
+
}
|
|
30455
30493
|
function evaluateBasicTableFormula(formula, getCellValue) {
|
|
30456
30494
|
const normalized = normalizeTableFormula(formula);
|
|
30457
30495
|
if (!normalized) {
|
|
@@ -30599,10 +30637,19 @@ var FormulaParser = class {
|
|
|
30599
30637
|
const range = parseTableCellRange(token.value);
|
|
30600
30638
|
if (!range) return { value: null, error: "invalid-reference" };
|
|
30601
30639
|
for (const label of getTableCellRangeLabels(range)) {
|
|
30640
|
+
if (name === "COUNT") {
|
|
30641
|
+
const cellValue2 = this.readOptionalCellNumber(label);
|
|
30642
|
+
if (cellValue2 != null) values.push(cellValue2);
|
|
30643
|
+
continue;
|
|
30644
|
+
}
|
|
30602
30645
|
const cellValue = this.readCellNumber(label);
|
|
30603
30646
|
if (cellValue.error) return cellValue;
|
|
30604
30647
|
values.push(cellValue.value);
|
|
30605
30648
|
}
|
|
30649
|
+
} else if (name === "COUNT" && token.type === "cell") {
|
|
30650
|
+
this.index += 1;
|
|
30651
|
+
const cellValue = this.readOptionalCellNumber(token.value);
|
|
30652
|
+
if (cellValue != null) values.push(cellValue);
|
|
30606
30653
|
} else {
|
|
30607
30654
|
const value = this.parseExpression();
|
|
30608
30655
|
if (value.error) return value;
|
|
@@ -30616,7 +30663,7 @@ var FormulaParser = class {
|
|
|
30616
30663
|
}
|
|
30617
30664
|
return { value: null, error: "invalid-formula" };
|
|
30618
30665
|
}
|
|
30619
|
-
if (values.length === 0) {
|
|
30666
|
+
if (values.length === 0 && name !== "COUNT") {
|
|
30620
30667
|
return { value: null, error: "invalid-formula" };
|
|
30621
30668
|
}
|
|
30622
30669
|
if (name === "SUM") return { value: values.reduce((sum, value) => sum + value, 0), error: null };
|
|
@@ -30634,6 +30681,11 @@ var FormulaParser = class {
|
|
|
30634
30681
|
}
|
|
30635
30682
|
return { value: parsed, error: null };
|
|
30636
30683
|
}
|
|
30684
|
+
readOptionalCellNumber(label) {
|
|
30685
|
+
const value = this.getCellValue(label);
|
|
30686
|
+
const parsed = typeof value === "number" ? value : Number.parseFloat(String(value ?? "").trim());
|
|
30687
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
30688
|
+
}
|
|
30637
30689
|
peekOperator(operators) {
|
|
30638
30690
|
const token = this.tokens[this.index];
|
|
30639
30691
|
return token?.type === "operator" && operators.includes(token.value) ? token : null;
|
|
@@ -30697,6 +30749,41 @@ function getSelectionTableCellNode(editor) {
|
|
|
30697
30749
|
}
|
|
30698
30750
|
return null;
|
|
30699
30751
|
}
|
|
30752
|
+
function getSelectionTableInfo(editor) {
|
|
30753
|
+
const { $from } = editor.state.selection;
|
|
30754
|
+
for (let depth = $from.depth; depth > 0; depth -= 1) {
|
|
30755
|
+
const node = $from.node(depth);
|
|
30756
|
+
if (node.type.name === "table") {
|
|
30757
|
+
return {
|
|
30758
|
+
node,
|
|
30759
|
+
pos: $from.before(depth)
|
|
30760
|
+
};
|
|
30761
|
+
}
|
|
30762
|
+
}
|
|
30763
|
+
return null;
|
|
30764
|
+
}
|
|
30765
|
+
function getSelectionTableCellLabel(editor) {
|
|
30766
|
+
const { $from } = editor.state.selection;
|
|
30767
|
+
let cellDepth = -1;
|
|
30768
|
+
let tableDepth = -1;
|
|
30769
|
+
for (let depth = $from.depth; depth > 0; depth -= 1) {
|
|
30770
|
+
const node = $from.node(depth);
|
|
30771
|
+
if (cellDepth < 0 && (node.type.name === "tableCell" || node.type.name === "tableHeader")) {
|
|
30772
|
+
cellDepth = depth;
|
|
30773
|
+
}
|
|
30774
|
+
if (node.type.name === "table") {
|
|
30775
|
+
tableDepth = depth;
|
|
30776
|
+
break;
|
|
30777
|
+
}
|
|
30778
|
+
}
|
|
30779
|
+
if (cellDepth < 0 || tableDepth < 0) return null;
|
|
30780
|
+
const tableNode = $from.node(tableDepth);
|
|
30781
|
+
const tableStart = $from.start(tableDepth);
|
|
30782
|
+
const relativeCellPos = $from.before(cellDepth) - tableStart;
|
|
30783
|
+
const rect = safeFindCell2(import_tables2.TableMap.get(tableNode), relativeCellPos);
|
|
30784
|
+
if (!rect) return null;
|
|
30785
|
+
return `${indexToColumnName(rect.left)}${rect.top + 1}`;
|
|
30786
|
+
}
|
|
30700
30787
|
function isEditingTableFormulaText(editor) {
|
|
30701
30788
|
const cellNode = getSelectionTableCellNode(editor);
|
|
30702
30789
|
return Boolean(cellNode && getCellText(cellNode).startsWith("="));
|
|
@@ -30708,20 +30795,6 @@ function createCellDisplayContent(cellNode, displayValue) {
|
|
|
30708
30795
|
}
|
|
30709
30796
|
return [paragraphType.create(null, cellNode.type.schema.text(displayValue))];
|
|
30710
30797
|
}
|
|
30711
|
-
function buildTableValueGetter(tableNode) {
|
|
30712
|
-
const map = import_tables2.TableMap.get(tableNode);
|
|
30713
|
-
const values = /* @__PURE__ */ new Map();
|
|
30714
|
-
for (const rowInfo of getTableRows2(tableNode)) {
|
|
30715
|
-
for (const entry of rowInfo.cells) {
|
|
30716
|
-
const rect = safeFindCell2(map, entry.relativePos);
|
|
30717
|
-
if (!rect) continue;
|
|
30718
|
-
const label = `${indexToColumnName(rect.left)}${rect.top + 1}`;
|
|
30719
|
-
const computedValue = entry.node.attrs.computedValue;
|
|
30720
|
-
values.set(label, typeof computedValue === "string" && computedValue.trim() ? computedValue : getCellText(entry.node));
|
|
30721
|
-
}
|
|
30722
|
-
}
|
|
30723
|
-
return (label) => values.get(label.toUpperCase());
|
|
30724
|
-
}
|
|
30725
30798
|
function buildTableValueMap(tableNode) {
|
|
30726
30799
|
const map = import_tables2.TableMap.get(tableNode);
|
|
30727
30800
|
const values = /* @__PURE__ */ new Map();
|
|
@@ -30736,10 +30809,6 @@ function buildTableValueMap(tableNode) {
|
|
|
30736
30809
|
}
|
|
30737
30810
|
return values;
|
|
30738
30811
|
}
|
|
30739
|
-
function getFormulaComputedValue(formula, tableNode) {
|
|
30740
|
-
const result = evaluateBasicTableFormula(formula, buildTableValueGetter(tableNode));
|
|
30741
|
-
return result.error ? `#${result.error.toUpperCase()}` : String(result.value);
|
|
30742
|
-
}
|
|
30743
30812
|
function normalizeFormulaInput(formula) {
|
|
30744
30813
|
const trimmed = formula.trim();
|
|
30745
30814
|
if (!trimmed) return "";
|
|
@@ -30750,19 +30819,19 @@ function setSelectedTableCellFormula(editor, formula) {
|
|
|
30750
30819
|
const { state, view } = editor;
|
|
30751
30820
|
if (!normalized) {
|
|
30752
30821
|
const clearedFormula = (0, import_tables2.setCellAttr)("formula", null)(state, view.dispatch.bind(view));
|
|
30753
|
-
const
|
|
30754
|
-
if (clearedFormula ||
|
|
30822
|
+
const clearedValue2 = (0, import_tables2.setCellAttr)("computedValue", null)(editor.state, view.dispatch.bind(view));
|
|
30823
|
+
if (clearedFormula || clearedValue2) {
|
|
30824
|
+
recalculateActiveTableFormulas(editor);
|
|
30755
30825
|
view.focus();
|
|
30756
30826
|
dispatchTableLayoutChange(editor);
|
|
30757
30827
|
return true;
|
|
30758
30828
|
}
|
|
30759
30829
|
return false;
|
|
30760
30830
|
}
|
|
30761
|
-
const rect = (0, import_tables2.selectedRect)(state);
|
|
30762
|
-
const computedValue = getFormulaComputedValue(normalized, rect.table);
|
|
30763
30831
|
const appliedFormula = (0, import_tables2.setCellAttr)("formula", normalized)(state, view.dispatch.bind(view));
|
|
30764
|
-
const
|
|
30765
|
-
if (appliedFormula ||
|
|
30832
|
+
const clearedValue = (0, import_tables2.setCellAttr)("computedValue", null)(editor.state, view.dispatch.bind(view));
|
|
30833
|
+
if (appliedFormula || clearedValue) {
|
|
30834
|
+
recalculateActiveTableFormulas(editor);
|
|
30766
30835
|
view.focus();
|
|
30767
30836
|
dispatchTableLayoutChange(editor);
|
|
30768
30837
|
return true;
|
|
@@ -30844,7 +30913,7 @@ function promoteFormulaTextInTableNode(tableNode) {
|
|
|
30844
30913
|
changed
|
|
30845
30914
|
};
|
|
30846
30915
|
}
|
|
30847
|
-
function recalculateTableNode(tableNode) {
|
|
30916
|
+
function recalculateTableNode(tableNode, options) {
|
|
30848
30917
|
const promoted = promoteFormulaTextInTableNode(tableNode);
|
|
30849
30918
|
tableNode = promoted.tableNode;
|
|
30850
30919
|
const map = import_tables2.TableMap.get(tableNode);
|
|
@@ -30874,13 +30943,16 @@ function recalculateTableNode(tableNode) {
|
|
|
30874
30943
|
}))
|
|
30875
30944
|
);
|
|
30876
30945
|
const { order, circular } = getTableFormulaRecalculationOrder(graph);
|
|
30946
|
+
const affectedLabels = options?.changedLabels ? getAffectedTableFormulaLabels(graph, options.changedLabels) : null;
|
|
30877
30947
|
const computedValues = /* @__PURE__ */ new Map();
|
|
30878
30948
|
const getCellValue = (label) => values.get(label.toUpperCase());
|
|
30879
30949
|
for (const label of circular) {
|
|
30950
|
+
if (affectedLabels && !affectedLabels.has(label)) continue;
|
|
30880
30951
|
computedValues.set(label, formatFormulaError("circular-reference"));
|
|
30881
30952
|
values.set(label, formatFormulaError("circular-reference"));
|
|
30882
30953
|
}
|
|
30883
30954
|
for (const label of order) {
|
|
30955
|
+
if (affectedLabels && !affectedLabels.has(label)) continue;
|
|
30884
30956
|
const entry = formulaEntries.get(label);
|
|
30885
30957
|
if (!entry) continue;
|
|
30886
30958
|
const result = evaluateBasicTableFormula(entry.formula, getCellValue);
|
|
@@ -30925,6 +30997,22 @@ function recalculateSelectedTable(editor) {
|
|
|
30925
30997
|
dispatchTableLayoutChange(editor);
|
|
30926
30998
|
return true;
|
|
30927
30999
|
}
|
|
31000
|
+
function recalculateActiveTableFormulas(editor) {
|
|
31001
|
+
const tableInfo = getSelectionTableInfo(editor);
|
|
31002
|
+
if (!tableInfo) {
|
|
31003
|
+
return recalculateAllTableFormulas(editor);
|
|
31004
|
+
}
|
|
31005
|
+
const activeCellLabel = getSelectionTableCellLabel(editor);
|
|
31006
|
+
const nextTable = recalculateTableNode(tableInfo.node, {
|
|
31007
|
+
changedLabels: activeCellLabel ? [activeCellLabel] : null
|
|
31008
|
+
});
|
|
31009
|
+
if (!nextTable) return false;
|
|
31010
|
+
editor.view.dispatch(
|
|
31011
|
+
editor.state.tr.replaceWith(tableInfo.pos, tableInfo.pos + tableInfo.node.nodeSize, nextTable).setMeta(UEDITOR_TABLE_FORMULA_RECALCULATE_META, true)
|
|
31012
|
+
);
|
|
31013
|
+
dispatchTableLayoutChange(editor);
|
|
31014
|
+
return true;
|
|
31015
|
+
}
|
|
30928
31016
|
function recalculateAllTableFormulas(editor) {
|
|
30929
31017
|
const replacements = [];
|
|
30930
31018
|
editor.state.doc.descendants((node, pos) => {
|
|
@@ -38921,6 +39009,146 @@ var MenuBar = ({
|
|
|
38921
39009
|
] });
|
|
38922
39010
|
};
|
|
38923
39011
|
|
|
39012
|
+
// src/components/UEditor/table-formula-range-picker.ts
|
|
39013
|
+
var import_state9 = require("@tiptap/pm/state");
|
|
39014
|
+
var import_tables4 = require("@tiptap/pm/tables");
|
|
39015
|
+
function getCellText2(cellNode) {
|
|
39016
|
+
return cellNode.textBetween(0, cellNode.content.size, "\n").trim();
|
|
39017
|
+
}
|
|
39018
|
+
function findSelectionFormulaCell(view) {
|
|
39019
|
+
const { $from } = view.state.selection;
|
|
39020
|
+
for (let depth = $from.depth; depth > 0; depth -= 1) {
|
|
39021
|
+
const node = $from.node(depth);
|
|
39022
|
+
if (node.type.name !== "tableCell" && node.type.name !== "tableHeader") continue;
|
|
39023
|
+
if (!getCellText2(node).startsWith("=")) return null;
|
|
39024
|
+
const cellPos = $from.before(depth);
|
|
39025
|
+
const cellDom = view.nodeDOM(cellPos);
|
|
39026
|
+
const tableDepth = depth - 2;
|
|
39027
|
+
const tableNode = tableDepth > 0 ? $from.node(tableDepth) : null;
|
|
39028
|
+
if (!tableNode || tableNode.type.name !== "table") return null;
|
|
39029
|
+
return {
|
|
39030
|
+
cellDom: cellDom instanceof HTMLTableCellElement ? cellDom : null,
|
|
39031
|
+
tablePos: $from.before(tableDepth)
|
|
39032
|
+
};
|
|
39033
|
+
}
|
|
39034
|
+
return null;
|
|
39035
|
+
}
|
|
39036
|
+
function findTableForPos(view, pos) {
|
|
39037
|
+
const $pos = view.state.doc.resolve(pos);
|
|
39038
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
39039
|
+
const node = $pos.node(depth);
|
|
39040
|
+
if (node.type.name === "table") {
|
|
39041
|
+
return {
|
|
39042
|
+
node,
|
|
39043
|
+
pos: $pos.before(depth),
|
|
39044
|
+
start: $pos.start(depth)
|
|
39045
|
+
};
|
|
39046
|
+
}
|
|
39047
|
+
}
|
|
39048
|
+
return null;
|
|
39049
|
+
}
|
|
39050
|
+
function getCellRelativePosFromDomPos2(map, tableStart, domPos) {
|
|
39051
|
+
const relativeDomPos = domPos - tableStart;
|
|
39052
|
+
const seen = /* @__PURE__ */ new Set();
|
|
39053
|
+
for (const relativeCellPos of map.map) {
|
|
39054
|
+
if (seen.has(relativeCellPos)) continue;
|
|
39055
|
+
seen.add(relativeCellPos);
|
|
39056
|
+
if (relativeDomPos === relativeCellPos || relativeDomPos === relativeCellPos + 1) {
|
|
39057
|
+
return relativeCellPos;
|
|
39058
|
+
}
|
|
39059
|
+
}
|
|
39060
|
+
return null;
|
|
39061
|
+
}
|
|
39062
|
+
function getPickedCellLabel(view, target, tablePos) {
|
|
39063
|
+
const element = resolveEventElement(target);
|
|
39064
|
+
const cell = element?.closest?.("th,td");
|
|
39065
|
+
if (!(cell instanceof HTMLTableCellElement)) return null;
|
|
39066
|
+
const domPos = view.posAtDOM(cell, 0);
|
|
39067
|
+
const tableInfo = findTableForPos(view, domPos);
|
|
39068
|
+
if (!tableInfo || tableInfo.pos !== tablePos) return null;
|
|
39069
|
+
const map = import_tables4.TableMap.get(tableInfo.node);
|
|
39070
|
+
const relativeCellPos = getCellRelativePosFromDomPos2(map, tableInfo.start, domPos);
|
|
39071
|
+
if (relativeCellPos == null) return null;
|
|
39072
|
+
const rect = map.findCell(relativeCellPos);
|
|
39073
|
+
return {
|
|
39074
|
+
cell,
|
|
39075
|
+
label: `${indexToColumnName(rect.left)}${rect.top + 1}`
|
|
39076
|
+
};
|
|
39077
|
+
}
|
|
39078
|
+
function normalizeFormulaRangeLabel(fromLabel, toLabel) {
|
|
39079
|
+
return fromLabel === toLabel ? fromLabel : `${fromLabel}:${toLabel}`;
|
|
39080
|
+
}
|
|
39081
|
+
function replacePickedLabel(view, pickState, nextLabel, currentCell) {
|
|
39082
|
+
if (nextLabel === pickState.currentLabel && currentCell === pickState.currentCell) return pickState;
|
|
39083
|
+
if (nextLabel === pickState.currentLabel) {
|
|
39084
|
+
return {
|
|
39085
|
+
...pickState,
|
|
39086
|
+
currentCell
|
|
39087
|
+
};
|
|
39088
|
+
}
|
|
39089
|
+
let tr = view.state.tr.insertText(nextLabel, pickState.insertedFrom, pickState.insertedTo);
|
|
39090
|
+
const nextTo = pickState.insertedFrom + nextLabel.length;
|
|
39091
|
+
tr = tr.setSelection(import_state9.TextSelection.create(tr.doc, nextTo));
|
|
39092
|
+
view.dispatch(tr);
|
|
39093
|
+
return {
|
|
39094
|
+
...pickState,
|
|
39095
|
+
insertedTo: nextTo,
|
|
39096
|
+
currentLabel: nextLabel,
|
|
39097
|
+
currentCell
|
|
39098
|
+
};
|
|
39099
|
+
}
|
|
39100
|
+
function beginFormulaRangePick(view, event) {
|
|
39101
|
+
if (event.button !== 0) return null;
|
|
39102
|
+
const formulaCell = findSelectionFormulaCell(view);
|
|
39103
|
+
if (!formulaCell) return null;
|
|
39104
|
+
const picked = getPickedCellLabel(view, event.target, formulaCell.tablePos);
|
|
39105
|
+
if (!picked || picked.cell === formulaCell.cellDom) return null;
|
|
39106
|
+
const { from, to } = view.state.selection;
|
|
39107
|
+
let tr = view.state.tr.insertText(picked.label, from, to);
|
|
39108
|
+
tr = tr.setSelection(import_state9.TextSelection.create(tr.doc, from + picked.label.length));
|
|
39109
|
+
view.dispatch(tr);
|
|
39110
|
+
view.focus();
|
|
39111
|
+
event.preventDefault();
|
|
39112
|
+
event.stopPropagation();
|
|
39113
|
+
return {
|
|
39114
|
+
anchorLabel: picked.label,
|
|
39115
|
+
anchorCell: picked.cell,
|
|
39116
|
+
tablePos: formulaCell.tablePos,
|
|
39117
|
+
insertedFrom: from,
|
|
39118
|
+
insertedTo: from + picked.label.length,
|
|
39119
|
+
currentLabel: picked.label,
|
|
39120
|
+
currentCell: picked.cell
|
|
39121
|
+
};
|
|
39122
|
+
}
|
|
39123
|
+
function updateFormulaRangePick(view, pickState, event) {
|
|
39124
|
+
const picked = getPickedCellLabel(view, event.target, pickState.tablePos);
|
|
39125
|
+
if (!picked) return pickState;
|
|
39126
|
+
event.preventDefault();
|
|
39127
|
+
event.stopPropagation();
|
|
39128
|
+
return replacePickedLabel(
|
|
39129
|
+
view,
|
|
39130
|
+
pickState,
|
|
39131
|
+
normalizeFormulaRangeLabel(pickState.anchorLabel, picked.label),
|
|
39132
|
+
picked.cell
|
|
39133
|
+
);
|
|
39134
|
+
}
|
|
39135
|
+
function getFormulaRangePickHighlight(container, pickState) {
|
|
39136
|
+
if (!container.contains(pickState.anchorCell) || !container.contains(pickState.currentCell)) return null;
|
|
39137
|
+
const containerRect = container.getBoundingClientRect();
|
|
39138
|
+
const anchorRect = pickState.anchorCell.getBoundingClientRect();
|
|
39139
|
+
const currentRect = pickState.currentCell.getBoundingClientRect();
|
|
39140
|
+
const left = Math.min(anchorRect.left, currentRect.left) - containerRect.left + container.scrollLeft;
|
|
39141
|
+
const top = Math.min(anchorRect.top, currentRect.top) - containerRect.top + container.scrollTop;
|
|
39142
|
+
const right = Math.max(anchorRect.right, currentRect.right) - containerRect.left + container.scrollLeft;
|
|
39143
|
+
const bottom = Math.max(anchorRect.bottom, currentRect.bottom) - containerRect.top + container.scrollTop;
|
|
39144
|
+
return {
|
|
39145
|
+
left,
|
|
39146
|
+
top,
|
|
39147
|
+
width: Math.max(0, right - left),
|
|
39148
|
+
height: Math.max(0, bottom - top)
|
|
39149
|
+
};
|
|
39150
|
+
}
|
|
39151
|
+
|
|
38924
39152
|
// src/components/UEditor/UEditor.tsx
|
|
38925
39153
|
var import_jsx_runtime95 = require("react/jsx-runtime");
|
|
38926
39154
|
var UEditor = import_react71.default.forwardRef(({
|
|
@@ -38965,6 +39193,9 @@ var UEditor = import_react71.default.forwardRef(({
|
|
|
38965
39193
|
const inFlightPrepareRef = (0, import_react71.useRef)(null);
|
|
38966
39194
|
const lastAppliedContentRef = (0, import_react71.useRef)(content ?? "");
|
|
38967
39195
|
const scheduledFormulaRecalculateRef = (0, import_react71.useRef)(false);
|
|
39196
|
+
const formulaRangePickRef = (0, import_react71.useRef)(null);
|
|
39197
|
+
const formulaRangeSurfaceRef = (0, import_react71.useRef)(null);
|
|
39198
|
+
const [formulaRangeHighlight, setFormulaRangeHighlight] = import_react71.default.useState(null);
|
|
38968
39199
|
const scheduleFormulaRecalculate = import_react71.default.useCallback((editor2, options) => {
|
|
38969
39200
|
if (editor2.isDestroyed || scheduledFormulaRecalculateRef.current) return;
|
|
38970
39201
|
if (!options?.force && isEditingTableFormulaText(editor2)) return;
|
|
@@ -38972,7 +39203,7 @@ var UEditor = import_react71.default.forwardRef(({
|
|
|
38972
39203
|
queueMicrotask(() => {
|
|
38973
39204
|
scheduledFormulaRecalculateRef.current = false;
|
|
38974
39205
|
if (!editor2.isDestroyed && (options?.force || !isEditingTableFormulaText(editor2))) {
|
|
38975
|
-
|
|
39206
|
+
recalculateActiveTableFormulas(editor2);
|
|
38976
39207
|
}
|
|
38977
39208
|
});
|
|
38978
39209
|
}, []);
|
|
@@ -39005,6 +39236,10 @@ var UEditor = import_react71.default.forwardRef(({
|
|
|
39005
39236
|
],
|
|
39006
39237
|
[effectivePlaceholder, t, maxCharacters, uploadImage, resolvedUploadFile, imageInsertMode, maxImageFileSize, allowedImageMimeTypes, fallbackToDataUrl, editable, fetchMetadata, extraExtensions]
|
|
39007
39238
|
);
|
|
39239
|
+
const syncFormulaRangeHighlight = import_react71.default.useCallback((pickState) => {
|
|
39240
|
+
const container = formulaRangeSurfaceRef.current;
|
|
39241
|
+
setFormulaRangeHighlight(container && pickState ? getFormulaRangePickHighlight(container, pickState) : null);
|
|
39242
|
+
}, []);
|
|
39008
39243
|
const editor = (0, import_react72.useEditor)({
|
|
39009
39244
|
immediatelyRender: false,
|
|
39010
39245
|
extensions,
|
|
@@ -39013,6 +39248,37 @@ var UEditor = import_react71.default.forwardRef(({
|
|
|
39013
39248
|
autofocus,
|
|
39014
39249
|
editorProps: {
|
|
39015
39250
|
handleDOMEvents: {
|
|
39251
|
+
mousedown: (view, event) => {
|
|
39252
|
+
if (!(event instanceof MouseEvent)) return false;
|
|
39253
|
+
const pickState = beginFormulaRangePick(view, event);
|
|
39254
|
+
if (!pickState) return false;
|
|
39255
|
+
formulaRangePickRef.current = pickState;
|
|
39256
|
+
syncFormulaRangeHighlight(pickState);
|
|
39257
|
+
return true;
|
|
39258
|
+
},
|
|
39259
|
+
mousemove: (view, event) => {
|
|
39260
|
+
if (!(event instanceof MouseEvent)) return false;
|
|
39261
|
+
const pickState = formulaRangePickRef.current;
|
|
39262
|
+
if (!pickState) return false;
|
|
39263
|
+
if (event.buttons === 0) {
|
|
39264
|
+
formulaRangePickRef.current = null;
|
|
39265
|
+
syncFormulaRangeHighlight(null);
|
|
39266
|
+
return false;
|
|
39267
|
+
}
|
|
39268
|
+
const nextPickState = updateFormulaRangePick(view, pickState, event);
|
|
39269
|
+
formulaRangePickRef.current = nextPickState;
|
|
39270
|
+
syncFormulaRangeHighlight(nextPickState);
|
|
39271
|
+
return true;
|
|
39272
|
+
},
|
|
39273
|
+
mouseup: (_view, event) => {
|
|
39274
|
+
if (!(event instanceof MouseEvent)) return false;
|
|
39275
|
+
if (!formulaRangePickRef.current) return false;
|
|
39276
|
+
formulaRangePickRef.current = null;
|
|
39277
|
+
syncFormulaRangeHighlight(null);
|
|
39278
|
+
event.preventDefault();
|
|
39279
|
+
event.stopPropagation();
|
|
39280
|
+
return true;
|
|
39281
|
+
},
|
|
39016
39282
|
keydown: (_view, event) => {
|
|
39017
39283
|
if (!(event instanceof KeyboardEvent)) return false;
|
|
39018
39284
|
if (event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "ArrowUp" || event.key === "ArrowDown") {
|
|
@@ -39178,7 +39444,10 @@ var UEditor = import_react71.default.forwardRef(({
|
|
|
39178
39444
|
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(
|
|
39179
39445
|
"div",
|
|
39180
39446
|
{
|
|
39181
|
-
ref:
|
|
39447
|
+
ref: (node) => {
|
|
39448
|
+
editorContentRef.current = node;
|
|
39449
|
+
formulaRangeSurfaceRef.current = node;
|
|
39450
|
+
},
|
|
39182
39451
|
className: "relative flex-1 overflow-y-auto",
|
|
39183
39452
|
style: {
|
|
39184
39453
|
minHeight: editable ? minHeight : void 0,
|
|
@@ -39210,6 +39479,20 @@ var UEditor = import_react71.default.forwardRef(({
|
|
|
39210
39479
|
className: "pointer-events-none hidden absolute z-20 rounded-[2px] border-2 border-primary bg-primary/10"
|
|
39211
39480
|
}
|
|
39212
39481
|
),
|
|
39482
|
+
formulaRangeHighlight && /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
39483
|
+
"span",
|
|
39484
|
+
{
|
|
39485
|
+
"aria-hidden": "true",
|
|
39486
|
+
"data-ueditor-formula-range-highlight": "",
|
|
39487
|
+
className: "pointer-events-none absolute z-20 rounded-[2px] border-2 border-primary bg-primary/10",
|
|
39488
|
+
style: {
|
|
39489
|
+
left: formulaRangeHighlight.left,
|
|
39490
|
+
top: formulaRangeHighlight.top,
|
|
39491
|
+
width: formulaRangeHighlight.width,
|
|
39492
|
+
height: formulaRangeHighlight.height
|
|
39493
|
+
}
|
|
39494
|
+
}
|
|
39495
|
+
),
|
|
39213
39496
|
editable && /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(TableControls, { editor, containerRef: editorContentRef }),
|
|
39214
39497
|
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
39215
39498
|
import_react72.EditorContent,
|