@douyinfe/semi-ui 2.10.0-beta.0 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/button/buttonGroup.tsx +2 -2
  2. package/carousel/CarouselArrow.tsx +4 -4
  3. package/carousel/CarouselIndicator.tsx +0 -1
  4. package/carousel/index.tsx +1 -3
  5. package/carousel/interface.ts +1 -2
  6. package/datePicker/monthsGrid.tsx +8 -8
  7. package/dist/css/semi.css +4 -4
  8. package/dist/css/semi.min.css +1 -1
  9. package/dist/umd/semi-ui.js +365 -211
  10. package/dist/umd/semi-ui.js.map +1 -1
  11. package/dist/umd/semi-ui.min.js +1 -1
  12. package/dist/umd/semi-ui.min.js.map +1 -1
  13. package/form/baseForm.tsx +10 -1
  14. package/form/hoc/withField.tsx +17 -5
  15. package/inputNumber/__test__/inputNumber.test.js +40 -3
  16. package/inputNumber/_story/inputNumber.stories.js +56 -1
  17. package/inputNumber/index.tsx +22 -14
  18. package/lib/cjs/button/buttonGroup.d.ts +1 -1
  19. package/lib/cjs/carousel/CarouselArrow.js +3 -6
  20. package/lib/cjs/carousel/index.js +1 -3
  21. package/lib/cjs/carousel/interface.d.ts +1 -2
  22. package/lib/cjs/datePicker/monthsGrid.js +6 -6
  23. package/lib/cjs/form/baseForm.d.ts +1 -0
  24. package/lib/cjs/form/baseForm.js +10 -1
  25. package/lib/cjs/form/hoc/withField.js +8 -1
  26. package/lib/cjs/inputNumber/index.d.ts +2 -6
  27. package/lib/cjs/inputNumber/index.js +27 -11
  28. package/lib/cjs/transfer/index.js +5 -5
  29. package/lib/cjs/treeSelect/index.js +1 -1
  30. package/lib/es/button/buttonGroup.d.ts +1 -1
  31. package/lib/es/carousel/CarouselArrow.js +3 -5
  32. package/lib/es/carousel/index.js +1 -3
  33. package/lib/es/carousel/interface.d.ts +1 -2
  34. package/lib/es/datePicker/monthsGrid.js +7 -7
  35. package/lib/es/form/baseForm.d.ts +1 -0
  36. package/lib/es/form/baseForm.js +10 -1
  37. package/lib/es/form/hoc/withField.js +8 -1
  38. package/lib/es/inputNumber/index.d.ts +2 -6
  39. package/lib/es/inputNumber/index.js +26 -11
  40. package/lib/es/transfer/index.js +1 -1
  41. package/lib/es/treeSelect/index.js +1 -1
  42. package/package.json +9 -9
  43. package/transfer/index.tsx +1 -1
  44. package/treeSelect/index.tsx +1 -1
package/form/baseForm.tsx CHANGED
@@ -122,7 +122,7 @@ class Form extends BaseComponent<BaseFormProps, BaseFormState> {
122
122
  constructor(props: BaseFormProps) {
123
123
  super(props);
124
124
  this.state = {
125
- formId: getUuidv4(),
125
+ formId: '',
126
126
  };
127
127
  warning(
128
128
  Boolean(props.component && props.render),
@@ -145,6 +145,10 @@ class Form extends BaseComponent<BaseFormProps, BaseFormState> {
145
145
  }
146
146
  }
147
147
 
148
+ componentDidMount() {
149
+ this.foundation.init();
150
+ }
151
+
148
152
  componentWillUnmount() {
149
153
  this.foundation.destroy();
150
154
  this.foundation = null;
@@ -173,6 +177,11 @@ class Form extends BaseComponent<BaseFormProps, BaseFormState> {
173
177
  notifyReset: () => {
174
178
  this.props.onReset();
175
179
  },
180
+ initFormId: () => {
181
+ this.setState({
182
+ formId: getUuidv4()
183
+ });
184
+ },
176
185
  getInitValues: () => this.props.initValues,
177
186
  getFormProps: (keys: undefined | string | Array<string>) => {
178
187
  if (typeof keys === 'undefined') {
@@ -379,12 +379,24 @@ function withField<
379
379
  return () => {};
380
380
  }
381
381
  // log('register: ' + field);
382
- updater.register(field, fieldState, {
382
+
383
+ // field value may change after field component mounted, we use ref value here to get changed value
384
+ const refValue = getVal();
385
+ updater.register(
383
386
  field,
384
- fieldApi,
385
- keepState,
386
- allowEmpty: allowEmpty || allowEmptyString,
387
- });
387
+ {
388
+ value: refValue,
389
+ error,
390
+ touched,
391
+ status,
392
+ },
393
+ {
394
+ field,
395
+ fieldApi,
396
+ keepState,
397
+ allowEmpty: allowEmpty || allowEmptyString,
398
+ }
399
+ );
388
400
  // return unRegister cb
389
401
  return () => {
390
402
  updater.unRegister(field);
@@ -6,7 +6,7 @@ import keyCode from '@douyinfe/semi-foundation/utils/keyCode';
6
6
  import * as _ from 'lodash';
7
7
  import { BASE_CLASS_PREFIX } from '../../../semi-foundation/base/constants';
8
8
  import { numbers } from '@douyinfe/semi-foundation/inputNumber/constants';
9
- import { Form, withField } from '../../index';
9
+ import { Form, withField, useFormApi } from '../../index';
10
10
 
11
11
  const log = (...args) => console.log(...args);
12
12
  const times = (n = 0, fn) => {
@@ -182,8 +182,9 @@ describe(`InputNumber`, () => {
182
182
  const inputElem = inputNumber.find('input');
183
183
 
184
184
  inputElem.simulate('change', event);
185
- expect(onChange.calledOnce).toBe(true);
186
- expect(onChange.calledWithMatch(Number(newValue.toFixed(precision)))).toBe(true);
185
+ expect(onChange.calledTwice).toBe(true);
186
+ expect(onChange.getCall(1).args[0]).toEqual(Number(newValue.toFixed(precision)));
187
+ // expect(onChange.calledWithMatch(Number(newValue.toFixed(precision)))).toBe(true);
187
188
  expect(inputElem.instance().value).toBe(formatter(newValue));
188
189
 
189
190
  inputElem.simulate('blur');
@@ -395,4 +396,40 @@ describe(`InputNumber`, () => {
395
396
  expect(onUpClick.called).toBe(false);
396
397
  expect(onDownClick.called).toBe(false);
397
398
  });
399
+
400
+ it('fix controlled min value didMount', () => {
401
+ const spyChange = sinon.spy();
402
+ const inputNumber = mount(
403
+ <InputNumber min={1} value={0} onChange={spyChange} />
404
+ );
405
+ expect(spyChange.calledOnce).toBe(true);
406
+ });
407
+
408
+ it('fix controlled min value didUpdate', () => {
409
+ const spyChange = sinon.spy();
410
+ const value = undefined;
411
+ const inputNumber = mount(
412
+ <InputNumber min={1} value={value} onChange={spyChange} />
413
+ );
414
+ inputNumber.setProps({ value: 0 });
415
+ expect(spyChange.calledTwice).toBe(true);
416
+ expect(spyChange.getCall(0).args[0]).toEqual('');
417
+ expect(spyChange.getCall(1).args[0]).toEqual(1);
418
+ });
419
+
420
+ it('fix controlled min value form field', () => {
421
+ const spyChange = sinon.spy();
422
+ let formApi = null;
423
+ let getFormApi = api => {
424
+ formApi = api;
425
+ };
426
+ const inputNumber = mount(
427
+ <Form initValues={{ minControlled: 0 }} getFormApi={getFormApi}>
428
+ <Form.InputNumber field="minControlled" min={1} onChange={spyChange} />
429
+ </Form>
430
+ );
431
+ expect(spyChange.calledOnce).toBe(true);
432
+ expect(spyChange.getCall(0).args[0]).toEqual(1);
433
+ expect(formApi.getValue('minControlled')).toBe(1);
434
+ });
398
435
  });
@@ -4,6 +4,7 @@ import './inputNumber.scss';
4
4
  import InputNumber from '../index';
5
5
  import Button from '../../button/index';
6
6
  import { withField, Form } from '../../index';
7
+ import { useFormApi } from '../../form';
7
8
 
8
9
  export default {
9
10
  title: 'InputNumber',
@@ -656,4 +657,58 @@ export const FixPrecision = () => {
656
657
  <InputNumber keepFocus onBlur={() => console.log('blur')} onChange={v => setValue2(v)} value={value2} style={{ width: 190 }} precision={2} />
657
658
  </div>
658
659
  );
659
- }
660
+ }
661
+
662
+ /**
663
+ * 受控传超出 min value 的值,需要触发 onChange
664
+ * 不然在 Form 中使用可能会导致 Form State 与 InputNumber 展示的值不同问题
665
+ */
666
+ export const FixMinValue = () => {
667
+ const [value, setValue] = useState();
668
+ const formRef = useFormApi();
669
+ return (
670
+ <div style={{ width: 280 }}>
671
+ <Button onClick={() => setValue(0)}>min=1, setValue=0</Button>
672
+ <InputNumber
673
+ min={1}
674
+ value={value}
675
+ onChange={(v, e) => {
676
+ console.log('inputNumber1 change', `'${v}'`, e);
677
+ setValue(v);
678
+ }}
679
+ />
680
+ <InputNumber
681
+ min={1}
682
+ value={0}
683
+ onChange={(v, e) => {
684
+ console.log('inputNumber2 change', v, e);
685
+ }}
686
+ />
687
+ <Form initValues={{ minControlled: 0 }}>
688
+ <Form.InputNumber
689
+ field='minControlled'
690
+ min={1}
691
+ onChange={(v, e) => {
692
+ console.log('form inputNumber change', v, e);
693
+ }}
694
+ />
695
+ </Form>
696
+ <Button onClick={() => formRef.current.setValue('minControlled', 0) }>set form value</Button>
697
+ <Button onClick={() => { console.log('form value', JSON.stringify(formRef.current.getValues()))}}>get form values</Button>
698
+ </div>
699
+ );
700
+ }
701
+ FixMinValue.storyName = 'fix min value';
702
+
703
+ /**
704
+ * fix InputNumber precision 删除后,输入非法字符显示 0.00
705
+ * https://github.com/DouyinFE/semi-design/issues/786
706
+ */
707
+ export const FixPrecision786 = () => {
708
+ return (
709
+ <div data-cy="fix-precision-786">
710
+ <InputNumber defaultValue={10.00} precision={2} />
711
+ </div>
712
+ );
713
+ }
714
+ FixPrecision786.storyName = 'fix precision 删除后输入非法值会显示 0.00';
@@ -10,13 +10,13 @@ import Input, { InputProps } from '../input';
10
10
  import { forwardStatics } from '@douyinfe/semi-foundation/utils/object';
11
11
  import isNullOrUndefined from '@douyinfe/semi-foundation/utils/isNullOrUndefined';
12
12
  import isBothNaN from '@douyinfe/semi-foundation/utils/isBothNaN';
13
- import InputNumberFoundation, { InputNumberAdapter } from '@douyinfe/semi-foundation/inputNumber/foundation';
13
+ import InputNumberFoundation, { BaseInputNumberState, InputNumberAdapter } from '@douyinfe/semi-foundation/inputNumber/foundation';
14
14
  import BaseComponent from '../_base/baseComponent';
15
15
  import { cssClasses, numbers, strings } from '@douyinfe/semi-foundation/inputNumber/constants';
16
16
  import { IconChevronUp, IconChevronDown } from '@douyinfe/semi-icons';
17
17
 
18
18
  import '@douyinfe/semi-foundation/inputNumber/inputNumber.scss';
19
- import { isNaN, noop } from 'lodash';
19
+ import { isNaN, isString, noop } from 'lodash';
20
20
  import { ArrayElement } from '../_base/base';
21
21
 
22
22
  export interface InputNumberProps extends InputProps {
@@ -54,12 +54,7 @@ export interface InputNumberProps extends InputProps {
54
54
  onUpClick?: (value: string, e: React.MouseEvent<HTMLButtonElement>) => void;
55
55
  }
56
56
 
57
- export interface InputNumberState {
58
- value?: number | string;
59
- number?: number | null; // Current parsed numbers
60
- focusing?: boolean;
61
- hovering?: boolean;
62
- }
57
+ export interface InputNumberState extends BaseInputNumberState {}
63
58
 
64
59
  class InputNumber extends BaseComponent<InputNumberProps, InputNumberState> {
65
60
  static propTypes = {
@@ -222,6 +217,9 @@ class InputNumber extends BaseComponent<InputNumberProps, InputNumberState> {
222
217
  },
223
218
  setClickUpOrDown: value => {
224
219
  this.clickUpOrDown = value;
220
+ },
221
+ updateStates: (states, callback) => {
222
+ this.setState(states, callback);
225
223
  }
226
224
  };
227
225
  }
@@ -250,13 +248,15 @@ class InputNumber extends BaseComponent<InputNumberProps, InputNumberState> {
250
248
  componentDidUpdate(prevProps: InputNumberProps) {
251
249
  const { value } = this.props;
252
250
  const { focusing } = this.state;
251
+ let newValue;
253
252
  /**
254
253
  * To determine whether the front and back are equal
255
254
  * NaN need to check whether both are NaN
256
255
  */
257
256
  if (value !== prevProps.value && !isBothNaN(value, prevProps.value)) {
258
257
  if (isNullOrUndefined(value) || value === '') {
259
- this.setState({ value: '', number: null });
258
+ newValue = '';
259
+ this.foundation.updateStates({ value: newValue, number: null });
260
260
  } else {
261
261
  let valueStr = value;
262
262
  if (typeof value === 'number') {
@@ -306,22 +306,30 @@ class InputNumber extends BaseComponent<InputNumberProps, InputNumberState> {
306
306
  */
307
307
  if (this.clickUpOrDown) {
308
308
  obj.value = this.foundation.doFormat(valueStr, true);
309
+ newValue = obj.value;
309
310
  }
310
- this.setState(obj, () => this.adapter.restoreCursor());
311
+ this.foundation.updateStates(obj, () => this.adapter.restoreCursor());
311
312
  } else if (!isNaN(toNum)) {
312
313
  // Update input content when controlled input is illegal and not NaN
313
- this.setState({ value: this.foundation.doFormat(toNum, false) });
314
+ newValue = this.foundation.doFormat(toNum, false);
315
+ this.foundation.updateStates({ value: newValue });
314
316
  } else {
315
317
  // Update input content when controlled input NaN
316
- this.setState({ value: this.foundation.doFormat(valueStr, false) });
318
+ newValue = this.foundation.doFormat(valueStr, false);
319
+ this.foundation.updateStates({ value: newValue });
317
320
  }
318
321
  } else if (this.foundation.isValidNumber(parsedNum)) {
319
- this.setState({ number: parsedNum, value: this.foundation.doFormat(parsedNum) });
322
+ newValue = this.foundation.doFormat(parsedNum);
323
+ this.foundation.updateStates({ number: parsedNum, value: newValue });
320
324
  } else {
321
325
  // Invalid digital analog blurring effect instead of controlled failure
322
- this.setState({ number: null, value: '' });
326
+ newValue = '';
327
+ this.foundation.updateStates({ number: null, value: newValue });
323
328
  }
324
329
  }
330
+ if (isString(newValue) && newValue !== String(this.props.value)) {
331
+ this.foundation.notifyChange(newValue, null);
332
+ }
325
333
  }
326
334
 
327
335
  if (!this.clickUpOrDown) {
@@ -10,7 +10,7 @@ export interface ButtonGroupProps extends BaseProps {
10
10
  size?: Size;
11
11
  theme?: Theme;
12
12
  className?: string;
13
- children?: React.ReactChild;
13
+ children?: React.ReactNode;
14
14
  'aria-label'?: React.AriaAttributes['aria-label'];
15
15
  }
16
16
  export default class ButtonGroup extends BaseComponent<ButtonGroupProps> {
@@ -14,8 +14,6 @@ var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-sta
14
14
 
15
15
  var _assign = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/assign"));
16
16
 
17
- var _throttle2 = _interopRequireDefault(require("lodash/throttle"));
18
-
19
17
  var _get2 = _interopRequireDefault(require("lodash/get"));
20
18
 
21
19
  var _react = _interopRequireDefault(require("react"));
@@ -55,8 +53,7 @@ class CarouselArrow extends _react.default.PureComponent {
55
53
  type,
56
54
  theme,
57
55
  prev,
58
- next,
59
- timing
56
+ next
60
57
  } = this.props;
61
58
  const classNames = (0, _classnames.default)({
62
59
  [_constants.cssClasses.CAROUSEL_ARROW]: true,
@@ -76,12 +73,12 @@ class CarouselArrow extends _react.default.PureComponent {
76
73
  }, /*#__PURE__*/_react.default.createElement("div", (0, _assign.default)({
77
74
  // role='button'
78
75
  className: leftClassNames,
79
- onClick: (0, _throttle2.default)(prev, timing)
76
+ onClick: prev
80
77
  }, (0, _get2.default)(this.props, 'arrowProps.leftArrow.props')), this.renderLeftIcon()), /*#__PURE__*/_react.default.createElement("div", (0, _assign.default)({
81
78
  // role='button'
82
79
  // tabIndex={0}
83
80
  className: rightClassNames,
84
- onClick: (0, _throttle2.default)(next, timing)
81
+ onClick: next
85
82
  }, (0, _get2.default)(this.props, 'arrowProps.rightArrow.props')), this.renderRightIcon()));
86
83
  }
87
84
 
@@ -100,7 +100,7 @@ class Carousel extends _baseComponent.default {
100
100
  };
101
101
 
102
102
  this.onIndicatorChange = activeIndex => {
103
- return this.foundation.throttleChange(activeIndex);
103
+ return this.foundation.onIndicatorChange(activeIndex);
104
104
  };
105
105
 
106
106
  this.getChildren = () => {
@@ -199,7 +199,6 @@ class Carousel extends _baseComponent.default {
199
199
  theme,
200
200
  arrowProps
201
201
  } = this.props;
202
- const timing = this.foundation.getSwitchingTime();
203
202
 
204
203
  if (showArrow && children.length > 1) {
205
204
  return /*#__PURE__*/_react.default.createElement(_CarouselArrow.default, {
@@ -207,7 +206,6 @@ class Carousel extends _baseComponent.default {
207
206
  theme: theme,
208
207
  prev: this.prev,
209
208
  next: this.next,
210
- timing: timing,
211
209
  arrowProps: arrowProps
212
210
  });
213
211
  }
@@ -3,7 +3,7 @@ import { strings } from '@douyinfe/semi-foundation/lib/cjs/carousel/constants';
3
3
  export interface CarouselMethod {
4
4
  next?: () => void;
5
5
  prev?: () => void;
6
- goTo?: () => void;
6
+ goTo?: (tagetIndex: number) => void;
7
7
  play?: () => void;
8
8
  stop?: () => void;
9
9
  }
@@ -50,7 +50,6 @@ export interface CarouselArrowProps {
50
50
  prev?: () => void;
51
51
  next?: () => void;
52
52
  arrowProps?: ArrowProps;
53
- timing: number;
54
53
  }
55
54
  export interface ArrowButton {
56
55
  props?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
@@ -505,7 +505,7 @@ class MonthsGrid extends _baseComponent.default {
505
505
  const dateFormat = this.foundation.getValidDateFormat();
506
506
  let startDate, endDate;
507
507
 
508
- if (type === 'dateTimeRange' && rangeStart && rangeEnd && (0, _dateFns.isSameDay)(startDate = (0, _parser.compatiableParse)(rangeStart, dateFormat, undefined, dateFnsLocale), endDate = (0, _parser.compatiableParse)(rangeEnd, dateFormat, undefined, dateFnsLocale))) {
508
+ if (type === 'dateTimeRange' && rangeStart && rangeEnd && (0, _dateFns.isSameDay)(startDate = (0, _parser.compatibleParse)(rangeStart, dateFormat, undefined, dateFnsLocale), endDate = (0, _parser.compatibleParse)(rangeEnd, dateFormat, undefined, dateFnsLocale))) {
509
509
  if (panelType === _constants.strings.PANEL_TYPE_RIGHT) {
510
510
  rangeStart && (restProps.startDate = startDate);
511
511
  } else {
@@ -591,10 +591,10 @@ class MonthsGrid extends _baseComponent.default {
591
591
 
592
592
  if (panelType === _constants.strings.PANEL_TYPE_LEFT) {
593
593
  panelDetail = monthLeft;
594
- dateText = rangeStart ? (0, _dateFns.format)((0, _parser.compatiableParse)(rangeStart, dateFormat, undefined, dateFnsLocale), FORMAT_SWITCH_DATE) : '';
594
+ dateText = rangeStart ? (0, _dateFns.format)((0, _parser.compatibleParse)(rangeStart, dateFormat, undefined, dateFnsLocale), FORMAT_SWITCH_DATE) : '';
595
595
  } else {
596
596
  panelDetail = monthRight;
597
- dateText = rangeEnd ? (0, _dateFns.format)((0, _parser.compatiableParse)(rangeEnd, dateFormat, undefined, dateFnsLocale), FORMAT_SWITCH_DATE) : '';
597
+ dateText = rangeEnd ? (0, _dateFns.format)((0, _parser.compatibleParse)(rangeEnd, dateFormat, undefined, dateFnsLocale), FORMAT_SWITCH_DATE) : '';
598
598
  }
599
599
 
600
600
  const {
@@ -603,7 +603,7 @@ class MonthsGrid extends _baseComponent.default {
603
603
  } = panelDetail;
604
604
  const monthText = showDate ? (0, _dateFns.format)(showDate, FORMAT_SWITCH_DATE) : '';
605
605
  const timeText = showDate ? (0, _dateFns.format)(showDate, formatTimePicker) : '';
606
- const showSwithIcon = (0, _includes.default)(_context3 = ['default']).call(_context3, density);
606
+ const showSwitchIcon = (0, _includes.default)(_context3 = ['default']).call(_context3, density);
607
607
  const switchCls = (0, _classnames.default)("".concat(prefixCls, "-switch"));
608
608
  const dateCls = (0, _classnames.default)({
609
609
  ["".concat(prefixCls, "-switch-date")]: true,
@@ -623,7 +623,7 @@ class MonthsGrid extends _baseComponent.default {
623
623
  "aria-label": "Switch to date panel",
624
624
  className: dateCls,
625
625
  onClick: e => this.foundation.showDatePanel(panelType)
626
- }, showSwithIcon && /*#__PURE__*/_react.default.createElement(_semiIcons.IconCalendar, {
626
+ }, showSwitchIcon && /*#__PURE__*/_react.default.createElement(_semiIcons.IconCalendar, {
627
627
  "aria-hidden": true
628
628
  }), /*#__PURE__*/_react.default.createElement("span", {
629
629
  className: textCls
@@ -632,7 +632,7 @@ class MonthsGrid extends _baseComponent.default {
632
632
  "aria-label": "Switch to time panel",
633
633
  className: timeCls,
634
634
  onClick: e => this.foundation.showTimePicker(panelType, true)
635
- }, showSwithIcon && /*#__PURE__*/_react.default.createElement(_semiIcons.IconClock, {
635
+ }, showSwitchIcon && /*#__PURE__*/_react.default.createElement(_semiIcons.IconClock, {
636
636
  "aria-hidden": true
637
637
  }), /*#__PURE__*/_react.default.createElement("span", {
638
638
  className: textCls
@@ -147,6 +147,7 @@ declare class Form extends BaseComponent<BaseFormProps, BaseFormState> {
147
147
  static Section: typeof Section;
148
148
  formApi: FormApi;
149
149
  constructor(props: BaseFormProps);
150
+ componentDidMount(): void;
150
151
  componentWillUnmount(): void;
151
152
  get adapter(): BaseFormAdapter<BaseFormProps, BaseFormState>;
152
153
  get content(): React.ReactNode;
@@ -85,7 +85,7 @@ class Form extends _baseComponent.default {
85
85
 
86
86
  super(props);
87
87
  this.state = {
88
- formId: (0, _uuid.getUuidv4)()
88
+ formId: ''
89
89
  };
90
90
  (0, _warning.default)(Boolean(props.component && props.render), '[Semi Form] You should not use <Form component> and <Form render> in ths same time; <Form render> will be ignored');
91
91
  (0, _warning.default)(props.component && props.children && !(0, _reactUtils.isEmptyChildren)(props.children), '[Semi Form] You should not use <Form component> and <Form>{children}</Form> in ths same time; <Form>{children}</Form> will be ignored');
@@ -100,6 +100,10 @@ class Form extends _baseComponent.default {
100
100
  }
101
101
  }
102
102
 
103
+ componentDidMount() {
104
+ this.foundation.init();
105
+ }
106
+
103
107
  componentWillUnmount() {
104
108
  this.foundation.destroy();
105
109
  this.foundation = null;
@@ -127,6 +131,11 @@ class Form extends _baseComponent.default {
127
131
  notifyReset: () => {
128
132
  this.props.onReset();
129
133
  },
134
+ initFormId: () => {
135
+ this.setState({
136
+ formId: (0, _uuid.getUuidv4)()
137
+ });
138
+ },
130
139
  getInitValues: () => this.props.initValues,
131
140
  getFormProps: keys => {
132
141
  if (typeof keys === 'undefined') {
@@ -413,9 +413,16 @@ function withField(Component, opts) {
413
413
  // eslint-disable-next-line @typescript-eslint/no-empty-function
414
414
  return () => {};
415
415
  } // log('register: ' + field);
416
+ // field value may change after field component mounted, we use ref value here to get changed value
416
417
 
417
418
 
418
- updater.register(field, fieldState, {
419
+ const refValue = getVal();
420
+ updater.register(field, {
421
+ value: refValue,
422
+ error,
423
+ touched,
424
+ status
425
+ }, {
419
426
  field,
420
427
  fieldApi,
421
428
  keepState,
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { InputProps } from '../input';
4
- import InputNumberFoundation, { InputNumberAdapter } from '@douyinfe/semi-foundation/lib/cjs/inputNumber/foundation';
4
+ import InputNumberFoundation, { BaseInputNumberState, InputNumberAdapter } from '@douyinfe/semi-foundation/lib/cjs/inputNumber/foundation';
5
5
  import BaseComponent from '../_base/baseComponent';
6
6
  import { strings } from '@douyinfe/semi-foundation/lib/cjs/inputNumber/constants';
7
7
  import '@douyinfe/semi-foundation/lib/cjs/inputNumber/inputNumber.css';
@@ -40,11 +40,7 @@ export interface InputNumberProps extends InputProps {
40
40
  onNumberChange?: (value: number, e?: React.ChangeEvent) => void;
41
41
  onUpClick?: (value: string, e: React.MouseEvent<HTMLButtonElement>) => void;
42
42
  }
43
- export interface InputNumberState {
44
- value?: number | string;
45
- number?: number | null;
46
- focusing?: boolean;
47
- hovering?: boolean;
43
+ export interface InputNumberState extends BaseInputNumberState {
48
44
  }
49
45
  declare class InputNumber extends BaseComponent<InputNumberProps, InputNumberState> {
50
46
  static propTypes: {
@@ -24,6 +24,8 @@ var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-sta
24
24
 
25
25
  var _noop2 = _interopRequireDefault(require("lodash/noop"));
26
26
 
27
+ var _isString2 = _interopRequireDefault(require("lodash/isString"));
28
+
27
29
  var _isNaN2 = _interopRequireDefault(require("lodash/isNaN"));
28
30
 
29
31
  var _react = _interopRequireDefault(require("react"));
@@ -300,6 +302,9 @@ class InputNumber extends _baseComponent.default {
300
302
  },
301
303
  setClickUpOrDown: value => {
302
304
  this.clickUpOrDown = value;
305
+ },
306
+ updateStates: (states, callback) => {
307
+ this.setState(states, callback);
303
308
  }
304
309
  });
305
310
  }
@@ -311,6 +316,7 @@ class InputNumber extends _baseComponent.default {
311
316
  const {
312
317
  focusing
313
318
  } = this.state;
319
+ let newValue;
314
320
  /**
315
321
  * To determine whether the front and back are equal
316
322
  * NaN need to check whether both are NaN
@@ -318,8 +324,9 @@ class InputNumber extends _baseComponent.default {
318
324
 
319
325
  if (value !== prevProps.value && !(0, _isBothNaN.default)(value, prevProps.value)) {
320
326
  if ((0, _isNullOrUndefined.default)(value) || value === '') {
321
- this.setState({
322
- value: '',
327
+ newValue = '';
328
+ this.foundation.updateStates({
329
+ value: newValue,
323
330
  number: null
324
331
  });
325
332
  } else {
@@ -375,33 +382,42 @@ class InputNumber extends _baseComponent.default {
375
382
 
376
383
  if (this.clickUpOrDown) {
377
384
  obj.value = this.foundation.doFormat(valueStr, true);
385
+ newValue = obj.value;
378
386
  }
379
387
 
380
- this.setState(obj, () => this.adapter.restoreCursor());
388
+ this.foundation.updateStates(obj, () => this.adapter.restoreCursor());
381
389
  } else if (!(0, _isNaN2.default)(toNum)) {
382
390
  // Update input content when controlled input is illegal and not NaN
383
- this.setState({
384
- value: this.foundation.doFormat(toNum, false)
391
+ newValue = this.foundation.doFormat(toNum, false);
392
+ this.foundation.updateStates({
393
+ value: newValue
385
394
  });
386
395
  } else {
387
396
  // Update input content when controlled input NaN
388
- this.setState({
389
- value: this.foundation.doFormat(valueStr, false)
397
+ newValue = this.foundation.doFormat(valueStr, false);
398
+ this.foundation.updateStates({
399
+ value: newValue
390
400
  });
391
401
  }
392
402
  } else if (this.foundation.isValidNumber(parsedNum)) {
393
- this.setState({
403
+ newValue = this.foundation.doFormat(parsedNum);
404
+ this.foundation.updateStates({
394
405
  number: parsedNum,
395
- value: this.foundation.doFormat(parsedNum)
406
+ value: newValue
396
407
  });
397
408
  } else {
398
409
  // Invalid digital analog blurring effect instead of controlled failure
399
- this.setState({
410
+ newValue = '';
411
+ this.foundation.updateStates({
400
412
  number: null,
401
- value: ''
413
+ value: newValue
402
414
  });
403
415
  }
404
416
  }
417
+
418
+ if ((0, _isString2.default)(newValue) && newValue !== String(this.props.value)) {
419
+ this.foundation.notifyChange(newValue, null);
420
+ }
405
421
  }
406
422
 
407
423
  if (!this.clickUpOrDown) {
@@ -52,7 +52,7 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
52
52
 
53
53
  var _foundation = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs/transfer/foundation"));
54
54
 
55
- var _transferUtlls = require("@douyinfe/semi-foundation/lib/cjs/transfer/transferUtlls");
55
+ var _transferUtils = require("@douyinfe/semi-foundation/lib/cjs/transfer/transferUtils");
56
56
 
57
57
  var _constants = require("@douyinfe/semi-foundation/lib/cjs/transfer/constants");
58
58
 
@@ -98,13 +98,13 @@ class Transfer extends _baseComponent.default {
98
98
  if (Boolean(dataSource) && (0, _isArray3.default)(dataSource)) {
99
99
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
100
100
  // @ts-ignore Avoid reporting errors this.state.xxx is read-only
101
- this.state.data = (0, _transferUtlls._generateDataByType)(dataSource, type);
101
+ this.state.data = (0, _transferUtils._generateDataByType)(dataSource, type);
102
102
  }
103
103
 
104
104
  if (Boolean(defaultValue) && (0, _isArray3.default)(defaultValue)) {
105
105
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
106
106
  // @ts-ignore Avoid reporting errors this.state.xxx is read-only
107
- this.state.selectedItems = (0, _transferUtlls._generateSelectedItems)(defaultValue, this.state.data);
107
+ this.state.selectedItems = (0, _transferUtils._generateSelectedItems)(defaultValue, this.state.data);
108
108
  }
109
109
 
110
110
  this.onSelectOrRemove = (0, _bind.default)(_context = this.onSelectOrRemove).call(_context, this);
@@ -124,12 +124,12 @@ class Transfer extends _baseComponent.default {
124
124
  let newSelectedItems = state.selectedItems;
125
125
 
126
126
  if (Boolean(dataSource) && (0, _isArray2.default)(dataSource)) {
127
- newData = (0, _transferUtlls._generateDataByType)(dataSource, type);
127
+ newData = (0, _transferUtils._generateDataByType)(dataSource, type);
128
128
  mergedState.data = newData;
129
129
  }
130
130
 
131
131
  if (Boolean(value) && (0, _isArray2.default)(value)) {
132
- newSelectedItems = (0, _transferUtlls._generateSelectedItems)(value, newData);
132
+ newSelectedItems = (0, _transferUtils._generateSelectedItems)(value, newData);
133
133
  mergedState.selectedItems = newSelectedItems;
134
134
  }
135
135
 
@@ -101,7 +101,7 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof _WeakMap !== "functi
101
101
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = _Object$defineProperty && _Object$getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? _Object$getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { _Object$defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
102
102
 
103
103
  const prefixcls = _constants.cssClasses.PREFIX;
104
- const prefixTree = _constants.cssClasses.PREFIXTREE;
104
+ const prefixTree = _constants.cssClasses.PREFIX_TREE;
105
105
  const key = 0;
106
106
 
107
107
  class TreeSelect extends _baseComponent.default {
@@ -10,7 +10,7 @@ export interface ButtonGroupProps extends BaseProps {
10
10
  size?: Size;
11
11
  theme?: Theme;
12
12
  className?: string;
13
- children?: React.ReactChild;
13
+ children?: React.ReactNode;
14
14
  'aria-label'?: React.AriaAttributes['aria-label'];
15
15
  }
16
16
  export default class ButtonGroup extends BaseComponent<ButtonGroupProps> {