@douyinfe/semi-ui 2.6.0-beta.0 → 2.7.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/button/index.tsx +1 -1
- package/cascader/__test__/cascader.test.js +159 -81
- package/cascader/_story/cascader.stories.js +36 -23
- package/cascader/index.tsx +26 -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 +95 -9
- package/datePicker/datePicker.tsx +89 -15
- package/datePicker/index.tsx +15 -0
- package/datePicker/insetInput.tsx +76 -0
- package/datePicker/monthsGrid.tsx +14 -7
- package/dist/css/semi.css +105 -2
- package/dist/css/semi.min.css +1 -1
- package/dist/umd/semi-ui.js +949 -163
- 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/hooks/useFormApi.tsx +3 -2
- package/input/_story/input.stories.js +13 -0
- package/lib/cjs/button/Button.d.ts +4 -4
- package/lib/cjs/button/buttonGroup.d.ts +3 -2
- package/lib/cjs/button/buttonGroup.js +6 -2
- package/lib/cjs/button/index.d.ts +5 -6
- package/lib/cjs/cascader/index.d.ts +1 -0
- package/lib/cjs/cascader/index.js +38 -9
- package/lib/cjs/datePicker/dateInput.d.ts +9 -2
- package/lib/cjs/datePicker/dateInput.js +92 -9
- package/lib/cjs/datePicker/datePicker.d.ts +7 -2
- package/lib/cjs/datePicker/datePicker.js +123 -18
- 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/monthsGrid.js +19 -7
- package/lib/cjs/form/hooks/useFormApi.d.ts +2 -1
- package/lib/cjs/iconButton/index.d.ts +2 -2
- 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/radio/radioGroup.js +6 -0
- package/lib/cjs/select/index.js +5 -2
- package/lib/cjs/table/Body/index.d.ts +2 -0
- package/lib/cjs/table/Body/index.js +13 -4
- package/lib/cjs/tag/group.d.ts +2 -0
- package/lib/cjs/tag/group.js +4 -2
- package/lib/cjs/tooltip/index.js +6 -2
- package/lib/cjs/tree/index.js +5 -3
- package/lib/cjs/tree/interface.d.ts +1 -0
- package/lib/cjs/tree/nodeList.js +3 -1
- package/lib/cjs/treeSelect/index.js +11 -3
- package/lib/es/button/Button.d.ts +4 -4
- package/lib/es/button/buttonGroup.d.ts +3 -2
- package/lib/es/button/buttonGroup.js +5 -2
- package/lib/es/button/index.d.ts +5 -6
- package/lib/es/cascader/index.d.ts +1 -0
- package/lib/es/cascader/index.js +35 -6
- package/lib/es/datePicker/dateInput.d.ts +9 -2
- package/lib/es/datePicker/dateInput.js +91 -9
- package/lib/es/datePicker/datePicker.d.ts +7 -2
- package/lib/es/datePicker/datePicker.js +124 -18
- 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/monthsGrid.js +19 -7
- package/lib/es/form/hooks/useFormApi.d.ts +2 -1
- package/lib/es/iconButton/index.d.ts +2 -2
- 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/radio/radioGroup.js +6 -0
- package/lib/es/select/index.js +5 -2
- package/lib/es/table/Body/index.d.ts +2 -0
- package/lib/es/table/Body/index.js +13 -4
- package/lib/es/tag/group.d.ts +2 -0
- package/lib/es/tag/group.js +4 -2
- package/lib/es/tooltip/index.js +6 -2
- package/lib/es/tree/index.js +5 -3
- package/lib/es/tree/interface.d.ts +1 -0
- package/lib/es/tree/nodeList.js +3 -1
- package/lib/es/treeSelect/index.js +11 -3
- package/navigation/Item.tsx +15 -12
- package/navigation/SubNav.tsx +4 -4
- package/package.json +9 -9
- package/radio/__test__/radioGroup.test.jsx +9 -1
- package/radio/_story/radio.stories.js +22 -1
- package/radio/radioGroup.tsx +9 -0
- package/select/_story/select.stories.js +73 -2
- package/select/index.tsx +5 -3
- 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/tag/group.tsx +5 -3
- package/tooltip/_story/tooltip.stories.js +702 -625
- package/tooltip/index.tsx +2 -2
- 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 +3 -2
- package/treeSelect/__test__/treeSelect.test.js +28 -0
- package/treeSelect/_story/treeSelect.stories.js +55 -2
- package/treeSelect/index.tsx +14 -3
package/tooltip/index.tsx
CHANGED
|
@@ -513,7 +513,7 @@ export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
|
|
|
513
513
|
<div
|
|
514
514
|
className={classNames(className, animateCls)}
|
|
515
515
|
style={{
|
|
516
|
-
|
|
516
|
+
visibility: 'visible',
|
|
517
517
|
...animateStyle,
|
|
518
518
|
transformOrigin,
|
|
519
519
|
...style,
|
|
@@ -532,7 +532,7 @@ export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
|
|
|
532
532
|
}
|
|
533
533
|
</TooltipTransition>
|
|
534
534
|
) : (
|
|
535
|
-
<div className={className} {...portalEventSet} x-placement={placement} style={style}>
|
|
535
|
+
<div className={className} {...portalEventSet} x-placement={placement} style={{ visibility: motion ? undefined : 'visible', ...style }}>
|
|
536
536
|
{content}
|
|
537
537
|
{icon}
|
|
538
538
|
</div>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { BASE_CLASS_PREFIX } from '../../../semi-foundation/base/constants';
|
|
1
|
+
import { isEqual } from 'lodash';
|
|
3
2
|
import { IconMapPin } from '@douyinfe/semi-icons';
|
|
3
|
+
import { BASE_CLASS_PREFIX } from '../../../semi-foundation/base/constants';
|
|
4
|
+
import { Tree, Button } from '../../index';
|
|
4
5
|
|
|
5
6
|
const treeChildren = [
|
|
6
7
|
{
|
|
@@ -672,6 +673,90 @@ describe('Tree', () => {
|
|
|
672
673
|
expect(tree.state().selectedKeys.length).toEqual(0);
|
|
673
674
|
});
|
|
674
675
|
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* Detect whether the expanded item will be expanded according to the value when the value
|
|
679
|
+
* or treeData is changed, when expandedKeys is not controlled
|
|
680
|
+
*/
|
|
681
|
+
const treeJsonData1 = {
|
|
682
|
+
"Node0": {
|
|
683
|
+
"Child Node0-0": '0-0',
|
|
684
|
+
"Child Node0-1": '0-1',
|
|
685
|
+
},
|
|
686
|
+
"Node1": {
|
|
687
|
+
"Child Node1-0": '1-0',
|
|
688
|
+
"Child Node1-1": '1-1',
|
|
689
|
+
}
|
|
690
|
+
};
|
|
691
|
+
const treeJsonData2 = {
|
|
692
|
+
"Updated Node0": {
|
|
693
|
+
"Updated Child Node0-0": {
|
|
694
|
+
'Updated Child Node0-0-0':'0-0'
|
|
695
|
+
},
|
|
696
|
+
"Updated Child Node0-1": '0-1',
|
|
697
|
+
},
|
|
698
|
+
"Updated Node1": {
|
|
699
|
+
"Updated Child Node1-0": '1-0',
|
|
700
|
+
"Updated Child Node1-1": '1-1',
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
|
|
704
|
+
it('expandedKeys when treeDataSimpleJson update', () => {
|
|
705
|
+
const tree = mount(
|
|
706
|
+
<Tree
|
|
707
|
+
value='0-0'
|
|
708
|
+
multiple
|
|
709
|
+
treeDataSimpleJson={treeJsonData1}
|
|
710
|
+
/>,
|
|
711
|
+
{
|
|
712
|
+
attachTo: document.getElementById('container')
|
|
713
|
+
}
|
|
714
|
+
);
|
|
715
|
+
const treeDataButton = mount(
|
|
716
|
+
<Button
|
|
717
|
+
onClick={() => {
|
|
718
|
+
if (isEqual(tree.props().treeDataSimpleJson, treeJsonData1)) {
|
|
719
|
+
tree.setProps({ treeDataSimpleJson: treeJsonData2 });
|
|
720
|
+
tree.update();
|
|
721
|
+
} else {
|
|
722
|
+
tree.setProps({ treeDataSimpleJson: treeJsonData1 });
|
|
723
|
+
tree.update();
|
|
724
|
+
}
|
|
725
|
+
}}
|
|
726
|
+
>
|
|
727
|
+
update treeData
|
|
728
|
+
</Button>
|
|
729
|
+
);
|
|
730
|
+
expect(
|
|
731
|
+
tree
|
|
732
|
+
.find(`.${BASE_CLASS_PREFIX}-tree-option.${BASE_CLASS_PREFIX}-tree-option-level-1`)
|
|
733
|
+
.at(0)
|
|
734
|
+
.hasClass(`${BASE_CLASS_PREFIX}-tree-option-collapsed`)
|
|
735
|
+
).toEqual(false);
|
|
736
|
+
expect(
|
|
737
|
+
tree
|
|
738
|
+
.find(`.${BASE_CLASS_PREFIX}-tree-option.${BASE_CLASS_PREFIX}-tree-option-level-2`)
|
|
739
|
+
.at(0)
|
|
740
|
+
.hasClass(`${BASE_CLASS_PREFIX}-tree-option-collapsed`)
|
|
741
|
+
).toEqual(true);
|
|
742
|
+
expect(
|
|
743
|
+
tree
|
|
744
|
+
.find(`.${BASE_CLASS_PREFIX}-tree-option.${BASE_CLASS_PREFIX}-tree-option-level-1`)
|
|
745
|
+
.at(1)
|
|
746
|
+
.hasClass(`${BASE_CLASS_PREFIX}-tree-option-collapsed`)
|
|
747
|
+
).toEqual(true);
|
|
748
|
+
treeDataButton.simulate('click');
|
|
749
|
+
expect(
|
|
750
|
+
tree
|
|
751
|
+
.find(`.${BASE_CLASS_PREFIX}-tree-option.${BASE_CLASS_PREFIX}-tree-option-level-2`)
|
|
752
|
+
.at(0)
|
|
753
|
+
.hasClass(`${BASE_CLASS_PREFIX}-tree-option-collapsed`)
|
|
754
|
+
).toEqual(false);
|
|
755
|
+
treeDataButton.simulate('click');
|
|
756
|
+
tree.unmount();
|
|
757
|
+
treeDataButton.unmount();
|
|
758
|
+
});
|
|
759
|
+
|
|
675
760
|
it('expandAction = false / default behavior', () => {
|
|
676
761
|
const nativeEvent = { nativeEvent: { stopImmediatePropagation: () => { } } }
|
|
677
762
|
let spyOnExpand = sinon.spy(() => { });
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import React, { useRef, useState } from 'react';
|
|
2
|
+
import { cloneDeep, difference, isEqual } from 'lodash';
|
|
3
|
+
import { IconEdit, IconMapPin, IconMore } from '@douyinfe/semi-icons';
|
|
2
4
|
import Tree from '../index';
|
|
3
5
|
import AutoSizer from '../autoSizer';
|
|
4
|
-
import { Button, ButtonGroup, Input, Popover, Toast } from '../../index';
|
|
6
|
+
import { Button, ButtonGroup, Input, Popover, Toast, Space } from '../../index';
|
|
5
7
|
import BigTree from './BigData';
|
|
6
8
|
import testData from './data';
|
|
7
|
-
import { cloneDeep, difference, isEqual } from 'lodash';
|
|
8
|
-
import { IconEdit, IconMapPin, IconMore } from '@douyinfe/semi-icons';
|
|
9
|
-
|
|
10
9
|
const TreeNode = Tree.TreeNode;
|
|
11
10
|
|
|
12
11
|
export default {
|
|
@@ -2338,4 +2337,65 @@ export const CheckRelationDemo = () => {
|
|
|
2338
2337
|
/>
|
|
2339
2338
|
</>
|
|
2340
2339
|
);
|
|
2341
|
-
};
|
|
2340
|
+
};
|
|
2341
|
+
|
|
2342
|
+
export const ValueImpactExpansionWithDynamicTreeData = () => {
|
|
2343
|
+
const json = {
|
|
2344
|
+
"Node0": {
|
|
2345
|
+
"Child Node0-0": '0-0',
|
|
2346
|
+
"Child Node0-1": '0-1',
|
|
2347
|
+
},
|
|
2348
|
+
"Node1": {
|
|
2349
|
+
"Child Node1-0": '1-0',
|
|
2350
|
+
"Child Node1-1": '1-1',
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
const json2 = {
|
|
2354
|
+
"Updated Node0": {
|
|
2355
|
+
"Updated Child Node0-0": {
|
|
2356
|
+
'Updated Child Node0-0-0':'0-0'
|
|
2357
|
+
},
|
|
2358
|
+
"Updated Child Node0-1": '0-1',
|
|
2359
|
+
},
|
|
2360
|
+
"Updated Node1": {
|
|
2361
|
+
"Updated Child Node1-0": '1-0',
|
|
2362
|
+
"Updated Child Node1-1": '1-1',
|
|
2363
|
+
}
|
|
2364
|
+
}
|
|
2365
|
+
const style = {
|
|
2366
|
+
width: 260,
|
|
2367
|
+
height: 420,
|
|
2368
|
+
border: '1px solid var(--color-border)'
|
|
2369
|
+
}
|
|
2370
|
+
const [value, setValue] = useState('0-0')
|
|
2371
|
+
const [tree, setTree] = useState(json);
|
|
2372
|
+
const handleValueButtonClick = () => {
|
|
2373
|
+
if (value === '0-0') {
|
|
2374
|
+
setValue('1-0');
|
|
2375
|
+
} else {
|
|
2376
|
+
setValue('0-0');
|
|
2377
|
+
}
|
|
2378
|
+
}
|
|
2379
|
+
const handleTreeDataButtonClick = () => {
|
|
2380
|
+
if(isEqual(tree, json)){
|
|
2381
|
+
setTree(json2);
|
|
2382
|
+
} else {
|
|
2383
|
+
setTree(json);
|
|
2384
|
+
}
|
|
2385
|
+
}
|
|
2386
|
+
return (
|
|
2387
|
+
<>
|
|
2388
|
+
<div>value 受控时,当 treeData/treeDataSimpleJson 改变时,应该根据 value 自动展开</div>
|
|
2389
|
+
<Tree
|
|
2390
|
+
value={value}
|
|
2391
|
+
treeDataSimpleJson={tree}
|
|
2392
|
+
style={style}
|
|
2393
|
+
onChange={v => setValue(v)}
|
|
2394
|
+
/>
|
|
2395
|
+
<Space>
|
|
2396
|
+
<Button onClick={handleValueButtonClick}>改变 value</Button>
|
|
2397
|
+
<Button onClick={handleTreeDataButtonClick}>改变 TreeData</Button>
|
|
2398
|
+
</Space>
|
|
2399
|
+
</>
|
|
2400
|
+
)
|
|
2401
|
+
}
|
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
|
@@ -55,13 +55,14 @@ export default class NodeList extends PureComponent<NodeListProps, NodeListState
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
onMotionEnd = () => {
|
|
58
|
+
typeof this.props.onMotionEnd === 'function' && this.props.onMotionEnd();
|
|
58
59
|
this.setState({ transitionNodes: [] });
|
|
59
60
|
};
|
|
60
61
|
|
|
61
62
|
render() {
|
|
62
|
-
const { flattenNodes, motionType, renderTreeNode } = this.props;
|
|
63
|
+
const { flattenNodes, motionType, searchTargetIsDeep, renderTreeNode } = this.props;
|
|
63
64
|
const { transitionNodes } = this.state;
|
|
64
|
-
const mapData = transitionNodes.length ? transitionNodes : flattenNodes;
|
|
65
|
+
const mapData = transitionNodes.length && !searchTargetIsDeep ? transitionNodes : flattenNodes;
|
|
65
66
|
const options = mapData.map(treeNode => {
|
|
66
67
|
const isMotionNode = Array.isArray(treeNode);
|
|
67
68
|
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
|
@@ -331,6 +331,9 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
|
|
|
331
331
|
this.clickOutsideHandler = null;
|
|
332
332
|
this.foundation = new TreeSelectFoundation(this.adapter);
|
|
333
333
|
this.treeSelectID = Math.random().toString(36).slice(2);
|
|
334
|
+
this.onMotionEnd = () => {
|
|
335
|
+
this.adapter.rePositionDropdown();
|
|
336
|
+
};
|
|
334
337
|
}
|
|
335
338
|
|
|
336
339
|
// eslint-disable-next-line max-lines-per-function
|
|
@@ -561,8 +564,8 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
|
|
|
561
564
|
notifySelect: ((selectKey, bool, node) => {
|
|
562
565
|
this.props.onSelect && this.props.onSelect(selectKey, bool, node);
|
|
563
566
|
}),
|
|
564
|
-
notifySearch: input => {
|
|
565
|
-
this.props.onSearch && this.props.onSearch(input);
|
|
567
|
+
notifySearch: (input, filteredExpandedKeys) => {
|
|
568
|
+
this.props.onSearch && this.props.onSearch(input, filteredExpandedKeys);
|
|
566
569
|
},
|
|
567
570
|
cacheFlattenNodes: bool => {
|
|
568
571
|
this._flattenNodes = bool ? cloneDeep(this.state.flattenNodes) : null;
|
|
@@ -1232,9 +1235,10 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
|
|
|
1232
1235
|
};
|
|
1233
1236
|
|
|
1234
1237
|
renderNodeList = () => {
|
|
1235
|
-
const { flattenNodes, motionKeys, motionType } = this.state;
|
|
1238
|
+
const { flattenNodes, motionKeys, motionType, filteredKeys } = this.state;
|
|
1236
1239
|
const { direction } = this.context;
|
|
1237
1240
|
const { virtualize, motionExpand } = this.props;
|
|
1241
|
+
const isExpandControlled = 'expandedKeys' in this.props;
|
|
1238
1242
|
if (!virtualize || isEmpty(virtualize)) {
|
|
1239
1243
|
return (
|
|
1240
1244
|
<NodeList
|
|
@@ -1242,6 +1246,13 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
|
|
|
1242
1246
|
flattenList={this._flattenNodes}
|
|
1243
1247
|
motionKeys={motionExpand ? motionKeys : new Set([])}
|
|
1244
1248
|
motionType={motionType}
|
|
1249
|
+
// When motionKeys is empty, but filteredKeys is not empty (that is, the search hits), this situation should be distinguished from ordinary motionKeys
|
|
1250
|
+
searchTargetIsDeep={
|
|
1251
|
+
isExpandControlled &&
|
|
1252
|
+
motionExpand &&
|
|
1253
|
+
isEmpty(motionKeys) &&
|
|
1254
|
+
!isEmpty(filteredKeys)
|
|
1255
|
+
}
|
|
1245
1256
|
onMotionEnd={this.onMotionEnd}
|
|
1246
1257
|
renderTreeNode={this.renderTreeNode}
|
|
1247
1258
|
/>
|