@douyinfe/semi-ui 2.3.0 → 2.4.1

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 (73) hide show
  1. package/datePicker/_story/RenderDate/index.js +13 -3
  2. package/datePicker/_story/RenderFullDate/index.js +36 -14
  3. package/datePicker/_story/RenderFullDate/index.scss +1 -1
  4. package/datePicker/_story/datePicker.stories.js +19 -11
  5. package/datePicker/_story/v2/PanelOpen.jsx +39 -0
  6. package/datePicker/_story/v2/index.js +2 -1
  7. package/datePicker/datePicker.tsx +1 -0
  8. package/dist/css/semi.css +34 -9
  9. package/dist/css/semi.min.css +1 -1
  10. package/dist/umd/semi-ui.js +92 -33
  11. package/dist/umd/semi-ui.js.map +1 -1
  12. package/dist/umd/semi-ui.min.js +1 -1
  13. package/dist/umd/semi-ui.min.js.map +1 -1
  14. package/dropdown/index.tsx +11 -3
  15. package/form/_story/demo.jsx +1 -0
  16. package/input/index.tsx +1 -0
  17. package/input/textarea.tsx +6 -4
  18. package/inputNumber/__test__/inputNumber.test.js +36 -8
  19. package/inputNumber/index.tsx +2 -1
  20. package/lib/cjs/datePicker/datePicker.js +12 -8
  21. package/lib/cjs/dropdown/index.d.ts +10 -3
  22. package/lib/cjs/input/index.js +2 -1
  23. package/lib/cjs/input/textarea.js +5 -3
  24. package/lib/cjs/inputNumber/index.js +3 -2
  25. package/lib/cjs/list/index.d.ts +4 -4
  26. package/lib/cjs/navigation/Item.js +1 -1
  27. package/lib/cjs/navigation/SubNav.js +1 -1
  28. package/lib/cjs/scrollList/scrollItem.d.ts +5 -1
  29. package/lib/cjs/scrollList/scrollItem.js +7 -0
  30. package/lib/cjs/select/index.js +1 -1
  31. package/lib/cjs/table/Table.js +9 -5
  32. package/lib/cjs/timePicker/TimePicker.d.ts +2 -0
  33. package/lib/cjs/timePicker/TimePicker.js +4 -4
  34. package/lib/cjs/timePicker/index.d.ts +1 -0
  35. package/lib/cjs/tree/treeNode.js +10 -1
  36. package/lib/cjs/treeSelect/index.js +11 -3
  37. package/lib/cjs/typography/util.js +0 -1
  38. package/lib/es/datePicker/datePicker.js +12 -8
  39. package/lib/es/dropdown/index.d.ts +10 -3
  40. package/lib/es/input/index.js +2 -1
  41. package/lib/es/input/textarea.js +5 -3
  42. package/lib/es/inputNumber/index.js +3 -2
  43. package/lib/es/list/index.d.ts +4 -4
  44. package/lib/es/navigation/Item.js +1 -1
  45. package/lib/es/navigation/SubNav.js +1 -1
  46. package/lib/es/scrollList/scrollItem.d.ts +5 -1
  47. package/lib/es/scrollList/scrollItem.js +7 -0
  48. package/lib/es/select/index.js +1 -1
  49. package/lib/es/table/Table.js +9 -5
  50. package/lib/es/timePicker/TimePicker.d.ts +2 -0
  51. package/lib/es/timePicker/TimePicker.js +4 -4
  52. package/lib/es/timePicker/index.d.ts +1 -0
  53. package/lib/es/tree/treeNode.js +9 -1
  54. package/lib/es/treeSelect/index.js +12 -4
  55. package/lib/es/typography/util.js +0 -1
  56. package/list/index.tsx +5 -5
  57. package/navigation/Item.tsx +1 -1
  58. package/navigation/SubNav.tsx +1 -1
  59. package/package.json +9 -8
  60. package/scrollList/scrollItem.tsx +10 -3
  61. package/select/index.tsx +6 -1
  62. package/table/Table.tsx +9 -6
  63. package/table/_story/table.stories.js +2 -0
  64. package/table/_story/v2/FixedColumnsChange/index.jsx +104 -0
  65. package/table/_story/v2/FixedZIndex/index.jsx +87 -0
  66. package/timePicker/TimePicker.tsx +4 -1
  67. package/timePicker/__test__/timePicker.test.js +42 -3
  68. package/timePicker/_story/timepicker.stories.js +18 -0
  69. package/tree/treeNode.tsx +9 -2
  70. package/treeSelect/__test__/treeSelect.test.js +157 -0
  71. package/treeSelect/index.tsx +21 -12
  72. package/typography/_story/typography.stories.js +8 -0
  73. package/typography/util.tsx +0 -1
@@ -0,0 +1,87 @@
1
+ import React from 'react';
2
+ import { Table, Tooltip, Tag } from '@douyinfe/semi-ui';
3
+
4
+ App.storyName = 'fixed z-index bug';
5
+ export default function App() {
6
+ const columns = [
7
+ {
8
+ title: 'Name',
9
+ dataIndex: 'name',
10
+ width: 150,
11
+ fixed: true,
12
+ filters: [
13
+ {
14
+ text: 'King 3',
15
+ value: 'King 3',
16
+ },
17
+ {
18
+ text: 'King 4',
19
+ value: 'King 4',
20
+ },
21
+ ],
22
+ onFilter: (value, record) => record.name.includes(value),
23
+ },
24
+ {
25
+ title: 'Age',
26
+ dataIndex: 'age',
27
+ width: 150,
28
+ sorter: (a, b) => (a.age - b.age > 0 ? 1 : -1),
29
+ },
30
+ {
31
+ title: 'Address',
32
+ width: 200,
33
+ dataIndex: 'address',
34
+ },
35
+ {
36
+ title: 'Description',
37
+ // width: 400,
38
+ dataIndex: 'description',
39
+ },
40
+ {
41
+ fixed: 'right',
42
+ width: 250,
43
+ render: (text, record) => <Tooltip content={record.description}><Tag color="green">Show Info</Tag></Tooltip>
44
+ }
45
+ ];
46
+
47
+ let data = [];
48
+
49
+ const rowSelection = {
50
+ onChange: (selectedRowKeys, selectedRows) => {
51
+ // console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
52
+ },
53
+ getCheckboxProps: record => ({
54
+ disabled: record.name === 'Michael James', // Column configuration not to be checked
55
+ name: record.name,
56
+ }),
57
+ // fixed: true,
58
+ };
59
+
60
+ for (let i = 0; i < 46; i++) {
61
+ let age = (i * 1000) % 149;
62
+ let name = `Edward King ${i}`;
63
+ data.push({
64
+ key: `${ i}`,
65
+ name,
66
+ age,
67
+ address: `London, Park Lane no. ${i}`,
68
+ description: `My name is ${name}, I am ${age} years old, living in New York No. ${i + 1} Lake Park.`,
69
+ });
70
+ }
71
+
72
+ const scroll = { y: 300, x: 1500 };
73
+
74
+ return (
75
+ <div style={{ position: 'relative', height: '100vh' }}>
76
+ <div style={{ height: 60, background: 'red', position: 'absolute', top: 0, left: 0, right: 0, zIndex: 2 }}>
77
+ Fixed Header
78
+ </div>
79
+ <Table
80
+ columns={columns}
81
+ dataSource={data}
82
+ scroll={scroll}
83
+ rowSelection={rowSelection}
84
+ />
85
+ </div>
86
+ );
87
+ }
@@ -90,6 +90,7 @@ export type TimePickerProps = {
90
90
  zIndex?: number | string;
91
91
  onBlur?: React.FocusEventHandler<HTMLInputElement>;
92
92
  onChange?: TimePickerAdapter['notifyChange'];
93
+ onChangeWithDateFirst?: boolean;
93
94
  onFocus?: React.FocusEventHandler<HTMLInputElement>;
94
95
  onOpenChange?: (open: boolean) => void;
95
96
  };
@@ -187,6 +188,7 @@ export default class TimePicker extends BaseComponent<TimePickerProps, TimePicke
187
188
  onFocus: noop,
188
189
  onBlur: noop,
189
190
  onChange: noop,
191
+ onChangeWithDateFirst: true,
190
192
  use12Hours: false,
191
193
  focusOnOpen: false,
192
194
  onKeyDown: noop,
@@ -257,7 +259,7 @@ export default class TimePicker extends BaseComponent<TimePickerProps, TimePicke
257
259
  }
258
260
  },
259
261
  notifyOpenChange: (...args) => this.props.onOpenChange(...args),
260
- notifyChange: (...args) => this.props.onChange && this.props.onChange(...args),
262
+ notifyChange: (agr1, arg2) => this.props.onChange && this.props.onChange(agr1, arg2),
261
263
  notifyFocus: (...args) => this.props.onFocus && this.props.onFocus(...args),
262
264
  notifyBlur: (...args) => this.props.onBlur && this.props.onBlur(...args),
263
265
  isRangePicker: () => this.props.type === strings.TYPE_TIME_RANGE_PICKER,
@@ -447,6 +449,7 @@ export default class TimePicker extends BaseComponent<TimePickerProps, TimePicke
447
449
  panelFooter,
448
450
  rangeSeparator,
449
451
  onOpenChange,
452
+ onChangeWithDateFirst,
450
453
  popupClassName: propPopupClassName,
451
454
  hideDisabledOptions,
452
455
  use12Hours,
@@ -22,11 +22,13 @@ describe(`TimePicker`, () => {
22
22
  const defaultMinute = 24;
23
23
  const defaultSeconds = 18;
24
24
 
25
- const onFoucs = sinon.spy();
25
+ const onFocus = sinon.spy();
26
+ const onChange = sinon.spy();
26
27
 
27
28
  const elem = mount(
28
29
  <TimePicker
29
- onFocus={onFoucs}
30
+ onChange={onChange}
31
+ onFocus={onFocus}
30
32
  panelHeader={<strong>Select Time</strong>}
31
33
  locale={Locale.TimePicker}
32
34
  localeCode={Locale.code}
@@ -59,7 +61,7 @@ describe(`TimePicker`, () => {
59
61
  // focus
60
62
  elem.find(`input`).simulate('focus');
61
63
  await sleep(200);
62
- expect(onFoucs.calledOnce).toBeTruthy();
64
+ expect(onFocus.calledOnce).toBeTruthy();
63
65
 
64
66
  // input value
65
67
  const newInputHour = 10;
@@ -82,6 +84,12 @@ describe(`TimePicker`, () => {
82
84
 
83
85
  await sleep(200);
84
86
  expect(elem.state('open')).toBe(false);
87
+
88
+ expect(onChange.called).toBeTruthy();
89
+ const args = onChange.getCall(0).args;
90
+ expect(args[0] instanceof Date).toBe(true);
91
+ expect(typeof args[1]).toBe('string');
92
+ elem.unmount();
85
93
  });
86
94
 
87
95
  it(`test controlled value`, async () => {
@@ -113,6 +121,7 @@ describe(`TimePicker`, () => {
113
121
  let currentDate0 = elem0.state('value')[0];
114
122
 
115
123
  expect(currentDate0.getMinutes()).toBe(defaultMinute);
124
+ elem0.unmount();
116
125
  });
117
126
 
118
127
  it(`test controlled value with onchange`, async () => {
@@ -149,6 +158,7 @@ describe(`TimePicker`, () => {
149
158
 
150
159
  let currentDate1 = elem1.state('value')[0];
151
160
  expect(currentDate1.getMinutes()).toBe(newInputMinute);
161
+ elem1.unmount();
152
162
  });
153
163
 
154
164
  it(`test controlled open`, async () => {
@@ -227,6 +237,7 @@ describe(`TimePicker`, () => {
227
237
  nextSelectedLi.simulate('click');
228
238
  await sleep(200);
229
239
  expect(elem.state('value')[0].getHours()).toBe(newHour);
240
+ elem.unmount();
230
241
  });
231
242
 
232
243
  it('test isTimeFormatLike function', () => {
@@ -279,5 +290,33 @@ describe(`TimePicker`, () => {
279
290
  const args = onChange.getCall(0).args;
280
291
  expect(args[0]).toBe(undefined);
281
292
  expect(args[1]).toBe('');
293
+ elem.unmount();
294
+ });
295
+
296
+ it('test onChangeWithDateFirst=false', async () => {
297
+ const onChange = sinon.spy();
298
+ let props = {
299
+ defaultValue: "10:23:15",
300
+ onChange,
301
+ defaultOpen: true,
302
+ onChangeWithDateFirst: false,
303
+ autofocus: true,
304
+ locale: Locale.TimePicker,
305
+ localeCode: Locale.code,
306
+ scrollItemProps: { cycled: false }
307
+ };
308
+ const elem = mount(<TimePicker {...props} />);
309
+ // click minute
310
+ const minuteUl = elem.find(`.${BASE_CLASS_PREFIX}-timepicker-panel-list-minute .${BASE_CLASS_PREFIX}-scrolllist-list-outer ul`);
311
+ const minuteLis = minuteUl.find(`li`);
312
+
313
+ minuteUl.simulate('click', { target: minuteLis.at(0).getDOMNode(), nativeEvent: null });
314
+ await sleep(200);
315
+
316
+ expect(onChange.called).toBeTruthy();
317
+ const args = onChange.getCall(0).args;
318
+ expect(typeof args[0]).toBe('string');
319
+ expect(args[1] instanceof Date).toBe(true);
320
+ elem.unmount();
282
321
  });
283
322
  });
@@ -262,3 +262,21 @@ export const ShowClear = () => (
262
262
  />
263
263
  </>
264
264
  );
265
+
266
+
267
+ export const TimePickerWithOnChangeWithDateFirst = () => {
268
+ return (
269
+ <div>
270
+ onChangeWithDateFirst=true (default)
271
+ <TimePicker onChange={(...val) => console.log(...val)} />
272
+ <br />
273
+ onChangeWithDateFirst=false
274
+ <TimePicker onChangeWithDateFirst={false} onChange={(...val) => console.log(...val)} />
275
+
276
+ </div>
277
+ );
278
+ };
279
+
280
+ TimePickerWithOnChangeWithDateFirst.story = {
281
+ name: 'OnChangeWithDateFirst',
282
+ };
package/tree/treeNode.tsx CHANGED
@@ -3,7 +3,7 @@ import cls from 'classnames';
3
3
  import PropTypes from 'prop-types';
4
4
  import { cssClasses } from '@douyinfe/semi-foundation/tree/constants';
5
5
  import isEnterPress from '@douyinfe/semi-foundation/utils/isEnterPress';
6
- import { debounce, isFunction, isString, get } from 'lodash';
6
+ import { debounce, isFunction, isString, get, isEmpty } from 'lodash';
7
7
  import { IconTreeTriangleDown, IconFile, IconFolder, IconFolderOpen } from '@douyinfe/semi-icons';
8
8
  import { Checkbox } from '../checkbox';
9
9
  import TreeContext from './treeContext';
@@ -392,7 +392,14 @@ export default class TreeNode extends PureComponent<TreeNodeProps, TreeNodeState
392
392
  ...dragProps
393
393
  });
394
394
  } else {
395
- return customLabel;
395
+ if (isEmpty(style)) {
396
+ return customLabel;
397
+ } else {
398
+ // In virtualization, props.style will contain location information
399
+ return React.cloneElement(customLabel, {
400
+ style: { ...get(customLabel, ['props', 'style']), ...style }
401
+ });
402
+ }
396
403
  }
397
404
  }
398
405
  const labelCls = cls(`${prefixcls}-label`, {
@@ -97,6 +97,26 @@ const treeData2 = [
97
97
  }
98
98
  ];
99
99
 
100
+ const treeData3 = [
101
+ {
102
+ label: '亚洲',
103
+ value: 'Asia',
104
+ key: '0',
105
+ children: [
106
+ {
107
+ label: '中国',
108
+ value: 'China',
109
+ key: '0-0',
110
+ },
111
+ ],
112
+ },
113
+ {
114
+ label: '北美洲',
115
+ value: 'North America',
116
+ key: '1',
117
+ }
118
+ ];
119
+
100
120
  let commonProps = {
101
121
  motion: false,
102
122
  motionExpand: false,
@@ -780,4 +800,141 @@ describe('TreeSelect', () => {
780
800
  done();
781
801
  }, 100);
782
802
  });
803
+
804
+ it('treeData is updated should not clear value when uncontrolled mode and single selection', () => {
805
+ const nativeEvent = { nativeEvent: { stopImmediatePropagation: () => { } } }
806
+ const treeSelect = getTreeSelect({
807
+ defaultExpandAll: true
808
+ });
809
+ treeSelect
810
+ .find(`.${BASE_CLASS_PREFIX}-tree-option-list .${BASE_CLASS_PREFIX}-tree-option`)
811
+ .at(2)
812
+ .simulate('click', nativeEvent);
813
+ expect(
814
+ treeSelect
815
+ .find(`.${BASE_CLASS_PREFIX}-tree-select .${BASE_CLASS_PREFIX}-tree-select-selection span`)
816
+ .getDOMNode()
817
+ .textContent
818
+ ).toEqual('北京');
819
+ treeSelect.setProps({ treeData: treeChildren});
820
+ treeSelect.update();
821
+ expect(
822
+ treeSelect
823
+ .find(`.${BASE_CLASS_PREFIX}-tree-select .${BASE_CLASS_PREFIX}-tree-select-selection span`)
824
+ .getDOMNode()
825
+ .textContent
826
+ ).toEqual('北京');
827
+ treeSelect.setProps({ treeData: treeData2});
828
+ treeSelect.update();
829
+ expect(
830
+ treeSelect
831
+ .find(`.${BASE_CLASS_PREFIX}-tree-select .${BASE_CLASS_PREFIX}-tree-select-selection span`)
832
+ .getDOMNode()
833
+ .textContent
834
+ ).toEqual('');
835
+ });
836
+
837
+ it('treeData is updated should not clear value when uncontrolled mode and multiple selection', () => {
838
+ const nativeEvent = { nativeEvent: { stopImmediatePropagation: () => { } } }
839
+ const treeSelect = getTreeSelect({
840
+ defaultExpandAll: true,
841
+ multiple: true,
842
+ });
843
+ treeSelect
844
+ .find(`.${BASE_CLASS_PREFIX}-tree-option-list .${BASE_CLASS_PREFIX}-tree-option`)
845
+ .at(2)
846
+ .simulate('click', nativeEvent);
847
+ expect(
848
+ treeSelect
849
+ .find(`.${BASE_CLASS_PREFIX}-tree-select-selection .${BASE_CLASS_PREFIX}-tag-group .${BASE_CLASS_PREFIX}-tag`)
850
+ .at(0)
851
+ .find(`.${BASE_CLASS_PREFIX}-tag-content`)
852
+ .getDOMNode()
853
+ .textContent
854
+ ).toEqual('北京');
855
+ treeSelect.setProps({ treeData: treeChildren});
856
+ treeSelect.update();
857
+ expect(
858
+ treeSelect
859
+ .find(`.${BASE_CLASS_PREFIX}-tree-select-selection .${BASE_CLASS_PREFIX}-tag-group .${BASE_CLASS_PREFIX}-tag`)
860
+ .at(0)
861
+ .find(`.${BASE_CLASS_PREFIX}-tag-content`)
862
+ .getDOMNode()
863
+ .textContent
864
+ ).toEqual('北京');
865
+ treeSelect.setProps({ treeData: treeData2});
866
+ treeSelect.update();
867
+ expect(
868
+ treeSelect
869
+ .find(`.${BASE_CLASS_PREFIX}-tree-select-selection .${BASE_CLASS_PREFIX}-tag-group .${BASE_CLASS_PREFIX}-tag`)
870
+ .at(0)
871
+ .find(`.${BASE_CLASS_PREFIX}-tag-content`)
872
+ .length
873
+ ).toEqual(0);
874
+ });
875
+
876
+ it('treeData is updated should not clear value when controlled mode and single selection', () => {
877
+ const treeSelect = getTreeSelect({
878
+ defaultExpandAll: true,
879
+ value: 'Beijing'
880
+ });
881
+ expect(
882
+ treeSelect
883
+ .find(`.${BASE_CLASS_PREFIX}-tree-select .${BASE_CLASS_PREFIX}-tree-select-selection span`)
884
+ .getDOMNode()
885
+ .textContent
886
+ ).toEqual('北京');
887
+ treeSelect.setProps({ treeData: treeChildren});
888
+ treeSelect.update();
889
+ expect(
890
+ treeSelect
891
+ .find(`.${BASE_CLASS_PREFIX}-tree-select .${BASE_CLASS_PREFIX}-tree-select-selection span`)
892
+ .getDOMNode()
893
+ .textContent
894
+ ).toEqual('北京');
895
+ treeSelect.setProps({ treeData: treeData3});
896
+ treeSelect.update();
897
+ expect(
898
+ treeSelect
899
+ .find(`.${BASE_CLASS_PREFIX}-tree-select .${BASE_CLASS_PREFIX}-tree-select-selection span`)
900
+ .getDOMNode()
901
+ .textContent
902
+ ).toEqual('');
903
+ });
904
+
905
+ it('treeData is updated should not clear value when controlled mode and multiple selection', () => {
906
+ const treeSelect = getTreeSelect({
907
+ defaultExpandAll: true,
908
+ multiple: true,
909
+ value: 'Beijing'
910
+ });
911
+ expect(
912
+ treeSelect
913
+ .find(`.${BASE_CLASS_PREFIX}-tree-select-selection .${BASE_CLASS_PREFIX}-tag-group .${BASE_CLASS_PREFIX}-tag`)
914
+ .at(0)
915
+ .find(`.${BASE_CLASS_PREFIX}-tag-content`)
916
+ .getDOMNode()
917
+ .textContent
918
+ ).toEqual('北京');
919
+ treeSelect.setProps({ treeData: treeChildren});
920
+ treeSelect.update();
921
+ expect(
922
+ treeSelect
923
+ .find(`.${BASE_CLASS_PREFIX}-tree-select-selection .${BASE_CLASS_PREFIX}-tag-group .${BASE_CLASS_PREFIX}-tag`)
924
+ .at(0)
925
+ .find(`.${BASE_CLASS_PREFIX}-tag-content`)
926
+ .getDOMNode()
927
+ .textContent
928
+ ).toEqual('北京');
929
+ treeSelect.setProps({ treeData: treeData3});
930
+ treeSelect.update();
931
+ expect(
932
+ treeSelect
933
+ .find(`.${BASE_CLASS_PREFIX}-tree-select-selection .${BASE_CLASS_PREFIX}-tag-group .${BASE_CLASS_PREFIX}-tag`)
934
+ .at(0)
935
+ .find(`.${BASE_CLASS_PREFIX}-tag-content`)
936
+ .length
937
+ ).toEqual(0);
938
+ });
939
+
783
940
  })
@@ -23,7 +23,8 @@ import {
23
23
  getValueOrKey,
24
24
  normalizeKeyList,
25
25
  calcDisabledKeys,
26
- normalizeValue
26
+ normalizeValue,
27
+ updateKeys,
27
28
  } from '@douyinfe/semi-foundation/tree/treeUtil';
28
29
  import { cssClasses, strings } from '@douyinfe/semi-foundation/treeSelect/constants';
29
30
  import { numbers as popoverNumbers } from '@douyinfe/semi-foundation/popover/constants';
@@ -362,7 +363,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
362
363
  if (
363
364
  treeData &&
364
365
  props.motion &&
365
- !isEqual(new Set(Object.keys(newState.keyEntities)), new Set(Object.keys(prevState.keyEntities)))
366
+ !isEqual(Object.keys(newState.keyEntities), Object.keys(prevState.keyEntities))
366
367
  ) {
367
368
  if (prevProps && props.motion) {
368
369
  newState.motionKeys = new Set([]);
@@ -432,11 +433,15 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
432
433
  );
433
434
  } else if (treeData) {
434
435
  // If `treeData` changed, we also need check it
435
- newState.selectedKeys = findKeysForValues(
436
- normalizeValue(props.value, withObject) || '',
437
- valueEntities,
438
- isMultiple
439
- );
436
+ if (props.value) {
437
+ newState.selectedKeys = findKeysForValues(
438
+ normalizeValue(props.value, withObject) || '',
439
+ valueEntities,
440
+ isMultiple
441
+ );
442
+ } else {
443
+ newState.selectedKeys = updateKeys(prevState.selectedKeys, keyEntities);
444
+ }
440
445
  }
441
446
  } else {
442
447
  // checkedKeys: multiple mode controlled || data changed
@@ -456,11 +461,15 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
456
461
  );
457
462
  } else if (treeData) {
458
463
  // If `treeData` changed, we also need check it
459
- checkedKeyValues = findKeysForValues(
460
- normalizeValue(props.value, withObject) || [],
461
- valueEntities,
462
- isMultiple
463
- );
464
+ if (props.value) {
465
+ checkedKeyValues = findKeysForValues(
466
+ normalizeValue(props.value, withObject) || [],
467
+ valueEntities,
468
+ isMultiple
469
+ );
470
+ } else {
471
+ checkedKeyValues = updateKeys(prevState.checkedKeys, keyEntities);
472
+ }
464
473
  }
465
474
 
466
475
  if (checkedKeyValues) {
@@ -309,6 +309,14 @@ export const EllipsisMultiple = () => (
309
309
  Web 应用。 区别于其他的设计系统而言,Semi Design
310
310
  以用户中心、内容优先、设计人性化为设计理念,具有四大优势。
311
311
  </Paragraph>
312
+ <br />
313
+ <Paragraph ellipsis={{ rows: 3, expandable: true }} style={{ width: 300, whiteSpace: 'pre-line' }}>
314
+ {'这是一个多行截断的\n例子: Semi Design 是由互娱社区\n前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。 区别于其他的设计系统而言,Semi Design 以用户中心、内容优先、设计人性化为设计理念,具有四大优势。'}
315
+ </Paragraph>
316
+ <br />
317
+ <Paragraph ellipsis={{ rows: 3, expandable: true }} style={{ width: 300, whiteSpace: 'pre-wrap' }}>
318
+ {'这是一个多行截断的\n例子: Semi Des ign 是由互 娱社区\n前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。 区别于其他的设计系统而言,Semi Design 以用户中心、内容优先、设计人性化为设计理念,具有四大优势。'}
319
+ </Paragraph>
312
320
  </div>
313
321
  );
314
322
 
@@ -63,7 +63,6 @@ const getRenderText = (
63
63
 
64
64
  // clean up css overflow
65
65
  ellipsisContainer.style.textOverflow = 'clip';
66
- ellipsisContainer.style.whiteSpace = 'normal';
67
66
  ellipsisContainer.style.webkitLineClamp = 'none';
68
67
 
69
68
  // Render fake container