@zhenliang/sheet 0.2.5-beta.4 → 0.2.5-beta.6

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,4 +1,5 @@
1
1
  import type { SheetType } from "../../../type";
2
+ import { InputNumberProps } from 'antd';
2
3
  import './index.less';
3
4
  export interface OptionItem {
4
5
  label: string;
@@ -6,9 +7,12 @@ export interface OptionItem {
6
7
  info?: string;
7
8
  children?: OptionItem[];
8
9
  }
9
- export interface FormulaInputProps {
10
- options: OptionItem[];
11
- value?: string;
12
- }
13
- export declare const getFormulaInputEditor: (options: OptionItem[], replaceIndex?: string) => SheetType.CellEditor;
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
+ }>;
17
+ export declare const getFormulaInputEditor: (options: OptionItem[], replaceIndex?: string, extraProps?: inputProps, getExtraProps?: ((props: SheetType.CellEditorProps) => inputProps) | undefined, choseEditor?: ((record: any) => boolean) | undefined) => SheetType.CellEditor;
14
18
  export default getFormulaInputEditor;
@@ -11,13 +11,15 @@ 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';
14
+ function _objectDestructuringEmpty(obj) { if (obj == null) throw new TypeError("Cannot destructure " + obj); }
15
+ import { InfoCircleOutlined } from '@ant-design/icons';
16
+ import { Dropdown, Input, Menu, Tooltip } from 'antd';
15
17
  import { get, head, isEmpty, isNil } from 'lodash';
16
18
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
17
- import { InfoCircleOutlined } from '@ant-design/icons';
18
- import { flattenOptions, getStringDiff, replaceLabelsWithValues, replaceLongestDiff, replaceValuesWithLabels, tokenize, validateVariables, getCursorPositionInSpan } from "./utils";
19
- import validateCalculationExpr from "./vaildFormula";
19
+ import { formulaString } from "../numberEditor";
20
20
  import "./index.less";
21
+ import { flattenOptions, getCursorPositionInSpan, getStringDiff, 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
25
  var OPERATORS = ['=', '+', '-', '*', '/'];
@@ -32,14 +34,25 @@ var getSpanAtCursor = function getSpanAtCursor(startContainer) {
32
34
  }
33
35
  return null;
34
36
  };
35
- export var getFormulaInputEditor = function getFormulaInputEditor(options, replaceIndex) {
37
+ export var getFormulaInputEditor = function getFormulaInputEditor(options, replaceIndex, extraProps, getExtraProps, choseEditor) {
38
+ var _ref = extraProps || {},
39
+ warnMethod = _ref.warnMethod,
40
+ rangeMethod = _ref.rangeMethod,
41
+ precision = _ref.precision,
42
+ max = _ref.max,
43
+ min = _ref.min;
36
44
  var FormulaInputEditor = function FormulaInputEditor(props) {
37
45
  var _get;
38
46
  var originValue = props.value,
39
47
  onChange = props.onChange,
40
48
  isEditing = props.isEditing,
41
49
  record = props.record;
42
- var calcValue = replaceIndex ? "".concat((_get = get(record, [replaceIndex])) !== null && _get !== void 0 ? _get : '') : originValue;
50
+ // 兼容number
51
+ var inputNumberRef = useRef(null);
52
+ var _ref2 = getExtraProps ? getExtraProps(props) : extraProps !== null && extraProps !== void 0 ? extraProps : {},
53
+ inputArgs = Object.assign({}, (_objectDestructuringEmpty(_ref2), _ref2));
54
+ var replaceValue = replaceIndex ? (_get = get(record, [replaceIndex])) !== null && _get !== void 0 ? _get : '' : originValue;
55
+ var calcValue = replaceValue.startsWith('=') ? replaceValue : "=".concat(replaceValue);
43
56
  var _useState = useState(calcValue),
44
57
  _useState2 = _slicedToArray(_useState, 1),
45
58
  inputValue = _useState2[0];
@@ -48,7 +61,7 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
48
61
  offsetX = _useState4[0],
49
62
  setOffsetX = _useState4[1];
50
63
  // 为了不重新render,再写一个
51
- var _useState5 = useState(calcValue),
64
+ var _useState5 = useState(replaceValue),
52
65
  _useState6 = _slicedToArray(_useState5, 2),
53
66
  containerValue = _useState6[0],
54
67
  setContainerValue = _useState6[1];
@@ -288,7 +301,7 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
288
301
  }, [closeDorpDown]);
289
302
  var handleKeyDown = useCallback(function (e) {
290
303
  var _currentSpan$textCont, _currentSpan$textCont2;
291
- if (e.key === 'ArrowUp' || e.key === "ArrowDown") {
304
+ if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
292
305
  e.preventDefault();
293
306
  e.stopPropagation();
294
307
  return;
@@ -519,6 +532,34 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
519
532
  }
520
533
  }, 0);
521
534
  }, []);
535
+
536
+ // 递归渲染多级菜单
537
+ var renderMenuItems = function renderMenuItems(items) {
538
+ return items.map(function (opt) {
539
+ if (opt.children && opt.children.length > 0) {
540
+ return /*#__PURE__*/_jsx(Menu.SubMenu, {
541
+ title: opt.label,
542
+ className: "formula-editor-dropdown-submenu",
543
+ children: renderMenuItems(opt.children)
544
+ }, opt.value);
545
+ }
546
+ return /*#__PURE__*/_jsxs(Menu.Item, {
547
+ className: "formula-editor-dropdown-item",
548
+ onClick: function onClick() {
549
+ return handleOptionClick(opt);
550
+ },
551
+ children: [opt.label, opt.info ? /*#__PURE__*/_jsx(Tooltip, {
552
+ title: opt.info,
553
+ children: /*#__PURE__*/_jsx(InfoCircleOutlined, {
554
+ style: {
555
+ color: '#FF9900',
556
+ marginLeft: 4
557
+ }
558
+ })
559
+ }) : null]
560
+ }, opt.value);
561
+ });
562
+ };
522
563
  var dropdownContent = /*#__PURE__*/_jsx(Menu, {
523
564
  className: "formula-editor-dropdown",
524
565
  style: {
@@ -534,36 +575,39 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
534
575
  className: "formula-editor-dropdown-no-data",
535
576
  children: "\u6682\u65E0\u6570\u636E"
536
577
  })
537
- }, "no-data") : filteredHierarchyOptions.map(function (opt) {
538
- return opt.children && opt.children.length > 0 ? /*#__PURE__*/_jsx(Menu.SubMenu, {
539
- title: opt.label,
540
- className: "formula-editor-dropdown-submenu",
541
- children: opt.children.map(function (child) {
542
- return /*#__PURE__*/_jsx(Menu.Item, {
543
- className: "formula-editor-dropdown-item",
544
- onClick: function onClick() {
545
- return handleOptionClick(child);
546
- },
547
- children: child.label
548
- }, child.value);
549
- })
550
- }, opt.value) : /*#__PURE__*/_jsxs(Menu.Item, {
551
- className: "formula-editor-dropdown-item",
552
- onClick: function onClick() {
553
- return handleOptionClick(opt);
554
- },
555
- children: [opt.label, opt.info ? /*#__PURE__*/_jsx(Tooltip, {
556
- title: opt.info,
557
- children: /*#__PURE__*/_jsx(InfoCircleOutlined, {
558
- style: {
559
- color: '#FF9900',
560
- marginLeft: 4
561
- }
562
- })
563
- }) : null]
564
- }, opt.value);
565
- })
578
+ }, "no-data") : renderMenuItems(filteredHierarchyOptions)
566
579
  });
580
+ var handleChange = useCallback(function (value) {
581
+ onChange(!isNil(value) ? value : null);
582
+ }, [onChange]);
583
+ useEffect(function () {
584
+ if (isEditing) {
585
+ var _inputNumberRef$curre;
586
+ inputNumberRef === null || inputNumberRef === void 0 || (_inputNumberRef$curre = inputNumberRef.current) === null || _inputNumberRef$curre === void 0 || _inputNumberRef$curre.focus();
587
+ }
588
+ }, [isEditing]);
589
+ var reFocus = useCallback(function () {
590
+ if (isEditing) {
591
+ var _inputNumberRef$curre2;
592
+ inputNumberRef === null || inputNumberRef === void 0 || (_inputNumberRef$curre2 = inputNumberRef.current) === null || _inputNumberRef$curre2 === void 0 || _inputNumberRef$curre2.focus();
593
+ }
594
+ }, [isEditing]);
595
+ if (choseEditor && choseEditor(record)) {
596
+ var _ref3;
597
+ return /*#__PURE__*/_jsx(Input, _objectSpread(_objectSpread({
598
+ ref: inputNumberRef,
599
+ onBlur: reFocus
600
+ }, inputArgs), {}, {
601
+ className: "number-editor",
602
+ onMouseDown: function onMouseDown(e) {
603
+ return e.stopPropagation();
604
+ },
605
+ value: (_ref3 = originValue) !== null && _ref3 !== void 0 ? _ref3 : '',
606
+ onChange: function onChange(e) {
607
+ handleChange(e.target.value);
608
+ }
609
+ }));
610
+ }
567
611
  return /*#__PURE__*/_jsx(Dropdown, {
568
612
  overlayClassName: "dropDownOffset",
569
613
  overlay: dropdownContent,
@@ -604,22 +648,40 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
604
648
  var flatOptions = flattenOptions(options);
605
649
 
606
650
  // checker:使用 validateCalculationExpr 校验语法 + 校验变量是否都在 options 中
607
- FormulaInputEditor.checker = function (value) {
651
+ FormulaInputEditor.checker = function (value, record, currentValue) {
608
652
  if (isNil(value)) return true;
653
+ if (choseEditor && choseEditor(record)) {
654
+ var _String;
655
+ var result = (_String = String(value)) === null || _String === void 0 ? void 0 : _String.replace(/,/g, '');
656
+ result = formulaString(result, currentValue, precision);
657
+ // parse number with thousands separator
658
+ var range = rangeMethod === null || rangeMethod === void 0 ? void 0 : rangeMethod(record);
659
+ if (!isNil(range === null || range === void 0 ? void 0 : range.max) && !isNil(range === null || range === void 0 ? void 0 : range.min)) {
660
+ var _ref4 = range || {},
661
+ _ref4$max = _ref4.max,
662
+ _max = _ref4$max === void 0 ? 0 : _ref4$max,
663
+ _ref4$min = _ref4.min,
664
+ _min = _ref4$min === void 0 ? 0 : _ref4$min;
665
+ if (result < _min || result > _max) {
666
+ warnMethod === null || warnMethod === void 0 || warnMethod(record);
667
+ return false;
668
+ }
669
+ }
670
+ if (isNaN(result)) {
671
+ return false;
672
+ }
673
+ return true;
674
+ }
609
675
  var strValue = String(value);
610
-
611
676
  // 如果以 = 开头,去掉 = 后校验
612
677
  var expr = strValue.startsWith('=') ? strValue.slice(1) : strValue;
613
678
  var parsedExpr = replaceLabelsWithValues(expr, flatOptions);
614
-
615
679
  // 空表达式不校验
616
680
  if (!parsedExpr.trim()) return true;
617
-
618
681
  // 1. 语法校验
619
682
  if (!validateCalculationExpr(parsedExpr)) {
620
683
  return false;
621
684
  }
622
-
623
685
  // 2. 变量校验:所有变量必须在 options 中
624
686
  if (!validateVariables(parsedExpr, flatOptions)) {
625
687
  return false;
@@ -628,10 +690,15 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
628
690
  };
629
691
 
630
692
  // formula:校验公式,校验成功返回 currentValue
631
- FormulaInputEditor.formula = function (value, currentValue) {
693
+ FormulaInputEditor.formula = function (value, record, currentValue) {
632
694
  if (isNil(value)) {
633
695
  return null;
634
696
  }
697
+ if (choseEditor && choseEditor(record)) {
698
+ var _String2;
699
+ var formatValue = (_String2 = String(value)) === null || _String2 === void 0 ? void 0 : _String2.replace(/,/g, '');
700
+ return formulaString(formatValue, currentValue, precision, max, min, true);
701
+ }
635
702
  var strValue = String(value);
636
703
  var hasEqualSign = strValue.startsWith('=');
637
704
  var expr = hasEqualSign ? strValue.slice(1) : strValue;
@@ -656,8 +723,17 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
656
723
  };
657
724
 
658
725
  // parser:粘贴时处理,将 label 转换为 value
659
- FormulaInputEditor.parser = function (value) {
726
+ FormulaInputEditor.parser = function (value, record, currentValue) {
660
727
  if (isNil(value)) return null;
728
+ if (choseEditor && choseEditor(record)) {
729
+ var _String3;
730
+ var result = (_String3 = String(value)) === null || _String3 === void 0 ? void 0 : _String3.replace(/[,|%]/g, '');
731
+ result = formulaString(result, currentValue, precision);
732
+ if (isNil(result) || isNaN(result)) {
733
+ return null;
734
+ }
735
+ return result;
736
+ }
661
737
  var strValue = String(value);
662
738
  var hasEqualSign = strValue.startsWith('=');
663
739
  var expr = hasEqualSign ? strValue.slice(1) : strValue;
@@ -668,15 +744,24 @@ export var getFormulaInputEditor = function getFormulaInputEditor(options, repla
668
744
  };
669
745
 
670
746
  // formatter:复制时触发,将 value 转换为 label
671
- FormulaInputEditor.formatter = function (value) {
672
- if (isNil(value)) return null;
673
- var strValue = String(value);
747
+ FormulaInputEditor.formatter = function (value, record) {
748
+ if (choseEditor && choseEditor(record)) {
749
+ var _String4;
750
+ if (isNil(value) || isNaN(value)) {
751
+ return null;
752
+ }
753
+ var result = parseFloat((_String4 = String(value)) === null || _String4 === void 0 ? void 0 : _String4.replace(/,/g, ''));
754
+ return result;
755
+ }
756
+ var replaceValue = replaceIndex ? get(record, [replaceIndex]) : value;
757
+ if (isNil(replaceValue)) return null;
758
+ var strValue = String(replaceValue);
674
759
  var hasEqualSign = strValue.startsWith('=');
675
760
  var expr = hasEqualSign ? strValue.slice(1) : strValue;
676
761
 
677
762
  // 将 value 替换为 label
678
763
  var displayExpr = replaceValuesWithLabels(expr, flatOptions);
679
- return hasEqualSign ? '=' + displayExpr : displayExpr;
764
+ return hasEqualSign ? displayExpr : '=' + displayExpr;
680
765
  };
681
766
  return FormulaInputEditor;
682
767
  };
@@ -40,7 +40,7 @@ export declare const validateVariables: (expr: string, flatOptions: {
40
40
  value: string;
41
41
  }[]) => boolean;
42
42
  /**
43
- * 扁平化选项列表(将 children 展开)
43
+ * 扁平化选项列表(只获取叶子节点)
44
44
  */
45
45
  export declare const flattenOptions: (options: {
46
46
  label: string;
@@ -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
  /**
@@ -207,7 +207,7 @@ export var validateVariables = function validateVariables(expr, flatOptions) {
207
207
  };
208
208
 
209
209
  /**
210
- * 扁平化选项列表(将 children 展开)
210
+ * 扁平化选项列表(只获取叶子节点)
211
211
  */
212
212
  export var flattenOptions = function flattenOptions(options) {
213
213
  var result = [];
@@ -216,12 +216,15 @@ export var flattenOptions = function flattenOptions(options) {
216
216
  try {
217
217
  for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
218
218
  var opt = _step5.value;
219
- result.push({
220
- label: opt.label,
221
- value: opt.value
222
- });
223
219
  if (opt.children && opt.children.length > 0) {
220
+ // 有 children,递归获取叶子节点,不添加当前节点
224
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
+ });
225
228
  }
226
229
  }
227
230
  } catch (err) {
@@ -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;
@@ -89,7 +89,7 @@ var Cell = function Cell(props) {
89
89
  // 转化一下公式
90
90
  if (cell !== null && cell !== void 0 && (_cell$dataEditor3 = cell.dataEditor) !== null && _cell$dataEditor3 !== void 0 && _cell$dataEditor3.formula) {
91
91
  var _cell$dataEditor4;
92
- 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);
93
93
  if (newValue === Infinity) {
94
94
  antConfirm({
95
95
  title: '公式有误',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhenliang/sheet",
3
- "version": "0.2.5-beta.4",
3
+ "version": "0.2.5-beta.6",
4
4
  "description": "A react library developed with dumi",
5
5
  "license": "MIT",
6
6
  "module": "dist/index.js",