@underverse-ui/underverse 1.0.150 → 1.0.151
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 +933 -296
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +934 -296
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -843,6 +843,10 @@ var en_default = {
|
|
|
843
843
|
borderWidth: "Border Width",
|
|
844
844
|
borderColor: "Border Color",
|
|
845
845
|
clearBorder: "Clear Border",
|
|
846
|
+
formula: "Formula",
|
|
847
|
+
apply: "Apply",
|
|
848
|
+
clear: "Clear",
|
|
849
|
+
recalculate: "Recalculate",
|
|
846
850
|
done: "Done"
|
|
847
851
|
},
|
|
848
852
|
callout: {
|
|
@@ -1219,6 +1223,10 @@ var vi_default = {
|
|
|
1219
1223
|
borderWidth: "\u0110\u1ED9 d\xE0y vi\u1EC1n",
|
|
1220
1224
|
borderColor: "M\xE0u vi\u1EC1n",
|
|
1221
1225
|
clearBorder: "X\xF3a vi\u1EC1n",
|
|
1226
|
+
formula: "C\xF4ng th\u1EE9c",
|
|
1227
|
+
apply: "\xC1p d\u1EE5ng",
|
|
1228
|
+
clear: "X\xF3a",
|
|
1229
|
+
recalculate: "T\xEDnh l\u1EA1i",
|
|
1222
1230
|
done: "Xong"
|
|
1223
1231
|
},
|
|
1224
1232
|
callout: {
|
|
@@ -27657,6 +27665,46 @@ var CustomTableCell = TableCell2.extend({
|
|
|
27657
27665
|
"data-border-width": attributes.borderWidth
|
|
27658
27666
|
};
|
|
27659
27667
|
}
|
|
27668
|
+
},
|
|
27669
|
+
cellId: {
|
|
27670
|
+
default: null,
|
|
27671
|
+
parseHTML: (element) => element.getAttribute("data-cell-id") || null,
|
|
27672
|
+
renderHTML: (attributes) => {
|
|
27673
|
+
if (!attributes.cellId) return {};
|
|
27674
|
+
return {
|
|
27675
|
+
"data-cell-id": attributes.cellId
|
|
27676
|
+
};
|
|
27677
|
+
}
|
|
27678
|
+
},
|
|
27679
|
+
numberFormat: {
|
|
27680
|
+
default: null,
|
|
27681
|
+
parseHTML: (element) => element.getAttribute("data-number-format") || null,
|
|
27682
|
+
renderHTML: (attributes) => {
|
|
27683
|
+
if (!attributes.numberFormat) return {};
|
|
27684
|
+
return {
|
|
27685
|
+
"data-number-format": attributes.numberFormat
|
|
27686
|
+
};
|
|
27687
|
+
}
|
|
27688
|
+
},
|
|
27689
|
+
formula: {
|
|
27690
|
+
default: null,
|
|
27691
|
+
parseHTML: (element) => element.getAttribute("data-formula") || null,
|
|
27692
|
+
renderHTML: (attributes) => {
|
|
27693
|
+
if (!attributes.formula) return {};
|
|
27694
|
+
return {
|
|
27695
|
+
"data-formula": attributes.formula
|
|
27696
|
+
};
|
|
27697
|
+
}
|
|
27698
|
+
},
|
|
27699
|
+
computedValue: {
|
|
27700
|
+
default: null,
|
|
27701
|
+
parseHTML: (element) => element.getAttribute("data-computed-value") || null,
|
|
27702
|
+
renderHTML: (attributes) => {
|
|
27703
|
+
if (!attributes.computedValue) return {};
|
|
27704
|
+
return {
|
|
27705
|
+
"data-computed-value": attributes.computedValue
|
|
27706
|
+
};
|
|
27707
|
+
}
|
|
27660
27708
|
}
|
|
27661
27709
|
};
|
|
27662
27710
|
},
|
|
@@ -27724,6 +27772,46 @@ var CustomTableHeader = TableHeader2.extend({
|
|
|
27724
27772
|
"data-border-width": attributes.borderWidth
|
|
27725
27773
|
};
|
|
27726
27774
|
}
|
|
27775
|
+
},
|
|
27776
|
+
cellId: {
|
|
27777
|
+
default: null,
|
|
27778
|
+
parseHTML: (element) => element.getAttribute("data-cell-id") || null,
|
|
27779
|
+
renderHTML: (attributes) => {
|
|
27780
|
+
if (!attributes.cellId) return {};
|
|
27781
|
+
return {
|
|
27782
|
+
"data-cell-id": attributes.cellId
|
|
27783
|
+
};
|
|
27784
|
+
}
|
|
27785
|
+
},
|
|
27786
|
+
numberFormat: {
|
|
27787
|
+
default: null,
|
|
27788
|
+
parseHTML: (element) => element.getAttribute("data-number-format") || null,
|
|
27789
|
+
renderHTML: (attributes) => {
|
|
27790
|
+
if (!attributes.numberFormat) return {};
|
|
27791
|
+
return {
|
|
27792
|
+
"data-number-format": attributes.numberFormat
|
|
27793
|
+
};
|
|
27794
|
+
}
|
|
27795
|
+
},
|
|
27796
|
+
formula: {
|
|
27797
|
+
default: null,
|
|
27798
|
+
parseHTML: (element) => element.getAttribute("data-formula") || null,
|
|
27799
|
+
renderHTML: (attributes) => {
|
|
27800
|
+
if (!attributes.formula) return {};
|
|
27801
|
+
return {
|
|
27802
|
+
"data-formula": attributes.formula
|
|
27803
|
+
};
|
|
27804
|
+
}
|
|
27805
|
+
},
|
|
27806
|
+
computedValue: {
|
|
27807
|
+
default: null,
|
|
27808
|
+
parseHTML: (element) => element.getAttribute("data-computed-value") || null,
|
|
27809
|
+
renderHTML: (attributes) => {
|
|
27810
|
+
if (!attributes.computedValue) return {};
|
|
27811
|
+
return {
|
|
27812
|
+
"data-computed-value": attributes.computedValue
|
|
27813
|
+
};
|
|
27814
|
+
}
|
|
27727
27815
|
}
|
|
27728
27816
|
};
|
|
27729
27817
|
},
|
|
@@ -28474,6 +28562,34 @@ function collectChildren(node) {
|
|
|
28474
28562
|
function createEmptyCellNode(cellNode) {
|
|
28475
28563
|
return cellNode.type.createAndFill(cellNode.attrs) ?? cellNode;
|
|
28476
28564
|
}
|
|
28565
|
+
function createCellCopyForColumnDuplicate(cellNode) {
|
|
28566
|
+
return cellNode.type.create(cellNode.attrs, cellNode.content);
|
|
28567
|
+
}
|
|
28568
|
+
function getTableRows(tableNode) {
|
|
28569
|
+
const rows = [];
|
|
28570
|
+
tableNode.forEach((rowNode, rowOffset) => {
|
|
28571
|
+
const cells = [];
|
|
28572
|
+
rowNode.forEach((cellNode, cellOffset, index) => {
|
|
28573
|
+
cells.push({
|
|
28574
|
+
index,
|
|
28575
|
+
node: cellNode,
|
|
28576
|
+
relativePos: rowOffset + 1 + cellOffset
|
|
28577
|
+
});
|
|
28578
|
+
});
|
|
28579
|
+
rows.push({
|
|
28580
|
+
node: rowNode,
|
|
28581
|
+
cells
|
|
28582
|
+
});
|
|
28583
|
+
});
|
|
28584
|
+
return rows;
|
|
28585
|
+
}
|
|
28586
|
+
function safeFindCell(map, relativePos) {
|
|
28587
|
+
try {
|
|
28588
|
+
return map.findCell(relativePos);
|
|
28589
|
+
} catch {
|
|
28590
|
+
return null;
|
|
28591
|
+
}
|
|
28592
|
+
}
|
|
28477
28593
|
function getSelectedTableRect(editor) {
|
|
28478
28594
|
const cellSelection = getCellSelectionPositions(editor.state.selection);
|
|
28479
28595
|
if (cellSelection) {
|
|
@@ -28599,34 +28715,49 @@ function duplicateTableRowAt(editor, rowIndex, cellPos) {
|
|
|
28599
28715
|
}
|
|
28600
28716
|
function clearTableRowAt(editor, rowIndex, cellPos) {
|
|
28601
28717
|
return replaceTableAtCellPos(editor, cellPos, (tableNode) => {
|
|
28602
|
-
const
|
|
28603
|
-
|
|
28604
|
-
|
|
28605
|
-
|
|
28606
|
-
|
|
28718
|
+
const map = TableMap.get(tableNode);
|
|
28719
|
+
if (rowIndex < 0 || rowIndex >= map.height) return null;
|
|
28720
|
+
const rows = getTableRows(tableNode).map((rowInfo) => {
|
|
28721
|
+
const cells = collectChildren(rowInfo.node);
|
|
28722
|
+
for (const entry of rowInfo.cells) {
|
|
28723
|
+
const rect = safeFindCell(map, entry.relativePos);
|
|
28724
|
+
if (!rect || rect.top > rowIndex || rowIndex >= rect.bottom) continue;
|
|
28725
|
+
cells[entry.index] = createEmptyCellNode(entry.node);
|
|
28726
|
+
}
|
|
28727
|
+
return rowInfo.node.type.create(rowInfo.node.attrs, cells);
|
|
28728
|
+
});
|
|
28607
28729
|
return tableNode.type.create(tableNode.attrs, rows);
|
|
28608
28730
|
});
|
|
28609
28731
|
}
|
|
28610
28732
|
function duplicateTableColumnAt(editor, columnIndex, cellPos) {
|
|
28611
28733
|
return replaceTableAtCellPos(editor, cellPos, (tableNode) => {
|
|
28612
|
-
const
|
|
28613
|
-
|
|
28614
|
-
|
|
28615
|
-
|
|
28616
|
-
|
|
28617
|
-
|
|
28734
|
+
const map = TableMap.get(tableNode);
|
|
28735
|
+
if (columnIndex < 0 || columnIndex >= map.width) return null;
|
|
28736
|
+
const rows = getTableRows(tableNode).map((rowInfo, rowIndex) => {
|
|
28737
|
+
const cells = collectChildren(rowInfo.node);
|
|
28738
|
+
const sourceCell = rowInfo.cells.find((entry) => {
|
|
28739
|
+
const rect = safeFindCell(map, entry.relativePos);
|
|
28740
|
+
return rect && rect.top === rowIndex && rect.left <= columnIndex && columnIndex < rect.right;
|
|
28741
|
+
});
|
|
28742
|
+
if (!sourceCell) return rowInfo.node;
|
|
28743
|
+
cells.splice(sourceCell.index + 1, 0, createCellCopyForColumnDuplicate(sourceCell.node));
|
|
28744
|
+
return rowInfo.node.type.create(rowInfo.node.attrs, cells);
|
|
28618
28745
|
});
|
|
28619
28746
|
return tableNode.type.create(tableNode.attrs, rows);
|
|
28620
28747
|
});
|
|
28621
28748
|
}
|
|
28622
28749
|
function clearTableColumnAt(editor, columnIndex, cellPos) {
|
|
28623
28750
|
return replaceTableAtCellPos(editor, cellPos, (tableNode) => {
|
|
28624
|
-
const
|
|
28625
|
-
|
|
28626
|
-
|
|
28627
|
-
|
|
28628
|
-
|
|
28629
|
-
|
|
28751
|
+
const map = TableMap.get(tableNode);
|
|
28752
|
+
if (columnIndex < 0 || columnIndex >= map.width) return null;
|
|
28753
|
+
const rows = getTableRows(tableNode).map((rowInfo) => {
|
|
28754
|
+
const cells = collectChildren(rowInfo.node);
|
|
28755
|
+
for (const entry of rowInfo.cells) {
|
|
28756
|
+
const rect = safeFindCell(map, entry.relativePos);
|
|
28757
|
+
if (!rect || rect.left > columnIndex || columnIndex >= rect.right) continue;
|
|
28758
|
+
cells[entry.index] = createEmptyCellNode(entry.node);
|
|
28759
|
+
}
|
|
28760
|
+
return rowInfo.node.type.create(rowInfo.node.attrs, cells);
|
|
28630
28761
|
});
|
|
28631
28762
|
return tableNode.type.create(tableNode.attrs, rows);
|
|
28632
28763
|
});
|
|
@@ -29678,7 +29809,7 @@ var EditorToolbar = ({
|
|
|
29678
29809
|
// src/components/UEditor/menus.tsx
|
|
29679
29810
|
import { useCallback as useCallback22, useEffect as useEffect36, useMemo as useMemo23, useRef as useRef33, useState as useState48 } from "react";
|
|
29680
29811
|
import { useEditorState as useEditorState2 } from "@tiptap/react";
|
|
29681
|
-
import { isInTable as isSelectionInTable, setCellAttr } from "@tiptap/pm/tables";
|
|
29812
|
+
import { isInTable as isSelectionInTable, setCellAttr as setCellAttr2 } from "@tiptap/pm/tables";
|
|
29682
29813
|
import { createPortal as createPortal8 } from "react-dom";
|
|
29683
29814
|
import {
|
|
29684
29815
|
AlignCenter as AlignCenter2,
|
|
@@ -29700,13 +29831,410 @@ import {
|
|
|
29700
29831
|
Strikethrough as StrikethroughIcon2,
|
|
29701
29832
|
Edit2,
|
|
29702
29833
|
Unlink,
|
|
29703
|
-
ExternalLink as ExternalLink3
|
|
29834
|
+
ExternalLink as ExternalLink3,
|
|
29835
|
+
Sigma
|
|
29704
29836
|
} from "lucide-react";
|
|
29837
|
+
|
|
29838
|
+
// src/components/UEditor/table-formula-commands.ts
|
|
29839
|
+
import { selectedRect as selectedRect2, setCellAttr, TableMap as TableMap2 } from "@tiptap/pm/tables";
|
|
29840
|
+
|
|
29841
|
+
// src/components/UEditor/table-formula.ts
|
|
29842
|
+
var CELL_ADDRESS_RE = /^([A-Z]+)([1-9]\d*)$/i;
|
|
29843
|
+
var CELL_RANGE_RE = /^([A-Z]+[1-9]\d*):([A-Z]+[1-9]\d*)$/i;
|
|
29844
|
+
var SUPPORTED_FUNCTIONS = /* @__PURE__ */ new Set(["SUM", "AVG", "MIN", "MAX", "COUNT"]);
|
|
29845
|
+
function columnNameToIndex(columnName) {
|
|
29846
|
+
const normalized = columnName.trim().toUpperCase();
|
|
29847
|
+
if (!/^[A-Z]+$/.test(normalized)) {
|
|
29848
|
+
return -1;
|
|
29849
|
+
}
|
|
29850
|
+
let index = 0;
|
|
29851
|
+
for (const char of normalized) {
|
|
29852
|
+
index = index * 26 + char.charCodeAt(0) - 64;
|
|
29853
|
+
}
|
|
29854
|
+
return index - 1;
|
|
29855
|
+
}
|
|
29856
|
+
function indexToColumnName(index) {
|
|
29857
|
+
if (!Number.isInteger(index) || index < 0) {
|
|
29858
|
+
return "";
|
|
29859
|
+
}
|
|
29860
|
+
let value = index + 1;
|
|
29861
|
+
let name = "";
|
|
29862
|
+
while (value > 0) {
|
|
29863
|
+
const remainder = (value - 1) % 26;
|
|
29864
|
+
name = String.fromCharCode(65 + remainder) + name;
|
|
29865
|
+
value = Math.floor((value - 1) / 26);
|
|
29866
|
+
}
|
|
29867
|
+
return name;
|
|
29868
|
+
}
|
|
29869
|
+
function parseTableCellAddress(input) {
|
|
29870
|
+
const match = input.trim().match(CELL_ADDRESS_RE);
|
|
29871
|
+
if (!match) {
|
|
29872
|
+
return null;
|
|
29873
|
+
}
|
|
29874
|
+
const column = columnNameToIndex(match[1] ?? "");
|
|
29875
|
+
const row = Number.parseInt(match[2] ?? "", 10) - 1;
|
|
29876
|
+
if (column < 0 || row < 0) {
|
|
29877
|
+
return null;
|
|
29878
|
+
}
|
|
29879
|
+
return {
|
|
29880
|
+
column,
|
|
29881
|
+
row,
|
|
29882
|
+
label: `${indexToColumnName(column)}${row + 1}`
|
|
29883
|
+
};
|
|
29884
|
+
}
|
|
29885
|
+
function parseTableCellRange(input) {
|
|
29886
|
+
const match = input.trim().match(CELL_RANGE_RE);
|
|
29887
|
+
if (!match) {
|
|
29888
|
+
return null;
|
|
29889
|
+
}
|
|
29890
|
+
const from = parseTableCellAddress(match[1] ?? "");
|
|
29891
|
+
const to = parseTableCellAddress(match[2] ?? "");
|
|
29892
|
+
if (!from || !to) {
|
|
29893
|
+
return null;
|
|
29894
|
+
}
|
|
29895
|
+
return { from, to };
|
|
29896
|
+
}
|
|
29897
|
+
function getTableCellRangeLabels(range) {
|
|
29898
|
+
const startColumn = Math.min(range.from.column, range.to.column);
|
|
29899
|
+
const endColumn = Math.max(range.from.column, range.to.column);
|
|
29900
|
+
const startRow = Math.min(range.from.row, range.to.row);
|
|
29901
|
+
const endRow = Math.max(range.from.row, range.to.row);
|
|
29902
|
+
const labels = [];
|
|
29903
|
+
for (let row = startRow; row <= endRow; row += 1) {
|
|
29904
|
+
for (let column = startColumn; column <= endColumn; column += 1) {
|
|
29905
|
+
labels.push(`${indexToColumnName(column)}${row + 1}`);
|
|
29906
|
+
}
|
|
29907
|
+
}
|
|
29908
|
+
return labels;
|
|
29909
|
+
}
|
|
29910
|
+
function normalizeTableFormula(formula) {
|
|
29911
|
+
return formula.trim().replace(/^=/, "").trim();
|
|
29912
|
+
}
|
|
29913
|
+
function evaluateBasicTableFormula(formula, getCellValue) {
|
|
29914
|
+
const normalized = normalizeTableFormula(formula);
|
|
29915
|
+
if (!normalized) {
|
|
29916
|
+
return { value: null, error: "empty" };
|
|
29917
|
+
}
|
|
29918
|
+
const tokens = tokenizeFormula(normalized);
|
|
29919
|
+
if (!tokens) {
|
|
29920
|
+
return { value: null, error: "invalid-formula" };
|
|
29921
|
+
}
|
|
29922
|
+
const parser = new FormulaParser(tokens, getCellValue);
|
|
29923
|
+
const result = parser.parseExpression();
|
|
29924
|
+
if (result.error) {
|
|
29925
|
+
return result;
|
|
29926
|
+
}
|
|
29927
|
+
if (!parser.isComplete()) {
|
|
29928
|
+
return { value: null, error: "invalid-formula" };
|
|
29929
|
+
}
|
|
29930
|
+
return result;
|
|
29931
|
+
}
|
|
29932
|
+
function tokenizeFormula(formula) {
|
|
29933
|
+
const tokens = [];
|
|
29934
|
+
let index = 0;
|
|
29935
|
+
while (index < formula.length) {
|
|
29936
|
+
const char = formula[index];
|
|
29937
|
+
if (!char) break;
|
|
29938
|
+
if (/\s/.test(char)) {
|
|
29939
|
+
index += 1;
|
|
29940
|
+
continue;
|
|
29941
|
+
}
|
|
29942
|
+
if (char === "," || char === "+" || char === "-" || char === "*" || char === "/" || char === "(" || char === ")") {
|
|
29943
|
+
if (char === ",") tokens.push({ type: "comma", value: char });
|
|
29944
|
+
else if (char === "(" || char === ")") tokens.push({ type: "paren", value: char });
|
|
29945
|
+
else tokens.push({ type: "operator", value: char });
|
|
29946
|
+
index += 1;
|
|
29947
|
+
continue;
|
|
29948
|
+
}
|
|
29949
|
+
const numberMatch = formula.slice(index).match(/^\d+(?:\.\d+)?/);
|
|
29950
|
+
if (numberMatch?.[0]) {
|
|
29951
|
+
tokens.push({ type: "number", value: Number.parseFloat(numberMatch[0]) });
|
|
29952
|
+
index += numberMatch[0].length;
|
|
29953
|
+
continue;
|
|
29954
|
+
}
|
|
29955
|
+
const identifierMatch = formula.slice(index).match(/^[A-Z]+[1-9]\d*(?::[A-Z]+[1-9]\d*)?|^[A-Z]+/i);
|
|
29956
|
+
if (identifierMatch?.[0]) {
|
|
29957
|
+
const value = identifierMatch[0].toUpperCase();
|
|
29958
|
+
if (CELL_RANGE_RE.test(value)) tokens.push({ type: "range", value });
|
|
29959
|
+
else if (parseTableCellAddress(value)) tokens.push({ type: "cell", value });
|
|
29960
|
+
else if (SUPPORTED_FUNCTIONS.has(value)) tokens.push({ type: "function", value });
|
|
29961
|
+
else return null;
|
|
29962
|
+
index += identifierMatch[0].length;
|
|
29963
|
+
continue;
|
|
29964
|
+
}
|
|
29965
|
+
return null;
|
|
29966
|
+
}
|
|
29967
|
+
return tokens;
|
|
29968
|
+
}
|
|
29969
|
+
var FormulaParser = class {
|
|
29970
|
+
constructor(tokens, getCellValue) {
|
|
29971
|
+
this.tokens = tokens;
|
|
29972
|
+
this.getCellValue = getCellValue;
|
|
29973
|
+
this.index = 0;
|
|
29974
|
+
}
|
|
29975
|
+
isComplete() {
|
|
29976
|
+
return this.index >= this.tokens.length;
|
|
29977
|
+
}
|
|
29978
|
+
parseExpression() {
|
|
29979
|
+
let left = this.parseTerm();
|
|
29980
|
+
while (!left.error) {
|
|
29981
|
+
const operator = this.peekOperator(["+", "-"]);
|
|
29982
|
+
if (!operator) break;
|
|
29983
|
+
this.index += 1;
|
|
29984
|
+
const right = this.parseTerm();
|
|
29985
|
+
if (right.error) return right;
|
|
29986
|
+
left = {
|
|
29987
|
+
value: operator.value === "+" ? left.value + right.value : left.value - right.value,
|
|
29988
|
+
error: null
|
|
29989
|
+
};
|
|
29990
|
+
}
|
|
29991
|
+
return left;
|
|
29992
|
+
}
|
|
29993
|
+
parseTerm() {
|
|
29994
|
+
let left = this.parseFactor();
|
|
29995
|
+
while (!left.error) {
|
|
29996
|
+
const operator = this.peekOperator(["*", "/"]);
|
|
29997
|
+
if (!operator) break;
|
|
29998
|
+
this.index += 1;
|
|
29999
|
+
const right = this.parseFactor();
|
|
30000
|
+
if (right.error) return right;
|
|
30001
|
+
if (operator.value === "/" && right.value === 0) {
|
|
30002
|
+
return { value: null, error: "division-by-zero" };
|
|
30003
|
+
}
|
|
30004
|
+
left = {
|
|
30005
|
+
value: operator.value === "*" ? left.value * right.value : left.value / right.value,
|
|
30006
|
+
error: null
|
|
30007
|
+
};
|
|
30008
|
+
}
|
|
30009
|
+
return left;
|
|
30010
|
+
}
|
|
30011
|
+
parseFactor() {
|
|
30012
|
+
const token = this.tokens[this.index];
|
|
30013
|
+
if (!token) {
|
|
30014
|
+
return { value: null, error: "invalid-formula" };
|
|
30015
|
+
}
|
|
30016
|
+
if (token.type === "operator" && token.value === "-") {
|
|
30017
|
+
this.index += 1;
|
|
30018
|
+
const value = this.parseFactor();
|
|
30019
|
+
if (value.error) return value;
|
|
30020
|
+
return { value: -value.value, error: null };
|
|
30021
|
+
}
|
|
30022
|
+
if (token.type === "number") {
|
|
30023
|
+
this.index += 1;
|
|
30024
|
+
return { value: token.value, error: null };
|
|
30025
|
+
}
|
|
30026
|
+
if (token.type === "cell") {
|
|
30027
|
+
this.index += 1;
|
|
30028
|
+
return this.readCellNumber(token.value);
|
|
30029
|
+
}
|
|
30030
|
+
if (token.type === "function") {
|
|
30031
|
+
return this.parseFunction(token.value);
|
|
30032
|
+
}
|
|
30033
|
+
if (token.type === "paren" && token.value === "(") {
|
|
30034
|
+
this.index += 1;
|
|
30035
|
+
const value = this.parseExpression();
|
|
30036
|
+
if (value.error) return value;
|
|
30037
|
+
if (!this.consumeParen(")")) {
|
|
30038
|
+
return { value: null, error: "invalid-formula" };
|
|
30039
|
+
}
|
|
30040
|
+
return value;
|
|
30041
|
+
}
|
|
30042
|
+
return { value: null, error: "invalid-formula" };
|
|
30043
|
+
}
|
|
30044
|
+
parseFunction(name) {
|
|
30045
|
+
this.index += 1;
|
|
30046
|
+
if (!this.consumeParen("(")) {
|
|
30047
|
+
return { value: null, error: "invalid-formula" };
|
|
30048
|
+
}
|
|
30049
|
+
const values = [];
|
|
30050
|
+
while (true) {
|
|
30051
|
+
const token = this.tokens[this.index];
|
|
30052
|
+
if (!token) {
|
|
30053
|
+
return { value: null, error: "invalid-formula" };
|
|
30054
|
+
}
|
|
30055
|
+
if (token.type === "range") {
|
|
30056
|
+
this.index += 1;
|
|
30057
|
+
const range = parseTableCellRange(token.value);
|
|
30058
|
+
if (!range) return { value: null, error: "invalid-reference" };
|
|
30059
|
+
for (const label of getTableCellRangeLabels(range)) {
|
|
30060
|
+
const cellValue = this.readCellNumber(label);
|
|
30061
|
+
if (cellValue.error) return cellValue;
|
|
30062
|
+
values.push(cellValue.value);
|
|
30063
|
+
}
|
|
30064
|
+
} else {
|
|
30065
|
+
const value = this.parseExpression();
|
|
30066
|
+
if (value.error) return value;
|
|
30067
|
+
values.push(value.value);
|
|
30068
|
+
}
|
|
30069
|
+
if (this.consumeComma()) {
|
|
30070
|
+
continue;
|
|
30071
|
+
}
|
|
30072
|
+
if (this.consumeParen(")")) {
|
|
30073
|
+
break;
|
|
30074
|
+
}
|
|
30075
|
+
return { value: null, error: "invalid-formula" };
|
|
30076
|
+
}
|
|
30077
|
+
if (values.length === 0) {
|
|
30078
|
+
return { value: null, error: "invalid-formula" };
|
|
30079
|
+
}
|
|
30080
|
+
if (name === "SUM") return { value: values.reduce((sum, value) => sum + value, 0), error: null };
|
|
30081
|
+
if (name === "AVG") return { value: values.reduce((sum, value) => sum + value, 0) / values.length, error: null };
|
|
30082
|
+
if (name === "MIN") return { value: Math.min(...values), error: null };
|
|
30083
|
+
if (name === "MAX") return { value: Math.max(...values), error: null };
|
|
30084
|
+
if (name === "COUNT") return { value: values.length, error: null };
|
|
30085
|
+
return { value: null, error: "invalid-formula" };
|
|
30086
|
+
}
|
|
30087
|
+
readCellNumber(label) {
|
|
30088
|
+
const value = this.getCellValue(label);
|
|
30089
|
+
const parsed = typeof value === "number" ? value : Number.parseFloat(String(value ?? "").trim());
|
|
30090
|
+
if (!Number.isFinite(parsed)) {
|
|
30091
|
+
return { value: null, error: "invalid-reference" };
|
|
30092
|
+
}
|
|
30093
|
+
return { value: parsed, error: null };
|
|
30094
|
+
}
|
|
30095
|
+
peekOperator(operators) {
|
|
30096
|
+
const token = this.tokens[this.index];
|
|
30097
|
+
return token?.type === "operator" && operators.includes(token.value) ? token : null;
|
|
30098
|
+
}
|
|
30099
|
+
consumeComma() {
|
|
30100
|
+
if (this.tokens[this.index]?.type !== "comma") {
|
|
30101
|
+
return false;
|
|
30102
|
+
}
|
|
30103
|
+
this.index += 1;
|
|
30104
|
+
return true;
|
|
30105
|
+
}
|
|
30106
|
+
consumeParen(value) {
|
|
30107
|
+
const token = this.tokens[this.index];
|
|
30108
|
+
if (token?.type !== "paren" || token.value !== value) {
|
|
30109
|
+
return false;
|
|
30110
|
+
}
|
|
30111
|
+
this.index += 1;
|
|
30112
|
+
return true;
|
|
30113
|
+
}
|
|
30114
|
+
};
|
|
30115
|
+
|
|
30116
|
+
// src/components/UEditor/table-formula-commands.ts
|
|
30117
|
+
function collectChildren2(node) {
|
|
30118
|
+
const children = [];
|
|
30119
|
+
node.forEach((child) => children.push(child));
|
|
30120
|
+
return children;
|
|
30121
|
+
}
|
|
30122
|
+
function getTableRows2(tableNode) {
|
|
30123
|
+
const rows = [];
|
|
30124
|
+
tableNode.forEach((rowNode, rowOffset) => {
|
|
30125
|
+
const cells = [];
|
|
30126
|
+
rowNode.forEach((cellNode, cellOffset, index) => {
|
|
30127
|
+
cells.push({
|
|
30128
|
+
index,
|
|
30129
|
+
node: cellNode,
|
|
30130
|
+
relativePos: rowOffset + 1 + cellOffset
|
|
30131
|
+
});
|
|
30132
|
+
});
|
|
30133
|
+
rows.push({ node: rowNode, cells });
|
|
30134
|
+
});
|
|
30135
|
+
return rows;
|
|
30136
|
+
}
|
|
30137
|
+
function safeFindCell2(map, relativePos) {
|
|
30138
|
+
try {
|
|
30139
|
+
return map.findCell(relativePos);
|
|
30140
|
+
} catch {
|
|
30141
|
+
return null;
|
|
30142
|
+
}
|
|
30143
|
+
}
|
|
30144
|
+
function getCellText(cellNode) {
|
|
30145
|
+
return cellNode.textBetween(0, cellNode.content.size, "\n").trim();
|
|
30146
|
+
}
|
|
30147
|
+
function buildTableValueGetter(tableNode) {
|
|
30148
|
+
const map = TableMap2.get(tableNode);
|
|
30149
|
+
const values = /* @__PURE__ */ new Map();
|
|
30150
|
+
for (const rowInfo of getTableRows2(tableNode)) {
|
|
30151
|
+
for (const entry of rowInfo.cells) {
|
|
30152
|
+
const rect = safeFindCell2(map, entry.relativePos);
|
|
30153
|
+
if (!rect) continue;
|
|
30154
|
+
const label = `${indexToColumnName(rect.left)}${rect.top + 1}`;
|
|
30155
|
+
const computedValue = entry.node.attrs.computedValue;
|
|
30156
|
+
values.set(label, typeof computedValue === "string" && computedValue.trim() ? computedValue : getCellText(entry.node));
|
|
30157
|
+
}
|
|
30158
|
+
}
|
|
30159
|
+
return (label) => values.get(label.toUpperCase());
|
|
30160
|
+
}
|
|
30161
|
+
function getFormulaComputedValue(formula, tableNode) {
|
|
30162
|
+
const result = evaluateBasicTableFormula(formula, buildTableValueGetter(tableNode));
|
|
30163
|
+
return result.error ? `#${result.error.toUpperCase()}` : String(result.value);
|
|
30164
|
+
}
|
|
30165
|
+
function normalizeFormulaInput(formula) {
|
|
30166
|
+
const trimmed = formula.trim();
|
|
30167
|
+
if (!trimmed) return "";
|
|
30168
|
+
return trimmed.startsWith("=") ? trimmed : `=${trimmed}`;
|
|
30169
|
+
}
|
|
30170
|
+
function setSelectedTableCellFormula(editor, formula) {
|
|
30171
|
+
const normalized = normalizeFormulaInput(formula);
|
|
30172
|
+
const { state, view } = editor;
|
|
30173
|
+
if (!normalized) {
|
|
30174
|
+
const clearedFormula = setCellAttr("formula", null)(state, view.dispatch.bind(view));
|
|
30175
|
+
const clearedValue = setCellAttr("computedValue", null)(editor.state, view.dispatch.bind(view));
|
|
30176
|
+
if (clearedFormula || clearedValue) {
|
|
30177
|
+
view.focus();
|
|
30178
|
+
dispatchTableLayoutChange(editor);
|
|
30179
|
+
return true;
|
|
30180
|
+
}
|
|
30181
|
+
return false;
|
|
30182
|
+
}
|
|
30183
|
+
const rect = selectedRect2(state);
|
|
30184
|
+
const computedValue = getFormulaComputedValue(normalized, rect.table);
|
|
30185
|
+
const appliedFormula = setCellAttr("formula", normalized)(state, view.dispatch.bind(view));
|
|
30186
|
+
const appliedValue = setCellAttr("computedValue", computedValue)(editor.state, view.dispatch.bind(view));
|
|
30187
|
+
if (appliedFormula || appliedValue) {
|
|
30188
|
+
view.focus();
|
|
30189
|
+
dispatchTableLayoutChange(editor);
|
|
30190
|
+
return true;
|
|
30191
|
+
}
|
|
30192
|
+
return false;
|
|
30193
|
+
}
|
|
30194
|
+
function clearSelectedTableCellFormula(editor) {
|
|
30195
|
+
return setSelectedTableCellFormula(editor, "");
|
|
30196
|
+
}
|
|
30197
|
+
function recalculateSelectedTable(editor) {
|
|
30198
|
+
const rect = selectedRect2(editor.state);
|
|
30199
|
+
const tableNode = rect.table;
|
|
30200
|
+
const map = TableMap2.get(tableNode);
|
|
30201
|
+
const getCellValue = buildTableValueGetter(tableNode);
|
|
30202
|
+
let changed = false;
|
|
30203
|
+
const rows = getTableRows2(tableNode).map((rowInfo) => {
|
|
30204
|
+
const cells = collectChildren2(rowInfo.node);
|
|
30205
|
+
for (const entry of rowInfo.cells) {
|
|
30206
|
+
const formula = typeof entry.node.attrs.formula === "string" ? entry.node.attrs.formula.trim() : "";
|
|
30207
|
+
if (!formula) continue;
|
|
30208
|
+
const rectForCell = safeFindCell2(map, entry.relativePos);
|
|
30209
|
+
if (!rectForCell) continue;
|
|
30210
|
+
const result = evaluateBasicTableFormula(formula, getCellValue);
|
|
30211
|
+
const computedValue = result.error ? `#${result.error.toUpperCase()}` : String(result.value);
|
|
30212
|
+
if (entry.node.attrs.computedValue === computedValue) continue;
|
|
30213
|
+
cells[entry.index] = entry.node.type.create(
|
|
30214
|
+
{
|
|
30215
|
+
...entry.node.attrs,
|
|
30216
|
+
computedValue
|
|
30217
|
+
},
|
|
30218
|
+
entry.node.content,
|
|
30219
|
+
entry.node.marks
|
|
30220
|
+
);
|
|
30221
|
+
changed = true;
|
|
30222
|
+
}
|
|
30223
|
+
return rowInfo.node.type.create(rowInfo.node.attrs, cells);
|
|
30224
|
+
});
|
|
30225
|
+
if (!changed) return false;
|
|
30226
|
+
const nextTable = tableNode.type.create(tableNode.attrs, rows);
|
|
30227
|
+
editor.view.dispatch(editor.state.tr.replaceWith(rect.tableStart - 1, rect.tableStart - 1 + tableNode.nodeSize, nextTable));
|
|
30228
|
+
dispatchTableLayoutChange(editor);
|
|
30229
|
+
return true;
|
|
30230
|
+
}
|
|
30231
|
+
|
|
30232
|
+
// src/components/UEditor/menus.tsx
|
|
29705
30233
|
import { Fragment as Fragment29, jsx as jsx86, jsxs as jsxs72 } from "react/jsx-runtime";
|
|
29706
30234
|
function applyTableCellBackground(editor, color) {
|
|
29707
30235
|
const value = color || null;
|
|
29708
30236
|
const { state, view } = editor;
|
|
29709
|
-
const applied =
|
|
30237
|
+
const applied = setCellAttr2("backgroundColor", value)(state, view.dispatch.bind(view));
|
|
29710
30238
|
if (applied) {
|
|
29711
30239
|
view.focus();
|
|
29712
30240
|
return;
|
|
@@ -29732,6 +30260,8 @@ var BubbleMenuContent = ({
|
|
|
29732
30260
|
setShowLinkInput(initialShowLinkInput);
|
|
29733
30261
|
}, [initialShowLinkInput]);
|
|
29734
30262
|
const [showTypographyPanel, setShowTypographyPanel] = useState48(false);
|
|
30263
|
+
const [showFormulaPanel, setShowFormulaPanel] = useState48(false);
|
|
30264
|
+
const [formulaDraft, setFormulaDraft] = useState48("");
|
|
29735
30265
|
const [showFontSizeOptions, setShowFontSizeOptions] = useState48(false);
|
|
29736
30266
|
const [fontSizeDraft, setFontSizeDraft] = useState48("");
|
|
29737
30267
|
const isImageSelected = editor.isActive("image");
|
|
@@ -29742,6 +30272,7 @@ var BubbleMenuContent = ({
|
|
|
29742
30272
|
const currentTextColor = normalizeStyleValue(textStyleAttrs.color) || "inherit";
|
|
29743
30273
|
const currentHighlightColor = normalizeStyleValue(editor.getAttributes("highlight").color) || "";
|
|
29744
30274
|
const currentCellBgColor = normalizeStyleValue(editor.getAttributes("tableCell").backgroundColor || editor.getAttributes("tableHeader").backgroundColor) || "";
|
|
30275
|
+
const currentCellFormula = normalizeStyleValue(editor.getAttributes("tableCell").formula || editor.getAttributes("tableHeader").formula) || "";
|
|
29745
30276
|
const isInTable2 = isSelectionInTable(editor.state);
|
|
29746
30277
|
const canMergeCells = isInTable2 && editor.can().mergeCells();
|
|
29747
30278
|
const canSplitCell = isInTable2 && editor.can().splitCell();
|
|
@@ -29758,6 +30289,9 @@ var BubbleMenuContent = ({
|
|
|
29758
30289
|
useEffect36(() => {
|
|
29759
30290
|
setFontSizeDraft(currentFontSize.replace(/px$/i, ""));
|
|
29760
30291
|
}, [currentFontSize]);
|
|
30292
|
+
useEffect36(() => {
|
|
30293
|
+
setFormulaDraft(currentCellFormula);
|
|
30294
|
+
}, [currentCellFormula]);
|
|
29761
30295
|
const applyFontSizeDraft = () => {
|
|
29762
30296
|
const normalized = fontSizeDraft.trim();
|
|
29763
30297
|
if (!normalized) {
|
|
@@ -29960,6 +30494,82 @@ var BubbleMenuContent = ({
|
|
|
29960
30494
|
)
|
|
29961
30495
|
] });
|
|
29962
30496
|
}
|
|
30497
|
+
if (showFormulaPanel && isInTable2) {
|
|
30498
|
+
return /* @__PURE__ */ jsxs72("div", { className: "w-72 p-2", children: [
|
|
30499
|
+
/* @__PURE__ */ jsxs72("div", { className: "mb-2 flex items-center justify-between gap-2", children: [
|
|
30500
|
+
/* @__PURE__ */ jsx86("span", { className: "px-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: t("tableMenu.formula") || "Formula" }),
|
|
30501
|
+
/* @__PURE__ */ jsx86(
|
|
30502
|
+
"button",
|
|
30503
|
+
{
|
|
30504
|
+
type: "button",
|
|
30505
|
+
onClick: () => {
|
|
30506
|
+
setShowFormulaPanel(false);
|
|
30507
|
+
onKeepOpenChange?.(false);
|
|
30508
|
+
},
|
|
30509
|
+
className: "rounded-md px-2 py-1 text-xs text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
30510
|
+
children: t("colors.done")
|
|
30511
|
+
}
|
|
30512
|
+
)
|
|
30513
|
+
] }),
|
|
30514
|
+
/* @__PURE__ */ jsx86("div", { className: "flex h-9 items-center overflow-hidden rounded-md border border-border/60 bg-muted/40", children: /* @__PURE__ */ jsx86(
|
|
30515
|
+
"input",
|
|
30516
|
+
{
|
|
30517
|
+
value: formulaDraft,
|
|
30518
|
+
onChange: (event) => setFormulaDraft(event.target.value),
|
|
30519
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
30520
|
+
onClick: (event) => event.stopPropagation(),
|
|
30521
|
+
onKeyDown: (event) => {
|
|
30522
|
+
event.stopPropagation();
|
|
30523
|
+
if (event.key === "Enter") {
|
|
30524
|
+
event.preventDefault();
|
|
30525
|
+
setSelectedTableCellFormula(editor, formulaDraft);
|
|
30526
|
+
setShowFormulaPanel(false);
|
|
30527
|
+
onKeepOpenChange?.(false);
|
|
30528
|
+
}
|
|
30529
|
+
},
|
|
30530
|
+
"aria-label": t("tableMenu.formula") || "Formula",
|
|
30531
|
+
placeholder: "=SUM(A1:A3)",
|
|
30532
|
+
className: "h-full min-w-0 flex-1 bg-transparent px-2 text-sm font-medium text-foreground outline-none"
|
|
30533
|
+
}
|
|
30534
|
+
) }),
|
|
30535
|
+
/* @__PURE__ */ jsxs72("div", { className: "mt-2 grid grid-cols-3 gap-1", children: [
|
|
30536
|
+
/* @__PURE__ */ jsx86(
|
|
30537
|
+
"button",
|
|
30538
|
+
{
|
|
30539
|
+
type: "button",
|
|
30540
|
+
onClick: () => {
|
|
30541
|
+
setSelectedTableCellFormula(editor, formulaDraft);
|
|
30542
|
+
setShowFormulaPanel(false);
|
|
30543
|
+
onKeepOpenChange?.(false);
|
|
30544
|
+
},
|
|
30545
|
+
className: "h-8 rounded-md bg-primary/10 text-xs font-semibold text-primary transition-colors hover:bg-primary/15",
|
|
30546
|
+
children: t("tableMenu.apply") || "Apply"
|
|
30547
|
+
}
|
|
30548
|
+
),
|
|
30549
|
+
/* @__PURE__ */ jsx86(
|
|
30550
|
+
"button",
|
|
30551
|
+
{
|
|
30552
|
+
type: "button",
|
|
30553
|
+
onClick: () => {
|
|
30554
|
+
clearSelectedTableCellFormula(editor);
|
|
30555
|
+
setFormulaDraft("");
|
|
30556
|
+
},
|
|
30557
|
+
className: "h-8 rounded-md bg-muted/40 text-xs font-semibold text-foreground transition-colors hover:bg-muted",
|
|
30558
|
+
children: t("tableMenu.clear") || "Clear"
|
|
30559
|
+
}
|
|
30560
|
+
),
|
|
30561
|
+
/* @__PURE__ */ jsx86(
|
|
30562
|
+
"button",
|
|
30563
|
+
{
|
|
30564
|
+
type: "button",
|
|
30565
|
+
onClick: () => recalculateSelectedTable(editor),
|
|
30566
|
+
className: "h-8 rounded-md bg-muted/40 text-xs font-semibold text-foreground transition-colors hover:bg-muted",
|
|
30567
|
+
children: t("tableMenu.recalculate") || "Recalc"
|
|
30568
|
+
}
|
|
30569
|
+
)
|
|
30570
|
+
] })
|
|
30571
|
+
] });
|
|
30572
|
+
}
|
|
29963
30573
|
if (showTypographyPanel) {
|
|
29964
30574
|
return /* @__PURE__ */ jsxs72("div", { className: "w-72 p-2", children: [
|
|
29965
30575
|
/* @__PURE__ */ jsxs72("div", { className: "mb-2 flex items-center justify-between gap-2", children: [
|
|
@@ -30173,6 +30783,21 @@ var BubbleMenuContent = ({
|
|
|
30173
30783
|
)
|
|
30174
30784
|
}
|
|
30175
30785
|
),
|
|
30786
|
+
/* @__PURE__ */ jsx86(
|
|
30787
|
+
ToolbarButton,
|
|
30788
|
+
{
|
|
30789
|
+
onMouseDown: () => {
|
|
30790
|
+
onKeepOpenChange?.(true);
|
|
30791
|
+
},
|
|
30792
|
+
onClick: () => {
|
|
30793
|
+
setFormulaDraft(currentCellFormula);
|
|
30794
|
+
setShowFormulaPanel(true);
|
|
30795
|
+
},
|
|
30796
|
+
active: Boolean(currentCellFormula),
|
|
30797
|
+
title: t("tableMenu.formula") || "Formula",
|
|
30798
|
+
children: /* @__PURE__ */ jsx86(Sigma, { className: "w-4 h-4" })
|
|
30799
|
+
}
|
|
30800
|
+
),
|
|
30176
30801
|
/* @__PURE__ */ jsx86(
|
|
30177
30802
|
ToolbarButton,
|
|
30178
30803
|
{
|
|
@@ -34014,7 +34639,7 @@ if (typeof WeakMap != "undefined") {
|
|
|
34014
34639
|
return cache[cachePos++] = value;
|
|
34015
34640
|
};
|
|
34016
34641
|
}
|
|
34017
|
-
var
|
|
34642
|
+
var TableMap3 = class {
|
|
34018
34643
|
constructor(width, height, map, problems) {
|
|
34019
34644
|
this.width = width;
|
|
34020
34645
|
this.height = height;
|
|
@@ -34151,7 +34776,7 @@ function computeMap(table) {
|
|
|
34151
34776
|
pos++;
|
|
34152
34777
|
}
|
|
34153
34778
|
if (width === 0 || height === 0) (problems || (problems = [])).push({ type: "zero_sized" });
|
|
34154
|
-
const tableMap = new
|
|
34779
|
+
const tableMap = new TableMap3(width, height, map, problems);
|
|
34155
34780
|
let badWidths = false;
|
|
34156
34781
|
for (let i = 0; !badWidths && i < colWidths.length; i += 2) if (colWidths[i] != null && colWidths[i + 1] < height) badWidths = true;
|
|
34157
34782
|
if (badWidths) findBadColWidths(tableMap, colWidths, table);
|
|
@@ -34255,7 +34880,7 @@ function inSameTable($cellA, $cellB) {
|
|
|
34255
34880
|
}
|
|
34256
34881
|
function nextCell($pos, axis, dir) {
|
|
34257
34882
|
const table = $pos.node(-1);
|
|
34258
|
-
const map =
|
|
34883
|
+
const map = TableMap3.get(table);
|
|
34259
34884
|
const tableStart = $pos.start(-1);
|
|
34260
34885
|
const moved = map.nextCell($pos.pos - tableStart, axis, dir);
|
|
34261
34886
|
return moved == null ? null : $pos.node(0).resolve(tableStart + moved);
|
|
@@ -34275,7 +34900,7 @@ function removeColSpan(attrs, pos, n = 1) {
|
|
|
34275
34900
|
var CellSelection = class CellSelection2 extends Selection {
|
|
34276
34901
|
constructor($anchorCell, $headCell = $anchorCell) {
|
|
34277
34902
|
const table = $anchorCell.node(-1);
|
|
34278
|
-
const map =
|
|
34903
|
+
const map = TableMap3.get(table);
|
|
34279
34904
|
const tableStart = $anchorCell.start(-1);
|
|
34280
34905
|
const rect = map.rectBetween($anchorCell.pos - tableStart, $headCell.pos - tableStart);
|
|
34281
34906
|
const doc = $anchorCell.node(0);
|
|
@@ -34304,7 +34929,7 @@ var CellSelection = class CellSelection2 extends Selection {
|
|
|
34304
34929
|
}
|
|
34305
34930
|
content() {
|
|
34306
34931
|
const table = this.$anchorCell.node(-1);
|
|
34307
|
-
const map =
|
|
34932
|
+
const map = TableMap3.get(table);
|
|
34308
34933
|
const tableStart = this.$anchorCell.start(-1);
|
|
34309
34934
|
const rect = map.rectBetween(this.$anchorCell.pos - tableStart, this.$headCell.pos - tableStart);
|
|
34310
34935
|
const seen = {};
|
|
@@ -34358,7 +34983,7 @@ var CellSelection = class CellSelection2 extends Selection {
|
|
|
34358
34983
|
}
|
|
34359
34984
|
forEachCell(f) {
|
|
34360
34985
|
const table = this.$anchorCell.node(-1);
|
|
34361
|
-
const map =
|
|
34986
|
+
const map = TableMap3.get(table);
|
|
34362
34987
|
const tableStart = this.$anchorCell.start(-1);
|
|
34363
34988
|
const cells = map.cellsInRect(map.rectBetween(this.$anchorCell.pos - tableStart, this.$headCell.pos - tableStart));
|
|
34364
34989
|
for (let i = 0; i < cells.length; i++) f(table.nodeAt(cells[i]), tableStart + cells[i]);
|
|
@@ -34373,7 +34998,7 @@ var CellSelection = class CellSelection2 extends Selection {
|
|
|
34373
34998
|
}
|
|
34374
34999
|
static colSelection($anchorCell, $headCell = $anchorCell) {
|
|
34375
35000
|
const table = $anchorCell.node(-1);
|
|
34376
|
-
const map =
|
|
35001
|
+
const map = TableMap3.get(table);
|
|
34377
35002
|
const tableStart = $anchorCell.start(-1);
|
|
34378
35003
|
const anchorRect = map.findCell($anchorCell.pos - tableStart);
|
|
34379
35004
|
const headRect = map.findCell($headCell.pos - tableStart);
|
|
@@ -34389,7 +35014,7 @@ var CellSelection = class CellSelection2 extends Selection {
|
|
|
34389
35014
|
}
|
|
34390
35015
|
isRowSelection() {
|
|
34391
35016
|
const table = this.$anchorCell.node(-1);
|
|
34392
|
-
const map =
|
|
35017
|
+
const map = TableMap3.get(table);
|
|
34393
35018
|
const tableStart = this.$anchorCell.start(-1);
|
|
34394
35019
|
const anchorLeft = map.colCount(this.$anchorCell.pos - tableStart);
|
|
34395
35020
|
const headLeft = map.colCount(this.$headCell.pos - tableStart);
|
|
@@ -34403,7 +35028,7 @@ var CellSelection = class CellSelection2 extends Selection {
|
|
|
34403
35028
|
}
|
|
34404
35029
|
static rowSelection($anchorCell, $headCell = $anchorCell) {
|
|
34405
35030
|
const table = $anchorCell.node(-1);
|
|
34406
|
-
const map =
|
|
35031
|
+
const map = TableMap3.get(table);
|
|
34407
35032
|
const tableStart = $anchorCell.start(-1);
|
|
34408
35033
|
const anchorRect = map.findCell($anchorCell.pos - tableStart);
|
|
34409
35034
|
const headRect = map.findCell($headCell.pos - tableStart);
|
|
@@ -34452,7 +35077,7 @@ var CellBookmark = class CellBookmark2 {
|
|
|
34452
35077
|
};
|
|
34453
35078
|
var fixTablesKey = new PluginKey4("fix-tables");
|
|
34454
35079
|
function convertTableNodeToArrayOfRows(tableNode) {
|
|
34455
|
-
const map =
|
|
35080
|
+
const map = TableMap3.get(tableNode);
|
|
34456
35081
|
const rows = [];
|
|
34457
35082
|
const rowCount = map.height;
|
|
34458
35083
|
const colCount$1 = map.width;
|
|
@@ -34483,7 +35108,7 @@ function convertTableNodeToArrayOfRows(tableNode) {
|
|
|
34483
35108
|
}
|
|
34484
35109
|
function convertArrayOfRowsToTableNode(tableNode, arrayOfNodes) {
|
|
34485
35110
|
const newRows = [];
|
|
34486
|
-
const map =
|
|
35111
|
+
const map = TableMap3.get(tableNode);
|
|
34487
35112
|
const rowCount = map.height;
|
|
34488
35113
|
const colCount$1 = map.width;
|
|
34489
35114
|
for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
|
|
@@ -34532,7 +35157,7 @@ function findParentNode(predicate, $pos) {
|
|
|
34532
35157
|
function getCellsInColumn(columnIndex, selection) {
|
|
34533
35158
|
const table = findTable(selection.$from);
|
|
34534
35159
|
if (!table) return;
|
|
34535
|
-
const map =
|
|
35160
|
+
const map = TableMap3.get(table.node);
|
|
34536
35161
|
if (columnIndex < 0 || columnIndex > map.width - 1) return;
|
|
34537
35162
|
return map.cellsInRect({
|
|
34538
35163
|
left: columnIndex,
|
|
@@ -34553,7 +35178,7 @@ function getCellsInColumn(columnIndex, selection) {
|
|
|
34553
35178
|
function getCellsInRow(rowIndex, selection) {
|
|
34554
35179
|
const table = findTable(selection.$from);
|
|
34555
35180
|
if (!table) return;
|
|
34556
|
-
const map =
|
|
35181
|
+
const map = TableMap3.get(table.node);
|
|
34557
35182
|
if (rowIndex < 0 || rowIndex > map.height - 1) return;
|
|
34558
35183
|
return map.cellsInRect({
|
|
34559
35184
|
left: 0,
|
|
@@ -34682,7 +35307,7 @@ function moveColumn(moveColParams) {
|
|
|
34682
35307
|
const newTable = moveTableColumn$1(table.node, indexesOriginColumn, indexesTargetColumn, 0);
|
|
34683
35308
|
tr.replaceWith(table.pos, table.pos + table.node.nodeSize, newTable);
|
|
34684
35309
|
if (!select) return true;
|
|
34685
|
-
const map =
|
|
35310
|
+
const map = TableMap3.get(newTable);
|
|
34686
35311
|
const start = table.start;
|
|
34687
35312
|
const index = targetIndex;
|
|
34688
35313
|
const lastCell = map.positionAt(map.height - 1, index, newTable);
|
|
@@ -34710,7 +35335,7 @@ function moveRow(moveRowParams) {
|
|
|
34710
35335
|
const newTable = moveTableRow$1(table.node, indexesOriginRow, indexesTargetRow, 0);
|
|
34711
35336
|
tr.replaceWith(table.pos, table.pos + table.node.nodeSize, newTable);
|
|
34712
35337
|
if (!select) return true;
|
|
34713
|
-
const map =
|
|
35338
|
+
const map = TableMap3.get(newTable);
|
|
34714
35339
|
const start = table.start;
|
|
34715
35340
|
const index = targetIndex;
|
|
34716
35341
|
const lastCell = map.positionAt(index, map.width - 1, newTable);
|
|
@@ -34725,12 +35350,12 @@ function moveTableRow$1(table, indexesOrigin, indexesTarget, direction) {
|
|
|
34725
35350
|
rows = moveRowInArrayOfRows(rows, indexesOrigin, indexesTarget, direction);
|
|
34726
35351
|
return convertArrayOfRowsToTableNode(table, rows);
|
|
34727
35352
|
}
|
|
34728
|
-
function
|
|
35353
|
+
function selectedRect3(state) {
|
|
34729
35354
|
const sel = state.selection;
|
|
34730
35355
|
const $pos = selectionCell(state);
|
|
34731
35356
|
const table = $pos.node(-1);
|
|
34732
35357
|
const tableStart = $pos.start(-1);
|
|
34733
|
-
const map =
|
|
35358
|
+
const map = TableMap3.get(table);
|
|
34734
35359
|
return {
|
|
34735
35360
|
...sel instanceof CellSelection ? map.rectBetween(sel.$anchorCell.pos - tableStart, sel.$headCell.pos - tableStart) : map.findCell($pos.pos - tableStart),
|
|
34736
35361
|
tableStart,
|
|
@@ -34743,7 +35368,7 @@ function deprecated_toggleHeader(type) {
|
|
|
34743
35368
|
if (!isInTable(state)) return false;
|
|
34744
35369
|
if (dispatch) {
|
|
34745
35370
|
const types = tableNodeTypes(state.schema);
|
|
34746
|
-
const rect =
|
|
35371
|
+
const rect = selectedRect3(state), tr = state.tr;
|
|
34747
35372
|
const cells = rect.map.cellsInRect(type == "column" ? {
|
|
34748
35373
|
left: rect.left,
|
|
34749
35374
|
top: 0,
|
|
@@ -34783,7 +35408,7 @@ function toggleHeader(type, options) {
|
|
|
34783
35408
|
if (!isInTable(state)) return false;
|
|
34784
35409
|
if (dispatch) {
|
|
34785
35410
|
const types = tableNodeTypes(state.schema);
|
|
34786
|
-
const rect =
|
|
35411
|
+
const rect = selectedRect3(state), tr = state.tr;
|
|
34787
35412
|
const isHeaderRowEnabled = isHeaderEnabledByType("row", rect, types);
|
|
34788
35413
|
const isHeaderColumnEnabled = isHeaderEnabledByType("column", rect, types);
|
|
34789
35414
|
const selectionStartsAt = (type === "column" ? isHeaderRowEnabled : type === "row" ? isHeaderColumnEnabled : false) ? 1 : 0;
|
|
@@ -34944,6 +35569,262 @@ import {
|
|
|
34944
35569
|
Trash2 as Trash24
|
|
34945
35570
|
} from "lucide-react";
|
|
34946
35571
|
|
|
35572
|
+
// src/components/UEditor/table-layout-model.ts
|
|
35573
|
+
var FALLBACK_TABLE_ROW_HEIGHT = 44;
|
|
35574
|
+
var FALLBACK_TABLE_COLUMN_WIDTH = 160;
|
|
35575
|
+
function getVisibleTableBounds(layout) {
|
|
35576
|
+
const left = Math.max(layout.tableLeft, layout.wrapperLeft);
|
|
35577
|
+
const top = Math.max(layout.tableTop, layout.wrapperTop);
|
|
35578
|
+
const right = Math.min(layout.tableLeft + layout.tableWidth, layout.wrapperLeft + layout.viewportWidth);
|
|
35579
|
+
const bottom = Math.min(layout.tableTop + layout.tableHeight, layout.wrapperTop + layout.viewportHeight);
|
|
35580
|
+
return {
|
|
35581
|
+
left,
|
|
35582
|
+
top,
|
|
35583
|
+
right,
|
|
35584
|
+
bottom,
|
|
35585
|
+
width: Math.max(0, right - left),
|
|
35586
|
+
height: Math.max(0, bottom - top)
|
|
35587
|
+
};
|
|
35588
|
+
}
|
|
35589
|
+
function metricOrFallback(value, fallback) {
|
|
35590
|
+
return Number.isFinite(value) && value > 0 ? value : fallback;
|
|
35591
|
+
}
|
|
35592
|
+
function parsePixelMetric(value) {
|
|
35593
|
+
if (!value) return null;
|
|
35594
|
+
const parsed = Number.parseFloat(value);
|
|
35595
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
|
|
35596
|
+
}
|
|
35597
|
+
function getPrimaryCell(table) {
|
|
35598
|
+
const cell = table.querySelector("th,td");
|
|
35599
|
+
return cell instanceof HTMLTableCellElement ? cell : null;
|
|
35600
|
+
}
|
|
35601
|
+
function getLastCell(table) {
|
|
35602
|
+
const lastRow = table.rows.item(table.rows.length - 1);
|
|
35603
|
+
if (!(lastRow instanceof HTMLTableRowElement)) return null;
|
|
35604
|
+
const cell = lastRow.cells.item(lastRow.cells.length - 1);
|
|
35605
|
+
return cell instanceof HTMLTableCellElement ? cell : null;
|
|
35606
|
+
}
|
|
35607
|
+
function getCellFromTarget(target) {
|
|
35608
|
+
const element = resolveEventElement(target);
|
|
35609
|
+
if (!element) return null;
|
|
35610
|
+
const directCell = element.closest("th,td");
|
|
35611
|
+
if (directCell instanceof HTMLTableCellElement) {
|
|
35612
|
+
return directCell;
|
|
35613
|
+
}
|
|
35614
|
+
const table = element.closest("table");
|
|
35615
|
+
if (table instanceof HTMLTableElement) {
|
|
35616
|
+
return getPrimaryCell(table);
|
|
35617
|
+
}
|
|
35618
|
+
return null;
|
|
35619
|
+
}
|
|
35620
|
+
function findTableInfo(editor, pos) {
|
|
35621
|
+
const $pos = editor.state.doc.resolve(pos);
|
|
35622
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
35623
|
+
const node = $pos.node(depth);
|
|
35624
|
+
if (node.type.name === "table") {
|
|
35625
|
+
return {
|
|
35626
|
+
node,
|
|
35627
|
+
pos: $pos.before(depth),
|
|
35628
|
+
start: $pos.start(depth)
|
|
35629
|
+
};
|
|
35630
|
+
}
|
|
35631
|
+
}
|
|
35632
|
+
return null;
|
|
35633
|
+
}
|
|
35634
|
+
function getCellRelativePosFromDomPos(map, tableStart, domPos) {
|
|
35635
|
+
const relativeDomPos = domPos - tableStart;
|
|
35636
|
+
const seen = /* @__PURE__ */ new Set();
|
|
35637
|
+
for (const relativeCellPos of map.map) {
|
|
35638
|
+
if (seen.has(relativeCellPos)) continue;
|
|
35639
|
+
seen.add(relativeCellPos);
|
|
35640
|
+
if (relativeDomPos === relativeCellPos || relativeDomPos === relativeCellPos + 1) {
|
|
35641
|
+
return relativeCellPos;
|
|
35642
|
+
}
|
|
35643
|
+
}
|
|
35644
|
+
return null;
|
|
35645
|
+
}
|
|
35646
|
+
function buildLogicalColumnMetrics({
|
|
35647
|
+
editor,
|
|
35648
|
+
surface,
|
|
35649
|
+
surfaceRect,
|
|
35650
|
+
tableElement,
|
|
35651
|
+
tableInfo,
|
|
35652
|
+
tableLeft,
|
|
35653
|
+
tableWidth
|
|
35654
|
+
}) {
|
|
35655
|
+
const map = TableMap3.get(tableInfo.node);
|
|
35656
|
+
const fallbackWidth = metricOrFallback(tableWidth / map.width, FALLBACK_TABLE_COLUMN_WIDTH);
|
|
35657
|
+
const firstRow = tableElement.rows.item(0);
|
|
35658
|
+
const visualColumns = [];
|
|
35659
|
+
if (firstRow) {
|
|
35660
|
+
for (const tableCell of Array.from(firstRow.cells)) {
|
|
35661
|
+
if (!(tableCell instanceof HTMLTableCellElement)) continue;
|
|
35662
|
+
const cellPos = editor.view.posAtDOM(tableCell, 0);
|
|
35663
|
+
const relativeCellPos = getCellRelativePosFromDomPos(map, tableInfo.start, cellPos);
|
|
35664
|
+
if (relativeCellPos == null) continue;
|
|
35665
|
+
const cellMapRect = map.findCell(relativeCellPos);
|
|
35666
|
+
const cellRect = tableCell.getBoundingClientRect();
|
|
35667
|
+
const cellStart = cellRect.width > 0 ? cellRect.left - surfaceRect.left + surface.scrollLeft : tableLeft + cellMapRect.left * fallbackWidth;
|
|
35668
|
+
const size = metricOrFallback(cellRect.width, fallbackWidth * Math.max(1, cellMapRect.right - cellMapRect.left));
|
|
35669
|
+
visualColumns.push({
|
|
35670
|
+
index: cellMapRect.left,
|
|
35671
|
+
cellPos: tableInfo.start + relativeCellPos,
|
|
35672
|
+
start: cellStart,
|
|
35673
|
+
size,
|
|
35674
|
+
center: cellStart + size / 2
|
|
35675
|
+
});
|
|
35676
|
+
}
|
|
35677
|
+
}
|
|
35678
|
+
if (visualColumns.length > 0) {
|
|
35679
|
+
return visualColumns.sort((a, b) => a.index - b.index);
|
|
35680
|
+
}
|
|
35681
|
+
const cols = Array.from(tableElement.querySelectorAll("colgroup > col"));
|
|
35682
|
+
const parsedWidths = cols.slice(0, map.width).map((col) => parsePixelMetric(col.style.width) ?? parsePixelMetric(col.getAttribute("width")));
|
|
35683
|
+
const hasCompleteColWidths = parsedWidths.length >= map.width && parsedWidths.every((width) => typeof width === "number");
|
|
35684
|
+
let cursor = tableLeft;
|
|
35685
|
+
return Array.from({ length: map.width }, (_, index) => {
|
|
35686
|
+
const size = hasCompleteColWidths ? parsedWidths[index] : fallbackWidth;
|
|
35687
|
+
const start = hasCompleteColWidths ? cursor : tableLeft + index * fallbackWidth;
|
|
35688
|
+
cursor += size;
|
|
35689
|
+
return {
|
|
35690
|
+
index,
|
|
35691
|
+
cellPos: tableInfo.start + map.positionAt(0, index, tableInfo.node),
|
|
35692
|
+
start,
|
|
35693
|
+
size,
|
|
35694
|
+
center: start + size / 2
|
|
35695
|
+
};
|
|
35696
|
+
});
|
|
35697
|
+
}
|
|
35698
|
+
function buildLogicalRowMetrics({
|
|
35699
|
+
editor,
|
|
35700
|
+
surface,
|
|
35701
|
+
surfaceRect,
|
|
35702
|
+
tableInfo,
|
|
35703
|
+
rows,
|
|
35704
|
+
tableTop,
|
|
35705
|
+
tableHeight,
|
|
35706
|
+
cornerCell
|
|
35707
|
+
}) {
|
|
35708
|
+
const map = TableMap3.get(tableInfo.node);
|
|
35709
|
+
const fallbackHeight = metricOrFallback(tableHeight / map.height, FALLBACK_TABLE_ROW_HEIGHT);
|
|
35710
|
+
const visualRows = [];
|
|
35711
|
+
const seenCellPositions = /* @__PURE__ */ new Set();
|
|
35712
|
+
for (let rowIndex = 0; rowIndex < map.height; rowIndex += 1) {
|
|
35713
|
+
const relativeCellPos = map.map[rowIndex * map.width];
|
|
35714
|
+
if (seenCellPositions.has(relativeCellPos)) continue;
|
|
35715
|
+
seenCellPositions.add(relativeCellPos);
|
|
35716
|
+
const cellMapRect = map.findCell(relativeCellPos);
|
|
35717
|
+
const cellDom = editor.view.nodeDOM(tableInfo.start + relativeCellPos);
|
|
35718
|
+
const tableCell = cellDom instanceof HTMLTableCellElement ? cellDom : null;
|
|
35719
|
+
if (tableCell) {
|
|
35720
|
+
const cellRect = tableCell.getBoundingClientRect();
|
|
35721
|
+
const start = cellRect.height > 0 ? cellRect.top - surfaceRect.top + surface.scrollTop : tableTop + cellMapRect.top * fallbackHeight;
|
|
35722
|
+
const size = metricOrFallback(cellRect.height, fallbackHeight * Math.max(1, cellMapRect.bottom - cellMapRect.top));
|
|
35723
|
+
visualRows.push({
|
|
35724
|
+
index: cellMapRect.top,
|
|
35725
|
+
cellPos: tableInfo.start + relativeCellPos,
|
|
35726
|
+
start,
|
|
35727
|
+
size,
|
|
35728
|
+
center: start + size / 2
|
|
35729
|
+
});
|
|
35730
|
+
}
|
|
35731
|
+
}
|
|
35732
|
+
if (visualRows.length > 0) {
|
|
35733
|
+
return visualRows.sort((a, b) => a.index - b.index);
|
|
35734
|
+
}
|
|
35735
|
+
return rows.map((tableRow, index) => {
|
|
35736
|
+
const rowRect = tableRow.getBoundingClientRect();
|
|
35737
|
+
const anchorCell = tableRow.cells.item(0) ?? cornerCell;
|
|
35738
|
+
const start = rowRect.height > 0 ? rowRect.top - surfaceRect.top + surface.scrollTop : tableTop + index * fallbackHeight;
|
|
35739
|
+
const size = metricOrFallback(rowRect.height, fallbackHeight);
|
|
35740
|
+
return {
|
|
35741
|
+
index,
|
|
35742
|
+
cellPos: editor.view.posAtDOM(anchorCell, 0),
|
|
35743
|
+
start,
|
|
35744
|
+
size,
|
|
35745
|
+
center: start + size / 2
|
|
35746
|
+
};
|
|
35747
|
+
});
|
|
35748
|
+
}
|
|
35749
|
+
function buildTableControlLayout(editor, surface, cell) {
|
|
35750
|
+
const row = cell.closest("tr");
|
|
35751
|
+
const table = cell.closest("table");
|
|
35752
|
+
if (!(row instanceof HTMLTableRowElement) || !(table instanceof HTMLTableElement)) {
|
|
35753
|
+
return null;
|
|
35754
|
+
}
|
|
35755
|
+
const rows = Array.from(table.rows).filter((item) => item instanceof HTMLTableRowElement);
|
|
35756
|
+
const cornerCell = getLastCell(table);
|
|
35757
|
+
const cellPos = editor.view.posAtDOM(cell, 0);
|
|
35758
|
+
const tableInfo = findTableInfo(editor, cellPos);
|
|
35759
|
+
if (rows.length === 0 || !tableInfo || !(cornerCell instanceof HTMLTableCellElement)) {
|
|
35760
|
+
return null;
|
|
35761
|
+
}
|
|
35762
|
+
const map = TableMap3.get(tableInfo.node);
|
|
35763
|
+
const surfaceRect = surface.getBoundingClientRect();
|
|
35764
|
+
const tableRect = table.getBoundingClientRect();
|
|
35765
|
+
const wrapperElement = table.closest(".tableWrapper");
|
|
35766
|
+
const wrapper = wrapperElement instanceof HTMLElement ? wrapperElement : null;
|
|
35767
|
+
const wrapperRect = wrapper?.getBoundingClientRect() ?? tableRect;
|
|
35768
|
+
const tableLeft = tableRect.left - surfaceRect.left + surface.scrollLeft;
|
|
35769
|
+
const tableTop = tableRect.top - surfaceRect.top + surface.scrollTop;
|
|
35770
|
+
const avgRowHeight = metricOrFallback(tableRect.height / rows.length, FALLBACK_TABLE_ROW_HEIGHT);
|
|
35771
|
+
const avgColumnWidth = metricOrFallback(tableRect.width / map.width, FALLBACK_TABLE_COLUMN_WIDTH);
|
|
35772
|
+
const tableWidth = metricOrFallback(tableRect.width, avgColumnWidth * map.width);
|
|
35773
|
+
const tableHeight = metricOrFallback(tableRect.height, avgRowHeight * rows.length);
|
|
35774
|
+
const wrapperLeft = wrapperRect.left - surfaceRect.left + surface.scrollLeft;
|
|
35775
|
+
const wrapperTop = wrapperRect.top - surfaceRect.top + surface.scrollTop;
|
|
35776
|
+
const wrapperWidth = metricOrFallback(wrapperRect.width, tableWidth);
|
|
35777
|
+
const wrapperHeight = metricOrFallback(wrapperRect.height, tableHeight);
|
|
35778
|
+
const viewportWidth = metricOrFallback(wrapper?.clientWidth ?? wrapperRect.width, tableWidth);
|
|
35779
|
+
const viewportHeight = metricOrFallback(wrapper?.clientHeight ?? wrapperRect.height, tableHeight);
|
|
35780
|
+
const verticalScrollbarWidth = Math.max(0, Math.round(wrapperWidth - viewportWidth));
|
|
35781
|
+
const horizontalScrollbarHeight = Math.max(0, Math.round(wrapperHeight - viewportHeight));
|
|
35782
|
+
const rowHandles = buildLogicalRowMetrics({
|
|
35783
|
+
editor,
|
|
35784
|
+
surface,
|
|
35785
|
+
surfaceRect,
|
|
35786
|
+
tableInfo,
|
|
35787
|
+
rows,
|
|
35788
|
+
tableTop,
|
|
35789
|
+
tableHeight,
|
|
35790
|
+
cornerCell
|
|
35791
|
+
});
|
|
35792
|
+
const columnHandles = buildLogicalColumnMetrics({
|
|
35793
|
+
editor,
|
|
35794
|
+
surface,
|
|
35795
|
+
surfaceRect,
|
|
35796
|
+
tableElement: table,
|
|
35797
|
+
tableInfo,
|
|
35798
|
+
tableLeft,
|
|
35799
|
+
tableWidth
|
|
35800
|
+
});
|
|
35801
|
+
const activeCellRelativePos = getCellRelativePosFromDomPos(map, tableInfo.start, cellPos);
|
|
35802
|
+
const activeCellRect = activeCellRelativePos != null ? map.findCell(activeCellRelativePos) : { left: cell.cellIndex, top: row.rowIndex };
|
|
35803
|
+
const normalizedCellPos = activeCellRelativePos != null ? tableInfo.start + activeCellRelativePos : cellPos;
|
|
35804
|
+
return {
|
|
35805
|
+
cellPos: normalizedCellPos,
|
|
35806
|
+
cornerCellPos: tableInfo.start + map.positionAt(map.height - 1, map.width - 1, tableInfo.node),
|
|
35807
|
+
activeRowIndex: activeCellRect.top,
|
|
35808
|
+
activeColumnIndex: activeCellRect.left,
|
|
35809
|
+
tableLeft,
|
|
35810
|
+
tableTop,
|
|
35811
|
+
tableWidth,
|
|
35812
|
+
tableHeight,
|
|
35813
|
+
wrapperLeft,
|
|
35814
|
+
wrapperTop,
|
|
35815
|
+
wrapperWidth,
|
|
35816
|
+
wrapperHeight,
|
|
35817
|
+
viewportWidth,
|
|
35818
|
+
viewportHeight,
|
|
35819
|
+
horizontalScrollbarHeight,
|
|
35820
|
+
verticalScrollbarWidth,
|
|
35821
|
+
avgRowHeight,
|
|
35822
|
+
avgColumnWidth,
|
|
35823
|
+
rowHandles,
|
|
35824
|
+
columnHandles
|
|
35825
|
+
};
|
|
35826
|
+
}
|
|
35827
|
+
|
|
34947
35828
|
// src/components/UEditor/table-hover-state.ts
|
|
34948
35829
|
var MENU_HOVER_PADDING = 18;
|
|
34949
35830
|
var ROW_HANDLE_HOVER_WIDTH = 28;
|
|
@@ -34977,18 +35858,18 @@ function buildTableHoverState({
|
|
|
34977
35858
|
const directAddRow = targetElement?.closest?.("[data-table-control='add-row']");
|
|
34978
35859
|
const directRowHandleIndex = directRowHandle instanceof HTMLElement ? Number.parseInt(directRowHandle.dataset.rowHandleIndex ?? "", 10) : Number.NaN;
|
|
34979
35860
|
const directColumnHandleIndex = directColumnHandle instanceof HTMLElement ? Number.parseInt(directColumnHandle.dataset.columnHandleIndex ?? "", 10) : Number.NaN;
|
|
34980
|
-
const
|
|
34981
|
-
const
|
|
35861
|
+
const visibleBounds = getVisibleTableBounds(layout);
|
|
35862
|
+
const rowRailTop = layout.wrapperTop + layout.wrapperHeight;
|
|
34982
35863
|
const isMouseInTable = relativeX >= layout.tableLeft && relativeX <= layout.tableLeft + layout.tableWidth && relativeY >= layout.tableTop && relativeY <= layout.tableTop + layout.tableHeight;
|
|
34983
35864
|
const rowHandleIndex = Number.isFinite(directRowHandleIndex) ? directRowHandleIndex : layout.rowHandles.find((rowHandle) => relativeX >= layout.tableLeft - ROW_HANDLE_HOVER_WIDTH && relativeX <= layout.tableLeft && Math.abs(relativeY - rowHandle.center) <= HANDLE_HOVER_RADIUS)?.index ?? null;
|
|
34984
35865
|
const columnHandleIndex = Number.isFinite(directColumnHandleIndex) ? directColumnHandleIndex : layout.columnHandles.find((columnHandle) => relativeY >= layout.tableTop - COLUMN_HANDLE_HOVER_HEIGHT && relativeY <= layout.tableTop && Math.abs(relativeX - columnHandle.center) <= HANDLE_HOVER_RADIUS)?.index ?? null;
|
|
34985
35866
|
const menuVisible = Boolean(directTableMenu) || isMouseInTable || relativeX >= layout.tableLeft - MENU_HOVER_PADDING && relativeX <= layout.tableLeft + 42 && relativeY >= layout.tableTop - COLUMN_HANDLE_HOVER_HEIGHT && relativeY <= layout.tableTop + MENU_HOVER_PADDING;
|
|
34986
35867
|
const lastRow = layout.rowHandles[layout.rowHandles.length - 1];
|
|
34987
35868
|
const lastCol = layout.columnHandles[layout.columnHandles.length - 1];
|
|
34988
|
-
const isMouseInLastColumn = lastCol ? relativeX >= lastCol.start && relativeX <= lastCol.start + lastCol.size && relativeY >=
|
|
34989
|
-
const addColumnVisible = Boolean(directAddColumn) || relativeX >=
|
|
34990
|
-
const isMouseInLastRow = lastRow ? relativeY >= lastRow.start && relativeY <= lastRow.start + lastRow.size && relativeX >=
|
|
34991
|
-
const addRowVisible = Boolean(directAddRow) || relativeY >=
|
|
35869
|
+
const isMouseInLastColumn = lastCol ? relativeX >= lastCol.start && relativeX <= lastCol.start + lastCol.size && relativeY >= visibleBounds.top && relativeY <= visibleBounds.bottom : false;
|
|
35870
|
+
const addColumnVisible = Boolean(directAddColumn) || relativeX >= visibleBounds.right && relativeX <= visibleBounds.right + ADD_COLUMN_HOVER_WIDTH && relativeY >= visibleBounds.top && relativeY <= visibleBounds.bottom || isMouseInLastColumn;
|
|
35871
|
+
const isMouseInLastRow = lastRow ? relativeY >= lastRow.start && relativeY <= lastRow.start + lastRow.size && relativeX >= visibleBounds.left && relativeX <= visibleBounds.right : false;
|
|
35872
|
+
const addRowVisible = Boolean(directAddRow) || relativeY >= rowRailTop && relativeY <= rowRailTop + ADD_ROW_HOVER_HEIGHT && relativeX >= visibleBounds.left && relativeX <= visibleBounds.right || isMouseInLastRow;
|
|
34992
35873
|
return {
|
|
34993
35874
|
menuVisible,
|
|
34994
35875
|
addColumnVisible,
|
|
@@ -35110,12 +35991,11 @@ function TableAddRails({
|
|
|
35110
35991
|
quickAddColumnLabel,
|
|
35111
35992
|
quickAddRowLabel
|
|
35112
35993
|
}) {
|
|
35113
|
-
const
|
|
35114
|
-
const
|
|
35115
|
-
const
|
|
35116
|
-
const columnRailLeft = layout.tableLeft + visibleTableWidth + ADD_COLUMN_RAIL_GAP;
|
|
35994
|
+
const visibleBounds = getVisibleTableBounds(layout);
|
|
35995
|
+
const columnRailTop = visibleBounds.top;
|
|
35996
|
+
const columnRailLeft = visibleBounds.right + ADD_COLUMN_RAIL_GAP;
|
|
35117
35997
|
const rowRailTop = layout.wrapperTop + layout.wrapperHeight + ADD_ROW_RAIL_GAP;
|
|
35118
|
-
const rowRailLeft =
|
|
35998
|
+
const rowRailLeft = visibleBounds.left;
|
|
35119
35999
|
const showColumnRail = controlsVisible || addColumnVisible;
|
|
35120
36000
|
const showRowRail = controlsVisible || addRowVisible;
|
|
35121
36001
|
return /* @__PURE__ */ jsxs75(Fragment32, { children: [
|
|
@@ -35143,10 +36023,10 @@ function TableAddRails({
|
|
|
35143
36023
|
"transition-[opacity,transform,colors] duration-150 hover:bg-accent hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed"
|
|
35144
36024
|
),
|
|
35145
36025
|
style: {
|
|
35146
|
-
top: showColumnRail ? columnRailTop : columnRailTop + Math.max(0,
|
|
36026
|
+
top: showColumnRail ? columnRailTop : columnRailTop + Math.max(0, visibleBounds.height / 2 - 24),
|
|
35147
36027
|
left: columnRailLeft,
|
|
35148
36028
|
width: showColumnRail ? 18 : 12,
|
|
35149
|
-
height: showColumnRail ?
|
|
36029
|
+
height: showColumnRail ? visibleBounds.height : 48,
|
|
35150
36030
|
opacity: showColumnRail ? 1 : 0,
|
|
35151
36031
|
transform: showColumnRail ? "scale(1)" : "scale(0.92)",
|
|
35152
36032
|
pointerEvents: showColumnRail ? "auto" : "none"
|
|
@@ -35181,8 +36061,8 @@ function TableAddRails({
|
|
|
35181
36061
|
),
|
|
35182
36062
|
style: {
|
|
35183
36063
|
top: rowRailTop,
|
|
35184
|
-
left: showRowRail ? rowRailLeft : rowRailLeft + Math.max(0,
|
|
35185
|
-
width: showRowRail ?
|
|
36064
|
+
left: showRowRail ? rowRailLeft : rowRailLeft + Math.max(0, visibleBounds.width / 2 - 24),
|
|
36065
|
+
width: showRowRail ? visibleBounds.width : 48,
|
|
35186
36066
|
height: showRowRail ? 16 : 12,
|
|
35187
36067
|
opacity: showRowRail ? 1 : 0,
|
|
35188
36068
|
transform: showRowRail ? "scale(1)" : "scale(0.92)",
|
|
@@ -35407,248 +36287,6 @@ function TableColumnHandles({
|
|
|
35407
36287
|
}) });
|
|
35408
36288
|
}
|
|
35409
36289
|
|
|
35410
|
-
// src/components/UEditor/table-layout-model.ts
|
|
35411
|
-
var FALLBACK_TABLE_ROW_HEIGHT = 44;
|
|
35412
|
-
var FALLBACK_TABLE_COLUMN_WIDTH = 160;
|
|
35413
|
-
function metricOrFallback(value, fallback) {
|
|
35414
|
-
return Number.isFinite(value) && value > 0 ? value : fallback;
|
|
35415
|
-
}
|
|
35416
|
-
function parsePixelMetric(value) {
|
|
35417
|
-
if (!value) return null;
|
|
35418
|
-
const parsed = Number.parseFloat(value);
|
|
35419
|
-
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
|
|
35420
|
-
}
|
|
35421
|
-
function getPrimaryCell(table) {
|
|
35422
|
-
const cell = table.querySelector("th,td");
|
|
35423
|
-
return cell instanceof HTMLTableCellElement ? cell : null;
|
|
35424
|
-
}
|
|
35425
|
-
function getLastCell(table) {
|
|
35426
|
-
const lastRow = table.rows.item(table.rows.length - 1);
|
|
35427
|
-
if (!(lastRow instanceof HTMLTableRowElement)) return null;
|
|
35428
|
-
const cell = lastRow.cells.item(lastRow.cells.length - 1);
|
|
35429
|
-
return cell instanceof HTMLTableCellElement ? cell : null;
|
|
35430
|
-
}
|
|
35431
|
-
function getCellFromTarget(target) {
|
|
35432
|
-
const element = resolveEventElement(target);
|
|
35433
|
-
if (!element) return null;
|
|
35434
|
-
const directCell = element.closest("th,td");
|
|
35435
|
-
if (directCell instanceof HTMLTableCellElement) {
|
|
35436
|
-
return directCell;
|
|
35437
|
-
}
|
|
35438
|
-
const table = element.closest("table");
|
|
35439
|
-
if (table instanceof HTMLTableElement) {
|
|
35440
|
-
return getPrimaryCell(table);
|
|
35441
|
-
}
|
|
35442
|
-
return null;
|
|
35443
|
-
}
|
|
35444
|
-
function findTableInfo(editor, pos) {
|
|
35445
|
-
const $pos = editor.state.doc.resolve(pos);
|
|
35446
|
-
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
35447
|
-
const node = $pos.node(depth);
|
|
35448
|
-
if (node.type.name === "table") {
|
|
35449
|
-
return {
|
|
35450
|
-
node,
|
|
35451
|
-
pos: $pos.before(depth),
|
|
35452
|
-
start: $pos.start(depth)
|
|
35453
|
-
};
|
|
35454
|
-
}
|
|
35455
|
-
}
|
|
35456
|
-
return null;
|
|
35457
|
-
}
|
|
35458
|
-
function getCellRelativePosFromDomPos(map, tableStart, domPos) {
|
|
35459
|
-
const relativeDomPos = domPos - tableStart;
|
|
35460
|
-
const seen = /* @__PURE__ */ new Set();
|
|
35461
|
-
for (const relativeCellPos of map.map) {
|
|
35462
|
-
if (seen.has(relativeCellPos)) continue;
|
|
35463
|
-
seen.add(relativeCellPos);
|
|
35464
|
-
if (relativeDomPos === relativeCellPos || relativeDomPos === relativeCellPos + 1) {
|
|
35465
|
-
return relativeCellPos;
|
|
35466
|
-
}
|
|
35467
|
-
}
|
|
35468
|
-
return null;
|
|
35469
|
-
}
|
|
35470
|
-
function buildLogicalColumnMetrics({
|
|
35471
|
-
editor,
|
|
35472
|
-
surface,
|
|
35473
|
-
surfaceRect,
|
|
35474
|
-
tableElement,
|
|
35475
|
-
tableInfo,
|
|
35476
|
-
tableLeft,
|
|
35477
|
-
tableWidth
|
|
35478
|
-
}) {
|
|
35479
|
-
const map = TableMap2.get(tableInfo.node);
|
|
35480
|
-
const fallbackWidth = metricOrFallback(tableWidth / map.width, FALLBACK_TABLE_COLUMN_WIDTH);
|
|
35481
|
-
const firstRow = tableElement.rows.item(0);
|
|
35482
|
-
const visualColumns = [];
|
|
35483
|
-
if (firstRow) {
|
|
35484
|
-
for (const tableCell of Array.from(firstRow.cells)) {
|
|
35485
|
-
if (!(tableCell instanceof HTMLTableCellElement)) continue;
|
|
35486
|
-
const cellPos = editor.view.posAtDOM(tableCell, 0);
|
|
35487
|
-
const relativeCellPos = getCellRelativePosFromDomPos(map, tableInfo.start, cellPos);
|
|
35488
|
-
if (relativeCellPos == null) continue;
|
|
35489
|
-
const cellMapRect = map.findCell(relativeCellPos);
|
|
35490
|
-
const cellRect = tableCell.getBoundingClientRect();
|
|
35491
|
-
const cellStart = cellRect.width > 0 ? cellRect.left - surfaceRect.left + surface.scrollLeft : tableLeft + cellMapRect.left * fallbackWidth;
|
|
35492
|
-
const size = metricOrFallback(cellRect.width, fallbackWidth * Math.max(1, cellMapRect.right - cellMapRect.left));
|
|
35493
|
-
visualColumns.push({
|
|
35494
|
-
index: cellMapRect.left,
|
|
35495
|
-
cellPos: tableInfo.start + relativeCellPos,
|
|
35496
|
-
start: cellStart,
|
|
35497
|
-
size,
|
|
35498
|
-
center: cellStart + size / 2
|
|
35499
|
-
});
|
|
35500
|
-
}
|
|
35501
|
-
}
|
|
35502
|
-
if (visualColumns.length > 0) {
|
|
35503
|
-
return visualColumns.sort((a, b) => a.index - b.index);
|
|
35504
|
-
}
|
|
35505
|
-
const cols = Array.from(tableElement.querySelectorAll("colgroup > col"));
|
|
35506
|
-
const parsedWidths = cols.slice(0, map.width).map((col) => parsePixelMetric(col.style.width) ?? parsePixelMetric(col.getAttribute("width")));
|
|
35507
|
-
const hasCompleteColWidths = parsedWidths.length >= map.width && parsedWidths.every((width) => typeof width === "number");
|
|
35508
|
-
let cursor = tableLeft;
|
|
35509
|
-
return Array.from({ length: map.width }, (_, index) => {
|
|
35510
|
-
const size = hasCompleteColWidths ? parsedWidths[index] : fallbackWidth;
|
|
35511
|
-
const start = hasCompleteColWidths ? cursor : tableLeft + index * fallbackWidth;
|
|
35512
|
-
cursor += size;
|
|
35513
|
-
return {
|
|
35514
|
-
index,
|
|
35515
|
-
cellPos: tableInfo.start + map.positionAt(0, index, tableInfo.node),
|
|
35516
|
-
start,
|
|
35517
|
-
size,
|
|
35518
|
-
center: start + size / 2
|
|
35519
|
-
};
|
|
35520
|
-
});
|
|
35521
|
-
}
|
|
35522
|
-
function buildLogicalRowMetrics({
|
|
35523
|
-
editor,
|
|
35524
|
-
surface,
|
|
35525
|
-
surfaceRect,
|
|
35526
|
-
tableInfo,
|
|
35527
|
-
rows,
|
|
35528
|
-
tableTop,
|
|
35529
|
-
tableHeight,
|
|
35530
|
-
cornerCell
|
|
35531
|
-
}) {
|
|
35532
|
-
const map = TableMap2.get(tableInfo.node);
|
|
35533
|
-
const fallbackHeight = metricOrFallback(tableHeight / map.height, FALLBACK_TABLE_ROW_HEIGHT);
|
|
35534
|
-
const visualRows = [];
|
|
35535
|
-
const seenCellPositions = /* @__PURE__ */ new Set();
|
|
35536
|
-
for (let rowIndex = 0; rowIndex < map.height; rowIndex += 1) {
|
|
35537
|
-
const relativeCellPos = map.map[rowIndex * map.width];
|
|
35538
|
-
if (seenCellPositions.has(relativeCellPos)) continue;
|
|
35539
|
-
seenCellPositions.add(relativeCellPos);
|
|
35540
|
-
const cellMapRect = map.findCell(relativeCellPos);
|
|
35541
|
-
const cellDom = editor.view.nodeDOM(tableInfo.start + relativeCellPos);
|
|
35542
|
-
const tableCell = cellDom instanceof HTMLTableCellElement ? cellDom : null;
|
|
35543
|
-
if (tableCell) {
|
|
35544
|
-
const cellRect = tableCell.getBoundingClientRect();
|
|
35545
|
-
const start = cellRect.height > 0 ? cellRect.top - surfaceRect.top + surface.scrollTop : tableTop + cellMapRect.top * fallbackHeight;
|
|
35546
|
-
const size = metricOrFallback(cellRect.height, fallbackHeight * Math.max(1, cellMapRect.bottom - cellMapRect.top));
|
|
35547
|
-
visualRows.push({
|
|
35548
|
-
index: cellMapRect.top,
|
|
35549
|
-
cellPos: tableInfo.start + relativeCellPos,
|
|
35550
|
-
start,
|
|
35551
|
-
size,
|
|
35552
|
-
center: start + size / 2
|
|
35553
|
-
});
|
|
35554
|
-
}
|
|
35555
|
-
}
|
|
35556
|
-
if (visualRows.length > 0) {
|
|
35557
|
-
return visualRows.sort((a, b) => a.index - b.index);
|
|
35558
|
-
}
|
|
35559
|
-
return rows.map((tableRow, index) => {
|
|
35560
|
-
const rowRect = tableRow.getBoundingClientRect();
|
|
35561
|
-
const anchorCell = tableRow.cells.item(0) ?? cornerCell;
|
|
35562
|
-
const start = rowRect.height > 0 ? rowRect.top - surfaceRect.top + surface.scrollTop : tableTop + index * fallbackHeight;
|
|
35563
|
-
const size = metricOrFallback(rowRect.height, fallbackHeight);
|
|
35564
|
-
return {
|
|
35565
|
-
index,
|
|
35566
|
-
cellPos: editor.view.posAtDOM(anchorCell, 0),
|
|
35567
|
-
start,
|
|
35568
|
-
size,
|
|
35569
|
-
center: start + size / 2
|
|
35570
|
-
};
|
|
35571
|
-
});
|
|
35572
|
-
}
|
|
35573
|
-
function buildTableControlLayout(editor, surface, cell) {
|
|
35574
|
-
const row = cell.closest("tr");
|
|
35575
|
-
const table = cell.closest("table");
|
|
35576
|
-
if (!(row instanceof HTMLTableRowElement) || !(table instanceof HTMLTableElement)) {
|
|
35577
|
-
return null;
|
|
35578
|
-
}
|
|
35579
|
-
const rows = Array.from(table.rows).filter((item) => item instanceof HTMLTableRowElement);
|
|
35580
|
-
const cornerCell = getLastCell(table);
|
|
35581
|
-
const cellPos = editor.view.posAtDOM(cell, 0);
|
|
35582
|
-
const tableInfo = findTableInfo(editor, cellPos);
|
|
35583
|
-
if (rows.length === 0 || !tableInfo || !(cornerCell instanceof HTMLTableCellElement)) {
|
|
35584
|
-
return null;
|
|
35585
|
-
}
|
|
35586
|
-
const map = TableMap2.get(tableInfo.node);
|
|
35587
|
-
const surfaceRect = surface.getBoundingClientRect();
|
|
35588
|
-
const tableRect = table.getBoundingClientRect();
|
|
35589
|
-
const wrapperElement = table.closest(".tableWrapper");
|
|
35590
|
-
const wrapper = wrapperElement instanceof HTMLElement ? wrapperElement : null;
|
|
35591
|
-
const wrapperRect = wrapper?.getBoundingClientRect() ?? tableRect;
|
|
35592
|
-
const tableLeft = tableRect.left - surfaceRect.left + surface.scrollLeft;
|
|
35593
|
-
const tableTop = tableRect.top - surfaceRect.top + surface.scrollTop;
|
|
35594
|
-
const avgRowHeight = metricOrFallback(tableRect.height / rows.length, FALLBACK_TABLE_ROW_HEIGHT);
|
|
35595
|
-
const avgColumnWidth = metricOrFallback(tableRect.width / map.width, FALLBACK_TABLE_COLUMN_WIDTH);
|
|
35596
|
-
const tableWidth = metricOrFallback(tableRect.width, avgColumnWidth * map.width);
|
|
35597
|
-
const tableHeight = metricOrFallback(tableRect.height, avgRowHeight * rows.length);
|
|
35598
|
-
const wrapperLeft = wrapperRect.left - surfaceRect.left + surface.scrollLeft;
|
|
35599
|
-
const wrapperTop = wrapperRect.top - surfaceRect.top + surface.scrollTop;
|
|
35600
|
-
const wrapperWidth = metricOrFallback(wrapperRect.width, tableWidth);
|
|
35601
|
-
const wrapperHeight = metricOrFallback(wrapperRect.height, tableHeight);
|
|
35602
|
-
const viewportWidth = metricOrFallback(wrapper?.clientWidth ?? wrapperRect.width, tableWidth);
|
|
35603
|
-
const viewportHeight = metricOrFallback(wrapper?.clientHeight ?? wrapperRect.height, tableHeight);
|
|
35604
|
-
const verticalScrollbarWidth = Math.max(0, Math.round(wrapperWidth - viewportWidth));
|
|
35605
|
-
const horizontalScrollbarHeight = Math.max(0, Math.round(wrapperHeight - viewportHeight));
|
|
35606
|
-
const rowHandles = buildLogicalRowMetrics({
|
|
35607
|
-
editor,
|
|
35608
|
-
surface,
|
|
35609
|
-
surfaceRect,
|
|
35610
|
-
tableInfo,
|
|
35611
|
-
rows,
|
|
35612
|
-
tableTop,
|
|
35613
|
-
tableHeight,
|
|
35614
|
-
cornerCell
|
|
35615
|
-
});
|
|
35616
|
-
const columnHandles = buildLogicalColumnMetrics({
|
|
35617
|
-
editor,
|
|
35618
|
-
surface,
|
|
35619
|
-
surfaceRect,
|
|
35620
|
-
tableElement: table,
|
|
35621
|
-
tableInfo,
|
|
35622
|
-
tableLeft,
|
|
35623
|
-
tableWidth
|
|
35624
|
-
});
|
|
35625
|
-
const activeCellRelativePos = getCellRelativePosFromDomPos(map, tableInfo.start, cellPos);
|
|
35626
|
-
const activeCellRect = activeCellRelativePos != null ? map.findCell(activeCellRelativePos) : { left: cell.cellIndex, top: row.rowIndex };
|
|
35627
|
-
const normalizedCellPos = activeCellRelativePos != null ? tableInfo.start + activeCellRelativePos : cellPos;
|
|
35628
|
-
return {
|
|
35629
|
-
cellPos: normalizedCellPos,
|
|
35630
|
-
cornerCellPos: tableInfo.start + map.positionAt(map.height - 1, map.width - 1, tableInfo.node),
|
|
35631
|
-
activeRowIndex: activeCellRect.top,
|
|
35632
|
-
activeColumnIndex: activeCellRect.left,
|
|
35633
|
-
tableLeft,
|
|
35634
|
-
tableTop,
|
|
35635
|
-
tableWidth,
|
|
35636
|
-
tableHeight,
|
|
35637
|
-
wrapperLeft,
|
|
35638
|
-
wrapperTop,
|
|
35639
|
-
wrapperWidth,
|
|
35640
|
-
wrapperHeight,
|
|
35641
|
-
viewportWidth,
|
|
35642
|
-
viewportHeight,
|
|
35643
|
-
horizontalScrollbarHeight,
|
|
35644
|
-
verticalScrollbarWidth,
|
|
35645
|
-
avgRowHeight,
|
|
35646
|
-
avgColumnWidth,
|
|
35647
|
-
rowHandles,
|
|
35648
|
-
columnHandles
|
|
35649
|
-
};
|
|
35650
|
-
}
|
|
35651
|
-
|
|
35652
36290
|
// src/components/UEditor/table-controls.tsx
|
|
35653
36291
|
import { Fragment as Fragment34, jsx as jsx91, jsxs as jsxs76 } from "react/jsx-runtime";
|
|
35654
36292
|
var TABLE_MENU_TOP_OFFSET = 10;
|