@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/dist/index.js CHANGED
@@ -28861,6 +28861,20 @@ function createEmptyCellNode(cellNode) {
28861
28861
  function createCellCopyForColumnDuplicate(cellNode) {
28862
28862
  return cellNode.type.create(cellNode.attrs, cellNode.content);
28863
28863
  }
28864
+ function createCellWithDuplicatedLogicalColumn(cellNode, widthIndex) {
28865
+ const colspan = Math.max(1, Number(cellNode.attrs.colspan) || 1);
28866
+ let nextColwidth = null;
28867
+ if (Array.isArray(cellNode.attrs.colwidth)) {
28868
+ nextColwidth = [...cellNode.attrs.colwidth];
28869
+ const duplicateWidth = nextColwidth[widthIndex];
28870
+ nextColwidth.splice(widthIndex + 1, 0, typeof duplicateWidth === "number" ? duplicateWidth : 0);
28871
+ }
28872
+ return cellNode.type.create({
28873
+ ...cellNode.attrs,
28874
+ colspan: colspan + 1,
28875
+ ...nextColwidth ? { colwidth: nextColwidth } : null
28876
+ }, cellNode.content);
28877
+ }
28864
28878
  function getTableRows(tableNode) {
28865
28879
  const rows = [];
28866
28880
  tableNode.forEach((rowNode, rowOffset) => {
@@ -29036,6 +29050,11 @@ function duplicateTableColumnAt(editor, columnIndex, cellPos) {
29036
29050
  return rect && rect.top === rowIndex && rect.left <= columnIndex && columnIndex < rect.right;
29037
29051
  });
29038
29052
  if (!sourceCell) return rowInfo.node;
29053
+ const sourceRect = safeFindCell(map, sourceCell.relativePos);
29054
+ if (sourceRect && (sourceRect.left < columnIndex || sourceRect.right > columnIndex + 1)) {
29055
+ cells[sourceCell.index] = createCellWithDuplicatedLogicalColumn(sourceCell.node, columnIndex - sourceRect.left);
29056
+ return rowInfo.node.type.create(rowInfo.node.attrs, cells);
29057
+ }
29039
29058
  cells.splice(sourceCell.index + 1, 0, createCellCopyForColumnDuplicate(sourceCell.node));
29040
29059
  return rowInfo.node.type.create(rowInfo.node.attrs, cells);
29041
29060
  });
@@ -30357,6 +30376,25 @@ function getTableFormulaRecalculationOrder(graph) {
30357
30376
  }
30358
30377
  return { order, circular };
30359
30378
  }
30379
+ function getAffectedTableFormulaLabels(graph, changedLabels) {
30380
+ const affected = /* @__PURE__ */ new Set();
30381
+ const queue = Array.from(changedLabels, (label) => label.toUpperCase());
30382
+ for (const label of queue) {
30383
+ if (graph.formulas.has(label)) {
30384
+ affected.add(label);
30385
+ }
30386
+ }
30387
+ for (let index = 0; index < queue.length; index += 1) {
30388
+ const label = queue[index];
30389
+ if (!label) continue;
30390
+ for (const dependent of graph.dependents.get(label) ?? []) {
30391
+ if (affected.has(dependent)) continue;
30392
+ affected.add(dependent);
30393
+ queue.push(dependent);
30394
+ }
30395
+ }
30396
+ return affected;
30397
+ }
30360
30398
  function evaluateBasicTableFormula(formula, getCellValue) {
30361
30399
  const normalized = normalizeTableFormula(formula);
30362
30400
  if (!normalized) {
@@ -30504,10 +30542,19 @@ var FormulaParser = class {
30504
30542
  const range = parseTableCellRange(token.value);
30505
30543
  if (!range) return { value: null, error: "invalid-reference" };
30506
30544
  for (const label of getTableCellRangeLabels(range)) {
30545
+ if (name === "COUNT") {
30546
+ const cellValue2 = this.readOptionalCellNumber(label);
30547
+ if (cellValue2 != null) values.push(cellValue2);
30548
+ continue;
30549
+ }
30507
30550
  const cellValue = this.readCellNumber(label);
30508
30551
  if (cellValue.error) return cellValue;
30509
30552
  values.push(cellValue.value);
30510
30553
  }
30554
+ } else if (name === "COUNT" && token.type === "cell") {
30555
+ this.index += 1;
30556
+ const cellValue = this.readOptionalCellNumber(token.value);
30557
+ if (cellValue != null) values.push(cellValue);
30511
30558
  } else {
30512
30559
  const value = this.parseExpression();
30513
30560
  if (value.error) return value;
@@ -30521,7 +30568,7 @@ var FormulaParser = class {
30521
30568
  }
30522
30569
  return { value: null, error: "invalid-formula" };
30523
30570
  }
30524
- if (values.length === 0) {
30571
+ if (values.length === 0 && name !== "COUNT") {
30525
30572
  return { value: null, error: "invalid-formula" };
30526
30573
  }
30527
30574
  if (name === "SUM") return { value: values.reduce((sum, value) => sum + value, 0), error: null };
@@ -30539,6 +30586,11 @@ var FormulaParser = class {
30539
30586
  }
30540
30587
  return { value: parsed, error: null };
30541
30588
  }
30589
+ readOptionalCellNumber(label) {
30590
+ const value = this.getCellValue(label);
30591
+ const parsed = typeof value === "number" ? value : Number.parseFloat(String(value ?? "").trim());
30592
+ return Number.isFinite(parsed) ? parsed : null;
30593
+ }
30542
30594
  peekOperator(operators) {
30543
30595
  const token = this.tokens[this.index];
30544
30596
  return token?.type === "operator" && operators.includes(token.value) ? token : null;
@@ -30602,6 +30654,41 @@ function getSelectionTableCellNode(editor) {
30602
30654
  }
30603
30655
  return null;
30604
30656
  }
30657
+ function getSelectionTableInfo(editor) {
30658
+ const { $from } = editor.state.selection;
30659
+ for (let depth = $from.depth; depth > 0; depth -= 1) {
30660
+ const node = $from.node(depth);
30661
+ if (node.type.name === "table") {
30662
+ return {
30663
+ node,
30664
+ pos: $from.before(depth)
30665
+ };
30666
+ }
30667
+ }
30668
+ return null;
30669
+ }
30670
+ function getSelectionTableCellLabel(editor) {
30671
+ const { $from } = editor.state.selection;
30672
+ let cellDepth = -1;
30673
+ let tableDepth = -1;
30674
+ for (let depth = $from.depth; depth > 0; depth -= 1) {
30675
+ const node = $from.node(depth);
30676
+ if (cellDepth < 0 && (node.type.name === "tableCell" || node.type.name === "tableHeader")) {
30677
+ cellDepth = depth;
30678
+ }
30679
+ if (node.type.name === "table") {
30680
+ tableDepth = depth;
30681
+ break;
30682
+ }
30683
+ }
30684
+ if (cellDepth < 0 || tableDepth < 0) return null;
30685
+ const tableNode = $from.node(tableDepth);
30686
+ const tableStart = $from.start(tableDepth);
30687
+ const relativeCellPos = $from.before(cellDepth) - tableStart;
30688
+ const rect = safeFindCell2(TableMap2.get(tableNode), relativeCellPos);
30689
+ if (!rect) return null;
30690
+ return `${indexToColumnName(rect.left)}${rect.top + 1}`;
30691
+ }
30605
30692
  function isEditingTableFormulaText(editor) {
30606
30693
  const cellNode = getSelectionTableCellNode(editor);
30607
30694
  return Boolean(cellNode && getCellText(cellNode).startsWith("="));
@@ -30613,20 +30700,6 @@ function createCellDisplayContent(cellNode, displayValue) {
30613
30700
  }
30614
30701
  return [paragraphType.create(null, cellNode.type.schema.text(displayValue))];
30615
30702
  }
30616
- function buildTableValueGetter(tableNode) {
30617
- const map = TableMap2.get(tableNode);
30618
- const values = /* @__PURE__ */ new Map();
30619
- for (const rowInfo of getTableRows2(tableNode)) {
30620
- for (const entry of rowInfo.cells) {
30621
- const rect = safeFindCell2(map, entry.relativePos);
30622
- if (!rect) continue;
30623
- const label = `${indexToColumnName(rect.left)}${rect.top + 1}`;
30624
- const computedValue = entry.node.attrs.computedValue;
30625
- values.set(label, typeof computedValue === "string" && computedValue.trim() ? computedValue : getCellText(entry.node));
30626
- }
30627
- }
30628
- return (label) => values.get(label.toUpperCase());
30629
- }
30630
30703
  function buildTableValueMap(tableNode) {
30631
30704
  const map = TableMap2.get(tableNode);
30632
30705
  const values = /* @__PURE__ */ new Map();
@@ -30641,10 +30714,6 @@ function buildTableValueMap(tableNode) {
30641
30714
  }
30642
30715
  return values;
30643
30716
  }
30644
- function getFormulaComputedValue(formula, tableNode) {
30645
- const result = evaluateBasicTableFormula(formula, buildTableValueGetter(tableNode));
30646
- return result.error ? `#${result.error.toUpperCase()}` : String(result.value);
30647
- }
30648
30717
  function normalizeFormulaInput(formula) {
30649
30718
  const trimmed = formula.trim();
30650
30719
  if (!trimmed) return "";
@@ -30655,19 +30724,19 @@ function setSelectedTableCellFormula(editor, formula) {
30655
30724
  const { state, view } = editor;
30656
30725
  if (!normalized) {
30657
30726
  const clearedFormula = setCellAttr("formula", null)(state, view.dispatch.bind(view));
30658
- const clearedValue = setCellAttr("computedValue", null)(editor.state, view.dispatch.bind(view));
30659
- if (clearedFormula || clearedValue) {
30727
+ const clearedValue2 = setCellAttr("computedValue", null)(editor.state, view.dispatch.bind(view));
30728
+ if (clearedFormula || clearedValue2) {
30729
+ recalculateActiveTableFormulas(editor);
30660
30730
  view.focus();
30661
30731
  dispatchTableLayoutChange(editor);
30662
30732
  return true;
30663
30733
  }
30664
30734
  return false;
30665
30735
  }
30666
- const rect = selectedRect2(state);
30667
- const computedValue = getFormulaComputedValue(normalized, rect.table);
30668
30736
  const appliedFormula = setCellAttr("formula", normalized)(state, view.dispatch.bind(view));
30669
- const appliedValue = setCellAttr("computedValue", computedValue)(editor.state, view.dispatch.bind(view));
30670
- if (appliedFormula || appliedValue) {
30737
+ const clearedValue = setCellAttr("computedValue", null)(editor.state, view.dispatch.bind(view));
30738
+ if (appliedFormula || clearedValue) {
30739
+ recalculateActiveTableFormulas(editor);
30671
30740
  view.focus();
30672
30741
  dispatchTableLayoutChange(editor);
30673
30742
  return true;
@@ -30749,7 +30818,7 @@ function promoteFormulaTextInTableNode(tableNode) {
30749
30818
  changed
30750
30819
  };
30751
30820
  }
30752
- function recalculateTableNode(tableNode) {
30821
+ function recalculateTableNode(tableNode, options) {
30753
30822
  const promoted = promoteFormulaTextInTableNode(tableNode);
30754
30823
  tableNode = promoted.tableNode;
30755
30824
  const map = TableMap2.get(tableNode);
@@ -30779,13 +30848,16 @@ function recalculateTableNode(tableNode) {
30779
30848
  }))
30780
30849
  );
30781
30850
  const { order, circular } = getTableFormulaRecalculationOrder(graph);
30851
+ const affectedLabels = options?.changedLabels ? getAffectedTableFormulaLabels(graph, options.changedLabels) : null;
30782
30852
  const computedValues = /* @__PURE__ */ new Map();
30783
30853
  const getCellValue = (label) => values.get(label.toUpperCase());
30784
30854
  for (const label of circular) {
30855
+ if (affectedLabels && !affectedLabels.has(label)) continue;
30785
30856
  computedValues.set(label, formatFormulaError("circular-reference"));
30786
30857
  values.set(label, formatFormulaError("circular-reference"));
30787
30858
  }
30788
30859
  for (const label of order) {
30860
+ if (affectedLabels && !affectedLabels.has(label)) continue;
30789
30861
  const entry = formulaEntries.get(label);
30790
30862
  if (!entry) continue;
30791
30863
  const result = evaluateBasicTableFormula(entry.formula, getCellValue);
@@ -30830,6 +30902,22 @@ function recalculateSelectedTable(editor) {
30830
30902
  dispatchTableLayoutChange(editor);
30831
30903
  return true;
30832
30904
  }
30905
+ function recalculateActiveTableFormulas(editor) {
30906
+ const tableInfo = getSelectionTableInfo(editor);
30907
+ if (!tableInfo) {
30908
+ return recalculateAllTableFormulas(editor);
30909
+ }
30910
+ const activeCellLabel = getSelectionTableCellLabel(editor);
30911
+ const nextTable = recalculateTableNode(tableInfo.node, {
30912
+ changedLabels: activeCellLabel ? [activeCellLabel] : null
30913
+ });
30914
+ if (!nextTable) return false;
30915
+ editor.view.dispatch(
30916
+ editor.state.tr.replaceWith(tableInfo.pos, tableInfo.pos + tableInfo.node.nodeSize, nextTable).setMeta(UEDITOR_TABLE_FORMULA_RECALCULATE_META, true)
30917
+ );
30918
+ dispatchTableLayoutChange(editor);
30919
+ return true;
30920
+ }
30833
30921
  function recalculateAllTableFormulas(editor) {
30834
30922
  const replacements = [];
30835
30923
  editor.state.doc.descendants((node, pos) => {
@@ -38865,6 +38953,146 @@ var MenuBar = ({
38865
38953
  ] });
38866
38954
  };
38867
38955
 
38956
+ // src/components/UEditor/table-formula-range-picker.ts
38957
+ import { TextSelection as TextSelection4 } from "@tiptap/pm/state";
38958
+ import { TableMap as TableMap4 } from "@tiptap/pm/tables";
38959
+ function getCellText2(cellNode) {
38960
+ return cellNode.textBetween(0, cellNode.content.size, "\n").trim();
38961
+ }
38962
+ function findSelectionFormulaCell(view) {
38963
+ const { $from } = view.state.selection;
38964
+ for (let depth = $from.depth; depth > 0; depth -= 1) {
38965
+ const node = $from.node(depth);
38966
+ if (node.type.name !== "tableCell" && node.type.name !== "tableHeader") continue;
38967
+ if (!getCellText2(node).startsWith("=")) return null;
38968
+ const cellPos = $from.before(depth);
38969
+ const cellDom = view.nodeDOM(cellPos);
38970
+ const tableDepth = depth - 2;
38971
+ const tableNode = tableDepth > 0 ? $from.node(tableDepth) : null;
38972
+ if (!tableNode || tableNode.type.name !== "table") return null;
38973
+ return {
38974
+ cellDom: cellDom instanceof HTMLTableCellElement ? cellDom : null,
38975
+ tablePos: $from.before(tableDepth)
38976
+ };
38977
+ }
38978
+ return null;
38979
+ }
38980
+ function findTableForPos(view, pos) {
38981
+ const $pos = view.state.doc.resolve(pos);
38982
+ for (let depth = $pos.depth; depth > 0; depth -= 1) {
38983
+ const node = $pos.node(depth);
38984
+ if (node.type.name === "table") {
38985
+ return {
38986
+ node,
38987
+ pos: $pos.before(depth),
38988
+ start: $pos.start(depth)
38989
+ };
38990
+ }
38991
+ }
38992
+ return null;
38993
+ }
38994
+ function getCellRelativePosFromDomPos2(map, tableStart, domPos) {
38995
+ const relativeDomPos = domPos - tableStart;
38996
+ const seen = /* @__PURE__ */ new Set();
38997
+ for (const relativeCellPos of map.map) {
38998
+ if (seen.has(relativeCellPos)) continue;
38999
+ seen.add(relativeCellPos);
39000
+ if (relativeDomPos === relativeCellPos || relativeDomPos === relativeCellPos + 1) {
39001
+ return relativeCellPos;
39002
+ }
39003
+ }
39004
+ return null;
39005
+ }
39006
+ function getPickedCellLabel(view, target, tablePos) {
39007
+ const element = resolveEventElement(target);
39008
+ const cell = element?.closest?.("th,td");
39009
+ if (!(cell instanceof HTMLTableCellElement)) return null;
39010
+ const domPos = view.posAtDOM(cell, 0);
39011
+ const tableInfo = findTableForPos(view, domPos);
39012
+ if (!tableInfo || tableInfo.pos !== tablePos) return null;
39013
+ const map = TableMap4.get(tableInfo.node);
39014
+ const relativeCellPos = getCellRelativePosFromDomPos2(map, tableInfo.start, domPos);
39015
+ if (relativeCellPos == null) return null;
39016
+ const rect = map.findCell(relativeCellPos);
39017
+ return {
39018
+ cell,
39019
+ label: `${indexToColumnName(rect.left)}${rect.top + 1}`
39020
+ };
39021
+ }
39022
+ function normalizeFormulaRangeLabel(fromLabel, toLabel) {
39023
+ return fromLabel === toLabel ? fromLabel : `${fromLabel}:${toLabel}`;
39024
+ }
39025
+ function replacePickedLabel(view, pickState, nextLabel, currentCell) {
39026
+ if (nextLabel === pickState.currentLabel && currentCell === pickState.currentCell) return pickState;
39027
+ if (nextLabel === pickState.currentLabel) {
39028
+ return {
39029
+ ...pickState,
39030
+ currentCell
39031
+ };
39032
+ }
39033
+ let tr = view.state.tr.insertText(nextLabel, pickState.insertedFrom, pickState.insertedTo);
39034
+ const nextTo = pickState.insertedFrom + nextLabel.length;
39035
+ tr = tr.setSelection(TextSelection4.create(tr.doc, nextTo));
39036
+ view.dispatch(tr);
39037
+ return {
39038
+ ...pickState,
39039
+ insertedTo: nextTo,
39040
+ currentLabel: nextLabel,
39041
+ currentCell
39042
+ };
39043
+ }
39044
+ function beginFormulaRangePick(view, event) {
39045
+ if (event.button !== 0) return null;
39046
+ const formulaCell = findSelectionFormulaCell(view);
39047
+ if (!formulaCell) return null;
39048
+ const picked = getPickedCellLabel(view, event.target, formulaCell.tablePos);
39049
+ if (!picked || picked.cell === formulaCell.cellDom) return null;
39050
+ const { from, to } = view.state.selection;
39051
+ let tr = view.state.tr.insertText(picked.label, from, to);
39052
+ tr = tr.setSelection(TextSelection4.create(tr.doc, from + picked.label.length));
39053
+ view.dispatch(tr);
39054
+ view.focus();
39055
+ event.preventDefault();
39056
+ event.stopPropagation();
39057
+ return {
39058
+ anchorLabel: picked.label,
39059
+ anchorCell: picked.cell,
39060
+ tablePos: formulaCell.tablePos,
39061
+ insertedFrom: from,
39062
+ insertedTo: from + picked.label.length,
39063
+ currentLabel: picked.label,
39064
+ currentCell: picked.cell
39065
+ };
39066
+ }
39067
+ function updateFormulaRangePick(view, pickState, event) {
39068
+ const picked = getPickedCellLabel(view, event.target, pickState.tablePos);
39069
+ if (!picked) return pickState;
39070
+ event.preventDefault();
39071
+ event.stopPropagation();
39072
+ return replacePickedLabel(
39073
+ view,
39074
+ pickState,
39075
+ normalizeFormulaRangeLabel(pickState.anchorLabel, picked.label),
39076
+ picked.cell
39077
+ );
39078
+ }
39079
+ function getFormulaRangePickHighlight(container, pickState) {
39080
+ if (!container.contains(pickState.anchorCell) || !container.contains(pickState.currentCell)) return null;
39081
+ const containerRect = container.getBoundingClientRect();
39082
+ const anchorRect = pickState.anchorCell.getBoundingClientRect();
39083
+ const currentRect = pickState.currentCell.getBoundingClientRect();
39084
+ const left = Math.min(anchorRect.left, currentRect.left) - containerRect.left + container.scrollLeft;
39085
+ const top = Math.min(anchorRect.top, currentRect.top) - containerRect.top + container.scrollTop;
39086
+ const right = Math.max(anchorRect.right, currentRect.right) - containerRect.left + container.scrollLeft;
39087
+ const bottom = Math.max(anchorRect.bottom, currentRect.bottom) - containerRect.top + container.scrollTop;
39088
+ return {
39089
+ left,
39090
+ top,
39091
+ width: Math.max(0, right - left),
39092
+ height: Math.max(0, bottom - top)
39093
+ };
39094
+ }
39095
+
38868
39096
  // src/components/UEditor/UEditor.tsx
38869
39097
  import { jsx as jsx94, jsxs as jsxs79 } from "react/jsx-runtime";
38870
39098
  var UEditor = React83.forwardRef(({
@@ -38909,6 +39137,9 @@ var UEditor = React83.forwardRef(({
38909
39137
  const inFlightPrepareRef = useRef37(null);
38910
39138
  const lastAppliedContentRef = useRef37(content ?? "");
38911
39139
  const scheduledFormulaRecalculateRef = useRef37(false);
39140
+ const formulaRangePickRef = useRef37(null);
39141
+ const formulaRangeSurfaceRef = useRef37(null);
39142
+ const [formulaRangeHighlight, setFormulaRangeHighlight] = React83.useState(null);
38912
39143
  const scheduleFormulaRecalculate = React83.useCallback((editor2, options) => {
38913
39144
  if (editor2.isDestroyed || scheduledFormulaRecalculateRef.current) return;
38914
39145
  if (!options?.force && isEditingTableFormulaText(editor2)) return;
@@ -38916,7 +39147,7 @@ var UEditor = React83.forwardRef(({
38916
39147
  queueMicrotask(() => {
38917
39148
  scheduledFormulaRecalculateRef.current = false;
38918
39149
  if (!editor2.isDestroyed && (options?.force || !isEditingTableFormulaText(editor2))) {
38919
- recalculateAllTableFormulas(editor2);
39150
+ recalculateActiveTableFormulas(editor2);
38920
39151
  }
38921
39152
  });
38922
39153
  }, []);
@@ -38949,6 +39180,10 @@ var UEditor = React83.forwardRef(({
38949
39180
  ],
38950
39181
  [effectivePlaceholder, t, maxCharacters, uploadImage, resolvedUploadFile, imageInsertMode, maxImageFileSize, allowedImageMimeTypes, fallbackToDataUrl, editable, fetchMetadata, extraExtensions]
38951
39182
  );
39183
+ const syncFormulaRangeHighlight = React83.useCallback((pickState) => {
39184
+ const container = formulaRangeSurfaceRef.current;
39185
+ setFormulaRangeHighlight(container && pickState ? getFormulaRangePickHighlight(container, pickState) : null);
39186
+ }, []);
38952
39187
  const editor = useEditor({
38953
39188
  immediatelyRender: false,
38954
39189
  extensions,
@@ -38957,6 +39192,37 @@ var UEditor = React83.forwardRef(({
38957
39192
  autofocus,
38958
39193
  editorProps: {
38959
39194
  handleDOMEvents: {
39195
+ mousedown: (view, event) => {
39196
+ if (!(event instanceof MouseEvent)) return false;
39197
+ const pickState = beginFormulaRangePick(view, event);
39198
+ if (!pickState) return false;
39199
+ formulaRangePickRef.current = pickState;
39200
+ syncFormulaRangeHighlight(pickState);
39201
+ return true;
39202
+ },
39203
+ mousemove: (view, event) => {
39204
+ if (!(event instanceof MouseEvent)) return false;
39205
+ const pickState = formulaRangePickRef.current;
39206
+ if (!pickState) return false;
39207
+ if (event.buttons === 0) {
39208
+ formulaRangePickRef.current = null;
39209
+ syncFormulaRangeHighlight(null);
39210
+ return false;
39211
+ }
39212
+ const nextPickState = updateFormulaRangePick(view, pickState, event);
39213
+ formulaRangePickRef.current = nextPickState;
39214
+ syncFormulaRangeHighlight(nextPickState);
39215
+ return true;
39216
+ },
39217
+ mouseup: (_view, event) => {
39218
+ if (!(event instanceof MouseEvent)) return false;
39219
+ if (!formulaRangePickRef.current) return false;
39220
+ formulaRangePickRef.current = null;
39221
+ syncFormulaRangeHighlight(null);
39222
+ event.preventDefault();
39223
+ event.stopPropagation();
39224
+ return true;
39225
+ },
38960
39226
  keydown: (_view, event) => {
38961
39227
  if (!(event instanceof KeyboardEvent)) return false;
38962
39228
  if (event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "ArrowUp" || event.key === "ArrowDown") {
@@ -39122,7 +39388,10 @@ var UEditor = React83.forwardRef(({
39122
39388
  /* @__PURE__ */ jsxs79(
39123
39389
  "div",
39124
39390
  {
39125
- ref: editorContentRef,
39391
+ ref: (node) => {
39392
+ editorContentRef.current = node;
39393
+ formulaRangeSurfaceRef.current = node;
39394
+ },
39126
39395
  className: "relative flex-1 overflow-y-auto",
39127
39396
  style: {
39128
39397
  minHeight: editable ? minHeight : void 0,
@@ -39154,6 +39423,20 @@ var UEditor = React83.forwardRef(({
39154
39423
  className: "pointer-events-none hidden absolute z-20 rounded-[2px] border-2 border-primary bg-primary/10"
39155
39424
  }
39156
39425
  ),
39426
+ formulaRangeHighlight && /* @__PURE__ */ jsx94(
39427
+ "span",
39428
+ {
39429
+ "aria-hidden": "true",
39430
+ "data-ueditor-formula-range-highlight": "",
39431
+ className: "pointer-events-none absolute z-20 rounded-[2px] border-2 border-primary bg-primary/10",
39432
+ style: {
39433
+ left: formulaRangeHighlight.left,
39434
+ top: formulaRangeHighlight.top,
39435
+ width: formulaRangeHighlight.width,
39436
+ height: formulaRangeHighlight.height
39437
+ }
39438
+ }
39439
+ ),
39157
39440
  editable && /* @__PURE__ */ jsx94(TableControls, { editor, containerRef: editorContentRef }),
39158
39441
  /* @__PURE__ */ jsx94(
39159
39442
  EditorContent,