@zhenliang/sheet 0.2.5-beta.6 → 0.2.5-beta.8
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.
|
@@ -74,6 +74,7 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
74
74
|
_useState10 = _slicedToArray(_useState9, 2),
|
|
75
75
|
inputAfterDropDownShow = _useState10[0],
|
|
76
76
|
setInputAfterDropDownShow = _useState10[1];
|
|
77
|
+
var tempSpanRef = useRef(null);
|
|
77
78
|
var containerRef = useRef(null);
|
|
78
79
|
var inputOperatorPosition = useRef(0);
|
|
79
80
|
|
|
@@ -123,23 +124,63 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
123
124
|
useEffect(function () {
|
|
124
125
|
if (!open) {
|
|
125
126
|
containerValueSnapShot.current = '';
|
|
127
|
+
tempSpanRef.current = null;
|
|
126
128
|
}
|
|
127
129
|
setInputAfterDropDownShow('');
|
|
128
130
|
}, [open]);
|
|
131
|
+
var closeDorpDown = useCallback(function () {
|
|
132
|
+
setInputAfterDropDownShow('');
|
|
133
|
+
tempSpanRef.current = null;
|
|
134
|
+
// 点击div内直接关闭
|
|
135
|
+
setOpen(false);
|
|
136
|
+
}, []);
|
|
129
137
|
|
|
130
|
-
//
|
|
138
|
+
// 处理选项点击
|
|
131
139
|
var handleOptionClick = useCallback(function (opt) {
|
|
132
140
|
var container = containerRef.current;
|
|
133
141
|
if (!container) return;
|
|
134
|
-
var newValue = replaceLongestDiff(containerValueSnapShot.current, opt.label, inputOperatorPosition.current);
|
|
135
142
|
setOpen(false);
|
|
136
143
|
containerValueSnapShot.current = '';
|
|
137
|
-
var expr = newValue;
|
|
138
|
-
var valueExpr = replaceLabelsWithValues(expr, flatOptions);
|
|
139
|
-
setContainerValue(valueExpr);
|
|
140
|
-
onChange(valueExpr);
|
|
141
144
|
|
|
142
|
-
//
|
|
145
|
+
// 如果有 tempSpanRef,用新逻辑:直接替换该 span 的内容
|
|
146
|
+
if (tempSpanRef.current) {
|
|
147
|
+
tempSpanRef.current.textContent = opt.label;
|
|
148
|
+
var replacedSpan = tempSpanRef.current;
|
|
149
|
+
tempSpanRef.current = null;
|
|
150
|
+
|
|
151
|
+
// 光标移到替换后的 span 后面
|
|
152
|
+
var _allSpans = Array.from(container.querySelectorAll('span'));
|
|
153
|
+
var replacedIndex = _allSpans.indexOf(replacedSpan);
|
|
154
|
+
var _targetSpan = _allSpans[replacedIndex + 1];
|
|
155
|
+
if (!_targetSpan || _targetSpan.classList.contains('formula-editor-token-label')) {
|
|
156
|
+
_targetSpan = document.createElement('span');
|
|
157
|
+
_targetSpan.className = 'formula-editor-token-other';
|
|
158
|
+
_targetSpan.textContent = '';
|
|
159
|
+
replacedSpan.after(_targetSpan);
|
|
160
|
+
}
|
|
161
|
+
var _selection = window.getSelection();
|
|
162
|
+
if (_selection && _selection.rangeCount > 0) {
|
|
163
|
+
var _newRange = document.createRange();
|
|
164
|
+
_newRange.selectNodeContents(_targetSpan);
|
|
165
|
+
_newRange.collapse(true);
|
|
166
|
+
_selection.removeAllRanges();
|
|
167
|
+
_selection.addRange(_newRange);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// 更新 containerValue
|
|
171
|
+
var newValue = container.textContent || '';
|
|
172
|
+
var valueExpr = replaceLabelsWithValues(newValue, flatOptions);
|
|
173
|
+
setContainerValue(valueExpr);
|
|
174
|
+
onChange(valueExpr);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// 原逻辑:删除 inputAfterDropDownShow,插入新 label
|
|
179
|
+
var newValueUser = replaceLongestDiff(containerValueSnapShot.current, opt.label, inputOperatorPosition.current);
|
|
180
|
+
var expr = newValueUser;
|
|
181
|
+
var valueExprUser = replaceLabelsWithValues(expr, flatOptions);
|
|
182
|
+
setContainerValue(valueExprUser);
|
|
183
|
+
onChange(valueExprUser);
|
|
143
184
|
var selection = window.getSelection();
|
|
144
185
|
if (!selection || selection.rangeCount === 0) return;
|
|
145
186
|
var range = selection.getRangeAt(0);
|
|
@@ -207,6 +248,9 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
207
248
|
var handleInput = useCallback(function () {
|
|
208
249
|
var container = containerRef.current;
|
|
209
250
|
if (!container) return;
|
|
251
|
+
if (tempSpanRef.current) {
|
|
252
|
+
closeDorpDown();
|
|
253
|
+
}
|
|
210
254
|
var newValue = container.textContent || '';
|
|
211
255
|
var processedValue = newValue;
|
|
212
256
|
var expr = processedValue;
|
|
@@ -267,12 +311,8 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
267
311
|
(_containerRef$current2 = containerRef.current) === null || _containerRef$current2 === void 0 || _containerRef$current2.focus();
|
|
268
312
|
}
|
|
269
313
|
}, [isEditing]);
|
|
270
|
-
var closeDorpDown = useCallback(function () {
|
|
271
|
-
// 点击div内直接关闭
|
|
272
|
-
setOpen(false);
|
|
273
|
-
}, []);
|
|
274
314
|
|
|
275
|
-
// 鼠标释放时,如果光标在 label span
|
|
315
|
+
// 鼠标释放时,如果光标在 label span 内,打开下拉框并记录 tempSpan
|
|
276
316
|
var handleMouseUp = useCallback(function () {
|
|
277
317
|
var div = containerRef.current;
|
|
278
318
|
if (!div) return;
|
|
@@ -285,8 +325,20 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
285
325
|
if (!currentSpan || currentSpan === div) return;
|
|
286
326
|
var isLabelSpan = currentSpan.classList.contains('formula-editor-token-label');
|
|
287
327
|
|
|
288
|
-
// 如果在 label span
|
|
328
|
+
// 如果在 label span 内,打开下拉框并记录 tempSpan
|
|
289
329
|
if (isLabelSpan) {
|
|
330
|
+
// 更新 offsetX 位置
|
|
331
|
+
var containerRect = div.getBoundingClientRect();
|
|
332
|
+
var cursorRect = range.getBoundingClientRect();
|
|
333
|
+
var cursorDistance = cursorRect ? cursorRect.left - containerRect.left : 0;
|
|
334
|
+
setOffsetX(cursorDistance < 150 ? 0 : cursorDistance - 8);
|
|
335
|
+
|
|
336
|
+
// 记录当前 label span 作为 tempSpan
|
|
337
|
+
tempSpanRef.current = currentSpan;
|
|
338
|
+
|
|
339
|
+
// 打开下拉框
|
|
340
|
+
setOpen(true);
|
|
341
|
+
// 移动到下一个 span 的开头
|
|
290
342
|
var allSpans = Array.from(div.querySelectorAll('span'));
|
|
291
343
|
var currentIndex = allSpans.indexOf(currentSpan);
|
|
292
344
|
if (currentIndex < allSpans.length - 1) {
|
|
@@ -321,13 +373,13 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
321
373
|
|
|
322
374
|
// 方向键:跳过 label span
|
|
323
375
|
if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') {
|
|
324
|
-
closeDorpDown();
|
|
325
376
|
var position = getCursorPositionInSpan(currentSpan);
|
|
326
377
|
var isAtEnd = startOffset >= textLen;
|
|
327
378
|
var isAtStart = startOffset === 0;
|
|
328
379
|
var isAlmostEnd = startOffset >= textLen - 1;
|
|
329
380
|
var isAlmostStart = position === 1;
|
|
330
381
|
if (e.key === 'ArrowRight' && isAtEnd) {
|
|
382
|
+
closeDorpDown();
|
|
331
383
|
// 向右 + 在末尾 -> 跳到下一个 span 的开头(跳过 label span)
|
|
332
384
|
var targetIndex = currentIndex + 1;
|
|
333
385
|
while (targetIndex < allSpans.length && allSpans[targetIndex].classList.contains('formula-editor-token-label')) {
|
|
@@ -343,6 +395,7 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
343
395
|
selection.addRange(newRange);
|
|
344
396
|
}
|
|
345
397
|
} else if (e.key === 'ArrowLeft' && isAtStart) {
|
|
398
|
+
closeDorpDown();
|
|
346
399
|
// 向左 + 在开头 -> 跳到上一个 span 的末尾(跳过 label span)
|
|
347
400
|
var _targetIndex = currentIndex - 1;
|
|
348
401
|
while (_targetIndex >= 0 && allSpans[_targetIndex].classList.contains('formula-editor-token-label')) {
|
|
@@ -350,34 +403,36 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
350
403
|
}
|
|
351
404
|
if (_targetIndex >= 0 && _targetIndex !== currentIndex - 1) {
|
|
352
405
|
e.preventDefault();
|
|
353
|
-
var
|
|
354
|
-
var
|
|
355
|
-
|
|
356
|
-
|
|
406
|
+
var _targetSpan2 = allSpans[_targetIndex];
|
|
407
|
+
var _newRange2 = document.createRange();
|
|
408
|
+
_newRange2.selectNodeContents(_targetSpan2);
|
|
409
|
+
_newRange2.collapse(false);
|
|
357
410
|
selection.removeAllRanges();
|
|
358
|
-
selection.addRange(
|
|
411
|
+
selection.addRange(_newRange2);
|
|
359
412
|
}
|
|
360
413
|
} else if (e.key === 'ArrowRight' && isAlmostEnd) {
|
|
414
|
+
closeDorpDown();
|
|
361
415
|
var _targetIndex2 = currentIndex + 1;
|
|
362
416
|
if (_targetIndex2 < allSpans.length && !allSpans[_targetIndex2].classList.contains('formula-editor-token-label')) {
|
|
363
417
|
e.preventDefault();
|
|
364
|
-
var
|
|
365
|
-
var
|
|
366
|
-
|
|
367
|
-
|
|
418
|
+
var _targetSpan3 = allSpans[_targetIndex2];
|
|
419
|
+
var _newRange3 = document.createRange();
|
|
420
|
+
_newRange3.selectNodeContents(_targetSpan3);
|
|
421
|
+
_newRange3.collapse(true);
|
|
368
422
|
selection.removeAllRanges();
|
|
369
|
-
selection.addRange(
|
|
423
|
+
selection.addRange(_newRange3);
|
|
370
424
|
}
|
|
371
425
|
} else if (e.key === 'ArrowLeft' && isAlmostStart) {
|
|
426
|
+
closeDorpDown();
|
|
372
427
|
var _targetIndex3 = currentIndex - 1;
|
|
373
428
|
if (_targetIndex3 >= 0 && !allSpans[_targetIndex3].classList.contains('formula-editor-token-label')) {
|
|
374
429
|
e.preventDefault();
|
|
375
|
-
var
|
|
376
|
-
var
|
|
377
|
-
|
|
378
|
-
|
|
430
|
+
var _targetSpan4 = allSpans[_targetIndex3];
|
|
431
|
+
var _newRange4 = document.createRange();
|
|
432
|
+
_newRange4.selectNodeContents(_targetSpan4);
|
|
433
|
+
_newRange4.collapse(false);
|
|
379
434
|
selection.removeAllRanges();
|
|
380
|
-
selection.addRange(
|
|
435
|
+
selection.addRange(_newRange4);
|
|
381
436
|
}
|
|
382
437
|
}
|
|
383
438
|
return;
|
|
@@ -385,7 +440,10 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
385
440
|
|
|
386
441
|
// 删除键逻辑
|
|
387
442
|
if (e.key !== 'Delete' && e.key !== 'Backspace') return;
|
|
388
|
-
if (e.key === 'Backspace') {
|
|
443
|
+
if (e.key === 'Backspace' || e.key === 'Delete') {
|
|
444
|
+
if (tempSpanRef.current) {
|
|
445
|
+
closeDorpDown();
|
|
446
|
+
}
|
|
389
447
|
// 检查删除后是否只剩一个空的 span
|
|
390
448
|
var allSpansNow = Array.from(div.querySelectorAll('span'));
|
|
391
449
|
var isOnlyOneEmptySpan = allSpansNow.length === 1 && allSpansNow[0].textContent === '';
|
|
@@ -403,31 +461,31 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
403
461
|
e.preventDefault();
|
|
404
462
|
e.stopPropagation();
|
|
405
463
|
prevSpan.remove();
|
|
406
|
-
var
|
|
464
|
+
var _newRange5 = document.createRange();
|
|
407
465
|
|
|
408
466
|
// 如果当前 span 有内容,光标放在开头;否则找最近的有内容的 span
|
|
409
467
|
if (currentSpan.textContent !== '') {
|
|
410
|
-
|
|
411
|
-
|
|
468
|
+
_newRange5.selectNodeContents(currentSpan);
|
|
469
|
+
_newRange5.collapse(true);
|
|
412
470
|
} else {
|
|
413
471
|
// 找前一个最近的有内容的 span
|
|
414
|
-
var
|
|
472
|
+
var _targetSpan5;
|
|
415
473
|
for (var i = currentIndex - 2; i >= 0; i--) {
|
|
416
474
|
if (allSpans[i].textContent !== '') {
|
|
417
|
-
|
|
475
|
+
_targetSpan5 = allSpans[i];
|
|
418
476
|
break;
|
|
419
477
|
}
|
|
420
478
|
}
|
|
421
|
-
if (
|
|
422
|
-
|
|
423
|
-
|
|
479
|
+
if (_targetSpan5) {
|
|
480
|
+
_newRange5.selectNodeContents(_targetSpan5);
|
|
481
|
+
_newRange5.collapse(false);
|
|
424
482
|
} else {
|
|
425
|
-
|
|
426
|
-
|
|
483
|
+
_newRange5.selectNodeContents(div);
|
|
484
|
+
_newRange5.collapse(true);
|
|
427
485
|
}
|
|
428
486
|
}
|
|
429
487
|
selection.removeAllRanges();
|
|
430
|
-
selection.addRange(
|
|
488
|
+
selection.addRange(_newRange5);
|
|
431
489
|
return;
|
|
432
490
|
}
|
|
433
491
|
}
|
|
@@ -443,11 +501,11 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
443
501
|
if (prevText.length > 0) {
|
|
444
502
|
_prevSpan.textContent = prevText.slice(0, -1);
|
|
445
503
|
}
|
|
446
|
-
var
|
|
447
|
-
|
|
448
|
-
|
|
504
|
+
var _newRange6 = document.createRange();
|
|
505
|
+
_newRange6.selectNodeContents(_prevSpan);
|
|
506
|
+
_newRange6.collapse(false);
|
|
449
507
|
selection.removeAllRanges();
|
|
450
|
-
selection.addRange(
|
|
508
|
+
selection.addRange(_newRange6);
|
|
451
509
|
}
|
|
452
510
|
}
|
|
453
511
|
|
|
@@ -462,73 +520,73 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
|
|
|
462
520
|
// 如果光标在 span 开头 + Delete 键,currentIndex 指向的是被删 span 的后一个,所以要 -1
|
|
463
521
|
var searchIndex = startOffset === 0 ? currentIndex - 1 : currentIndex;
|
|
464
522
|
// 从 searchIndex 位置往前找
|
|
465
|
-
var
|
|
523
|
+
var _targetSpan6;
|
|
466
524
|
for (var _i = searchIndex; _i >= 0; _i--) {
|
|
467
525
|
var span = allSpansNow[_i];
|
|
468
526
|
if (span.textContent !== '') {
|
|
469
|
-
|
|
527
|
+
_targetSpan6 = span;
|
|
470
528
|
break;
|
|
471
529
|
}
|
|
472
530
|
}
|
|
473
531
|
// 如果找到的有内容 span 是 label,则把光标放在 label span 的后一个 span 的开头
|
|
474
|
-
if (
|
|
475
|
-
var labelIndex = allSpansNow.indexOf(
|
|
532
|
+
if (_targetSpan6 && _targetSpan6.classList.contains('formula-editor-token-label')) {
|
|
533
|
+
var labelIndex = allSpansNow.indexOf(_targetSpan6);
|
|
476
534
|
if (labelIndex < allSpansNow.length - 1) {
|
|
477
535
|
var nextSpan = allSpansNow[labelIndex + 1];
|
|
478
|
-
var
|
|
479
|
-
|
|
480
|
-
|
|
536
|
+
var _newRange7 = document.createRange();
|
|
537
|
+
_newRange7.selectNodeContents(nextSpan);
|
|
538
|
+
_newRange7.collapse(true);
|
|
481
539
|
selection.removeAllRanges();
|
|
482
|
-
selection.addRange(
|
|
540
|
+
selection.addRange(_newRange7);
|
|
483
541
|
return;
|
|
484
542
|
}
|
|
485
543
|
}
|
|
486
544
|
|
|
487
545
|
// 否则把光标放在找到的 span 的末尾
|
|
488
|
-
if (
|
|
489
|
-
var
|
|
490
|
-
|
|
491
|
-
|
|
546
|
+
if (_targetSpan6) {
|
|
547
|
+
var _newRange8 = document.createRange();
|
|
548
|
+
_newRange8.selectNodeContents(_targetSpan6);
|
|
549
|
+
_newRange8.collapse(false);
|
|
492
550
|
selection.removeAllRanges();
|
|
493
|
-
selection.addRange(
|
|
551
|
+
selection.addRange(_newRange8);
|
|
494
552
|
return;
|
|
495
553
|
}
|
|
496
554
|
}
|
|
497
555
|
if (!currentSpanNow || currentSpanNow === div) return;
|
|
498
556
|
if (currentSpanNow.textContent === '') {
|
|
499
557
|
var currentIndexNow = allSpansNow.indexOf(currentSpanNow);
|
|
500
|
-
var
|
|
558
|
+
var _newRange9 = document.createRange();
|
|
501
559
|
if (currentIndexNow > 0) {
|
|
502
560
|
// 移到前一个 span 的末尾,但如果前一个 span 是 label,则移到后一个 span 的开头
|
|
503
|
-
var
|
|
504
|
-
if (
|
|
561
|
+
var _targetSpan7 = allSpansNow[currentIndexNow - 1];
|
|
562
|
+
if (_targetSpan7.classList.contains('formula-editor-token-label')) {
|
|
505
563
|
// 移到 label span 的后一个 span 的开头
|
|
506
564
|
if (currentIndexNow < allSpansNow.length - 1) {
|
|
507
565
|
var _nextSpan = allSpansNow[currentIndexNow + 1];
|
|
508
|
-
|
|
509
|
-
|
|
566
|
+
_newRange9.selectNodeContents(_nextSpan);
|
|
567
|
+
_newRange9.collapse(true);
|
|
510
568
|
} else {
|
|
511
|
-
|
|
512
|
-
|
|
569
|
+
_newRange9.selectNodeContents(div);
|
|
570
|
+
_newRange9.collapse(false);
|
|
513
571
|
}
|
|
514
572
|
} else {
|
|
515
|
-
|
|
516
|
-
|
|
573
|
+
_newRange9.selectNodeContents(_targetSpan7);
|
|
574
|
+
_newRange9.collapse(false);
|
|
517
575
|
}
|
|
518
576
|
currentSpanNow.remove();
|
|
519
577
|
} else if (allSpansNow.length > 1) {
|
|
520
578
|
// 第一个 span 为空,移到下一个 span 的开头
|
|
521
579
|
var _nextSpan2 = allSpansNow[currentIndexNow + 1];
|
|
522
|
-
|
|
523
|
-
|
|
580
|
+
_newRange9.selectNodeContents(_nextSpan2);
|
|
581
|
+
_newRange9.collapse(true);
|
|
524
582
|
currentSpanNow.remove();
|
|
525
583
|
} else {
|
|
526
584
|
// 只有一个空 span,保持空
|
|
527
|
-
|
|
528
|
-
|
|
585
|
+
_newRange9.selectNodeContents(div);
|
|
586
|
+
_newRange9.collapse(true);
|
|
529
587
|
}
|
|
530
588
|
selection.removeAllRanges();
|
|
531
|
-
selection.addRange(
|
|
589
|
+
selection.addRange(_newRange9);
|
|
532
590
|
}
|
|
533
591
|
}, 0);
|
|
534
592
|
}, []);
|
|
@@ -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