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