@fileverse-dev/fortune-react 1.3.13-create-3 → 1.3.13-create-5

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.
Files changed (35) hide show
  1. package/es/components/FxEditor/index.js +73 -18
  2. package/es/components/SheetOverlay/ContentEditable.js +4 -3
  3. package/es/components/SheetOverlay/InputBox.js +193 -44
  4. package/es/components/SheetOverlay/drag_and_drop/column-helpers.js +4 -27
  5. package/es/components/SheetOverlay/drag_and_drop/row-helpers.js +4 -25
  6. package/es/components/SheetOverlay/formula-segment-boundary.js +1 -1
  7. package/es/components/SheetOverlay/helper.d.ts +7 -0
  8. package/es/components/SheetOverlay/helper.js +75 -0
  9. package/es/components/SheetOverlay/index.css +10 -83
  10. package/es/components/SheetOverlay/index.js +1 -26
  11. package/es/components/Toolbar/ColorPicker.js +3 -2
  12. package/es/components/Toolbar/CustomColor.js +7 -3
  13. package/es/components/Toolbar/index.js +11 -2
  14. package/es/hooks/useFormulaEditorHistory.d.ts +4 -4
  15. package/es/hooks/useFormulaEditorHistory.js +87 -59
  16. package/es/hooks/useRerenderOnFormulaCaret.d.ts +1 -1
  17. package/es/hooks/useRerenderOnFormulaCaret.js +6 -3
  18. package/lib/components/FxEditor/index.js +72 -17
  19. package/lib/components/SheetOverlay/ContentEditable.js +4 -3
  20. package/lib/components/SheetOverlay/InputBox.js +192 -43
  21. package/lib/components/SheetOverlay/drag_and_drop/column-helpers.js +3 -26
  22. package/lib/components/SheetOverlay/drag_and_drop/row-helpers.js +3 -24
  23. package/lib/components/SheetOverlay/formula-segment-boundary.js +1 -1
  24. package/lib/components/SheetOverlay/helper.d.ts +7 -0
  25. package/lib/components/SheetOverlay/helper.js +79 -0
  26. package/lib/components/SheetOverlay/index.css +10 -83
  27. package/lib/components/SheetOverlay/index.js +1 -26
  28. package/lib/components/Toolbar/ColorPicker.js +3 -2
  29. package/lib/components/Toolbar/CustomColor.js +7 -3
  30. package/lib/components/Toolbar/index.js +10 -1
  31. package/lib/hooks/useFormulaEditorHistory.d.ts +4 -4
  32. package/lib/hooks/useFormulaEditorHistory.js +85 -58
  33. package/lib/hooks/useRerenderOnFormulaCaret.d.ts +1 -1
  34. package/lib/hooks/useRerenderOnFormulaCaret.js +5 -2
  35. package/package.json +2 -2
@@ -9,14 +9,18 @@ exports.decrementColumn = decrementColumn;
9
9
  exports.decrementRow = decrementRow;
10
10
  exports.getCursorPosition = getCursorPosition;
11
11
  exports.getFunctionNameFromFormulaCaretSpans = getFunctionNameFromFormulaCaretSpans;
12
+ exports.getSelectionOffsets = getSelectionOffsets;
12
13
  exports.incrementColumn = incrementColumn;
13
14
  exports.incrementRow = incrementRow;
15
+ exports.isEditorUndoRedoKeyEvent = isEditorUndoRedoKeyEvent;
14
16
  exports.isLetterNumberPattern = isLetterNumberPattern;
15
17
  exports.moveCursorToEnd = moveCursorToEnd;
16
18
  exports.numberToColumn = numberToColumn;
17
19
  exports.removeLastSpan = removeLastSpan;
18
20
  exports.setCursorPosition = setCursorPosition;
21
+ exports.setSelectionOffsets = setSelectionOffsets;
19
22
  exports.shouldShowFormulaFunctionList = shouldShowFormulaFunctionList;
23
+ exports.shouldUseCustomEditorHistory = shouldUseCustomEditorHistory;
20
24
  function moveCursorToEnd(editableDiv) {
21
25
  editableDiv.focus();
22
26
  var range = document.createRange();
@@ -37,6 +41,44 @@ function getCursorPosition(editableDiv) {
37
41
  preRange.setEnd(range.endContainer, range.endOffset);
38
42
  return preRange.toString().length;
39
43
  }
44
+ function getSelectionOffsets(editableDiv) {
45
+ var selection = window.getSelection();
46
+ if (!selection || selection.rangeCount === 0) {
47
+ var caret = getCursorPosition(editableDiv);
48
+ return {
49
+ start: caret,
50
+ end: caret
51
+ };
52
+ }
53
+ var range = selection.getRangeAt(0);
54
+ if (!editableDiv.contains(range.startContainer) || !editableDiv.contains(range.endContainer)) {
55
+ var caret = getCursorPosition(editableDiv);
56
+ return {
57
+ start: caret,
58
+ end: caret
59
+ };
60
+ }
61
+ var startRange = range.cloneRange();
62
+ startRange.selectNodeContents(editableDiv);
63
+ startRange.setEnd(range.startContainer, range.startOffset);
64
+ var start = startRange.toString().length;
65
+ var endRange = range.cloneRange();
66
+ endRange.selectNodeContents(editableDiv);
67
+ endRange.setEnd(range.endContainer, range.endOffset);
68
+ var end = endRange.toString().length;
69
+ return {
70
+ start: Math.max(0, Math.min(start, end)),
71
+ end: Math.max(start, end)
72
+ };
73
+ }
74
+ function isEditorUndoRedoKeyEvent(e) {
75
+ if (!e.metaKey && !e.ctrlKey) return false;
76
+ if (e.code === "KeyZ" || e.code === "KeyY") return true;
77
+ return e.keyCode === 90 || e.keyCode === 89;
78
+ }
79
+ function shouldUseCustomEditorHistory(editorInnerTextTrimmed, historyActive) {
80
+ return historyActive || editorInnerTextTrimmed.length > 0;
81
+ }
40
82
  function setCursorPosition(editableDiv, targetOffset) {
41
83
  var _a, _b;
42
84
  editableDiv.focus();
@@ -63,6 +105,43 @@ function setCursorPosition(editableDiv, targetOffset) {
63
105
  selection.removeAllRanges();
64
106
  selection.addRange(range);
65
107
  }
108
+ function setSelectionOffsets(editableDiv, startOffset, endOffset) {
109
+ editableDiv.focus();
110
+ var selection = window.getSelection();
111
+ if (!selection) return;
112
+ var startTarget = Math.max(0, Math.min(startOffset, endOffset));
113
+ var endTarget = Math.max(startTarget, endOffset);
114
+ var walker = document.createTreeWalker(editableDiv, NodeFilter.SHOW_TEXT);
115
+ var resolve = function resolve(target) {
116
+ var _a, _b;
117
+ var remaining = target;
118
+ var node = walker.nextNode();
119
+ while (node) {
120
+ var len = (_b = (_a = node.textContent) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
121
+ if (remaining <= len) return {
122
+ node: node,
123
+ offset: remaining
124
+ };
125
+ remaining -= len;
126
+ node = walker.nextNode();
127
+ }
128
+ return null;
129
+ };
130
+ walker.currentNode = editableDiv;
131
+ var startPos = resolve(startTarget);
132
+ walker.currentNode = editableDiv;
133
+ var endPos = resolve(endTarget);
134
+ var range = document.createRange();
135
+ if (startPos && endPos) {
136
+ range.setStart(startPos.node, startPos.offset);
137
+ range.setEnd(endPos.node, endPos.offset);
138
+ } else {
139
+ range.selectNodeContents(editableDiv);
140
+ range.collapse(false);
141
+ }
142
+ selection.removeAllRanges();
143
+ selection.addRange(range);
144
+ }
66
145
  function buildFormulaSuggestionText(editableDiv, formulaName) {
67
146
  var fullText = editableDiv.innerText || "";
68
147
  var selection = window.getSelection();
@@ -145,12 +145,6 @@
145
145
  margin: 0px 0 0 0px;
146
146
  }
147
147
 
148
- .fortune-selection-copy .fortune-copy {
149
- position: absolute;
150
- z-index: 18;
151
- background-color: transparent;
152
- }
153
-
154
148
  .fortune-selection-copy-hc {
155
149
  position: absolute;
156
150
  top: 0;
@@ -330,7 +324,7 @@
330
324
  max-height: 9900px;
331
325
  max-width: 9900px;
332
326
  border: 2px #efc703 solid;
333
- padding: 0 2px;
327
+ padding: 2px 2px;
334
328
  margin: 0;
335
329
  resize: none;
336
330
  overflow: hidden;
@@ -363,6 +357,14 @@
363
357
  color: forestgreen;
364
358
  }
365
359
 
360
+ .luckysheet-formula-text-calc,
361
+ .luckysheet-formula-text-lpar,
362
+ .luckysheet-formula-text-comma,
363
+ .luckysheet-formula-text-rpar {
364
+ padding-left: 2px;
365
+ padding-right: 2px;
366
+ }
367
+
366
368
  .luckysheet-cell-flow {
367
369
  margin: 0;
368
370
  padding: 0;
@@ -647,50 +649,6 @@
647
649
  cursor: se-resize;
648
650
  }
649
651
 
650
- .fortune-selection-copy-top {
651
- left: 0;
652
- right: 0;
653
- height: 2px;
654
- top: 0;
655
- background-position: bottom;
656
- /* background-image: url("EwaAntH.gif"); */
657
- }
658
-
659
- .fortune-selection-copy-right {
660
- top: 0;
661
- bottom: 0;
662
- width: 2px;
663
- right: 0;
664
- /* background-image: url("EwaAntV.gif"); */
665
- }
666
-
667
- .fortune-selection-copy-bottom {
668
- left: 0;
669
- right: 0;
670
- height: 2px;
671
- bottom: 0;
672
- /* background-image: url("EwaAntH.gif"); */
673
- }
674
-
675
- .fortune-selection-copy-left {
676
- top: 0;
677
- bottom: 0;
678
- width: 2px;
679
- left: 0;
680
- background-position: right;
681
- /* background-image: url("EwaAntV.gif"); */
682
- }
683
-
684
- .fortune-selection-copy-hc {
685
- position: absolute;
686
- top: 0;
687
- right: 0;
688
- bottom: 0;
689
- left: 0;
690
- border: 2px dashed #12a5ff;
691
- z-index: 8;
692
- }
693
-
694
652
  .luckysheet-modal-dialog-resize {
695
653
  position: absolute;
696
654
  border: 2px solid #0188fb;
@@ -765,39 +723,8 @@
765
723
  cursor: se-resize;
766
724
  }
767
725
 
768
- .fortune-formula-functionrange-highlight .fortune-copy {
769
- background-image: none;
770
- background: #0188fb;
771
- position: absolute;
772
- z-index: 18;
726
+ .fortune-formula-functionrange-highlight {
773
727
  cursor: move;
774
- opacity: 0.9;
775
- box-sizing: content-box;
776
- /*border: 1px solid #fff;*/
777
- }
778
-
779
- .fortune-formula-functionrange-highlight .fortune-selection-copy-top {
780
- top: -2px;
781
- border-top: 2px solid #fff;
782
- border-bottom: 2px solid #fff;
783
- }
784
-
785
- .fortune-formula-functionrange-highlight .fortune-selection-copy-right {
786
- right: -2px;
787
- border-left: 2px solid #fff;
788
- border-right: 2px solid #fff;
789
- }
790
-
791
- .fortune-formula-functionrange-highlight .fortune-selection-copy-bottom {
792
- bottom: -2px;
793
- border-top: 2px solid #fff;
794
- border-bottom: 2px solid #fff;
795
- }
796
-
797
- .fortune-formula-functionrange-highlight .fortune-selection-copy-left {
798
- left: -2px;
799
- border-left: 2px solid #fff;
800
- border-right: 2px solid #fff;
801
728
  }
802
729
 
803
730
  .fortune-formula-functionrange-highlight .fortune-selection-copy-hc {
@@ -294,14 +294,6 @@ var SheetOverlay = function SheetOverlay() {
294
294
  className: "fortune-selection-copy fortune-formula-functionrange-select",
295
295
  style: context.formulaRangeSelect
296
296
  }, /*#__PURE__*/_react.default.createElement("div", {
297
- className: "fortune-selection-copy-top fortune-copy"
298
- }), /*#__PURE__*/_react.default.createElement("div", {
299
- className: "fortune-selection-copy-right fortune-copy"
300
- }), /*#__PURE__*/_react.default.createElement("div", {
301
- className: "fortune-selection-copy-bottom fortune-copy"
302
- }), /*#__PURE__*/_react.default.createElement("div", {
303
- className: "fortune-selection-copy-left fortune-copy"
304
- }), /*#__PURE__*/_react.default.createElement("div", {
305
297
  className: "fortune-selection-copy-hc"
306
298
  }))), context.formulaRangeHighlight.map(function (v) {
307
299
  var rangeIndex = v.rangeIndex,
@@ -311,16 +303,7 @@ var SheetOverlay = function SheetOverlay() {
311
303
  id: "fortune-formula-functionrange-highlight",
312
304
  className: "fortune-selection-highlight fortune-formula-functionrange-highlight",
313
305
  style: _lodash.default.omit(v, "backgroundColor")
314
- }, ["top", "right", "bottom", "left"].map(function (d) {
315
- return /*#__PURE__*/_react.default.createElement("div", {
316
- key: d,
317
- "data-type": d,
318
- className: "fortune-selection-copy-".concat(d, " fortune-copy"),
319
- style: {
320
- backgroundColor: backgroundColor
321
- }
322
- });
323
- }), /*#__PURE__*/_react.default.createElement("div", {
306
+ }, /*#__PURE__*/_react.default.createElement("div", {
324
307
  className: "fortune-selection-copy-hc",
325
308
  style: formulaRangeHighlightHcStyle(backgroundColor)
326
309
  }));
@@ -373,14 +356,6 @@ var SheetOverlay = function SheetOverlay() {
373
356
  height: row - row_pre - 1
374
357
  }
375
358
  }, /*#__PURE__*/_react.default.createElement("div", {
376
- className: "fortune-selection-copy-top fortune-copy"
377
- }), /*#__PURE__*/_react.default.createElement("div", {
378
- className: "fortune-selection-copy-right fortune-copy"
379
- }), /*#__PURE__*/_react.default.createElement("div", {
380
- className: "fortune-selection-copy-bottom fortune-copy"
381
- }), /*#__PURE__*/_react.default.createElement("div", {
382
- className: "fortune-selection-copy-left fortune-copy"
383
- }), /*#__PURE__*/_react.default.createElement("div", {
384
359
  className: "fortune-selection-copy-hc"
385
360
  }));
386
361
  }))), /*#__PURE__*/_react.default.createElement("div", {
@@ -19,8 +19,9 @@ var ColorPicker = function ColorPicker(_a) {
19
19
  return /*#__PURE__*/_react.default.createElement("div", {
20
20
  key: c,
21
21
  className: "fortune-toolbar-color-picker-item",
22
- onClick: function onClick() {
23
- return onPick(c);
22
+ onMouseDown: function onMouseDown(e) {
23
+ e.preventDefault();
24
+ onPick(c);
24
25
  },
25
26
  tabIndex: 0,
26
27
  style: {
@@ -13,11 +13,15 @@ var CustomColor = exports.CustomColor = function CustomColor(_a) {
13
13
  var onCustomPick = _a.onCustomPick,
14
14
  onColorPick = _a.onColorPick;
15
15
  return /*#__PURE__*/_react.default.createElement("div", {
16
- id: "fortune-custom-color"
16
+ id: "fortune-custom-color",
17
+ onMouseDown: function onMouseDown(e) {
18
+ e.preventDefault();
19
+ }
17
20
  }, /*#__PURE__*/_react.default.createElement("div", {
18
21
  className: "color-reset",
19
- onClick: function onClick() {
20
- return onCustomPick(undefined);
22
+ onMouseDown: function onMouseDown(e) {
23
+ e.preventDefault();
24
+ onCustomPick(undefined);
21
25
  },
22
26
  tabIndex: 0
23
27
  }, /*#__PURE__*/_react.default.createElement(_SVGIcon.default, {
@@ -472,6 +472,14 @@ var Toolbar = function Toolbar(_a) {
472
472
  settings = _f.settings,
473
473
  handleUndo = _f.handleUndo,
474
474
  handleRedo = _f.handleRedo;
475
+ var restoreEditorFocusAfterToolbarAction = (0, _react.useCallback)(function () {
476
+ if (context.luckysheetCellUpdate.length === 0) return;
477
+ requestAnimationFrame(function () {
478
+ var owner = (0, _fortuneCore.getFormulaEditorOwner)(context);
479
+ var target = owner === "fx" ? refs.fxInput.current : refs.cellInput.current;
480
+ target === null || target === void 0 ? void 0 : target.focus();
481
+ });
482
+ }, [context, refs.cellInput, refs.fxInput]);
475
483
  var contextRef = (0, _react.useRef)(context);
476
484
  var containerRef = (0, _react.useRef)(null);
477
485
  var _g = (0, _react.useState)(-1),
@@ -1721,7 +1729,8 @@ var Toolbar = function Toolbar(_a) {
1721
1729
  return /*#__PURE__*/_react.default.createElement("div", {
1722
1730
  ref: containerRef,
1723
1731
  className: "fortune-toolbar",
1724
- "aria-label": toolbar.toolbar
1732
+ "aria-label": toolbar.toolbar,
1733
+ onMouseUpCapture: restoreEditorFocusAfterToolbarAction
1725
1734
  }, /*#__PURE__*/_react.default.createElement(_dataVerificationPortal.default, {
1726
1735
  visible: showDataValidation
1727
1736
  }), /*#__PURE__*/_react.default.createElement(_conditionalFormatPortal.default, {
@@ -2,22 +2,22 @@ import { type RefObject } from "react";
2
2
  import { type Context } from "@fileverse-dev/fortune-core";
3
3
  import type { SetContextOptions } from "../context";
4
4
  export type FormulaHistoryEntry = {
5
- text: string;
5
+ html: string;
6
6
  caret: number;
7
- spanValues: string[];
8
7
  };
9
8
  export type FormulaEditorHistoryPrimary = "cell" | "fx";
10
9
  type SetContext = (recipe: (ctx: Context) => void, options?: SetContextOptions) => void;
11
- export declare function useFormulaEditorHistory(primaryRef: RefObject<HTMLDivElement | null>, cellInputRef: RefObject<HTMLDivElement | null>, fxInputRef: RefObject<HTMLDivElement | null>, setContext: SetContext, primary: FormulaEditorHistoryPrimary): {
10
+ export declare function useFormulaEditorHistory(primaryRef: RefObject<HTMLDivElement | null>, cellInputRef: RefObject<HTMLDivElement | null>, fxInputRef: RefObject<HTMLDivElement | null>, _setContext: SetContext, primary: FormulaEditorHistoryPrimary): {
12
11
  formulaHistoryRef: RefObject<{
13
12
  active: boolean;
14
13
  entries: FormulaHistoryEntry[];
15
14
  index: number;
16
15
  }>;
17
16
  preTextRef: RefObject<string>;
18
- preFormulaSpanValuesRef: RefObject<string[] | null>;
19
17
  resetFormulaHistory: () => void;
20
18
  handleFormulaHistoryUndoRedo: (isRedo: boolean) => boolean;
19
+ capturePreEditorHistoryState: () => void;
20
+ appendEditorHistoryFromPrimaryEditor: (getCaret: () => number) => void;
21
21
  capturePreFormulaState: () => void;
22
22
  appendFormulaHistoryFromPrimaryEditor: (getCaret: () => number) => void;
23
23
  };
@@ -5,50 +5,56 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.useFormulaEditorHistory = useFormulaEditorHistory;
7
7
  var _react = require("react");
8
- var _lodash = _interopRequireDefault(require("lodash"));
9
8
  var _fortuneCore = require("@fileverse-dev/fortune-core");
10
9
  var _helper = require("../components/SheetOverlay/helper");
11
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
10
  var MAX_FORMULA_HISTORY = 100;
13
- function useFormulaEditorHistory(primaryRef, cellInputRef, fxInputRef, setContext, primary) {
11
+ function normalizeEditorHtmlSnapshot(html) {
12
+ var stripped = (html !== null && html !== void 0 ? html : "").replace(/\u200B/g, "").trim();
13
+ if (stripped === "" || stripped === "<br>" || stripped === "<div><br></div>" || stripped === "<div></div>") {
14
+ return "";
15
+ }
16
+ return html !== null && html !== void 0 ? html : "";
17
+ }
18
+ function useFormulaEditorHistory(primaryRef, cellInputRef, fxInputRef, _setContext, primary) {
14
19
  var preTextRef = (0, _react.useRef)("");
15
- var preFormulaSpanValuesRef = (0, _react.useRef)(null);
20
+ var preHtmlRef = (0, _react.useRef)("");
21
+ var preCaretRef = (0, _react.useRef)(0);
22
+ var startedFromEmptyRef = (0, _react.useRef)(true);
16
23
  var formulaHistoryRef = (0, _react.useRef)({
17
24
  active: false,
18
25
  entries: [],
19
26
  index: -1
20
27
  });
28
+ var isApplyingHistoryRef = (0, _react.useRef)(false);
21
29
  var resetFormulaHistory = (0, _react.useCallback)(function () {
22
30
  formulaHistoryRef.current = {
23
31
  active: false,
24
32
  entries: [],
25
33
  index: -1
26
34
  };
27
- preFormulaSpanValuesRef.current = null;
35
+ preHtmlRef.current = "";
36
+ preCaretRef.current = 0;
37
+ startedFromEmptyRef.current = true;
28
38
  }, []);
29
39
  var pushFormulaHistoryEntry = (0, _react.useCallback)(function (entry) {
30
40
  var history = formulaHistoryRef.current;
31
41
  var current = history.entries[history.index];
32
- if (current && current.spanValues.length > 0 && entry.spanValues.length > 0 && _lodash.default.isEqual(current.spanValues, entry.spanValues)) {
33
- return;
34
- }
35
- if (current && current.spanValues.length === 0 && entry.spanValues.length === 0 && current.text === entry.text && current.caret === entry.caret) {
42
+ if (current && current.html === entry.html) {
36
43
  return;
37
44
  }
38
45
  var nextEntries = history.entries.slice(0, history.index + 1);
39
46
  nextEntries.push(entry);
40
- if (nextEntries.length > MAX_FORMULA_HISTORY) {
41
- nextEntries.shift();
42
- }
47
+ if (nextEntries.length > MAX_FORMULA_HISTORY) nextEntries.shift();
43
48
  history.entries = nextEntries;
44
49
  history.index = nextEntries.length - 1;
45
50
  history.active = true;
46
51
  }, []);
47
- var applyFormulaHistoryEntry = (0, _react.useCallback)(function (entry) {
52
+ var applyFormulaHistoryEntry = (0, _react.useCallback)(function (entry, preserveSelection) {
53
+ var _a, _b, _c;
48
54
  var primaryEl = primaryRef.current;
49
55
  if (!primaryEl) return;
50
- var safeText = (0, _fortuneCore.escapeScriptTag)(entry.text || "");
51
- var html = safeText.startsWith("=") ? (0, _fortuneCore.functionHTMLGenerate)(safeText) : (0, _fortuneCore.escapeHTMLTag)(safeText);
56
+ isApplyingHistoryRef.current = true;
57
+ var html = (0, _fortuneCore.escapeScriptTag)((_a = entry.html) !== null && _a !== void 0 ? _a : "");
52
58
  var cell = cellInputRef.current;
53
59
  var fx = fxInputRef.current;
54
60
  primaryEl.innerHTML = html;
@@ -57,70 +63,91 @@ function useFormulaEditorHistory(primaryRef, cellInputRef, fxInputRef, setContex
57
63
  } else if (cell) {
58
64
  cell.innerHTML = html;
59
65
  }
60
- (0, _helper.setCursorPosition)(primaryEl, Math.min(entry.caret, entry.text.length));
61
- setContext(function (draftCtx) {
62
- if (primary === "cell") {
63
- if (!cellInputRef.current) return;
64
- (0, _fortuneCore.handleFormulaInput)(draftCtx, fxInputRef.current, cellInputRef.current, 0);
65
- } else {
66
- if (!fxInputRef.current) return;
67
- (0, _fortuneCore.handleFormulaInput)(draftCtx, cellInputRef.current, fxInputRef.current, 0);
68
- }
66
+ var textLen = (_c = (_b = primaryEl.innerText) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0;
67
+ if (preserveSelection && preserveSelection.end > preserveSelection.start && textLen > 0) {
68
+ var start = Math.max(0, Math.min(preserveSelection.start, textLen));
69
+ var end = Math.max(start, Math.min(preserveSelection.end, textLen));
70
+ (0, _helper.setSelectionOffsets)(primaryEl, start, end);
71
+ } else {
72
+ (0, _helper.setCursorPosition)(primaryEl, Math.max(0, textLen));
73
+ }
74
+ requestAnimationFrame(function () {
75
+ requestAnimationFrame(function () {
76
+ setTimeout(function () {
77
+ isApplyingHistoryRef.current = false;
78
+ }, 120);
79
+ });
69
80
  });
70
- }, [cellInputRef, fxInputRef, primary, primaryRef, setContext]);
81
+ }, [cellInputRef, fxInputRef, primary, primaryRef]);
71
82
  var handleFormulaHistoryUndoRedo = (0, _react.useCallback)(function (isRedo) {
83
+ var _a, _b;
72
84
  var history = formulaHistoryRef.current;
73
85
  if (!history.active || history.entries.length === 0) return false;
74
86
  var nextIndex = isRedo ? history.index + 1 : history.index - 1;
75
- if (nextIndex < 0 || nextIndex >= history.entries.length) return true;
87
+ if (nextIndex < 0 || nextIndex >= history.entries.length) {
88
+ if (!isRedo && nextIndex < 0 && startedFromEmptyRef.current) {
89
+ var liveHtml = normalizeEditorHtmlSnapshot((_b = (_a = primaryRef.current) === null || _a === void 0 ? void 0 : _a.innerHTML) !== null && _b !== void 0 ? _b : "");
90
+ if (liveHtml !== "") {
91
+ history.entries[0] = {
92
+ html: "",
93
+ caret: 0
94
+ };
95
+ history.index = 0;
96
+ var currentSelection_1 = primaryRef.current ? (0, _helper.getSelectionOffsets)(primaryRef.current) : undefined;
97
+ applyFormulaHistoryEntry(history.entries[0], currentSelection_1);
98
+ return true;
99
+ }
100
+ }
101
+ return false;
102
+ }
76
103
  history.index = nextIndex;
77
- applyFormulaHistoryEntry(history.entries[nextIndex]);
104
+ var entry = history.entries[nextIndex];
105
+ var currentSelection = primaryRef.current ? (0, _helper.getSelectionOffsets)(primaryRef.current) : undefined;
106
+ applyFormulaHistoryEntry(entry, currentSelection);
78
107
  return true;
79
- }, [applyFormulaHistoryEntry]);
80
- var capturePreFormulaState = (0, _react.useCallback)(function () {
108
+ }, [applyFormulaHistoryEntry, primaryRef]);
109
+ var capturePreEditorHistoryState = (0, _react.useCallback)(function () {
110
+ var _a;
81
111
  var el = primaryRef.current;
82
112
  if (!el) return;
83
113
  preTextRef.current = el.innerText;
84
- preFormulaSpanValuesRef.current = Array.from(el.querySelectorAll("span.fortune-formula-functionrange-cell")).map(function (node) {
85
- var _a;
86
- return (_a = node.textContent) !== null && _a !== void 0 ? _a : "";
87
- });
114
+ preHtmlRef.current = el.innerHTML;
115
+ preCaretRef.current = (0, _helper.getCursorPosition)(el);
116
+ if (!formulaHistoryRef.current.active) {
117
+ startedFromEmptyRef.current = normalizeEditorHtmlSnapshot((_a = preHtmlRef.current) !== null && _a !== void 0 ? _a : "") === "";
118
+ }
88
119
  }, [primaryRef]);
89
- var appendFormulaHistoryFromPrimaryEditor = (0, _react.useCallback)(function (getCaret) {
120
+ var appendEditorHistoryFromPrimaryEditor = (0, _react.useCallback)(function (getCaret) {
90
121
  var _a, _b;
122
+ if (isApplyingHistoryRef.current) return;
91
123
  var el = primaryRef.current;
92
124
  if (!el) return;
93
- var currentText = el.innerText || "";
94
- if (currentText.startsWith("=")) {
95
- var caret = getCaret();
96
- var spanValues = Array.from(el.querySelectorAll("span.fortune-formula-functionrange-cell")).map(function (node) {
97
- var _a;
98
- return (_a = node.textContent) !== null && _a !== void 0 ? _a : "";
99
- });
100
- if (!formulaHistoryRef.current.active) {
101
- var seedText = preTextRef.current || "";
102
- pushFormulaHistoryEntry({
103
- text: seedText,
104
- caret: Math.min(caret, seedText.length),
105
- spanValues: (_b = (_a = preFormulaSpanValuesRef.current) !== null && _a !== void 0 ? _a : spanValues) !== null && _b !== void 0 ? _b : []
106
- });
107
- }
125
+ var preHtmlSnapshot = normalizeEditorHtmlSnapshot((_a = preHtmlRef.current) !== null && _a !== void 0 ? _a : "");
126
+ var snapshotHtml = normalizeEditorHtmlSnapshot((_b = el.innerHTML) !== null && _b !== void 0 ? _b : "");
127
+ var caret = getCaret();
128
+ var history = formulaHistoryRef.current;
129
+ var wasInactive = !history.active || history.entries.length === 0;
130
+ if (wasInactive) {
131
+ startedFromEmptyRef.current = preHtmlSnapshot === "";
132
+ var seedHtml = preHtmlSnapshot === snapshotHtml ? "" : preHtmlSnapshot !== null && preHtmlSnapshot !== void 0 ? preHtmlSnapshot : "";
108
133
  pushFormulaHistoryEntry({
109
- text: currentText,
110
- caret: caret,
111
- spanValues: spanValues
134
+ html: seedHtml,
135
+ caret: preCaretRef.current
112
136
  });
113
- } else if (formulaHistoryRef.current.active) {
114
- resetFormulaHistory();
115
137
  }
116
- }, [primaryRef, pushFormulaHistoryEntry, resetFormulaHistory]);
138
+ pushFormulaHistoryEntry({
139
+ html: snapshotHtml,
140
+ caret: caret
141
+ });
142
+ }, [primaryRef, pushFormulaHistoryEntry]);
117
143
  return {
118
144
  formulaHistoryRef: formulaHistoryRef,
119
145
  preTextRef: preTextRef,
120
- preFormulaSpanValuesRef: preFormulaSpanValuesRef,
121
146
  resetFormulaHistory: resetFormulaHistory,
122
147
  handleFormulaHistoryUndoRedo: handleFormulaHistoryUndoRedo,
123
- capturePreFormulaState: capturePreFormulaState,
124
- appendFormulaHistoryFromPrimaryEditor: appendFormulaHistoryFromPrimaryEditor
148
+ capturePreEditorHistoryState: capturePreEditorHistoryState,
149
+ appendEditorHistoryFromPrimaryEditor: appendEditorHistoryFromPrimaryEditor,
150
+ capturePreFormulaState: capturePreEditorHistoryState,
151
+ appendFormulaHistoryFromPrimaryEditor: appendEditorHistoryFromPrimaryEditor
125
152
  };
126
153
  }
@@ -1,2 +1,2 @@
1
1
  import { type RefObject } from "react";
2
- export declare function useRerenderOnFormulaCaret(editorRef: RefObject<HTMLDivElement | null>, editSessionActive: boolean): void;
2
+ export declare function useRerenderOnFormulaCaret(editorRef: RefObject<HTMLDivElement | null>, editSessionActive: boolean, onAfterCaretMove?: () => void): void;
@@ -5,15 +5,17 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.useRerenderOnFormulaCaret = useRerenderOnFormulaCaret;
7
7
  var _react = require("react");
8
- function useRerenderOnFormulaCaret(editorRef, editSessionActive) {
8
+ function useRerenderOnFormulaCaret(editorRef, editSessionActive, onAfterCaretMove) {
9
9
  var _a = (0, _react.useState)(0),
10
10
  bump = _a[1];
11
+ var onAfterCaretMoveRef = (0, _react.useRef)(onAfterCaretMove);
12
+ onAfterCaretMoveRef.current = onAfterCaretMove;
11
13
  (0, _react.useEffect)(function () {
12
14
  if (!editSessionActive) {
13
15
  return function () {};
14
16
  }
15
17
  var onSelectionChange = function onSelectionChange() {
16
- var _a, _b;
18
+ var _a, _b, _c;
17
19
  var el = editorRef.current;
18
20
  if (!el) return;
19
21
  var text = (_b = (_a = el.innerText) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : "";
@@ -25,6 +27,7 @@ function useRerenderOnFormulaCaret(editorRef, editSessionActive) {
25
27
  bump(function (n) {
26
28
  return n + 1;
27
29
  });
30
+ (_c = onAfterCaretMoveRef.current) === null || _c === void 0 ? void 0 : _c.call(onAfterCaretMoveRef);
28
31
  };
29
32
  document.addEventListener("selectionchange", onSelectionChange);
30
33
  return function () {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fileverse-dev/fortune-react",
3
- "version": "1.3.13-create-3",
3
+ "version": "1.3.13-create-5",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "module": "es/index.js",
@@ -16,7 +16,7 @@
16
16
  "tsc": "tsc"
17
17
  },
18
18
  "dependencies": {
19
- "@fileverse-dev/fortune-core": "1.3.13-create-3",
19
+ "@fileverse-dev/fortune-core": "1.3.13-create-5",
20
20
  "@fileverse/ui": "5.0.0",
21
21
  "@tippyjs/react": "^4.2.6",
22
22
  "@types/regenerator-runtime": "^0.13.6",