@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.
- package/datePicker/_story/RenderDate/index.js +13 -3
- package/datePicker/_story/RenderFullDate/index.js +36 -14
- package/datePicker/_story/RenderFullDate/index.scss +1 -1
- package/datePicker/_story/datePicker.stories.js +19 -11
- package/datePicker/_story/v2/PanelOpen.jsx +39 -0
- package/datePicker/_story/v2/index.js +2 -1
- package/datePicker/datePicker.tsx +1 -0
- package/dist/css/semi.css +34 -9
- package/dist/css/semi.min.css +1 -1
- package/dist/umd/semi-ui.js +92 -33
- package/dist/umd/semi-ui.js.map +1 -1
- package/dist/umd/semi-ui.min.js +1 -1
- package/dist/umd/semi-ui.min.js.map +1 -1
- package/dropdown/index.tsx +11 -3
- package/form/_story/demo.jsx +1 -0
- package/input/index.tsx +1 -0
- package/input/textarea.tsx +6 -4
- package/inputNumber/__test__/inputNumber.test.js +36 -8
- package/inputNumber/index.tsx +2 -1
- package/lib/cjs/datePicker/datePicker.js +12 -8
- package/lib/cjs/dropdown/index.d.ts +10 -3
- package/lib/cjs/input/index.js +2 -1
- package/lib/cjs/input/textarea.js +5 -3
- package/lib/cjs/inputNumber/index.js +3 -2
- package/lib/cjs/list/index.d.ts +4 -4
- package/lib/cjs/navigation/Item.js +1 -1
- package/lib/cjs/navigation/SubNav.js +1 -1
- package/lib/cjs/scrollList/scrollItem.d.ts +5 -1
- package/lib/cjs/scrollList/scrollItem.js +7 -0
- package/lib/cjs/select/index.js +1 -1
- package/lib/cjs/table/Table.js +9 -5
- package/lib/cjs/timePicker/TimePicker.d.ts +2 -0
- package/lib/cjs/timePicker/TimePicker.js +4 -4
- package/lib/cjs/timePicker/index.d.ts +1 -0
- package/lib/cjs/tree/treeNode.js +10 -1
- package/lib/cjs/treeSelect/index.js +11 -3
- package/lib/cjs/typography/util.js +0 -1
- package/lib/es/datePicker/datePicker.js +12 -8
- package/lib/es/dropdown/index.d.ts +10 -3
- package/lib/es/input/index.js +2 -1
- package/lib/es/input/textarea.js +5 -3
- package/lib/es/inputNumber/index.js +3 -2
- package/lib/es/list/index.d.ts +4 -4
- package/lib/es/navigation/Item.js +1 -1
- package/lib/es/navigation/SubNav.js +1 -1
- package/lib/es/scrollList/scrollItem.d.ts +5 -1
- package/lib/es/scrollList/scrollItem.js +7 -0
- package/lib/es/select/index.js +1 -1
- package/lib/es/table/Table.js +9 -5
- package/lib/es/timePicker/TimePicker.d.ts +2 -0
- package/lib/es/timePicker/TimePicker.js +4 -4
- package/lib/es/timePicker/index.d.ts +1 -0
- package/lib/es/tree/treeNode.js +9 -1
- package/lib/es/treeSelect/index.js +12 -4
- package/lib/es/typography/util.js +0 -1
- package/list/index.tsx +5 -5
- package/navigation/Item.tsx +1 -1
- package/navigation/SubNav.tsx +1 -1
- package/package.json +9 -8
- package/scrollList/scrollItem.tsx +10 -3
- package/select/index.tsx +6 -1
- package/table/Table.tsx +9 -6
- package/table/_story/table.stories.js +2 -0
- package/table/_story/v2/FixedColumnsChange/index.jsx +104 -0
- package/table/_story/v2/FixedZIndex/index.jsx +87 -0
- package/timePicker/TimePicker.tsx +4 -1
- package/timePicker/__test__/timePicker.test.js +42 -3
- package/timePicker/_story/timepicker.stories.js +18 -0
- package/tree/treeNode.tsx +9 -2
- package/treeSelect/__test__/treeSelect.test.js +157 -0
- package/treeSelect/index.tsx +21 -12
- package/typography/_story/typography.stories.js +8 -0
- 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: (
|
|
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
|
|
25
|
+
const onFocus = sinon.spy();
|
|
26
|
+
const onChange = sinon.spy();
|
|
26
27
|
|
|
27
28
|
const elem = mount(
|
|
28
29
|
<TimePicker
|
|
29
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
})
|
package/treeSelect/index.tsx
CHANGED
|
@@ -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(
|
|
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
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
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
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
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
|
|
package/typography/util.tsx
CHANGED