@douyinfe/semi-ui 2.5.1 → 2.7.0-beta.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/button/__test__/button.test.js +7 -0
- package/button/buttonGroup.tsx +5 -2
- package/calendar/monthCalendar.tsx +14 -13
- package/cascader/__test__/cascader.test.js +159 -81
- package/cascader/_story/cascader.stories.js +36 -23
- package/cascader/index.tsx +47 -8
- package/cascader/item.tsx +25 -5
- package/datePicker/_story/v2/InsetInput.jsx +104 -0
- package/datePicker/_story/v2/InsetInputE2E.jsx +69 -0
- package/datePicker/_story/v2/index.js +2 -0
- package/datePicker/dateInput.tsx +102 -13
- package/datePicker/datePicker.tsx +95 -16
- package/datePicker/index.tsx +15 -0
- package/datePicker/insetInput.tsx +76 -0
- package/datePicker/month.tsx +14 -7
- package/datePicker/monthsGrid.tsx +31 -12
- package/datePicker/navigation.tsx +8 -4
- package/datePicker/quickControl.tsx +1 -0
- package/datePicker/yearAndMonth.tsx +1 -1
- package/dist/css/semi.css +120 -8
- package/dist/css/semi.min.css +1 -1
- package/dist/umd/semi-ui.js +1100 -193
- 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/form/hoc/withField.tsx +1 -1
- package/input/_story/input.stories.js +13 -0
- package/lib/cjs/_base/base.css +5 -5
- package/lib/cjs/button/buttonGroup.d.ts +1 -0
- package/lib/cjs/button/buttonGroup.js +6 -2
- package/lib/cjs/calendar/monthCalendar.js +21 -5
- package/lib/cjs/cascader/index.d.ts +10 -2
- package/lib/cjs/cascader/index.js +52 -10
- package/lib/cjs/cascader/item.d.ts +6 -2
- package/lib/cjs/cascader/item.js +33 -4
- package/lib/cjs/datePicker/dateInput.d.ts +9 -4
- package/lib/cjs/datePicker/dateInput.js +107 -13
- package/lib/cjs/datePicker/datePicker.d.ts +7 -2
- package/lib/cjs/datePicker/datePicker.js +138 -30
- package/lib/cjs/datePicker/index.js +24 -2
- package/lib/cjs/datePicker/insetInput.d.ts +21 -0
- package/lib/cjs/datePicker/insetInput.js +80 -0
- package/lib/cjs/datePicker/month.d.ts +1 -0
- package/lib/cjs/datePicker/month.js +18 -2
- package/lib/cjs/datePicker/monthsGrid.js +35 -11
- package/lib/cjs/datePicker/navigation.js +8 -0
- package/lib/cjs/datePicker/quickControl.js +1 -0
- package/lib/cjs/datePicker/yearAndMonth.js +1 -0
- package/lib/cjs/form/hoc/withField.js +1 -1
- package/lib/cjs/navigation/Item.d.ts +2 -2
- package/lib/cjs/navigation/Item.js +8 -6
- package/lib/cjs/navigation/SubNav.js +2 -2
- package/lib/cjs/scrollList/scrollItem.d.ts +2 -1
- package/lib/cjs/scrollList/scrollItem.js +13 -3
- package/lib/cjs/table/Body/index.d.ts +2 -0
- package/lib/cjs/table/Body/index.js +13 -4
- package/lib/cjs/tree/index.js +5 -3
- package/lib/cjs/tree/interface.d.ts +1 -0
- package/lib/cjs/tree/nodeList.js +2 -1
- package/lib/cjs/treeSelect/index.js +7 -3
- package/lib/es/_base/base.css +5 -5
- package/lib/es/button/buttonGroup.d.ts +1 -0
- package/lib/es/button/buttonGroup.js +5 -2
- package/lib/es/calendar/monthCalendar.js +22 -5
- package/lib/es/cascader/index.d.ts +10 -2
- package/lib/es/cascader/index.js +49 -7
- package/lib/es/cascader/item.d.ts +6 -2
- package/lib/es/cascader/item.js +31 -4
- package/lib/es/datePicker/dateInput.d.ts +9 -4
- package/lib/es/datePicker/dateInput.js +106 -13
- package/lib/es/datePicker/datePicker.d.ts +7 -2
- package/lib/es/datePicker/datePicker.js +139 -30
- package/lib/es/datePicker/index.js +20 -0
- package/lib/es/datePicker/insetInput.d.ts +21 -0
- package/lib/es/datePicker/insetInput.js +65 -0
- package/lib/es/datePicker/month.d.ts +1 -0
- package/lib/es/datePicker/month.js +18 -2
- package/lib/es/datePicker/monthsGrid.js +35 -11
- package/lib/es/datePicker/navigation.js +8 -0
- package/lib/es/datePicker/quickControl.js +2 -0
- package/lib/es/datePicker/yearAndMonth.js +1 -0
- package/lib/es/form/hoc/withField.js +1 -1
- package/lib/es/navigation/Item.d.ts +2 -2
- package/lib/es/navigation/Item.js +8 -6
- package/lib/es/navigation/SubNav.js +2 -2
- package/lib/es/scrollList/scrollItem.d.ts +2 -1
- package/lib/es/scrollList/scrollItem.js +13 -3
- package/lib/es/table/Body/index.d.ts +2 -0
- package/lib/es/table/Body/index.js +13 -4
- package/lib/es/tree/index.js +5 -3
- package/lib/es/tree/interface.d.ts +1 -0
- package/lib/es/tree/nodeList.js +2 -1
- package/lib/es/treeSelect/index.js +7 -3
- package/navigation/Item.tsx +15 -12
- package/navigation/SubNav.tsx +4 -4
- package/package.json +9 -9
- package/scrollList/_story/ScrollList/index.js +3 -0
- package/scrollList/_story/WheelList/index.js +3 -0
- package/scrollList/scrollItem.tsx +30 -9
- package/table/Body/index.tsx +15 -4
- package/table/__test__/table.test.js +18 -0
- package/table/_story/v2/FixedExpandedRow/index.jsx +95 -0
- package/table/_story/v2/index.js +2 -1
- package/tree/__test__/tree.test.js +87 -2
- package/tree/_story/tree.stories.js +65 -5
- package/tree/index.tsx +4 -2
- package/tree/interface.ts +1 -0
- package/tree/nodeList.tsx +2 -2
- package/treeSelect/__test__/treeSelect.test.js +28 -0
- package/treeSelect/_story/treeSelect.stories.js +55 -2
- package/treeSelect/index.tsx +11 -3
package/tree/index.tsx
CHANGED
|
@@ -192,6 +192,7 @@ class Tree extends BaseComponent<TreeProps, TreeState> {
|
|
|
192
192
|
const newState: Partial<TreeState> = {
|
|
193
193
|
prevProps: props,
|
|
194
194
|
};
|
|
195
|
+
const isExpandControlled = 'expandedKeys' in props;
|
|
195
196
|
|
|
196
197
|
// Accept a props field as a parameter to determine whether to update the field
|
|
197
198
|
const needUpdate = (name: string) => {
|
|
@@ -239,7 +240,8 @@ class Tree extends BaseComponent<TreeProps, TreeState> {
|
|
|
239
240
|
newState.motionType = null;
|
|
240
241
|
}
|
|
241
242
|
}
|
|
242
|
-
const
|
|
243
|
+
const dataUpdated = needUpdate('treeDataSimpleJson') || needUpdate('treeData');
|
|
244
|
+
const expandAllWhenDataChange = dataUpdated && props.expandAll;
|
|
243
245
|
if (!isSeaching) {
|
|
244
246
|
// Update expandedKeys
|
|
245
247
|
if (needUpdate('expandedKeys') || (prevProps && needUpdate('autoExpandParent'))) {
|
|
@@ -273,7 +275,7 @@ class Tree extends BaseComponent<TreeProps, TreeState> {
|
|
|
273
275
|
props.multiple,
|
|
274
276
|
valueEntities
|
|
275
277
|
);
|
|
276
|
-
} else if (!prevProps && props.value) {
|
|
278
|
+
} else if ((!prevProps || (!isExpandControlled && dataUpdated)) && props.value) {
|
|
277
279
|
newState.expandedKeys = calcExpandedKeysForValues(
|
|
278
280
|
props.value,
|
|
279
281
|
keyEntities,
|
package/tree/interface.ts
CHANGED
|
@@ -131,6 +131,7 @@ export interface NodeListProps {
|
|
|
131
131
|
motionKeys: Set<string>;
|
|
132
132
|
motionType: string;
|
|
133
133
|
flattenList: FlattenNode[] | undefined;
|
|
134
|
+
searchTargetIsDeep?: boolean;
|
|
134
135
|
renderTreeNode: (treeNode: FlattenNode, ind?: number, style?: React.CSSProperties) => ReactNode;
|
|
135
136
|
}
|
|
136
137
|
export type TransitionNodes<T> = Array<T | Array<T>>;
|
package/tree/nodeList.tsx
CHANGED
|
@@ -59,9 +59,9 @@ export default class NodeList extends PureComponent<NodeListProps, NodeListState
|
|
|
59
59
|
};
|
|
60
60
|
|
|
61
61
|
render() {
|
|
62
|
-
const { flattenNodes, motionType, renderTreeNode } = this.props;
|
|
62
|
+
const { flattenNodes, motionType, searchTargetIsDeep, renderTreeNode } = this.props;
|
|
63
63
|
const { transitionNodes } = this.state;
|
|
64
|
-
const mapData = transitionNodes.length ? transitionNodes : flattenNodes;
|
|
64
|
+
const mapData = transitionNodes.length && !searchTargetIsDeep ? transitionNodes : flattenNodes;
|
|
65
65
|
const options = mapData.map(treeNode => {
|
|
66
66
|
const isMotionNode = Array.isArray(treeNode);
|
|
67
67
|
if (isMotionNode && !(treeNode as FlattenNode[]).length) {
|
|
@@ -552,6 +552,17 @@ describe('TreeSelect', () => {
|
|
|
552
552
|
searchWrapper.find('input').simulate('change', event);
|
|
553
553
|
expect(spyOnSearch.calledOnce).toBe(true);
|
|
554
554
|
expect(spyOnSearch.calledWithMatch(searchValue)).toBe(true);
|
|
555
|
+
|
|
556
|
+
/* Check the input parameters of onSearch */
|
|
557
|
+
searchValue = '北京';
|
|
558
|
+
event = { target: { value: searchValue } };
|
|
559
|
+
searchWrapper.find('input').simulate('change', event);
|
|
560
|
+
expect(spyOnSearch.callCount).toBe(2);
|
|
561
|
+
const firstCall = spyOnSearch.getCall(1);
|
|
562
|
+
const args = firstCall.args;
|
|
563
|
+
expect(args[0]).toEqual('北京');
|
|
564
|
+
expect(args[1].includes('yazhou')).toEqual(true);
|
|
565
|
+
expect(args[1].includes('zhongguo')).toEqual(true);
|
|
555
566
|
});
|
|
556
567
|
|
|
557
568
|
it('filterTreeNode shows correct result', () => {
|
|
@@ -937,4 +948,21 @@ describe('TreeSelect', () => {
|
|
|
937
948
|
).toEqual(0);
|
|
938
949
|
});
|
|
939
950
|
|
|
951
|
+
it('expandedKeys controlled + filterTreeNode', () => {
|
|
952
|
+
const spyOnExpand = sinon.spy(() => { });
|
|
953
|
+
const treeSelect = getTreeSelect({
|
|
954
|
+
expandedKeys: [],
|
|
955
|
+
onExpand: spyOnExpand,
|
|
956
|
+
filterTreeNode: true,
|
|
957
|
+
});
|
|
958
|
+
const searchWrapper = treeSelect.find(`.${BASE_CLASS_PREFIX}-tree-search-wrapper`);
|
|
959
|
+
const searchValue = '北京';
|
|
960
|
+
const event = { target: { value: searchValue } };
|
|
961
|
+
searchWrapper.find('input').simulate('change', event);
|
|
962
|
+
expect(spyOnExpand.callCount).toBe(0);
|
|
963
|
+
/* filter won't impact on the expansion of node when expandedKeys is controlled */
|
|
964
|
+
const topNode = treeSelect.find(`.${BASE_CLASS_PREFIX}-tree-option.${BASE_CLASS_PREFIX}-tree-option-level-1`);
|
|
965
|
+
expect(topNode.at(0).hasClass(`${BASE_CLASS_PREFIX}-tree-option-collapsed`)).toEqual(true);
|
|
966
|
+
expect(topNode.at(1).hasClass(`${BASE_CLASS_PREFIX}-tree-option-collapsed`)).toEqual(true);
|
|
967
|
+
});
|
|
940
968
|
})
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
|
-
import { Icon, Button, Form, Popover, Tag } from '../../index';
|
|
2
|
+
import { Icon, Button, Form, Popover, Tag, Typography } from '../../index';
|
|
3
3
|
import TreeSelect from '../index';
|
|
4
4
|
import { flattenDeep } from 'lodash';
|
|
5
5
|
import CustomTrigger from './CustomTrigger';
|
|
6
6
|
import { IconCreditCard } from '@douyinfe/semi-icons';
|
|
7
7
|
const TreeNode = TreeSelect.TreeNode;
|
|
8
|
+
const { Title } = Typography;
|
|
8
9
|
|
|
9
10
|
export default {
|
|
10
11
|
title: 'TreeSelect',
|
|
@@ -1406,4 +1407,56 @@ export const CheckRelationDemo = () => {
|
|
|
1406
1407
|
/>
|
|
1407
1408
|
</>
|
|
1408
1409
|
);
|
|
1409
|
-
};
|
|
1410
|
+
};
|
|
1411
|
+
|
|
1412
|
+
export const SearchableAndExpandedKeys = () => {
|
|
1413
|
+
const [expandedKeys1, setExpandedKeys1] = useState([]);
|
|
1414
|
+
const [expandedKeys2, setExpandedKeys2] = useState([]);
|
|
1415
|
+
const [expandedKeys3, setExpandedKeys3] = useState([]);
|
|
1416
|
+
return (
|
|
1417
|
+
<>
|
|
1418
|
+
<Title heading={6}>expandedKeys 受控</Title>
|
|
1419
|
+
<TreeSelect
|
|
1420
|
+
style={{ width: 300, marginBottom: 30 }}
|
|
1421
|
+
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
|
1422
|
+
treeData={treeData2}
|
|
1423
|
+
expandedKeys={expandedKeys1}
|
|
1424
|
+
defaultValue='beijing'
|
|
1425
|
+
onExpand={v => {
|
|
1426
|
+
console.log('onExpand value: ', v);
|
|
1427
|
+
setExpandedKeys1(v);
|
|
1428
|
+
}}
|
|
1429
|
+
/>
|
|
1430
|
+
<Title heading={6}>expandedKeys 受控 + 开启搜索</Title>
|
|
1431
|
+
<TreeSelect
|
|
1432
|
+
style={{ width: 300, marginBottom: 30 }}
|
|
1433
|
+
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
|
1434
|
+
treeData={treeData2}
|
|
1435
|
+
filterTreeNode
|
|
1436
|
+
defaultValue='beijing'
|
|
1437
|
+
expandedKeys={expandedKeys2}
|
|
1438
|
+
onExpand={v => {
|
|
1439
|
+
console.log('onExpand value: ', v);
|
|
1440
|
+
setExpandedKeys2(v);
|
|
1441
|
+
}}
|
|
1442
|
+
/>
|
|
1443
|
+
<Title heading={6}>expandedKeys 受控 + 开启搜索 + 搜索时更新 expandedKeys</Title>
|
|
1444
|
+
<TreeSelect
|
|
1445
|
+
style={{ width: 300, marginBottom: 30 }}
|
|
1446
|
+
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
|
1447
|
+
treeData={treeData2}
|
|
1448
|
+
filterTreeNode
|
|
1449
|
+
expandedKeys={expandedKeys3}
|
|
1450
|
+
defaultValue='beijing'
|
|
1451
|
+
onExpand={v => {
|
|
1452
|
+
console.log('onExpand value: ', v);
|
|
1453
|
+
setExpandedKeys3(v)
|
|
1454
|
+
}}
|
|
1455
|
+
onSearch={(input, filterExpandedKeys) => {
|
|
1456
|
+
console.log('onExpand filterExpandedKeys: ', filterExpandedKeys);
|
|
1457
|
+
setExpandedKeys3(filterExpandedKeys);
|
|
1458
|
+
}}
|
|
1459
|
+
/>
|
|
1460
|
+
</>
|
|
1461
|
+
)
|
|
1462
|
+
}
|
package/treeSelect/index.tsx
CHANGED
|
@@ -561,8 +561,8 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
|
|
|
561
561
|
notifySelect: ((selectKey, bool, node) => {
|
|
562
562
|
this.props.onSelect && this.props.onSelect(selectKey, bool, node);
|
|
563
563
|
}),
|
|
564
|
-
notifySearch: input => {
|
|
565
|
-
this.props.onSearch && this.props.onSearch(input);
|
|
564
|
+
notifySearch: (input, filteredExpandedKeys) => {
|
|
565
|
+
this.props.onSearch && this.props.onSearch(input, filteredExpandedKeys);
|
|
566
566
|
},
|
|
567
567
|
cacheFlattenNodes: bool => {
|
|
568
568
|
this._flattenNodes = bool ? cloneDeep(this.state.flattenNodes) : null;
|
|
@@ -1232,9 +1232,10 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
|
|
|
1232
1232
|
};
|
|
1233
1233
|
|
|
1234
1234
|
renderNodeList = () => {
|
|
1235
|
-
const { flattenNodes, motionKeys, motionType } = this.state;
|
|
1235
|
+
const { flattenNodes, motionKeys, motionType, filteredKeys } = this.state;
|
|
1236
1236
|
const { direction } = this.context;
|
|
1237
1237
|
const { virtualize, motionExpand } = this.props;
|
|
1238
|
+
const isExpandControlled = 'expandedKeys' in this.props;
|
|
1238
1239
|
if (!virtualize || isEmpty(virtualize)) {
|
|
1239
1240
|
return (
|
|
1240
1241
|
<NodeList
|
|
@@ -1242,6 +1243,13 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
|
|
|
1242
1243
|
flattenList={this._flattenNodes}
|
|
1243
1244
|
motionKeys={motionExpand ? motionKeys : new Set([])}
|
|
1244
1245
|
motionType={motionType}
|
|
1246
|
+
// When motionKeys is empty, but filteredKeys is not empty (that is, the search hits), this situation should be distinguished from ordinary motionKeys
|
|
1247
|
+
searchTargetIsDeep={
|
|
1248
|
+
isExpandControlled &&
|
|
1249
|
+
motionExpand &&
|
|
1250
|
+
isEmpty(motionKeys) &&
|
|
1251
|
+
!isEmpty(filteredKeys)
|
|
1252
|
+
}
|
|
1245
1253
|
onMotionEnd={this.onMotionEnd}
|
|
1246
1254
|
renderTreeNode={this.renderTreeNode}
|
|
1247
1255
|
/>
|