@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.
Files changed (111) hide show
  1. package/button/__test__/button.test.js +7 -0
  2. package/button/buttonGroup.tsx +5 -2
  3. package/calendar/monthCalendar.tsx +14 -13
  4. package/cascader/__test__/cascader.test.js +159 -81
  5. package/cascader/_story/cascader.stories.js +36 -23
  6. package/cascader/index.tsx +47 -8
  7. package/cascader/item.tsx +25 -5
  8. package/datePicker/_story/v2/InsetInput.jsx +104 -0
  9. package/datePicker/_story/v2/InsetInputE2E.jsx +69 -0
  10. package/datePicker/_story/v2/index.js +2 -0
  11. package/datePicker/dateInput.tsx +102 -13
  12. package/datePicker/datePicker.tsx +95 -16
  13. package/datePicker/index.tsx +15 -0
  14. package/datePicker/insetInput.tsx +76 -0
  15. package/datePicker/month.tsx +14 -7
  16. package/datePicker/monthsGrid.tsx +31 -12
  17. package/datePicker/navigation.tsx +8 -4
  18. package/datePicker/quickControl.tsx +1 -0
  19. package/datePicker/yearAndMonth.tsx +1 -1
  20. package/dist/css/semi.css +120 -8
  21. package/dist/css/semi.min.css +1 -1
  22. package/dist/umd/semi-ui.js +1100 -193
  23. package/dist/umd/semi-ui.js.map +1 -1
  24. package/dist/umd/semi-ui.min.js +1 -1
  25. package/dist/umd/semi-ui.min.js.map +1 -1
  26. package/form/hoc/withField.tsx +1 -1
  27. package/input/_story/input.stories.js +13 -0
  28. package/lib/cjs/_base/base.css +5 -5
  29. package/lib/cjs/button/buttonGroup.d.ts +1 -0
  30. package/lib/cjs/button/buttonGroup.js +6 -2
  31. package/lib/cjs/calendar/monthCalendar.js +21 -5
  32. package/lib/cjs/cascader/index.d.ts +10 -2
  33. package/lib/cjs/cascader/index.js +52 -10
  34. package/lib/cjs/cascader/item.d.ts +6 -2
  35. package/lib/cjs/cascader/item.js +33 -4
  36. package/lib/cjs/datePicker/dateInput.d.ts +9 -4
  37. package/lib/cjs/datePicker/dateInput.js +107 -13
  38. package/lib/cjs/datePicker/datePicker.d.ts +7 -2
  39. package/lib/cjs/datePicker/datePicker.js +138 -30
  40. package/lib/cjs/datePicker/index.js +24 -2
  41. package/lib/cjs/datePicker/insetInput.d.ts +21 -0
  42. package/lib/cjs/datePicker/insetInput.js +80 -0
  43. package/lib/cjs/datePicker/month.d.ts +1 -0
  44. package/lib/cjs/datePicker/month.js +18 -2
  45. package/lib/cjs/datePicker/monthsGrid.js +35 -11
  46. package/lib/cjs/datePicker/navigation.js +8 -0
  47. package/lib/cjs/datePicker/quickControl.js +1 -0
  48. package/lib/cjs/datePicker/yearAndMonth.js +1 -0
  49. package/lib/cjs/form/hoc/withField.js +1 -1
  50. package/lib/cjs/navigation/Item.d.ts +2 -2
  51. package/lib/cjs/navigation/Item.js +8 -6
  52. package/lib/cjs/navigation/SubNav.js +2 -2
  53. package/lib/cjs/scrollList/scrollItem.d.ts +2 -1
  54. package/lib/cjs/scrollList/scrollItem.js +13 -3
  55. package/lib/cjs/table/Body/index.d.ts +2 -0
  56. package/lib/cjs/table/Body/index.js +13 -4
  57. package/lib/cjs/tree/index.js +5 -3
  58. package/lib/cjs/tree/interface.d.ts +1 -0
  59. package/lib/cjs/tree/nodeList.js +2 -1
  60. package/lib/cjs/treeSelect/index.js +7 -3
  61. package/lib/es/_base/base.css +5 -5
  62. package/lib/es/button/buttonGroup.d.ts +1 -0
  63. package/lib/es/button/buttonGroup.js +5 -2
  64. package/lib/es/calendar/monthCalendar.js +22 -5
  65. package/lib/es/cascader/index.d.ts +10 -2
  66. package/lib/es/cascader/index.js +49 -7
  67. package/lib/es/cascader/item.d.ts +6 -2
  68. package/lib/es/cascader/item.js +31 -4
  69. package/lib/es/datePicker/dateInput.d.ts +9 -4
  70. package/lib/es/datePicker/dateInput.js +106 -13
  71. package/lib/es/datePicker/datePicker.d.ts +7 -2
  72. package/lib/es/datePicker/datePicker.js +139 -30
  73. package/lib/es/datePicker/index.js +20 -0
  74. package/lib/es/datePicker/insetInput.d.ts +21 -0
  75. package/lib/es/datePicker/insetInput.js +65 -0
  76. package/lib/es/datePicker/month.d.ts +1 -0
  77. package/lib/es/datePicker/month.js +18 -2
  78. package/lib/es/datePicker/monthsGrid.js +35 -11
  79. package/lib/es/datePicker/navigation.js +8 -0
  80. package/lib/es/datePicker/quickControl.js +2 -0
  81. package/lib/es/datePicker/yearAndMonth.js +1 -0
  82. package/lib/es/form/hoc/withField.js +1 -1
  83. package/lib/es/navigation/Item.d.ts +2 -2
  84. package/lib/es/navigation/Item.js +8 -6
  85. package/lib/es/navigation/SubNav.js +2 -2
  86. package/lib/es/scrollList/scrollItem.d.ts +2 -1
  87. package/lib/es/scrollList/scrollItem.js +13 -3
  88. package/lib/es/table/Body/index.d.ts +2 -0
  89. package/lib/es/table/Body/index.js +13 -4
  90. package/lib/es/tree/index.js +5 -3
  91. package/lib/es/tree/interface.d.ts +1 -0
  92. package/lib/es/tree/nodeList.js +2 -1
  93. package/lib/es/treeSelect/index.js +7 -3
  94. package/navigation/Item.tsx +15 -12
  95. package/navigation/SubNav.tsx +4 -4
  96. package/package.json +9 -9
  97. package/scrollList/_story/ScrollList/index.js +3 -0
  98. package/scrollList/_story/WheelList/index.js +3 -0
  99. package/scrollList/scrollItem.tsx +30 -9
  100. package/table/Body/index.tsx +15 -4
  101. package/table/__test__/table.test.js +18 -0
  102. package/table/_story/v2/FixedExpandedRow/index.jsx +95 -0
  103. package/table/_story/v2/index.js +2 -1
  104. package/tree/__test__/tree.test.js +87 -2
  105. package/tree/_story/tree.stories.js +65 -5
  106. package/tree/index.tsx +4 -2
  107. package/tree/interface.ts +1 -0
  108. package/tree/nodeList.tsx +2 -2
  109. package/treeSelect/__test__/treeSelect.test.js +28 -0
  110. package/treeSelect/_story/treeSelect.stories.js +55 -2
  111. 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 expandAllWhenDataChange = (needUpdate('treeDataSimpleJson') || needUpdate('treeData')) && props.expandAll;
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
+ }
@@ -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
  />