@zhenliang/sheet 0.2.5-beta.6 → 0.2.5-beta.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/editor/InputOptionsEditor/index.d.ts +1 -14
- package/dist/core/editor/InputOptionsEditor/index.js +145 -110
- package/dist/core/editor/InputOptionsEditor/utils.d.ts +16 -0
- package/dist/core/editor/InputOptionsEditor/utils.js +22 -0
- package/dist/core/editor/InputOptionsEditor/vaildFormula.js +14 -2
- package/dist/example/basic.js +1 -1
- package/package.json +1 -1
|
@@ -1,18 +1,5 @@
|
|
|
1
1
|
import type { SheetType } from "../../../type";
|
|
2
|
-
import { InputNumberProps } from 'antd';
|
|
3
2
|
import './index.less';
|
|
4
|
-
|
|
5
|
-
label: string;
|
|
6
|
-
value: string;
|
|
7
|
-
info?: string;
|
|
8
|
-
children?: OptionItem[];
|
|
9
|
-
}
|
|
10
|
-
type inputProps = Partial<Pick<InputNumberProps, 'max' | 'min' | 'addonBefore' | 'addonAfter' | 'precision'> & {
|
|
11
|
-
warnMethod?: (record: any) => void;
|
|
12
|
-
rangeMethod?: (record: any) => {
|
|
13
|
-
max?: number;
|
|
14
|
-
min?: number;
|
|
15
|
-
};
|
|
16
|
-
}>;
|
|
3
|
+
import { OptionItem, inputProps } from './utils';
|
|
17
4
|
export declare const getFormulaInputEditor: (options: OptionItem[], replaceIndex?: string, extraProps?: inputProps, getExtraProps?: ((props: SheetType.CellEditorProps) => inputProps) | undefined, choseEditor?: ((record: any) => boolean) | undefined) => SheetType.CellEditor;
|
|
18
5
|
export default getFormulaInputEditor;
|
|
@@ -18,22 +18,28 @@ import { get, head, isEmpty, isNil } from 'lodash';
|
|
|
18
18
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
19
19
|
import { formulaString } from "../numberEditor";
|
|
20
20
|
import "./index.less";
|
|
21
|
-
import { flattenOptions, getCursorPositionInSpan, getStringDiff, replaceLabelsWithValues, replaceLongestDiff, replaceValuesWithLabels, tokenize, validateVariables } from "./utils";
|
|
21
|
+
import { flattenOptions, getCursorPositionInSpan, getSpanAtCursor, getStringDiff, moveCursorToSpan, replaceLabelsWithValues, replaceLongestDiff, replaceValuesWithLabels, tokenize, validateVariables } from "./utils";
|
|
22
22
|
import validateCalculationExpr from "./vaildFormula";
|
|
23
23
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
24
24
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
25
|
-
var OPERATORS = ['=', '+', '-', '*', '/'];
|
|
26
|
-
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
+
|
|
37
43
|
export var getFormulaInputEditor = function getFormulaInputEditor(options, replaceIndex, extraProps, getExtraProps, choseEditor) {
|
|
38
44
|
var _ref = extraProps || {},
|
|
39
45
|
warnMethod = _ref.warnMethod,
|
|
@@ -74,6 +80,7 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
74
80
|
_useState10 = _slicedToArray(_useState9, 2),
|
|
75
81
|
inputAfterDropDownShow = _useState10[0],
|
|
76
82
|
setInputAfterDropDownShow = _useState10[1];
|
|
83
|
+
var tempSpanRef = useRef(null);
|
|
77
84
|
var containerRef = useRef(null);
|
|
78
85
|
var inputOperatorPosition = useRef(0);
|
|
79
86
|
|
|
@@ -123,23 +130,56 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
123
130
|
useEffect(function () {
|
|
124
131
|
if (!open) {
|
|
125
132
|
containerValueSnapShot.current = '';
|
|
133
|
+
tempSpanRef.current = null;
|
|
126
134
|
}
|
|
127
135
|
setInputAfterDropDownShow('');
|
|
128
136
|
}, [open]);
|
|
137
|
+
var closeDorpDown = useCallback(function () {
|
|
138
|
+
setInputAfterDropDownShow('');
|
|
139
|
+
tempSpanRef.current = null;
|
|
140
|
+
// 点击div内直接关闭
|
|
141
|
+
setOpen(false);
|
|
142
|
+
}, []);
|
|
129
143
|
|
|
130
|
-
//
|
|
144
|
+
// 处理选项点击
|
|
131
145
|
var handleOptionClick = useCallback(function (opt) {
|
|
132
146
|
var container = containerRef.current;
|
|
133
147
|
if (!container) return;
|
|
134
|
-
var newValue = replaceLongestDiff(containerValueSnapShot.current, opt.label, inputOperatorPosition.current);
|
|
135
148
|
setOpen(false);
|
|
136
149
|
containerValueSnapShot.current = '';
|
|
137
|
-
var expr = newValue;
|
|
138
|
-
var valueExpr = replaceLabelsWithValues(expr, flatOptions);
|
|
139
|
-
setContainerValue(valueExpr);
|
|
140
|
-
onChange(valueExpr);
|
|
141
150
|
|
|
142
|
-
//
|
|
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);
|
|
168
|
+
|
|
169
|
+
// 更新 containerValue
|
|
170
|
+
var newValue = container.textContent || '';
|
|
171
|
+
var valueExpr = replaceLabelsWithValues(newValue, flatOptions);
|
|
172
|
+
setContainerValue(valueExpr);
|
|
173
|
+
onChange(valueExpr);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// 原逻辑:删除 inputAfterDropDownShow,插入新 label
|
|
178
|
+
var newValueUser = replaceLongestDiff(containerValueSnapShot.current, opt.label, inputOperatorPosition.current);
|
|
179
|
+
var expr = newValueUser;
|
|
180
|
+
var valueExprUser = replaceLabelsWithValues(expr, flatOptions);
|
|
181
|
+
setContainerValue(valueExprUser);
|
|
182
|
+
onChange(valueExprUser);
|
|
143
183
|
var selection = window.getSelection();
|
|
144
184
|
if (!selection || selection.rangeCount === 0) return;
|
|
145
185
|
var range = selection.getRangeAt(0);
|
|
@@ -194,19 +234,16 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
194
234
|
targetSpan.textContent = '';
|
|
195
235
|
labelSpan.after(targetSpan);
|
|
196
236
|
}
|
|
197
|
-
|
|
198
|
-
// 将光标移到目标 span 的开头
|
|
199
|
-
var newRange = document.createRange();
|
|
200
|
-
newRange.selectNodeContents(targetSpan);
|
|
201
|
-
newRange.collapse(true);
|
|
202
|
-
selection.removeAllRanges();
|
|
203
|
-
selection.addRange(newRange);
|
|
237
|
+
moveCursorToSpan(targetSpan);
|
|
204
238
|
}, [inputAfterDropDownShow]);
|
|
205
239
|
|
|
206
240
|
// 处理输入变化
|
|
207
241
|
var handleInput = useCallback(function () {
|
|
208
242
|
var container = containerRef.current;
|
|
209
243
|
if (!container) return;
|
|
244
|
+
if (tempSpanRef.current) {
|
|
245
|
+
closeDorpDown();
|
|
246
|
+
}
|
|
210
247
|
var newValue = container.textContent || '';
|
|
211
248
|
var processedValue = newValue;
|
|
212
249
|
var expr = processedValue;
|
|
@@ -267,12 +304,8 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
267
304
|
(_containerRef$current2 = containerRef.current) === null || _containerRef$current2 === void 0 || _containerRef$current2.focus();
|
|
268
305
|
}
|
|
269
306
|
}, [isEditing]);
|
|
270
|
-
var closeDorpDown = useCallback(function () {
|
|
271
|
-
// 点击div内直接关闭
|
|
272
|
-
setOpen(false);
|
|
273
|
-
}, []);
|
|
274
307
|
|
|
275
|
-
// 鼠标释放时,如果光标在 label span
|
|
308
|
+
// 鼠标释放时,如果光标在 label span 内,打开下拉框并记录 tempSpan
|
|
276
309
|
var handleMouseUp = useCallback(function () {
|
|
277
310
|
var div = containerRef.current;
|
|
278
311
|
if (!div) return;
|
|
@@ -285,8 +318,20 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
285
318
|
if (!currentSpan || currentSpan === div) return;
|
|
286
319
|
var isLabelSpan = currentSpan.classList.contains('formula-editor-token-label');
|
|
287
320
|
|
|
288
|
-
// 如果在 label span
|
|
321
|
+
// 如果在 label span 内,打开下拉框并记录 tempSpan
|
|
289
322
|
if (isLabelSpan) {
|
|
323
|
+
// 更新 offsetX 位置
|
|
324
|
+
var containerRect = div.getBoundingClientRect();
|
|
325
|
+
var cursorRect = range.getBoundingClientRect();
|
|
326
|
+
var cursorDistance = cursorRect ? cursorRect.left - containerRect.left : 0;
|
|
327
|
+
setOffsetX(cursorDistance < 150 ? 0 : cursorDistance - 8);
|
|
328
|
+
|
|
329
|
+
// 记录当前 label span 作为 tempSpan
|
|
330
|
+
tempSpanRef.current = currentSpan;
|
|
331
|
+
|
|
332
|
+
// 打开下拉框
|
|
333
|
+
setOpen(true);
|
|
334
|
+
// 移动到下一个 span 的开头
|
|
290
335
|
var allSpans = Array.from(div.querySelectorAll('span'));
|
|
291
336
|
var currentIndex = allSpans.indexOf(currentSpan);
|
|
292
337
|
if (currentIndex < allSpans.length - 1) {
|
|
@@ -298,7 +343,7 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
298
343
|
selection.addRange(newRange);
|
|
299
344
|
}
|
|
300
345
|
}
|
|
301
|
-
}, [closeDorpDown]);
|
|
346
|
+
}, [closeDorpDown, setOffsetX, setOpen]);
|
|
302
347
|
var handleKeyDown = useCallback(function (e) {
|
|
303
348
|
var _currentSpan$textCont, _currentSpan$textCont2;
|
|
304
349
|
if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
|
|
@@ -321,13 +366,13 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
321
366
|
|
|
322
367
|
// 方向键:跳过 label span
|
|
323
368
|
if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') {
|
|
324
|
-
closeDorpDown();
|
|
325
369
|
var position = getCursorPositionInSpan(currentSpan);
|
|
326
370
|
var isAtEnd = startOffset >= textLen;
|
|
327
371
|
var isAtStart = startOffset === 0;
|
|
328
372
|
var isAlmostEnd = startOffset >= textLen - 1;
|
|
329
373
|
var isAlmostStart = position === 1;
|
|
330
374
|
if (e.key === 'ArrowRight' && isAtEnd) {
|
|
375
|
+
closeDorpDown();
|
|
331
376
|
// 向右 + 在末尾 -> 跳到下一个 span 的开头(跳过 label span)
|
|
332
377
|
var targetIndex = currentIndex + 1;
|
|
333
378
|
while (targetIndex < allSpans.length && allSpans[targetIndex].classList.contains('formula-editor-token-label')) {
|
|
@@ -336,48 +381,35 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
336
381
|
if (targetIndex < allSpans.length && targetIndex !== currentIndex + 1) {
|
|
337
382
|
e.preventDefault();
|
|
338
383
|
var targetSpan = allSpans[targetIndex];
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
384
|
+
moveCursorToSpan(targetSpan);
|
|
385
|
+
}
|
|
386
|
+
} else if (e.key === 'ArrowRight' && isAlmostEnd) {
|
|
387
|
+
closeDorpDown();
|
|
388
|
+
var _targetIndex = currentIndex + 1;
|
|
389
|
+
if (_targetIndex < allSpans.length && !allSpans[_targetIndex].classList.contains('formula-editor-token-label')) {
|
|
390
|
+
e.preventDefault();
|
|
391
|
+
var _targetSpan2 = allSpans[_targetIndex];
|
|
392
|
+
moveCursorToSpan(_targetSpan2);
|
|
344
393
|
}
|
|
345
394
|
} else if (e.key === 'ArrowLeft' && isAtStart) {
|
|
395
|
+
closeDorpDown();
|
|
346
396
|
// 向左 + 在开头 -> 跳到上一个 span 的末尾(跳过 label span)
|
|
347
|
-
var
|
|
348
|
-
while (
|
|
349
|
-
|
|
397
|
+
var _targetIndex2 = currentIndex - 1;
|
|
398
|
+
while (_targetIndex2 >= 0 && allSpans[_targetIndex2].classList.contains('formula-editor-token-label')) {
|
|
399
|
+
_targetIndex2--;
|
|
350
400
|
}
|
|
351
|
-
if (
|
|
352
|
-
e.preventDefault();
|
|
353
|
-
var _targetSpan = allSpans[_targetIndex];
|
|
354
|
-
var _newRange = document.createRange();
|
|
355
|
-
_newRange.selectNodeContents(_targetSpan);
|
|
356
|
-
_newRange.collapse(false);
|
|
357
|
-
selection.removeAllRanges();
|
|
358
|
-
selection.addRange(_newRange);
|
|
359
|
-
}
|
|
360
|
-
} else if (e.key === 'ArrowRight' && isAlmostEnd) {
|
|
361
|
-
var _targetIndex2 = currentIndex + 1;
|
|
362
|
-
if (_targetIndex2 < allSpans.length && !allSpans[_targetIndex2].classList.contains('formula-editor-token-label')) {
|
|
401
|
+
if (_targetIndex2 >= 0 && _targetIndex2 !== currentIndex - 1) {
|
|
363
402
|
e.preventDefault();
|
|
364
|
-
var
|
|
365
|
-
|
|
366
|
-
_newRange2.selectNodeContents(_targetSpan2);
|
|
367
|
-
_newRange2.collapse(true);
|
|
368
|
-
selection.removeAllRanges();
|
|
369
|
-
selection.addRange(_newRange2);
|
|
403
|
+
var _targetSpan3 = allSpans[_targetIndex2];
|
|
404
|
+
moveCursorToSpan(_targetSpan3, false);
|
|
370
405
|
}
|
|
371
406
|
} else if (e.key === 'ArrowLeft' && isAlmostStart) {
|
|
407
|
+
closeDorpDown();
|
|
372
408
|
var _targetIndex3 = currentIndex - 1;
|
|
373
409
|
if (_targetIndex3 >= 0 && !allSpans[_targetIndex3].classList.contains('formula-editor-token-label')) {
|
|
374
410
|
e.preventDefault();
|
|
375
|
-
var
|
|
376
|
-
|
|
377
|
-
_newRange3.selectNodeContents(_targetSpan3);
|
|
378
|
-
_newRange3.collapse(false);
|
|
379
|
-
selection.removeAllRanges();
|
|
380
|
-
selection.addRange(_newRange3);
|
|
411
|
+
var _targetSpan4 = allSpans[_targetIndex3];
|
|
412
|
+
moveCursorToSpan(_targetSpan4, false);
|
|
381
413
|
}
|
|
382
414
|
}
|
|
383
415
|
return;
|
|
@@ -385,7 +417,10 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
385
417
|
|
|
386
418
|
// 删除键逻辑
|
|
387
419
|
if (e.key !== 'Delete' && e.key !== 'Backspace') return;
|
|
388
|
-
if (e.key === 'Backspace') {
|
|
420
|
+
if (e.key === 'Backspace' || e.key === 'Delete') {
|
|
421
|
+
if (tempSpanRef.current) {
|
|
422
|
+
closeDorpDown();
|
|
423
|
+
}
|
|
389
424
|
// 检查删除后是否只剩一个空的 span
|
|
390
425
|
var allSpansNow = Array.from(div.querySelectorAll('span'));
|
|
391
426
|
var isOnlyOneEmptySpan = allSpansNow.length === 1 && allSpansNow[0].textContent === '';
|
|
@@ -403,31 +438,31 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
403
438
|
e.preventDefault();
|
|
404
439
|
e.stopPropagation();
|
|
405
440
|
prevSpan.remove();
|
|
406
|
-
var
|
|
441
|
+
var newRange = document.createRange();
|
|
407
442
|
|
|
408
443
|
// 如果当前 span 有内容,光标放在开头;否则找最近的有内容的 span
|
|
409
444
|
if (currentSpan.textContent !== '') {
|
|
410
|
-
|
|
411
|
-
|
|
445
|
+
newRange.selectNodeContents(currentSpan);
|
|
446
|
+
newRange.collapse(true);
|
|
412
447
|
} else {
|
|
413
448
|
// 找前一个最近的有内容的 span
|
|
414
|
-
var
|
|
449
|
+
var _targetSpan5;
|
|
415
450
|
for (var i = currentIndex - 2; i >= 0; i--) {
|
|
416
451
|
if (allSpans[i].textContent !== '') {
|
|
417
|
-
|
|
452
|
+
_targetSpan5 = allSpans[i];
|
|
418
453
|
break;
|
|
419
454
|
}
|
|
420
455
|
}
|
|
421
|
-
if (
|
|
422
|
-
|
|
423
|
-
|
|
456
|
+
if (_targetSpan5) {
|
|
457
|
+
newRange.selectNodeContents(_targetSpan5);
|
|
458
|
+
newRange.collapse(false);
|
|
424
459
|
} else {
|
|
425
|
-
|
|
426
|
-
|
|
460
|
+
newRange.selectNodeContents(div);
|
|
461
|
+
newRange.collapse(true);
|
|
427
462
|
}
|
|
428
463
|
}
|
|
429
464
|
selection.removeAllRanges();
|
|
430
|
-
selection.addRange(
|
|
465
|
+
selection.addRange(newRange);
|
|
431
466
|
return;
|
|
432
467
|
}
|
|
433
468
|
}
|
|
@@ -443,11 +478,11 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
443
478
|
if (prevText.length > 0) {
|
|
444
479
|
_prevSpan.textContent = prevText.slice(0, -1);
|
|
445
480
|
}
|
|
446
|
-
var
|
|
447
|
-
|
|
448
|
-
|
|
481
|
+
var _newRange = document.createRange();
|
|
482
|
+
_newRange.selectNodeContents(_prevSpan);
|
|
483
|
+
_newRange.collapse(false);
|
|
449
484
|
selection.removeAllRanges();
|
|
450
|
-
selection.addRange(
|
|
485
|
+
selection.addRange(_newRange);
|
|
451
486
|
}
|
|
452
487
|
}
|
|
453
488
|
|
|
@@ -462,73 +497,73 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
462
497
|
// 如果光标在 span 开头 + Delete 键,currentIndex 指向的是被删 span 的后一个,所以要 -1
|
|
463
498
|
var searchIndex = startOffset === 0 ? currentIndex - 1 : currentIndex;
|
|
464
499
|
// 从 searchIndex 位置往前找
|
|
465
|
-
var
|
|
500
|
+
var _targetSpan6;
|
|
466
501
|
for (var _i = searchIndex; _i >= 0; _i--) {
|
|
467
502
|
var span = allSpansNow[_i];
|
|
468
503
|
if (span.textContent !== '') {
|
|
469
|
-
|
|
504
|
+
_targetSpan6 = span;
|
|
470
505
|
break;
|
|
471
506
|
}
|
|
472
507
|
}
|
|
473
508
|
// 如果找到的有内容 span 是 label,则把光标放在 label span 的后一个 span 的开头
|
|
474
|
-
if (
|
|
475
|
-
var labelIndex = allSpansNow.indexOf(
|
|
509
|
+
if (_targetSpan6 && _targetSpan6.classList.contains('formula-editor-token-label')) {
|
|
510
|
+
var labelIndex = allSpansNow.indexOf(_targetSpan6);
|
|
476
511
|
if (labelIndex < allSpansNow.length - 1) {
|
|
477
512
|
var nextSpan = allSpansNow[labelIndex + 1];
|
|
478
|
-
var
|
|
479
|
-
|
|
480
|
-
|
|
513
|
+
var _newRange2 = document.createRange();
|
|
514
|
+
_newRange2.selectNodeContents(nextSpan);
|
|
515
|
+
_newRange2.collapse(true);
|
|
481
516
|
selection.removeAllRanges();
|
|
482
|
-
selection.addRange(
|
|
517
|
+
selection.addRange(_newRange2);
|
|
483
518
|
return;
|
|
484
519
|
}
|
|
485
520
|
}
|
|
486
521
|
|
|
487
522
|
// 否则把光标放在找到的 span 的末尾
|
|
488
|
-
if (
|
|
489
|
-
var
|
|
490
|
-
|
|
491
|
-
|
|
523
|
+
if (_targetSpan6) {
|
|
524
|
+
var _newRange3 = document.createRange();
|
|
525
|
+
_newRange3.selectNodeContents(_targetSpan6);
|
|
526
|
+
_newRange3.collapse(false);
|
|
492
527
|
selection.removeAllRanges();
|
|
493
|
-
selection.addRange(
|
|
528
|
+
selection.addRange(_newRange3);
|
|
494
529
|
return;
|
|
495
530
|
}
|
|
496
531
|
}
|
|
497
532
|
if (!currentSpanNow || currentSpanNow === div) return;
|
|
498
533
|
if (currentSpanNow.textContent === '') {
|
|
499
534
|
var currentIndexNow = allSpansNow.indexOf(currentSpanNow);
|
|
500
|
-
var
|
|
535
|
+
var _newRange4 = document.createRange();
|
|
501
536
|
if (currentIndexNow > 0) {
|
|
502
537
|
// 移到前一个 span 的末尾,但如果前一个 span 是 label,则移到后一个 span 的开头
|
|
503
|
-
var
|
|
504
|
-
if (
|
|
538
|
+
var _targetSpan7 = allSpansNow[currentIndexNow - 1];
|
|
539
|
+
if (_targetSpan7.classList.contains('formula-editor-token-label')) {
|
|
505
540
|
// 移到 label span 的后一个 span 的开头
|
|
506
541
|
if (currentIndexNow < allSpansNow.length - 1) {
|
|
507
542
|
var _nextSpan = allSpansNow[currentIndexNow + 1];
|
|
508
|
-
|
|
509
|
-
|
|
543
|
+
_newRange4.selectNodeContents(_nextSpan);
|
|
544
|
+
_newRange4.collapse(true);
|
|
510
545
|
} else {
|
|
511
|
-
|
|
512
|
-
|
|
546
|
+
_newRange4.selectNodeContents(div);
|
|
547
|
+
_newRange4.collapse(false);
|
|
513
548
|
}
|
|
514
549
|
} else {
|
|
515
|
-
|
|
516
|
-
|
|
550
|
+
_newRange4.selectNodeContents(_targetSpan7);
|
|
551
|
+
_newRange4.collapse(false);
|
|
517
552
|
}
|
|
518
553
|
currentSpanNow.remove();
|
|
519
554
|
} else if (allSpansNow.length > 1) {
|
|
520
555
|
// 第一个 span 为空,移到下一个 span 的开头
|
|
521
556
|
var _nextSpan2 = allSpansNow[currentIndexNow + 1];
|
|
522
|
-
|
|
523
|
-
|
|
557
|
+
_newRange4.selectNodeContents(_nextSpan2);
|
|
558
|
+
_newRange4.collapse(true);
|
|
524
559
|
currentSpanNow.remove();
|
|
525
560
|
} else {
|
|
526
561
|
// 只有一个空 span,保持空
|
|
527
|
-
|
|
528
|
-
|
|
562
|
+
_newRange4.selectNodeContents(div);
|
|
563
|
+
_newRange4.collapse(true);
|
|
529
564
|
}
|
|
530
565
|
selection.removeAllRanges();
|
|
531
|
-
selection.addRange(
|
|
566
|
+
selection.addRange(_newRange4);
|
|
532
567
|
}
|
|
533
568
|
}, 0);
|
|
534
569
|
}, []);
|
|
@@ -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;
|
|
@@ -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) => void;
|
|
@@ -338,4 +338,26 @@ export var getCursorPositionInSpan = function getCursorPositionInSpan(span) {
|
|
|
338
338
|
preCaretRange.selectNodeContents(span);
|
|
339
339
|
preCaretRange.setEnd(range.startContainer, range.startOffset);
|
|
340
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 = window.getSelection();
|
|
357
|
+
if (!selection) return;
|
|
358
|
+
var newRange = document.createRange();
|
|
359
|
+
newRange.selectNodeContents(targetSpan);
|
|
360
|
+
newRange.collapse(atStart);
|
|
361
|
+
selection.removeAllRanges();
|
|
362
|
+
selection.addRange(newRange);
|
|
341
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++;
|
package/dist/example/basic.js
CHANGED