@zhenliang/sheet 0.2.5-beta.0 → 0.2.5-beta.10

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,14 +1,5 @@
1
1
  import type { SheetType } from "../../../type";
2
2
  import './index.less';
3
- export interface OptionItem {
4
- label: string;
5
- value: string;
6
- info?: string;
7
- children?: OptionItem[];
8
- }
9
- export interface FormulaInputProps {
10
- options: OptionItem[];
11
- value?: string;
12
- }
13
- export declare const getFormulaInputEditor: (options: OptionItem[]) => SheetType.CellEditor;
3
+ import { OptionItem, inputProps } from './utils';
4
+ export declare const getFormulaInputEditor: (options: OptionItem[], replaceIndex?: string, extraProps?: inputProps, getExtraProps?: ((props: SheetType.CellEditorProps) => inputProps) | undefined, choseEditor?: ((record: any) => boolean) | undefined) => SheetType.CellEditor;
14
5
  export default getFormulaInputEditor;
@@ -11,42 +11,63 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
11
11
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
12
12
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
13
13
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
14
- import { Dropdown, Menu, Tooltip } from 'antd';
15
- import { head, isEmpty, isNil } from 'lodash';
16
- import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
14
+ function _objectDestructuringEmpty(obj) { if (obj == null) throw new TypeError("Cannot destructure " + obj); }
17
15
  import { InfoCircleOutlined } from '@ant-design/icons';
18
- import { flattenOptions, getStringDiff, replaceLabelsWithValues, replaceLongestDiff, replaceValuesWithLabels, tokenize, validateVariables, getCursorPositionInSpan } from "./utils";
19
- import validateCalculationExpr from "./vaildFormula";
16
+ import { Dropdown, Input, Menu, Tooltip } from 'antd';
17
+ import { get, head, isEmpty, isNil } from 'lodash';
18
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
19
+ import { formulaString } from "../numberEditor";
20
20
  import "./index.less";
21
+ import { flattenOptions, getCursorPositionInSpan, getSpanAtCursor, getStringDiff, moveCursorToSpan, replaceLabelsWithValues, replaceLongestDiff, replaceValuesWithLabels, tokenize, validateVariables } from "./utils";
22
+ import validateCalculationExpr from "./vaildFormula";
21
23
  import { jsx as _jsx } from "react/jsx-runtime";
22
24
  import { jsxs as _jsxs } from "react/jsx-runtime";
23
- var OPERATORS = ['=', '+', '-', '*', '/'];
24
-
25
- // 获取光标所在的 span
26
- var getSpanAtCursor = function getSpanAtCursor(startContainer) {
27
- if (startContainer.nodeType === Node.TEXT_NODE) {
28
- return startContainer.parentElement;
29
- }
30
- if (startContainer.nodeType === Node.ELEMENT_NODE) {
31
- return startContainer;
32
- }
33
- return null;
34
- };
35
- export var getFormulaInputEditor = function getFormulaInputEditor(options) {
25
+ var OPERATORS = ['=', '+', '-', '*', '/', '('];
26
+
27
+ // // 创建 label span
28
+ // const createLabelSpan = (label: string): HTMLElement => {
29
+ // const span = document.createElement('span');
30
+ // span.className = 'formula-editor-token-label';
31
+ // span.textContent = label;
32
+ // return span;
33
+ // };
34
+
35
+ // // 创建 empty other span
36
+ // const createEmptyOtherSpan = (): HTMLElement => {
37
+ // const span = document.createElement('span');
38
+ // span.className = 'formula-editor-token-other';
39
+ // span.textContent = '';
40
+ // return span;
41
+ // };
42
+
43
+ export var getFormulaInputEditor = function getFormulaInputEditor(options, replaceIndex, extraProps, getExtraProps, choseEditor) {
44
+ var _ref = extraProps || {},
45
+ warnMethod = _ref.warnMethod,
46
+ rangeMethod = _ref.rangeMethod,
47
+ precision = _ref.precision,
48
+ max = _ref.max,
49
+ min = _ref.min;
36
50
  var FormulaInputEditor = function FormulaInputEditor(props) {
37
- var value = props.value,
51
+ var _get;
52
+ var originValue = props.value,
38
53
  onChange = props.onChange,
39
- isEditing = props.isEditing;
40
- var _useState = useState(value),
41
- _useState2 = _slicedToArray(_useState, 2),
42
- inputValue = _useState2[0],
43
- setInputValue = _useState2[1];
54
+ isEditing = props.isEditing,
55
+ record = props.record;
56
+ // 兼容number
57
+ var inputNumberRef = useRef(null);
58
+ var _ref2 = getExtraProps ? getExtraProps(props) : extraProps !== null && extraProps !== void 0 ? extraProps : {},
59
+ inputArgs = Object.assign({}, (_objectDestructuringEmpty(_ref2), _ref2));
60
+ var replaceValue = replaceIndex ? (_get = get(record, [replaceIndex])) !== null && _get !== void 0 ? _get : '' : originValue;
61
+ var calcValue = replaceValue.startsWith('=') ? replaceValue : "=".concat(replaceValue);
62
+ var _useState = useState(calcValue),
63
+ _useState2 = _slicedToArray(_useState, 1),
64
+ inputValue = _useState2[0];
44
65
  var _useState3 = useState(0),
45
66
  _useState4 = _slicedToArray(_useState3, 2),
46
67
  offsetX = _useState4[0],
47
68
  setOffsetX = _useState4[1];
48
69
  // 为了不重新render,再写一个
49
- var _useState5 = useState(value),
70
+ var _useState5 = useState(replaceValue),
50
71
  _useState6 = _slicedToArray(_useState5, 2),
51
72
  containerValue = _useState6[0],
52
73
  setContainerValue = _useState6[1];
@@ -59,6 +80,7 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
59
80
  _useState10 = _slicedToArray(_useState9, 2),
60
81
  inputAfterDropDownShow = _useState10[0],
61
82
  setInputAfterDropDownShow = _useState10[1];
83
+ var tempSpanRef = useRef(null);
62
84
  var containerRef = useRef(null);
63
85
  var inputOperatorPosition = useRef(0);
64
86
 
@@ -73,7 +95,7 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
73
95
  }, [inputValue, flatOptions]);
74
96
  // 根据搜索文本获取筛选后的层级选项(保持层级结构)
75
97
  var filteredHierarchyOptions = useMemo(function () {
76
- var searchText = inputAfterDropDownShow;
98
+ var searchText = inputAfterDropDownShow.trim();
77
99
  // 如果搜索文本为空,显示所有选项(保持层级)
78
100
  if (!searchText) {
79
101
  return options;
@@ -108,43 +130,94 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
108
130
  useEffect(function () {
109
131
  if (!open) {
110
132
  containerValueSnapShot.current = '';
133
+ tempSpanRef.current = null;
111
134
  }
112
135
  setInputAfterDropDownShow('');
113
136
  }, [open]);
137
+ var closeDorpDown = useCallback(function () {
138
+ setInputAfterDropDownShow('');
139
+ tempSpanRef.current = null;
140
+ // 点击div内直接关闭
141
+ setOpen(false);
142
+ }, []);
114
143
 
115
- // 处理选项点击:删除用户刚输入的值,将选中的 label 放到运算符后面
144
+ // 处理选项点击
116
145
  var handleOptionClick = useCallback(function (opt) {
117
146
  var container = containerRef.current;
118
147
  if (!container) return;
119
- var newValue = replaceLongestDiff(containerValueSnapShot.current, opt.label, inputOperatorPosition.current);
120
- setOpen(false);
121
- containerValueSnapShot.current = '';
122
- var expr = newValue;
123
- var valueExpr = replaceLabelsWithValues(expr, flatOptions);
124
- setContainerValue(valueExpr);
125
- onChange(valueExpr);
126
-
127
- // 获取当前光标所在的 span
128
148
  var selection = window.getSelection();
129
149
  if (!selection || selection.rangeCount === 0) return;
150
+
151
+ // 如果有 tempSpanRef,用新逻辑:直接替换该 span 的内容
152
+ if (tempSpanRef.current) {
153
+ tempSpanRef.current.textContent = opt.label;
154
+ var replacedSpan = tempSpanRef.current;
155
+ tempSpanRef.current = null;
156
+
157
+ // 光标移到替换后的 span 后面
158
+ var _allSpans = Array.from(container.querySelectorAll('span'));
159
+ var replacedIndex = _allSpans.indexOf(replacedSpan);
160
+ var _targetSpan = _allSpans[replacedIndex + 1];
161
+ if (!_targetSpan || _targetSpan.classList.contains('formula-editor-token-label')) {
162
+ _targetSpan = document.createElement('span');
163
+ _targetSpan.className = 'formula-editor-token-other';
164
+ _targetSpan.textContent = '';
165
+ replacedSpan.after(_targetSpan);
166
+ }
167
+ moveCursorToSpan(_targetSpan, true, selection);
168
+ // 更新 containerValue
169
+ var newValue = container.textContent || '';
170
+ var valueExpr = replaceLabelsWithValues(newValue, flatOptions);
171
+ setContainerValue(valueExpr);
172
+ onChange(valueExpr);
173
+ setOpen(false);
174
+ return;
175
+ }
176
+ // 原逻辑:删除 inputAfterDropDownShow,插入新 label
177
+ var newValueUser = replaceLongestDiff(containerValueSnapShot.current, opt.label, inputOperatorPosition.current);
178
+ var expr = newValueUser;
179
+ var valueExprUser = replaceLabelsWithValues(expr, flatOptions);
180
+ setContainerValue(valueExprUser);
181
+ onChange(valueExprUser);
130
182
  var range = selection.getRangeAt(0);
131
183
  var startContainer = range.startContainer;
132
184
  var currentSpan = startContainer.nodeType === Node.TEXT_NODE ? startContainer.parentElement : startContainer;
133
185
  if (!currentSpan || currentSpan === container) return;
134
186
 
135
- // 删除 inputAfterDropDownShow
187
+ // 获取删除 inputAfterDropDownShow 后的前半部分和后半部分
136
188
  var spanText = currentSpan.textContent || '';
137
189
  var deleteText = inputAfterDropDownShow;
138
190
  var deleteIndex = spanText.indexOf(deleteText);
139
- if (deleteIndex !== -1) {
140
- currentSpan.textContent = spanText.slice(0, deleteIndex) + spanText.slice(deleteIndex + deleteText.length);
191
+ // 如果找不到 deleteText,用当前光标位置作为 deleteIndex
192
+ if (deleteIndex === -1 || !deleteText) {
193
+ deleteIndex = range.startOffset;
141
194
  }
195
+ var beforePart = spanText.slice(0, deleteIndex);
196
+ var afterPart = spanText.slice(deleteIndex + deleteText.length);
142
197
 
143
- // 新建 label span,内容为 opt.label,插入到当前 span 后面
198
+ // 删除当前 span,用三个 span 替换:other(前)、label、other(后)
144
199
  var labelSpan = document.createElement('span');
145
200
  labelSpan.className = 'formula-editor-token-label';
146
201
  labelSpan.textContent = opt.label;
147
- currentSpan.after(labelSpan);
202
+
203
+ // 创建待插入的 span 列表
204
+ var spansToInsert = [];
205
+ if (beforePart) {
206
+ var beforeSpan = document.createElement('span');
207
+ beforeSpan.className = 'formula-editor-token-other';
208
+ beforeSpan.textContent = beforePart;
209
+ spansToInsert.push(beforeSpan);
210
+ }
211
+ spansToInsert.push(labelSpan);
212
+ if (afterPart) {
213
+ var afterSpan = document.createElement('span');
214
+ afterSpan.className = 'formula-editor-token-other';
215
+ afterSpan.textContent = afterPart;
216
+ spansToInsert.push(afterSpan);
217
+ }
218
+ // 插入所有 span
219
+ currentSpan.after.apply(currentSpan, spansToInsert);
220
+ currentSpan.remove();
148
221
 
149
222
  // 将光标移到下一个 span 的开头
150
223
  var allSpans = Array.from(container.querySelectorAll('span'));
@@ -158,19 +231,17 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
158
231
  targetSpan.textContent = '';
159
232
  labelSpan.after(targetSpan);
160
233
  }
161
-
162
- // 将光标移到目标 span 的开头
163
- var newRange = document.createRange();
164
- newRange.selectNodeContents(targetSpan);
165
- newRange.collapse(true);
166
- selection.removeAllRanges();
167
- selection.addRange(newRange);
234
+ moveCursorToSpan(targetSpan, true, selection);
235
+ setOpen(false);
168
236
  }, [inputAfterDropDownShow]);
169
237
 
170
238
  // 处理输入变化
171
239
  var handleInput = useCallback(function () {
172
240
  var container = containerRef.current;
173
241
  if (!container) return;
242
+ if (tempSpanRef.current) {
243
+ closeDorpDown();
244
+ }
174
245
  var newValue = container.textContent || '';
175
246
  var processedValue = newValue;
176
247
  var expr = processedValue;
@@ -194,7 +265,7 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
194
265
  if (open) {
195
266
  var _getStringDiff2 = getStringDiff(containerValueSnapShot.current, newValue),
196
267
  addedOnSnapShot = _getStringDiff2.added;
197
- isBeginWithNumber = /^\d$/.test(head(addedOnSnapShot));
268
+ isBeginWithNumber = /^\d$/.test(head(addedOnSnapShot.join('').trim()));
198
269
  inputStringAfterDropDownShow = addedOnSnapShot.join('');
199
270
  }
200
271
  if (pressAOperator) {
@@ -231,12 +302,8 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
231
302
  (_containerRef$current2 = containerRef.current) === null || _containerRef$current2 === void 0 || _containerRef$current2.focus();
232
303
  }
233
304
  }, [isEditing]);
234
- var closeDorpDown = useCallback(function () {
235
- // 点击div内直接关闭
236
- setOpen(false);
237
- }, []);
238
305
 
239
- // 鼠标释放时,如果光标在 label span 内,移动到后一个 span 的开头
306
+ // 鼠标释放时,如果光标在 label span 内,打开下拉框并记录 tempSpan
240
307
  var handleMouseUp = useCallback(function () {
241
308
  var div = containerRef.current;
242
309
  if (!div) return;
@@ -249,8 +316,20 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
249
316
  if (!currentSpan || currentSpan === div) return;
250
317
  var isLabelSpan = currentSpan.classList.contains('formula-editor-token-label');
251
318
 
252
- // 如果在 label span 内,移动到下一个 span 的开头
319
+ // 如果在 label span 内,打开下拉框并记录 tempSpan
253
320
  if (isLabelSpan) {
321
+ // 更新 offsetX 位置
322
+ var containerRect = div.getBoundingClientRect();
323
+ var cursorRect = range.getBoundingClientRect();
324
+ var cursorDistance = cursorRect ? cursorRect.left - containerRect.left : 0;
325
+ setOffsetX(cursorDistance < 150 ? 0 : cursorDistance - 8);
326
+
327
+ // 记录当前 label span 作为 tempSpan
328
+ tempSpanRef.current = currentSpan;
329
+
330
+ // 打开下拉框
331
+ setOpen(true);
332
+ // 移动到下一个 span 的开头
254
333
  var allSpans = Array.from(div.querySelectorAll('span'));
255
334
  var currentIndex = allSpans.indexOf(currentSpan);
256
335
  if (currentIndex < allSpans.length - 1) {
@@ -262,9 +341,14 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
262
341
  selection.addRange(newRange);
263
342
  }
264
343
  }
265
- }, [closeDorpDown]);
344
+ }, [closeDorpDown, setOffsetX, setOpen]);
266
345
  var handleKeyDown = useCallback(function (e) {
267
346
  var _currentSpan$textCont, _currentSpan$textCont2;
347
+ if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
348
+ e.preventDefault();
349
+ e.stopPropagation();
350
+ return;
351
+ }
268
352
  var div = containerRef.current;
269
353
  if (!div) return;
270
354
  var selection = window.getSelection();
@@ -280,13 +364,13 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
280
364
 
281
365
  // 方向键:跳过 label span
282
366
  if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') {
283
- closeDorpDown();
284
367
  var position = getCursorPositionInSpan(currentSpan);
285
368
  var isAtEnd = startOffset >= textLen;
286
369
  var isAtStart = startOffset === 0;
287
370
  var isAlmostEnd = startOffset >= textLen - 1;
288
371
  var isAlmostStart = position === 1;
289
372
  if (e.key === 'ArrowRight' && isAtEnd) {
373
+ closeDorpDown();
290
374
  // 向右 + 在末尾 -> 跳到下一个 span 的开头(跳过 label span)
291
375
  var targetIndex = currentIndex + 1;
292
376
  while (targetIndex < allSpans.length && allSpans[targetIndex].classList.contains('formula-editor-token-label')) {
@@ -295,48 +379,35 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
295
379
  if (targetIndex < allSpans.length && targetIndex !== currentIndex + 1) {
296
380
  e.preventDefault();
297
381
  var targetSpan = allSpans[targetIndex];
298
- var newRange = document.createRange();
299
- newRange.selectNodeContents(targetSpan);
300
- newRange.collapse(true);
301
- selection.removeAllRanges();
302
- selection.addRange(newRange);
382
+ moveCursorToSpan(targetSpan, true, selection);
383
+ }
384
+ } else if (e.key === 'ArrowRight' && isAlmostEnd) {
385
+ closeDorpDown();
386
+ var _targetIndex = currentIndex + 1;
387
+ if (_targetIndex < allSpans.length && !allSpans[_targetIndex].classList.contains('formula-editor-token-label')) {
388
+ e.preventDefault();
389
+ var _targetSpan2 = allSpans[_targetIndex];
390
+ moveCursorToSpan(_targetSpan2, true, selection);
303
391
  }
304
392
  } else if (e.key === 'ArrowLeft' && isAtStart) {
393
+ closeDorpDown();
305
394
  // 向左 + 在开头 -> 跳到上一个 span 的末尾(跳过 label span)
306
- var _targetIndex = currentIndex - 1;
307
- while (_targetIndex >= 0 && allSpans[_targetIndex].classList.contains('formula-editor-token-label')) {
308
- _targetIndex--;
309
- }
310
- if (_targetIndex >= 0 && _targetIndex !== currentIndex - 1) {
311
- e.preventDefault();
312
- var _targetSpan = allSpans[_targetIndex];
313
- var _newRange = document.createRange();
314
- _newRange.selectNodeContents(_targetSpan);
315
- _newRange.collapse(false);
316
- selection.removeAllRanges();
317
- selection.addRange(_newRange);
395
+ var _targetIndex2 = currentIndex - 1;
396
+ while (_targetIndex2 >= 0 && allSpans[_targetIndex2].classList.contains('formula-editor-token-label')) {
397
+ _targetIndex2--;
318
398
  }
319
- } else if (e.key === 'ArrowRight' && isAlmostEnd) {
320
- var _targetIndex2 = currentIndex + 1;
321
- if (_targetIndex2 < allSpans.length && !allSpans[_targetIndex2].classList.contains('formula-editor-token-label')) {
399
+ if (_targetIndex2 >= 0 && _targetIndex2 !== currentIndex - 1) {
322
400
  e.preventDefault();
323
- var _targetSpan2 = allSpans[_targetIndex2];
324
- var _newRange2 = document.createRange();
325
- _newRange2.selectNodeContents(_targetSpan2);
326
- _newRange2.collapse(true);
327
- selection.removeAllRanges();
328
- selection.addRange(_newRange2);
401
+ var _targetSpan3 = allSpans[_targetIndex2];
402
+ moveCursorToSpan(_targetSpan3, false, selection);
329
403
  }
330
404
  } else if (e.key === 'ArrowLeft' && isAlmostStart) {
405
+ closeDorpDown();
331
406
  var _targetIndex3 = currentIndex - 1;
332
407
  if (_targetIndex3 >= 0 && !allSpans[_targetIndex3].classList.contains('formula-editor-token-label')) {
333
408
  e.preventDefault();
334
- var _targetSpan3 = allSpans[_targetIndex3];
335
- var _newRange3 = document.createRange();
336
- _newRange3.selectNodeContents(_targetSpan3);
337
- _newRange3.collapse(false);
338
- selection.removeAllRanges();
339
- selection.addRange(_newRange3);
409
+ var _targetSpan4 = allSpans[_targetIndex3];
410
+ moveCursorToSpan(_targetSpan4, false, selection);
340
411
  }
341
412
  }
342
413
  return;
@@ -344,6 +415,19 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
344
415
 
345
416
  // 删除键逻辑
346
417
  if (e.key !== 'Delete' && e.key !== 'Backspace') return;
418
+ if (e.key === 'Backspace' || e.key === 'Delete') {
419
+ if (tempSpanRef.current) {
420
+ closeDorpDown();
421
+ }
422
+ // 检查删除后是否只剩一个空的 span
423
+ var allSpansNow = Array.from(div.querySelectorAll('span'));
424
+ var isOnlyOneEmptySpan = allSpansNow.length === 1 && allSpansNow[0].textContent === '';
425
+ if (isOnlyOneEmptySpan) {
426
+ e.preventDefault();
427
+ e.stopPropagation();
428
+ return;
429
+ }
430
+ }
347
431
 
348
432
  // 不在 label span 内,在 span 开头且前一个是 label 时,删除整个 label span
349
433
  if (startOffset === 0 && e.key === 'Backspace' && currentIndex > 0) {
@@ -352,31 +436,31 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
352
436
  e.preventDefault();
353
437
  e.stopPropagation();
354
438
  prevSpan.remove();
355
- var _newRange4 = document.createRange();
439
+ var newRange = document.createRange();
356
440
 
357
441
  // 如果当前 span 有内容,光标放在开头;否则找最近的有内容的 span
358
442
  if (currentSpan.textContent !== '') {
359
- _newRange4.selectNodeContents(currentSpan);
360
- _newRange4.collapse(true);
443
+ newRange.selectNodeContents(currentSpan);
444
+ newRange.collapse(true);
361
445
  } else {
362
446
  // 找前一个最近的有内容的 span
363
- var _targetSpan4;
447
+ var _targetSpan5;
364
448
  for (var i = currentIndex - 2; i >= 0; i--) {
365
449
  if (allSpans[i].textContent !== '') {
366
- _targetSpan4 = allSpans[i];
450
+ _targetSpan5 = allSpans[i];
367
451
  break;
368
452
  }
369
453
  }
370
- if (_targetSpan4) {
371
- _newRange4.selectNodeContents(_targetSpan4);
372
- _newRange4.collapse(false);
454
+ if (_targetSpan5) {
455
+ newRange.selectNodeContents(_targetSpan5);
456
+ newRange.collapse(false);
373
457
  } else {
374
- _newRange4.selectNodeContents(div);
375
- _newRange4.collapse(true);
458
+ newRange.selectNodeContents(div);
459
+ newRange.collapse(true);
376
460
  }
377
461
  }
378
462
  selection.removeAllRanges();
379
- selection.addRange(_newRange4);
463
+ selection.addRange(newRange);
380
464
  return;
381
465
  }
382
466
  }
@@ -392,11 +476,11 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
392
476
  if (prevText.length > 0) {
393
477
  _prevSpan.textContent = prevText.slice(0, -1);
394
478
  }
395
- var _newRange5 = document.createRange();
396
- _newRange5.selectNodeContents(_prevSpan);
397
- _newRange5.collapse(false);
479
+ var _newRange = document.createRange();
480
+ _newRange.selectNodeContents(_prevSpan);
481
+ _newRange.collapse(false);
398
482
  selection.removeAllRanges();
399
- selection.addRange(_newRange5);
483
+ selection.addRange(_newRange);
400
484
  }
401
485
  }
402
486
 
@@ -411,76 +495,104 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
411
495
  // 如果光标在 span 开头 + Delete 键,currentIndex 指向的是被删 span 的后一个,所以要 -1
412
496
  var searchIndex = startOffset === 0 ? currentIndex - 1 : currentIndex;
413
497
  // 从 searchIndex 位置往前找
414
- var _targetSpan5;
498
+ var _targetSpan6;
415
499
  for (var _i = searchIndex; _i >= 0; _i--) {
416
500
  var span = allSpansNow[_i];
417
501
  if (span.textContent !== '') {
418
- _targetSpan5 = span;
502
+ _targetSpan6 = span;
419
503
  break;
420
504
  }
421
505
  }
422
506
  // 如果找到的有内容 span 是 label,则把光标放在 label span 的后一个 span 的开头
423
- if (_targetSpan5 && _targetSpan5.classList.contains('formula-editor-token-label')) {
424
- var labelIndex = allSpansNow.indexOf(_targetSpan5);
507
+ if (_targetSpan6 && _targetSpan6.classList.contains('formula-editor-token-label')) {
508
+ var labelIndex = allSpansNow.indexOf(_targetSpan6);
425
509
  if (labelIndex < allSpansNow.length - 1) {
426
510
  var nextSpan = allSpansNow[labelIndex + 1];
427
- var _newRange6 = document.createRange();
428
- _newRange6.selectNodeContents(nextSpan);
429
- _newRange6.collapse(true);
511
+ var _newRange2 = document.createRange();
512
+ _newRange2.selectNodeContents(nextSpan);
513
+ _newRange2.collapse(true);
430
514
  selection.removeAllRanges();
431
- selection.addRange(_newRange6);
515
+ selection.addRange(_newRange2);
432
516
  return;
433
517
  }
434
518
  }
435
519
 
436
520
  // 否则把光标放在找到的 span 的末尾
437
- if (_targetSpan5) {
438
- var _newRange7 = document.createRange();
439
- _newRange7.selectNodeContents(_targetSpan5);
440
- _newRange7.collapse(false);
521
+ if (_targetSpan6) {
522
+ var _newRange3 = document.createRange();
523
+ _newRange3.selectNodeContents(_targetSpan6);
524
+ _newRange3.collapse(false);
441
525
  selection.removeAllRanges();
442
- selection.addRange(_newRange7);
526
+ selection.addRange(_newRange3);
443
527
  return;
444
528
  }
445
529
  }
446
530
  if (!currentSpanNow || currentSpanNow === div) return;
447
531
  if (currentSpanNow.textContent === '') {
448
532
  var currentIndexNow = allSpansNow.indexOf(currentSpanNow);
449
- var _newRange8 = document.createRange();
533
+ var _newRange4 = document.createRange();
450
534
  if (currentIndexNow > 0) {
451
535
  // 移到前一个 span 的末尾,但如果前一个 span 是 label,则移到后一个 span 的开头
452
- var _targetSpan6 = allSpansNow[currentIndexNow - 1];
453
- if (_targetSpan6.classList.contains('formula-editor-token-label')) {
536
+ var _targetSpan7 = allSpansNow[currentIndexNow - 1];
537
+ if (_targetSpan7.classList.contains('formula-editor-token-label')) {
454
538
  // 移到 label span 的后一个 span 的开头
455
539
  if (currentIndexNow < allSpansNow.length - 1) {
456
540
  var _nextSpan = allSpansNow[currentIndexNow + 1];
457
- _newRange8.selectNodeContents(_nextSpan);
458
- _newRange8.collapse(true);
541
+ _newRange4.selectNodeContents(_nextSpan);
542
+ _newRange4.collapse(true);
459
543
  } else {
460
- _newRange8.selectNodeContents(div);
461
- _newRange8.collapse(false);
544
+ _newRange4.selectNodeContents(div);
545
+ _newRange4.collapse(false);
462
546
  }
463
547
  } else {
464
- _newRange8.selectNodeContents(_targetSpan6);
465
- _newRange8.collapse(false);
548
+ _newRange4.selectNodeContents(_targetSpan7);
549
+ _newRange4.collapse(false);
466
550
  }
467
551
  currentSpanNow.remove();
468
552
  } else if (allSpansNow.length > 1) {
469
553
  // 第一个 span 为空,移到下一个 span 的开头
470
554
  var _nextSpan2 = allSpansNow[currentIndexNow + 1];
471
- _newRange8.selectNodeContents(_nextSpan2);
472
- _newRange8.collapse(true);
555
+ _newRange4.selectNodeContents(_nextSpan2);
556
+ _newRange4.collapse(true);
473
557
  currentSpanNow.remove();
474
558
  } else {
475
559
  // 只有一个空 span,保持空
476
- _newRange8.selectNodeContents(div);
477
- _newRange8.collapse(true);
560
+ _newRange4.selectNodeContents(div);
561
+ _newRange4.collapse(true);
478
562
  }
479
563
  selection.removeAllRanges();
480
- selection.addRange(_newRange8);
564
+ selection.addRange(_newRange4);
481
565
  }
482
566
  }, 0);
483
567
  }, []);
568
+
569
+ // 递归渲染多级菜单
570
+ var renderMenuItems = function renderMenuItems(items) {
571
+ return items.map(function (opt) {
572
+ if (opt.children && opt.children.length > 0) {
573
+ return /*#__PURE__*/_jsx(Menu.SubMenu, {
574
+ title: opt.label,
575
+ className: "formula-editor-dropdown-submenu",
576
+ children: renderMenuItems(opt.children)
577
+ }, opt.value);
578
+ }
579
+ return /*#__PURE__*/_jsxs(Menu.Item, {
580
+ className: "formula-editor-dropdown-item",
581
+ onClick: function onClick() {
582
+ return handleOptionClick(opt);
583
+ },
584
+ children: [opt.label, opt.info ? /*#__PURE__*/_jsx(Tooltip, {
585
+ title: opt.info,
586
+ children: /*#__PURE__*/_jsx(InfoCircleOutlined, {
587
+ style: {
588
+ color: '#FF9900',
589
+ marginLeft: 4
590
+ }
591
+ })
592
+ }) : null]
593
+ }, opt.value);
594
+ });
595
+ };
484
596
  var dropdownContent = /*#__PURE__*/_jsx(Menu, {
485
597
  className: "formula-editor-dropdown",
486
598
  style: {
@@ -496,36 +608,39 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
496
608
  className: "formula-editor-dropdown-no-data",
497
609
  children: "\u6682\u65E0\u6570\u636E"
498
610
  })
499
- }, "no-data") : filteredHierarchyOptions.map(function (opt) {
500
- return opt.children && opt.children.length > 0 ? /*#__PURE__*/_jsx(Menu.SubMenu, {
501
- title: opt.label,
502
- className: "formula-editor-dropdown-submenu",
503
- children: opt.children.map(function (child) {
504
- return /*#__PURE__*/_jsx(Menu.Item, {
505
- className: "formula-editor-dropdown-item",
506
- onClick: function onClick() {
507
- return handleOptionClick(child);
508
- },
509
- children: child.label
510
- }, child.value);
511
- })
512
- }, opt.value) : /*#__PURE__*/_jsxs(Menu.Item, {
513
- className: "formula-editor-dropdown-item",
514
- onClick: function onClick() {
515
- return handleOptionClick(opt);
516
- },
517
- children: [opt.label, opt.info ? /*#__PURE__*/_jsx(Tooltip, {
518
- title: opt.info,
519
- children: /*#__PURE__*/_jsx(InfoCircleOutlined, {
520
- style: {
521
- color: '#FF9900',
522
- marginLeft: 4
523
- }
524
- })
525
- }) : null]
526
- }, opt.value);
527
- })
611
+ }, "no-data") : renderMenuItems(filteredHierarchyOptions)
528
612
  });
613
+ var handleChange = useCallback(function (value) {
614
+ onChange(!isNil(value) ? value : null);
615
+ }, [onChange]);
616
+ useEffect(function () {
617
+ if (isEditing) {
618
+ var _inputNumberRef$curre;
619
+ inputNumberRef === null || inputNumberRef === void 0 || (_inputNumberRef$curre = inputNumberRef.current) === null || _inputNumberRef$curre === void 0 || _inputNumberRef$curre.focus();
620
+ }
621
+ }, [isEditing]);
622
+ var reFocus = useCallback(function () {
623
+ if (isEditing) {
624
+ var _inputNumberRef$curre2;
625
+ inputNumberRef === null || inputNumberRef === void 0 || (_inputNumberRef$curre2 = inputNumberRef.current) === null || _inputNumberRef$curre2 === void 0 || _inputNumberRef$curre2.focus();
626
+ }
627
+ }, [isEditing]);
628
+ if (choseEditor && choseEditor(record)) {
629
+ var _ref3;
630
+ return /*#__PURE__*/_jsx(Input, _objectSpread(_objectSpread({
631
+ ref: inputNumberRef,
632
+ onBlur: reFocus
633
+ }, inputArgs), {}, {
634
+ className: "number-editor",
635
+ onMouseDown: function onMouseDown(e) {
636
+ return e.stopPropagation();
637
+ },
638
+ value: (_ref3 = originValue) !== null && _ref3 !== void 0 ? _ref3 : '',
639
+ onChange: function onChange(e) {
640
+ handleChange(e.target.value);
641
+ }
642
+ }));
643
+ }
529
644
  return /*#__PURE__*/_jsx(Dropdown, {
530
645
  overlayClassName: "dropDownOffset",
531
646
  overlay: dropdownContent,
@@ -544,13 +659,13 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
544
659
  spellCheck: false,
545
660
  children: isEmpty(tokens) ? /*#__PURE__*/_jsx("span", {
546
661
  style: {
547
- minWidth: 8,
662
+ minWidth: 1,
548
663
  height: 40
549
664
  }
550
665
  }) : tokens.map(function (token, index) {
551
666
  return token.type === 'end' ? /*#__PURE__*/_jsx("span", {
552
667
  style: {
553
- minWidth: 8,
668
+ minWidth: 1,
554
669
  height: 40
555
670
  }
556
671
  }, index) : /*#__PURE__*/_jsx("span", {
@@ -566,22 +681,40 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
566
681
  var flatOptions = flattenOptions(options);
567
682
 
568
683
  // checker:使用 validateCalculationExpr 校验语法 + 校验变量是否都在 options 中
569
- FormulaInputEditor.checker = function (value) {
684
+ FormulaInputEditor.checker = function (value, record, currentValue) {
570
685
  if (isNil(value)) return true;
686
+ if (choseEditor && choseEditor(record)) {
687
+ var _String;
688
+ var result = (_String = String(value)) === null || _String === void 0 ? void 0 : _String.replace(/,/g, '');
689
+ result = formulaString(result, currentValue, precision);
690
+ // parse number with thousands separator
691
+ var range = rangeMethod === null || rangeMethod === void 0 ? void 0 : rangeMethod(record);
692
+ if (!isNil(range === null || range === void 0 ? void 0 : range.max) && !isNil(range === null || range === void 0 ? void 0 : range.min)) {
693
+ var _ref4 = range || {},
694
+ _ref4$max = _ref4.max,
695
+ _max = _ref4$max === void 0 ? 0 : _ref4$max,
696
+ _ref4$min = _ref4.min,
697
+ _min = _ref4$min === void 0 ? 0 : _ref4$min;
698
+ if (result < _min || result > _max) {
699
+ warnMethod === null || warnMethod === void 0 || warnMethod(record);
700
+ return false;
701
+ }
702
+ }
703
+ if (isNaN(result)) {
704
+ return false;
705
+ }
706
+ return true;
707
+ }
571
708
  var strValue = String(value);
572
-
573
709
  // 如果以 = 开头,去掉 = 后校验
574
710
  var expr = strValue.startsWith('=') ? strValue.slice(1) : strValue;
575
711
  var parsedExpr = replaceLabelsWithValues(expr, flatOptions);
576
-
577
712
  // 空表达式不校验
578
713
  if (!parsedExpr.trim()) return true;
579
-
580
714
  // 1. 语法校验
581
715
  if (!validateCalculationExpr(parsedExpr)) {
582
716
  return false;
583
717
  }
584
-
585
718
  // 2. 变量校验:所有变量必须在 options 中
586
719
  if (!validateVariables(parsedExpr, flatOptions)) {
587
720
  return false;
@@ -590,10 +723,15 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
590
723
  };
591
724
 
592
725
  // formula:校验公式,校验成功返回 currentValue
593
- FormulaInputEditor.formula = function (value, currentValue) {
726
+ FormulaInputEditor.formula = function (value, record, currentValue) {
594
727
  if (isNil(value)) {
595
728
  return null;
596
729
  }
730
+ if (choseEditor && choseEditor(record)) {
731
+ var _String2;
732
+ var formatValue = (_String2 = String(value)) === null || _String2 === void 0 ? void 0 : _String2.replace(/,/g, '');
733
+ return formulaString(formatValue, currentValue, precision, max, min, true);
734
+ }
597
735
  var strValue = String(value);
598
736
  var hasEqualSign = strValue.startsWith('=');
599
737
  var expr = hasEqualSign ? strValue.slice(1) : strValue;
@@ -614,12 +752,21 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
614
752
  if (!validateVariables(expr, flatOptions)) {
615
753
  return Infinity;
616
754
  }
617
- return currentValue;
755
+ return value;
618
756
  };
619
757
 
620
758
  // parser:粘贴时处理,将 label 转换为 value
621
- FormulaInputEditor.parser = function (value) {
759
+ FormulaInputEditor.parser = function (value, record, currentValue) {
622
760
  if (isNil(value)) return null;
761
+ if (choseEditor && choseEditor(record)) {
762
+ var _String3;
763
+ var result = (_String3 = String(value)) === null || _String3 === void 0 ? void 0 : _String3.replace(/[,|%]/g, '');
764
+ result = formulaString(result, currentValue, precision);
765
+ if (isNil(result) || isNaN(result)) {
766
+ return null;
767
+ }
768
+ return result;
769
+ }
623
770
  var strValue = String(value);
624
771
  var hasEqualSign = strValue.startsWith('=');
625
772
  var expr = hasEqualSign ? strValue.slice(1) : strValue;
@@ -630,15 +777,24 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options) {
630
777
  };
631
778
 
632
779
  // formatter:复制时触发,将 value 转换为 label
633
- FormulaInputEditor.formatter = function (value) {
634
- if (isNil(value)) return null;
635
- var strValue = String(value);
780
+ FormulaInputEditor.formatter = function (value, record) {
781
+ if (choseEditor && choseEditor(record)) {
782
+ var _String4;
783
+ if (isNil(value) || isNaN(value)) {
784
+ return null;
785
+ }
786
+ var result = parseFloat((_String4 = String(value)) === null || _String4 === void 0 ? void 0 : _String4.replace(/,/g, ''));
787
+ return result;
788
+ }
789
+ var replaceValue = replaceIndex ? get(record, [replaceIndex]) : value;
790
+ if (isNil(replaceValue)) return null;
791
+ var strValue = String(replaceValue);
636
792
  var hasEqualSign = strValue.startsWith('=');
637
793
  var expr = hasEqualSign ? strValue.slice(1) : strValue;
638
794
 
639
795
  // 将 value 替换为 label
640
796
  var displayExpr = replaceValuesWithLabels(expr, flatOptions);
641
- return hasEqualSign ? '=' + displayExpr : displayExpr;
797
+ return hasEqualSign ? displayExpr : '=' + displayExpr;
642
798
  };
643
799
  return FormulaInputEditor;
644
800
  };
@@ -4,12 +4,13 @@
4
4
  white-space: nowrap;
5
5
  overflow: hidden;
6
6
  outline: none;
7
- min-width: 95%;
7
+ min-width: 90%;
8
8
  max-height: 100%;
9
9
  box-shadow: inset 0 -100px 0 rgba(33, 133, 208, 15%);
10
10
  position: absolute;
11
11
  top: 0;
12
12
  background: #fff;
13
+ padding-right: 8px;
13
14
  }
14
15
 
15
16
  .formula-editor-equal {
@@ -1,3 +1,4 @@
1
+ import { InputNumberProps } from "antd";
1
2
  export declare const OPERATORS: string[];
2
3
  export declare const VARIABLE_REGEX: RegExp;
3
4
  export declare const NUMBER_REGEX: RegExp;
@@ -40,7 +41,7 @@ export declare const validateVariables: (expr: string, flatOptions: {
40
41
  value: string;
41
42
  }[]) => boolean;
42
43
  /**
43
- * 扁平化选项列表(将 children 展开)
44
+ * 扁平化选项列表(只获取叶子节点)
44
45
  */
45
46
  export declare const flattenOptions: (options: {
46
47
  label: string;
@@ -57,3 +58,18 @@ export declare const longestCommonSubsequence: (arr1: string, arr2: string) => s
57
58
  export declare const getStringDiff: (str1: any, str2: any, mode?: string) => any;
58
59
  export declare const replaceLongestDiff: (a: string, str: string, position: number) => string;
59
60
  export declare const getCursorPositionInSpan: (span: any) => any;
61
+ export interface OptionItem {
62
+ label: string;
63
+ value: string;
64
+ info?: string;
65
+ children?: OptionItem[];
66
+ }
67
+ export type inputProps = Partial<Pick<InputNumberProps, 'max' | 'min' | 'addonBefore' | 'addonAfter' | 'precision'> & {
68
+ warnMethod?: (record: any) => void;
69
+ rangeMethod?: (record: any) => {
70
+ max?: number;
71
+ min?: number;
72
+ };
73
+ }>;
74
+ export declare const getSpanAtCursor: (startContainer: any) => HTMLElement | null;
75
+ export declare const moveCursorToSpan: (targetSpan: HTMLElement, atStart: boolean | undefined, selection: any) => void;
@@ -38,7 +38,7 @@ export var replaceValuesWithLabels = function replaceValuesWithLabels(expr, flat
38
38
  } finally {
39
39
  _iterator.f();
40
40
  }
41
- return result.replace(/\s/g, '');
41
+ return result.trim();
42
42
  };
43
43
 
44
44
  /**
@@ -115,6 +115,9 @@ var splitSegmentByLabels = function splitSegmentByLabels(segment, sortedLabels)
115
115
  * 有效 label 为 type 'label',其他为 'other'
116
116
  */
117
117
  export var tokenize = function tokenize(text, flatOptions) {
118
+ if (!text) {
119
+ return [];
120
+ }
118
121
  var tokens = [];
119
122
 
120
123
  // 将 value 转换为 label
@@ -204,7 +207,7 @@ export var validateVariables = function validateVariables(expr, flatOptions) {
204
207
  };
205
208
 
206
209
  /**
207
- * 扁平化选项列表(将 children 展开)
210
+ * 扁平化选项列表(只获取叶子节点)
208
211
  */
209
212
  export var flattenOptions = function flattenOptions(options) {
210
213
  var result = [];
@@ -213,12 +216,15 @@ export var flattenOptions = function flattenOptions(options) {
213
216
  try {
214
217
  for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
215
218
  var opt = _step5.value;
216
- result.push({
217
- label: opt.label,
218
- value: opt.value
219
- });
220
219
  if (opt.children && opt.children.length > 0) {
220
+ // 有 children,递归获取叶子节点,不添加当前节点
221
221
  result.push.apply(result, _toConsumableArray(flattenOptions(opt.children)));
222
+ } else {
223
+ // 没有 children,是叶子节点,添加到结果
224
+ result.push({
225
+ label: opt.label,
226
+ value: opt.value
227
+ });
222
228
  }
223
229
  }
224
230
  } catch (err) {
@@ -332,4 +338,26 @@ export var getCursorPositionInSpan = function getCursorPositionInSpan(span) {
332
338
  preCaretRange.selectNodeContents(span);
333
339
  preCaretRange.setEnd(range.startContainer, range.startOffset);
334
340
  return preCaretRange.toString().length;
341
+ };
342
+ // 获取光标所在的 span
343
+ export var getSpanAtCursor = function getSpanAtCursor(startContainer) {
344
+ if (startContainer.nodeType === Node.TEXT_NODE) {
345
+ return startContainer.parentElement;
346
+ }
347
+ if (startContainer.nodeType === Node.ELEMENT_NODE) {
348
+ return startContainer;
349
+ }
350
+ return null;
351
+ };
352
+
353
+ // 将光标移到目标 span 的开头或末尾
354
+ export var moveCursorToSpan = function moveCursorToSpan(targetSpan) {
355
+ var atStart = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
356
+ var selection = arguments.length > 2 ? arguments[2] : undefined;
357
+ if (!selection) return;
358
+ var newRange = document.createRange();
359
+ newRange.selectNodeContents(targetSpan);
360
+ newRange.collapse(atStart);
361
+ selection.removeAllRanges();
362
+ selection.addRange(newRange);
335
363
  };
@@ -257,14 +257,26 @@ var Parser = /*#__PURE__*/function () {
257
257
  return true;
258
258
  }
259
259
 
260
- // 解析基本表达式(括号、数字、百分比、变量)
261
- // factor: '(' expr ')' | NUMBER | PERCENT | REFVAR
260
+ // 解析基本表达式(括号、数字、百分比、变量、带符号的数字)
261
+ // factor: '(' expr ')' | NUMBER | PERCENT | REFVAR | ('+' | '-') factor
262
+ // 注意:一元正负号后不能紧跟另一个一元正负号
262
263
  }, {
263
264
  key: "parseFactor",
264
265
  value: function parseFactor() {
265
266
  var token = this.currentToken();
266
267
  if (!token) return false;
267
268
 
269
+ // 处理一元正负号
270
+ if (token.type === 'ADD' || token.type === 'SUB') {
271
+ this.pos++;
272
+ var nextToken = this.currentToken();
273
+ // 一元正负号后不能是另一个一元正负号
274
+ if (nextToken && (nextToken.type === 'ADD' || nextToken.type === 'SUB')) {
275
+ return false;
276
+ }
277
+ return this.parseFactor();
278
+ }
279
+
268
280
  // 处理括号表达式
269
281
  if (token.type === 'LPAREN') {
270
282
  this.pos++;
@@ -9,6 +9,7 @@ type inputProps = Partial<Pick<InputNumberProps, 'max' | 'min' | 'addonBefore' |
9
9
  min?: number;
10
10
  };
11
11
  }>;
12
+ export declare const formulaString: (value: unknown, currentValue: unknown, precision?: number, max?: number, min?: number, isEdit?: boolean) => unknown;
12
13
  export declare const NumberEditor: SheetType.CellEditor;
13
14
  export declare const getNumberEditor: (extraProps?: inputProps, getExtraProps?: ((props: SheetType.CellEditorProps) => inputProps) | undefined) => SheetType.CellEditor;
14
15
  export {};
@@ -13,7 +13,7 @@ import { evaluate } from 'mathjs';
13
13
  import { useCallback, useEffect, useRef } from 'react';
14
14
  import "./index.less";
15
15
  import { jsx as _jsx } from "react/jsx-runtime";
16
- var formulaString = function formulaString(value, currentValue, precision, max, min, isEdit) {
16
+ export var formulaString = function formulaString(value, currentValue, precision, max, min, isEdit) {
17
17
  var curNumber = currentValue !== null && currentValue !== void 0 ? currentValue : 0;
18
18
  var headStr = head(String(value).trim());
19
19
  var formula = String(value).replace('=', '');
@@ -106,7 +106,7 @@ export var getNumberEditor = function getNumberEditor(extraProps, getExtraProps)
106
106
  }
107
107
  }));
108
108
  };
109
- NumberEditor.formula = function (value, currentValue) {
109
+ NumberEditor.formula = function (value, record, currentValue) {
110
110
  var _String;
111
111
  if (isNil(value)) {
112
112
  return null;
@@ -78,15 +78,18 @@ var Cell = function Cell(props) {
78
78
  return;
79
79
  }
80
80
  if (confirm) {
81
- var _cell$dataEditor3;
81
+ var _cell$dataEditor3, _cell$dataEditor5, _cell$dataEditor6, _cell$dataEditor6$che;
82
82
  setEventState({
83
83
  confirm: false
84
84
  });
85
85
  var newValue = value;
86
+ if (newValue === valueRef.current) {
87
+ return;
88
+ }
86
89
  // 转化一下公式
87
90
  if (cell !== null && cell !== void 0 && (_cell$dataEditor3 = cell.dataEditor) !== null && _cell$dataEditor3 !== void 0 && _cell$dataEditor3.formula) {
88
91
  var _cell$dataEditor4;
89
- newValue = cell === null || cell === void 0 || (_cell$dataEditor4 = cell.dataEditor) === null || _cell$dataEditor4 === void 0 ? void 0 : _cell$dataEditor4.formula(value, valueRef.current);
92
+ newValue = cell === null || cell === void 0 || (_cell$dataEditor4 = cell.dataEditor) === null || _cell$dataEditor4 === void 0 ? void 0 : _cell$dataEditor4.formula(value, cell.record, valueRef.current);
90
93
  if (newValue === Infinity) {
91
94
  antConfirm({
92
95
  title: '公式有误',
@@ -113,20 +116,17 @@ var Cell = function Cell(props) {
113
116
  return;
114
117
  }
115
118
  }
116
- if (newValue !== valueRef.current) {
117
- var _cell$dataEditor5, _cell$dataEditor6, _cell$dataEditor6$che;
118
- if (cell !== null && cell !== void 0 && (_cell$dataEditor5 = cell.dataEditor) !== null && _cell$dataEditor5 !== void 0 && _cell$dataEditor5.checker && ((_cell$dataEditor6 = cell.dataEditor) === null || _cell$dataEditor6 === void 0 || (_cell$dataEditor6$che = _cell$dataEditor6.checker) === null || _cell$dataEditor6$che === void 0 ? void 0 : _cell$dataEditor6$che.call(_cell$dataEditor6, newValue, cell.record)) === false) {
119
- setValue(valueRef.current);
120
- return;
121
- }
122
- eventBus.emit('cell-change', {
123
- row: row,
124
- col: col,
125
- id: cell.id,
126
- value: newValue,
127
- key: cell.dataIndex
128
- });
119
+ if (cell !== null && cell !== void 0 && (_cell$dataEditor5 = cell.dataEditor) !== null && _cell$dataEditor5 !== void 0 && _cell$dataEditor5.checker && ((_cell$dataEditor6 = cell.dataEditor) === null || _cell$dataEditor6 === void 0 || (_cell$dataEditor6$che = _cell$dataEditor6.checker) === null || _cell$dataEditor6$che === void 0 ? void 0 : _cell$dataEditor6$che.call(_cell$dataEditor6, newValue, cell.record)) === false) {
120
+ setValue(valueRef.current);
121
+ return;
129
122
  }
123
+ eventBus.emit('cell-change', {
124
+ row: row,
125
+ col: col,
126
+ id: cell.id,
127
+ value: newValue,
128
+ key: cell.dataIndex
129
+ });
130
130
  }
131
131
  }, [confirm, eventBus, value, cell]);
132
132
  var handleCommit = useCallback(function (value) {
@@ -1,5 +1,5 @@
1
1
  import { SheetTableType } from "../..";
2
2
  export declare const useRowSelection: (dataSource: Record<string, unknown>[], rowSelection?: SheetTableType.TableRowSelection, hasChildren?: boolean) => [boolean[], (value: boolean[]) => void];
3
- export declare const formatSelectionData: (param: Pick<SheetTableType.TableProps, "columns" | "dataSource" | "rowKey" | "showRemark" | "rowSelection"> & {
3
+ export declare const formatSelectionData: (param: Pick<SheetTableType.TableProps, "columns" | "showRemark" | "rowSelection" | "dataSource" | "rowKey"> & {
4
4
  checked: boolean[];
5
5
  }) => any[][];
@@ -67,8 +67,7 @@ var columns = [{
67
67
  })
68
68
  }, {
69
69
  title: 'Formula',
70
- dataIndex: 'formula',
71
- key: 'formula',
70
+ dataIndex: 'amount',
72
71
  width: 200,
73
72
  cellConfig: {
74
73
  className: 'testCell'
@@ -93,7 +92,7 @@ var columns = [{
93
92
  label: '批发价',
94
93
  value: 'wholesale'
95
94
  }]
96
- }])
95
+ }], 'formula')
97
96
  }, {
98
97
  title: 'Address',
99
98
  editable: false,
@@ -142,17 +141,20 @@ var data = [{
142
141
  age: 32,
143
142
  address: 'New York No. 1 Lake Park',
144
143
  tags: ['nice', 'developer'],
145
- formula: '=price*qty'
144
+ formula: '=price*qty',
145
+ amount: 100
146
146
  }, {
147
147
  key: '2',
148
148
  name: 'Jim Green',
149
149
  age: 42,
150
150
  address: 'London No. 1 Lake Park',
151
151
  tags: ['loser'],
152
- formula: '=price+discount'
152
+ formula: '=price+discount',
153
+ amount: 100
153
154
  }, {
154
155
  key: '3',
155
156
  name: 'Joe Black',
157
+ amount: 100,
156
158
  age: 32,
157
159
  address: 'Sidney No. 1 Lake Park',
158
160
  tags: ['cool', 'teacher'],
@@ -163,14 +165,24 @@ var data = [{
163
165
  age: 92,
164
166
  address: 'Sidney No. 1 Lake Park',
165
167
  tags: ['cool', 'teacher'],
166
- formula: '=(123 + 456) * price'
168
+ formula: '=(123 + 456) * price',
169
+ amount: 100
167
170
  }, {
168
171
  key: '5',
169
172
  name: 'Joe ll',
170
173
  age: 37,
171
174
  address: 'Sidney No. 1 Lake Park',
172
175
  tags: ['cool', 'teacher'],
173
- formula: '=(123 + 456) * price + 888'
176
+ formula: '=(123 + 456) * price + 888',
177
+ amount: 100
178
+ }, {
179
+ key: '6',
180
+ name: 'Joe 23',
181
+ age: 41,
182
+ address: 'Sidney No. 1 Lake Park',
183
+ tags: ['cool', 'teacher'],
184
+ formula: '=(123 + -456) * price *-discount',
185
+ amount: 100
174
186
  }];
175
187
  var App = function App() {
176
188
  var _useState = useState(data),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhenliang/sheet",
3
- "version": "0.2.5-beta.0",
3
+ "version": "0.2.5-beta.10",
4
4
  "description": "A react library developed with dumi",
5
5
  "license": "MIT",
6
6
  "module": "dist/index.js",