@douyinfe/semi-ui 2.4.0-beta.0 → 2.4.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.
- 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/dist/css/semi.css +18 -0
- package/dist/css/semi.min.css +1 -1
- package/dist/umd/semi-ui.js +20 -6
- 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/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/treeSelect/index.js +11 -3
- package/lib/cjs/typography/util.js +0 -1
- 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/treeSelect/index.js +12 -4
- package/lib/es/typography/util.js +0 -1
- package/navigation/Item.tsx +1 -1
- package/navigation/SubNav.tsx +1 -1
- package/package.json +8 -8
- package/scrollList/scrollItem.tsx +10 -3
- package/table/_story/v2/FixedColumnsChange/index.jsx +1 -1
- package/table/_story/v2/FixedZIndex/index.jsx +1 -1
- package/timePicker/__test__/timePicker.test.js +9 -1
- 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
|
@@ -204,7 +204,7 @@ class NavItem extends _baseComponent.default {
|
|
|
204
204
|
} else {
|
|
205
205
|
let placeholderIcons = null;
|
|
206
206
|
|
|
207
|
-
if (mode === _constants.strings.MODE_VERTICAL && !limitIndent) {
|
|
207
|
+
if (mode === _constants.strings.MODE_VERTICAL && !limitIndent && !isCollapsed) {
|
|
208
208
|
const iconAmount = icon && !indent ? level : level - 1;
|
|
209
209
|
placeholderIcons = (0, _times2.default)(iconAmount, () => this.renderIcon(null, _constants.strings.ICON_POS_RIGHT, false));
|
|
210
210
|
}
|
|
@@ -230,7 +230,7 @@ class SubNav extends _baseComponent.default {
|
|
|
230
230
|
|
|
231
231
|
let placeholderIcons = null;
|
|
232
232
|
|
|
233
|
-
if (mode === _constants.strings.MODE_VERTICAL && !limitIndent) {
|
|
233
|
+
if (mode === _constants.strings.MODE_VERTICAL && !limitIndent && !isCollapsed) {
|
|
234
234
|
/* Different icons' amount means different indents.*/
|
|
235
235
|
const iconAmount = icon && !indent ? level : level - 1;
|
|
236
236
|
placeholderIcons = (0, _times2.default)(iconAmount, index => this.renderIcon(null, _constants.strings.ICON_POS_RIGHT, false, undefined, index));
|
|
@@ -3,7 +3,10 @@ import BaseComponent from '../_base/baseComponent';
|
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import { Item, ScrollItemAdapter } from '@douyinfe/semi-foundation/lib/cjs/scrollList/itemFoundation';
|
|
5
5
|
import { Motion } from '../_base/base';
|
|
6
|
-
|
|
6
|
+
interface DebounceSelectFn {
|
|
7
|
+
(e: React.UIEvent, newSelectedNode: HTMLElement): void;
|
|
8
|
+
cancel(): void;
|
|
9
|
+
}
|
|
7
10
|
export interface ScrollItemProps<T extends Item> {
|
|
8
11
|
mode?: string;
|
|
9
12
|
cycled?: boolean;
|
|
@@ -52,6 +55,7 @@ export default class ScrollItem<T extends Item> extends BaseComponent<ScrollItem
|
|
|
52
55
|
debouncedSelect: DebounceSelectFn;
|
|
53
56
|
constructor(props?: {});
|
|
54
57
|
get adapter(): ScrollItemAdapter<ScrollItemProps<T>, ScrollItemState, T>;
|
|
58
|
+
componentWillUnmount(): void;
|
|
55
59
|
componentDidMount(): void;
|
|
56
60
|
componentDidUpdate(prevProps: ScrollItemProps<T>): void;
|
|
57
61
|
_cacheNode: (name: string, node: Element) => Element;
|
|
@@ -451,6 +451,13 @@ class ScrollItem extends _baseComponent.default {
|
|
|
451
451
|
});
|
|
452
452
|
}
|
|
453
453
|
|
|
454
|
+
componentWillUnmount() {
|
|
455
|
+
if (this.props.cycled) {
|
|
456
|
+
this.throttledAdjustList.cancel();
|
|
457
|
+
this.debouncedSelect.cancel();
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
454
461
|
componentDidMount() {
|
|
455
462
|
this.foundation.init();
|
|
456
463
|
const {
|
|
@@ -950,7 +950,7 @@ class TreeSelect extends _baseComponent.default {
|
|
|
950
950
|
} // if treeData keys changes, we won't show animation
|
|
951
951
|
|
|
952
952
|
|
|
953
|
-
if (treeData && props.motion && !(0, _isEqual2.default)(
|
|
953
|
+
if (treeData && props.motion && !(0, _isEqual2.default)((0, _keys.default)(newState.keyEntities), (0, _keys.default)(prevState.keyEntities))) {
|
|
954
954
|
if (prevProps && props.motion) {
|
|
955
955
|
newState.motionKeys = new _set.default([]);
|
|
956
956
|
newState.motionType = null;
|
|
@@ -996,7 +996,11 @@ class TreeSelect extends _baseComponent.default {
|
|
|
996
996
|
newState.selectedKeys = (0, _treeUtil.findKeysForValues)((0, _treeUtil.normalizeValue)(props.defaultValue, withObject), valueEntities, isMultiple);
|
|
997
997
|
} else if (treeData) {
|
|
998
998
|
// If `treeData` changed, we also need check it
|
|
999
|
-
|
|
999
|
+
if (props.value) {
|
|
1000
|
+
newState.selectedKeys = (0, _treeUtil.findKeysForValues)((0, _treeUtil.normalizeValue)(props.value, withObject) || '', valueEntities, isMultiple);
|
|
1001
|
+
} else {
|
|
1002
|
+
newState.selectedKeys = (0, _treeUtil.updateKeys)(prevState.selectedKeys, keyEntities);
|
|
1003
|
+
}
|
|
1000
1004
|
}
|
|
1001
1005
|
} else {
|
|
1002
1006
|
// checkedKeys: multiple mode controlled || data changed
|
|
@@ -1008,7 +1012,11 @@ class TreeSelect extends _baseComponent.default {
|
|
|
1008
1012
|
checkedKeyValues = (0, _treeUtil.findKeysForValues)((0, _treeUtil.normalizeValue)(props.defaultValue, withObject), valueEntities, isMultiple);
|
|
1009
1013
|
} else if (treeData) {
|
|
1010
1014
|
// If `treeData` changed, we also need check it
|
|
1011
|
-
|
|
1015
|
+
if (props.value) {
|
|
1016
|
+
checkedKeyValues = (0, _treeUtil.findKeysForValues)((0, _treeUtil.normalizeValue)(props.value, withObject) || [], valueEntities, isMultiple);
|
|
1017
|
+
} else {
|
|
1018
|
+
checkedKeyValues = (0, _treeUtil.updateKeys)(prevState.checkedKeys, keyEntities);
|
|
1019
|
+
}
|
|
1012
1020
|
}
|
|
1013
1021
|
|
|
1014
1022
|
if (checkedKeyValues) {
|
|
@@ -77,7 +77,6 @@ const getRenderText = function (originEle, rows) {
|
|
|
77
77
|
ellipsisContainer.style.zIndex = '-1000'; // clean up css overflow
|
|
78
78
|
|
|
79
79
|
ellipsisContainer.style.textOverflow = 'clip';
|
|
80
|
-
ellipsisContainer.style.whiteSpace = 'normal';
|
|
81
80
|
ellipsisContainer.style.webkitLineClamp = 'none'; // Render fake container
|
|
82
81
|
|
|
83
82
|
_reactDom.default.render( /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null), ellipsisContainer); // Check if ellipsis in measure div is height enough for content
|
|
@@ -176,7 +176,7 @@ export default class NavItem extends BaseComponent {
|
|
|
176
176
|
} else {
|
|
177
177
|
let placeholderIcons = null;
|
|
178
178
|
|
|
179
|
-
if (mode === strings.MODE_VERTICAL && !limitIndent) {
|
|
179
|
+
if (mode === strings.MODE_VERTICAL && !limitIndent && !isCollapsed) {
|
|
180
180
|
const iconAmount = icon && !indent ? level : level - 1;
|
|
181
181
|
placeholderIcons = _times(iconAmount, () => this.renderIcon(null, strings.ICON_POS_RIGHT, false));
|
|
182
182
|
}
|
|
@@ -200,7 +200,7 @@ export default class SubNav extends BaseComponent {
|
|
|
200
200
|
|
|
201
201
|
let placeholderIcons = null;
|
|
202
202
|
|
|
203
|
-
if (mode === strings.MODE_VERTICAL && !limitIndent) {
|
|
203
|
+
if (mode === strings.MODE_VERTICAL && !limitIndent && !isCollapsed) {
|
|
204
204
|
/* Different icons' amount means different indents.*/
|
|
205
205
|
const iconAmount = icon && !indent ? level : level - 1;
|
|
206
206
|
placeholderIcons = _times(iconAmount, index => this.renderIcon(null, strings.ICON_POS_RIGHT, false, undefined, index));
|
|
@@ -3,7 +3,10 @@ import BaseComponent from '../_base/baseComponent';
|
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import { Item, ScrollItemAdapter } from '@douyinfe/semi-foundation/lib/es/scrollList/itemFoundation';
|
|
5
5
|
import { Motion } from '../_base/base';
|
|
6
|
-
|
|
6
|
+
interface DebounceSelectFn {
|
|
7
|
+
(e: React.UIEvent, newSelectedNode: HTMLElement): void;
|
|
8
|
+
cancel(): void;
|
|
9
|
+
}
|
|
7
10
|
export interface ScrollItemProps<T extends Item> {
|
|
8
11
|
mode?: string;
|
|
9
12
|
cycled?: boolean;
|
|
@@ -52,6 +55,7 @@ export default class ScrollItem<T extends Item> extends BaseComponent<ScrollItem
|
|
|
52
55
|
debouncedSelect: DebounceSelectFn;
|
|
53
56
|
constructor(props?: {});
|
|
54
57
|
get adapter(): ScrollItemAdapter<ScrollItemProps<T>, ScrollItemState, T>;
|
|
58
|
+
componentWillUnmount(): void;
|
|
55
59
|
componentDidMount(): void;
|
|
56
60
|
componentDidUpdate(prevProps: ScrollItemProps<T>): void;
|
|
57
61
|
_cacheNode: (name: string, node: Element) => Element;
|
|
@@ -429,6 +429,13 @@ export default class ScrollItem extends BaseComponent {
|
|
|
429
429
|
});
|
|
430
430
|
}
|
|
431
431
|
|
|
432
|
+
componentWillUnmount() {
|
|
433
|
+
if (this.props.cycled) {
|
|
434
|
+
this.throttledAdjustList.cancel();
|
|
435
|
+
this.debouncedSelect.cancel();
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
432
439
|
componentDidMount() {
|
|
433
440
|
this.foundation.init();
|
|
434
441
|
const {
|
|
@@ -17,7 +17,7 @@ import ReactDOM from 'react-dom';
|
|
|
17
17
|
import cls from 'classnames';
|
|
18
18
|
import PropTypes from 'prop-types';
|
|
19
19
|
import TreeSelectFoundation from '@douyinfe/semi-foundation/lib/es/treeSelect/foundation';
|
|
20
|
-
import { convertDataToEntities, flattenTreeData, calcExpandedKeysForValues, calcMotionKeys, findKeysForValues, calcCheckedKeys, calcExpandedKeys, getValueOrKey, normalizeKeyList, calcDisabledKeys, normalizeValue } from '@douyinfe/semi-foundation/lib/es/tree/treeUtil';
|
|
20
|
+
import { convertDataToEntities, flattenTreeData, calcExpandedKeysForValues, calcMotionKeys, findKeysForValues, calcCheckedKeys, calcExpandedKeys, getValueOrKey, normalizeKeyList, calcDisabledKeys, normalizeValue, updateKeys } from '@douyinfe/semi-foundation/lib/es/tree/treeUtil';
|
|
21
21
|
import { cssClasses, strings } from '@douyinfe/semi-foundation/lib/es/treeSelect/constants';
|
|
22
22
|
import { numbers as popoverNumbers } from '@douyinfe/semi-foundation/lib/es/popover/constants';
|
|
23
23
|
import { FixedSizeList as VirtualList } from 'react-window';
|
|
@@ -896,7 +896,7 @@ class TreeSelect extends BaseComponent {
|
|
|
896
896
|
} // if treeData keys changes, we won't show animation
|
|
897
897
|
|
|
898
898
|
|
|
899
|
-
if (treeData && props.motion && !_isEqual(
|
|
899
|
+
if (treeData && props.motion && !_isEqual(_Object$keys(newState.keyEntities), _Object$keys(prevState.keyEntities))) {
|
|
900
900
|
if (prevProps && props.motion) {
|
|
901
901
|
newState.motionKeys = new _Set([]);
|
|
902
902
|
newState.motionType = null;
|
|
@@ -942,7 +942,11 @@ class TreeSelect extends BaseComponent {
|
|
|
942
942
|
newState.selectedKeys = findKeysForValues(normalizeValue(props.defaultValue, withObject), valueEntities, isMultiple);
|
|
943
943
|
} else if (treeData) {
|
|
944
944
|
// If `treeData` changed, we also need check it
|
|
945
|
-
|
|
945
|
+
if (props.value) {
|
|
946
|
+
newState.selectedKeys = findKeysForValues(normalizeValue(props.value, withObject) || '', valueEntities, isMultiple);
|
|
947
|
+
} else {
|
|
948
|
+
newState.selectedKeys = updateKeys(prevState.selectedKeys, keyEntities);
|
|
949
|
+
}
|
|
946
950
|
}
|
|
947
951
|
} else {
|
|
948
952
|
// checkedKeys: multiple mode controlled || data changed
|
|
@@ -954,7 +958,11 @@ class TreeSelect extends BaseComponent {
|
|
|
954
958
|
checkedKeyValues = findKeysForValues(normalizeValue(props.defaultValue, withObject), valueEntities, isMultiple);
|
|
955
959
|
} else if (treeData) {
|
|
956
960
|
// If `treeData` changed, we also need check it
|
|
957
|
-
|
|
961
|
+
if (props.value) {
|
|
962
|
+
checkedKeyValues = findKeysForValues(normalizeValue(props.value, withObject) || [], valueEntities, isMultiple);
|
|
963
|
+
} else {
|
|
964
|
+
checkedKeyValues = updateKeys(prevState.checkedKeys, keyEntities);
|
|
965
|
+
}
|
|
958
966
|
}
|
|
959
967
|
|
|
960
968
|
if (checkedKeyValues) {
|
|
@@ -62,7 +62,6 @@ const getRenderText = function (originEle, rows) {
|
|
|
62
62
|
ellipsisContainer.style.zIndex = '-1000'; // clean up css overflow
|
|
63
63
|
|
|
64
64
|
ellipsisContainer.style.textOverflow = 'clip';
|
|
65
|
-
ellipsisContainer.style.whiteSpace = 'normal';
|
|
66
65
|
ellipsisContainer.style.webkitLineClamp = 'none'; // Render fake container
|
|
67
66
|
|
|
68
67
|
ReactDOM.render( /*#__PURE__*/React.createElement(React.Fragment, null), ellipsisContainer); // Check if ellipsis in measure div is height enough for content
|
package/navigation/Item.tsx
CHANGED
|
@@ -195,7 +195,7 @@ export default class NavItem extends BaseComponent<NavItemProps, NavItemState> {
|
|
|
195
195
|
itemChildren = children;
|
|
196
196
|
} else {
|
|
197
197
|
let placeholderIcons = null;
|
|
198
|
-
if (mode === strings.MODE_VERTICAL && !limitIndent) {
|
|
198
|
+
if (mode === strings.MODE_VERTICAL && !limitIndent && !isCollapsed) {
|
|
199
199
|
const iconAmount = (icon && !indent) ? level : level - 1;
|
|
200
200
|
placeholderIcons = times(iconAmount, () => this.renderIcon(null, strings.ICON_POS_RIGHT, false));
|
|
201
201
|
}
|
package/navigation/SubNav.tsx
CHANGED
|
@@ -237,7 +237,7 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
|
|
|
237
237
|
}
|
|
238
238
|
|
|
239
239
|
let placeholderIcons = null;
|
|
240
|
-
if (mode === strings.MODE_VERTICAL && !limitIndent) {
|
|
240
|
+
if (mode === strings.MODE_VERTICAL && !limitIndent && !isCollapsed) {
|
|
241
241
|
/* Different icons' amount means different indents.*/
|
|
242
242
|
const iconAmount = (icon && !indent) ? level : level - 1;
|
|
243
243
|
placeholderIcons = times(iconAmount, index => this.renderIcon(null, strings.ICON_POS_RIGHT, false, undefined, index));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@douyinfe/semi-ui",
|
|
3
|
-
"version": "2.4.0
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "lib/cjs/index.js",
|
|
6
6
|
"module": "lib/es/index.js",
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@babel/runtime-corejs3": "^7.15.4",
|
|
17
|
-
"@douyinfe/semi-animation-react": "2.4.0
|
|
18
|
-
"@douyinfe/semi-foundation": "2.4.0
|
|
19
|
-
"@douyinfe/semi-icons": "2.4.0
|
|
20
|
-
"@douyinfe/semi-illustrations": "2.4.0
|
|
21
|
-
"@douyinfe/semi-theme-default": "2.4.0
|
|
17
|
+
"@douyinfe/semi-animation-react": "2.4.0",
|
|
18
|
+
"@douyinfe/semi-foundation": "2.4.0",
|
|
19
|
+
"@douyinfe/semi-icons": "2.4.0",
|
|
20
|
+
"@douyinfe/semi-illustrations": "2.4.0",
|
|
21
|
+
"@douyinfe/semi-theme-default": "2.4.0",
|
|
22
22
|
"@types/react-window": "^1.8.2",
|
|
23
23
|
"async-validator": "^3.5.0",
|
|
24
24
|
"classnames": "^2.2.6",
|
|
@@ -68,13 +68,13 @@
|
|
|
68
68
|
],
|
|
69
69
|
"author": "",
|
|
70
70
|
"license": "MIT",
|
|
71
|
-
"gitHead": "
|
|
71
|
+
"gitHead": "d902a6f731475dea585d63907aee06ebe1153419",
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"@babel/plugin-proposal-decorators": "^7.15.8",
|
|
74
74
|
"@babel/plugin-transform-runtime": "^7.15.8",
|
|
75
75
|
"@babel/preset-env": "^7.15.8",
|
|
76
76
|
"@babel/preset-react": "^7.14.5",
|
|
77
|
-
"@douyinfe/semi-scss-compile": "2.4.0
|
|
77
|
+
"@douyinfe/semi-scss-compile": "2.4.0",
|
|
78
78
|
"@storybook/addon-knobs": "^6.3.1",
|
|
79
79
|
"@types/lodash": "^4.14.176",
|
|
80
80
|
"babel-loader": "^8.2.2",
|
|
@@ -13,8 +13,10 @@ import { Motion } from '../_base/base';
|
|
|
13
13
|
const msPerFrame = 1000 / 60;
|
|
14
14
|
const blankReg = /^\s*$/;
|
|
15
15
|
const wheelMode = 'wheel';
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
interface DebounceSelectFn {
|
|
17
|
+
(e: React.UIEvent, newSelectedNode: HTMLElement): void;
|
|
18
|
+
cancel(): void
|
|
19
|
+
}
|
|
18
20
|
export interface ScrollItemProps<T extends Item> {
|
|
19
21
|
mode?: string;
|
|
20
22
|
cycled?: boolean;
|
|
@@ -110,7 +112,12 @@ export default class ScrollItem<T extends Item> extends BaseComponent<ScrollItem
|
|
|
110
112
|
scrollToCenter: this.scrollToCenter,
|
|
111
113
|
};
|
|
112
114
|
}
|
|
113
|
-
|
|
115
|
+
componentWillUnmount(){
|
|
116
|
+
if (this.props.cycled) {
|
|
117
|
+
this.throttledAdjustList.cancel();
|
|
118
|
+
this.debouncedSelect.cancel();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
114
121
|
componentDidMount() {
|
|
115
122
|
this.foundation.init();
|
|
116
123
|
|
|
@@ -15,7 +15,7 @@ const getData = () => {
|
|
|
15
15
|
name: isSemiDesign ? `Semi Design 设计稿${i}.fig` : `Semi Pro 设计稿${i}.fig`,
|
|
16
16
|
owner: isSemiDesign ? '姜鹏志' : '郝宣',
|
|
17
17
|
size: randomNumber,
|
|
18
|
-
updateTime: new Date().valueOf() + randomNumber * DAY,
|
|
18
|
+
updateTime: new Date('2022-01-01').valueOf() + randomNumber * DAY,
|
|
19
19
|
avatarBg: isSemiDesign ? 'grey' : 'red'
|
|
20
20
|
});
|
|
21
21
|
}
|
|
@@ -89,6 +89,7 @@ describe(`TimePicker`, () => {
|
|
|
89
89
|
const args = onChange.getCall(0).args;
|
|
90
90
|
expect(args[0] instanceof Date).toBe(true);
|
|
91
91
|
expect(typeof args[1]).toBe('string');
|
|
92
|
+
elem.unmount();
|
|
92
93
|
});
|
|
93
94
|
|
|
94
95
|
it(`test controlled value`, async () => {
|
|
@@ -120,6 +121,7 @@ describe(`TimePicker`, () => {
|
|
|
120
121
|
let currentDate0 = elem0.state('value')[0];
|
|
121
122
|
|
|
122
123
|
expect(currentDate0.getMinutes()).toBe(defaultMinute);
|
|
124
|
+
elem0.unmount();
|
|
123
125
|
});
|
|
124
126
|
|
|
125
127
|
it(`test controlled value with onchange`, async () => {
|
|
@@ -156,6 +158,7 @@ describe(`TimePicker`, () => {
|
|
|
156
158
|
|
|
157
159
|
let currentDate1 = elem1.state('value')[0];
|
|
158
160
|
expect(currentDate1.getMinutes()).toBe(newInputMinute);
|
|
161
|
+
elem1.unmount();
|
|
159
162
|
});
|
|
160
163
|
|
|
161
164
|
it(`test controlled open`, async () => {
|
|
@@ -234,6 +237,7 @@ describe(`TimePicker`, () => {
|
|
|
234
237
|
nextSelectedLi.simulate('click');
|
|
235
238
|
await sleep(200);
|
|
236
239
|
expect(elem.state('value')[0].getHours()).toBe(newHour);
|
|
240
|
+
elem.unmount();
|
|
237
241
|
});
|
|
238
242
|
|
|
239
243
|
it('test isTimeFormatLike function', () => {
|
|
@@ -286,6 +290,7 @@ describe(`TimePicker`, () => {
|
|
|
286
290
|
const args = onChange.getCall(0).args;
|
|
287
291
|
expect(args[0]).toBe(undefined);
|
|
288
292
|
expect(args[1]).toBe('');
|
|
293
|
+
elem.unmount();
|
|
289
294
|
});
|
|
290
295
|
|
|
291
296
|
it('test onChangeWithDateFirst=false', async () => {
|
|
@@ -297,7 +302,8 @@ describe(`TimePicker`, () => {
|
|
|
297
302
|
onChangeWithDateFirst: false,
|
|
298
303
|
autofocus: true,
|
|
299
304
|
locale: Locale.TimePicker,
|
|
300
|
-
localeCode: Locale.code
|
|
305
|
+
localeCode: Locale.code,
|
|
306
|
+
scrollItemProps: { cycled: false }
|
|
301
307
|
};
|
|
302
308
|
const elem = mount(<TimePicker {...props} />);
|
|
303
309
|
// click minute
|
|
@@ -305,10 +311,12 @@ describe(`TimePicker`, () => {
|
|
|
305
311
|
const minuteLis = minuteUl.find(`li`);
|
|
306
312
|
|
|
307
313
|
minuteUl.simulate('click', { target: minuteLis.at(0).getDOMNode(), nativeEvent: null });
|
|
314
|
+
await sleep(200);
|
|
308
315
|
|
|
309
316
|
expect(onChange.called).toBeTruthy();
|
|
310
317
|
const args = onChange.getCall(0).args;
|
|
311
318
|
expect(typeof args[0]).toBe('string');
|
|
312
319
|
expect(args[1] instanceof Date).toBe(true);
|
|
320
|
+
elem.unmount();
|
|
313
321
|
});
|
|
314
322
|
});
|
|
@@ -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