@douyinfe/semi-ui 2.3.1 → 2.5.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 (119) hide show
  1. package/cascader/__test__/cascader.test.js +24 -0
  2. package/cascader/_story/cascader.stories.js +73 -0
  3. package/cascader/index.tsx +5 -2
  4. package/datePicker/_story/RenderDate/index.js +13 -3
  5. package/datePicker/_story/RenderFullDate/index.js +36 -14
  6. package/datePicker/_story/RenderFullDate/index.scss +1 -1
  7. package/datePicker/_story/datePicker.stories.js +19 -11
  8. package/datePicker/_story/v2/PanelOpen.jsx +39 -0
  9. package/datePicker/_story/v2/index.js +2 -1
  10. package/datePicker/datePicker.tsx +1 -0
  11. package/dist/css/semi.css +84 -36
  12. package/dist/css/semi.min.css +1 -1
  13. package/dist/umd/semi-ui.js +487 -170
  14. package/dist/umd/semi-ui.js.map +1 -1
  15. package/dist/umd/semi-ui.min.js +1 -1
  16. package/dist/umd/semi-ui.min.js.map +1 -1
  17. package/form/_story/demo.jsx +1 -0
  18. package/input/index.tsx +1 -0
  19. package/input/textarea.tsx +6 -4
  20. package/inputNumber/__test__/inputNumber.test.js +36 -8
  21. package/lib/cjs/autoComplete/index.d.ts +1 -1
  22. package/lib/cjs/cascader/index.js +6 -0
  23. package/lib/cjs/datePicker/datePicker.js +12 -8
  24. package/lib/cjs/dropdown/index.d.ts +1 -1
  25. package/lib/cjs/form/baseForm.d.ts +1 -1
  26. package/lib/cjs/form/field.d.ts +1 -1
  27. package/lib/cjs/input/index.js +2 -1
  28. package/lib/cjs/input/textarea.js +5 -3
  29. package/lib/cjs/navigation/Item.js +1 -1
  30. package/lib/cjs/navigation/SubNav.js +1 -1
  31. package/lib/cjs/scrollList/scrollItem.d.ts +5 -1
  32. package/lib/cjs/scrollList/scrollItem.js +7 -0
  33. package/lib/cjs/select/index.d.ts +1 -1
  34. package/lib/cjs/select/index.js +1 -1
  35. package/lib/cjs/select/option.js +2 -2
  36. package/lib/cjs/table/Table.d.ts +1 -1
  37. package/lib/cjs/table/Table.js +17 -7
  38. package/lib/cjs/table/interface.d.ts +1 -0
  39. package/lib/cjs/tabs/interface.d.ts +1 -1
  40. package/lib/cjs/timePicker/TimePicker.d.ts +2 -0
  41. package/lib/cjs/timePicker/TimePicker.js +4 -4
  42. package/lib/cjs/timePicker/index.d.ts +1 -0
  43. package/lib/cjs/tooltip/index.d.ts +1 -1
  44. package/lib/cjs/tree/index.d.ts +2 -0
  45. package/lib/cjs/tree/index.js +15 -8
  46. package/lib/cjs/tree/treeNode.js +10 -1
  47. package/lib/cjs/treeSelect/index.d.ts +2 -0
  48. package/lib/cjs/treeSelect/index.js +75 -30
  49. package/lib/cjs/typography/util.js +0 -1
  50. package/lib/cjs/upload/fileCard.js +31 -22
  51. package/lib/cjs/upload/index.d.ts +6 -0
  52. package/lib/cjs/upload/index.js +15 -8
  53. package/lib/cjs/upload/interface.d.ts +8 -6
  54. package/lib/es/autoComplete/index.d.ts +1 -1
  55. package/lib/es/cascader/index.js +5 -0
  56. package/lib/es/datePicker/datePicker.js +12 -8
  57. package/lib/es/dropdown/index.d.ts +1 -1
  58. package/lib/es/form/baseForm.d.ts +1 -1
  59. package/lib/es/form/field.d.ts +1 -1
  60. package/lib/es/input/index.js +2 -1
  61. package/lib/es/input/textarea.js +5 -3
  62. package/lib/es/navigation/Item.js +1 -1
  63. package/lib/es/navigation/SubNav.js +1 -1
  64. package/lib/es/scrollList/scrollItem.d.ts +5 -1
  65. package/lib/es/scrollList/scrollItem.js +7 -0
  66. package/lib/es/select/index.d.ts +1 -1
  67. package/lib/es/select/index.js +1 -1
  68. package/lib/es/select/option.js +2 -2
  69. package/lib/es/table/Table.d.ts +1 -1
  70. package/lib/es/table/Table.js +19 -7
  71. package/lib/es/table/interface.d.ts +1 -0
  72. package/lib/es/tabs/interface.d.ts +1 -1
  73. package/lib/es/timePicker/TimePicker.d.ts +2 -0
  74. package/lib/es/timePicker/TimePicker.js +4 -4
  75. package/lib/es/timePicker/index.d.ts +1 -0
  76. package/lib/es/tooltip/index.d.ts +1 -1
  77. package/lib/es/tree/index.d.ts +2 -0
  78. package/lib/es/tree/index.js +15 -8
  79. package/lib/es/tree/treeNode.js +9 -1
  80. package/lib/es/treeSelect/index.d.ts +2 -0
  81. package/lib/es/treeSelect/index.js +76 -31
  82. package/lib/es/typography/util.js +0 -1
  83. package/lib/es/upload/fileCard.js +31 -24
  84. package/lib/es/upload/index.d.ts +6 -0
  85. package/lib/es/upload/index.js +14 -8
  86. package/lib/es/upload/interface.d.ts +8 -6
  87. package/navigation/Item.tsx +1 -1
  88. package/navigation/SubNav.tsx +1 -1
  89. package/package.json +9 -8
  90. package/scrollList/scrollItem.tsx +10 -3
  91. package/select/index.tsx +6 -1
  92. package/select/option.tsx +2 -2
  93. package/table/Table.tsx +16 -8
  94. package/table/_story/table.stories.js +1 -0
  95. package/table/_story/v2/FixedColumnsChange/index.jsx +104 -0
  96. package/table/_story/v2/FixedHeaderMerge/index.jsx +98 -0
  97. package/table/_story/v2/FixedZIndex/index.jsx +87 -0
  98. package/table/_story/v2/defaultFilteredValue.tsx +123 -0
  99. package/table/_story/v2/index.js +4 -0
  100. package/table/interface.ts +1 -0
  101. package/tabs/interface.ts +1 -1
  102. package/timePicker/TimePicker.tsx +4 -1
  103. package/timePicker/__test__/timePicker.test.js +42 -3
  104. package/timePicker/_story/timepicker.stories.js +18 -0
  105. package/tooltip/_story/tooltip.stories.js +83 -1
  106. package/tree/__test__/treeMultiple.test.js +94 -0
  107. package/tree/_story/tree.stories.js +169 -0
  108. package/tree/index.tsx +12 -5
  109. package/tree/treeNode.tsx +9 -2
  110. package/treeSelect/__test__/treeMultiple.test.js +94 -0
  111. package/treeSelect/__test__/treeSelect.test.js +157 -0
  112. package/treeSelect/_story/treeSelect.stories.js +242 -0
  113. package/treeSelect/index.tsx +93 -52
  114. package/typography/_story/typography.stories.js +8 -0
  115. package/typography/util.tsx +0 -1
  116. package/upload/_story/upload.stories.js +22 -6
  117. package/upload/fileCard.tsx +23 -23
  118. package/upload/index.tsx +15 -6
  119. package/upload/interface.ts +7 -5
@@ -1165,3 +1165,245 @@ export const DisabledStrictly = () => (
1165
1165
  DisabledStrictly.story = {
1166
1166
  name: 'disabledStrictly',
1167
1167
  };
1168
+
1169
+
1170
+ export const CheckRelationDemo = () => {
1171
+ const treeData = [
1172
+ {
1173
+ label: 'Asia',
1174
+ value: 'Asia',
1175
+ key: '0',
1176
+ children: [
1177
+ {
1178
+ label: 'China',
1179
+ value: 'China',
1180
+ key: '0-0',
1181
+ children: [
1182
+ {
1183
+ label: 'Beijing',
1184
+ value: 'Beijing',
1185
+ key: '0-0-0',
1186
+ },
1187
+ {
1188
+ label: 'Shanghai',
1189
+ value: 'Shanghai',
1190
+ key: '0-0-1',
1191
+ },
1192
+ {
1193
+ label: 'Chengdu',
1194
+ value: 'Chengdu',
1195
+ key: '0-0-2',
1196
+ },
1197
+ ],
1198
+ },
1199
+ {
1200
+ label: 'Japan',
1201
+ value: 'Japan',
1202
+ key: '0-1',
1203
+ children: [
1204
+ {
1205
+ label: 'Osaka',
1206
+ value: 'Osaka',
1207
+ key: '0-1-0'
1208
+ }
1209
+ ]
1210
+ },
1211
+ ],
1212
+ },
1213
+ {
1214
+ label: 'North America',
1215
+ value: 'North America',
1216
+ key: '1',
1217
+ children: [
1218
+ {
1219
+ label: 'United States',
1220
+ value: 'United States',
1221
+ key: '1-0'
1222
+ },
1223
+ {
1224
+ label: 'Canada',
1225
+ value: 'Canada',
1226
+ key: '1-1'
1227
+ }
1228
+ ]
1229
+ }
1230
+ ];
1231
+ const [value, setValue] = useState('China');
1232
+ const [value2, setValue2] = useState();
1233
+ const [value3, setValue3] = useState();
1234
+ const style = {
1235
+ width: 300,
1236
+ };
1237
+ const dropdownStyle = {
1238
+ maxHeight: 400,
1239
+ overflow: 'auto'
1240
+ };
1241
+ const handleChange = value => {
1242
+ console.log(value);
1243
+ setValue(value);
1244
+ };
1245
+ const handleChange2 = value => {
1246
+ console.log(value);
1247
+ setValue2(value);
1248
+ };
1249
+ const handleChange3 = value => {
1250
+ console.log(value);
1251
+ setValue3(value);
1252
+ };
1253
+ return (
1254
+ <>
1255
+ <div>checkRelation='unRelated'</div>
1256
+ <TreeSelect
1257
+ dropdownStyle={dropdownStyle}
1258
+ treeData={treeData}
1259
+ multiple
1260
+ checkRelation='unRelated'
1261
+ defaultExpandAll
1262
+ style={style}
1263
+ />
1264
+ <br /><br />
1265
+ <div>checkRelation='unRelated' + maxTagCount=2</div>
1266
+ <TreeSelect
1267
+ dropdownStyle={dropdownStyle}
1268
+ treeData={treeData}
1269
+ multiple
1270
+ maxTagCount={2}
1271
+ checkRelation='unRelated'
1272
+ defaultExpandAll
1273
+ style={style}
1274
+ />
1275
+ <br /><br />
1276
+ <div>checkRelation='unRelated' + maxTagCount=2 + 开启搜索</div>
1277
+ <TreeSelect
1278
+ dropdownStyle={dropdownStyle}
1279
+ treeData={treeData}
1280
+ multiple
1281
+ maxTagCount={2}
1282
+ filterTreeNode
1283
+ checkRelation='unRelated'
1284
+ defaultExpandAll
1285
+ style={style}
1286
+ />
1287
+ <br /><br />
1288
+ <div>checkRelation='unRelated' + maxTagCount=2 + 开启搜索 + searchBox in trigger</div>
1289
+ <TreeSelect
1290
+ dropdownStyle={dropdownStyle}
1291
+ treeData={treeData}
1292
+ multiple
1293
+ maxTagCount={2}
1294
+ filterTreeNode
1295
+ checkRelation='unRelated'
1296
+ searchPosition='trigger'
1297
+ defaultExpandAll
1298
+ style={style}
1299
+ />
1300
+ <br /><br />
1301
+ <div>checkRelation='unRelated' + 中国节点为 disabled</div>
1302
+ <TreeSelect
1303
+ dropdownStyle={dropdownStyle}
1304
+ treeData={treeDataWithoutValue}
1305
+ multiple
1306
+ checkRelation='unRelated'
1307
+ defaultExpandAll
1308
+ style={style}
1309
+ />
1310
+ <br /><br />
1311
+ <div>checkRelation='unRelated' + 中国节点为 disabled + 严格禁用</div>
1312
+ <TreeSelect
1313
+ dropdownStyle={dropdownStyle}
1314
+ treeData={treeDataWithoutValue}
1315
+ multiple
1316
+ checkRelation='unRelated'
1317
+ defaultExpandAll
1318
+ disableStrictly
1319
+ style={style}
1320
+ />
1321
+ <br /><br />
1322
+ <div>checkRelation='unRelated' + defaultValue 为 China</div>
1323
+ <TreeSelect
1324
+ dropdownStyle={dropdownStyle}
1325
+ treeData={treeData}
1326
+ multiple
1327
+ checkRelation='unRelated'
1328
+ defaultExpandAll
1329
+ style={style}
1330
+ defaultValue='China'
1331
+ />
1332
+ <br /><br />
1333
+ <div>checkRelation='unRelated' + defaultValue 为 China + 开启搜索</div>
1334
+ <TreeSelect
1335
+ dropdownStyle={dropdownStyle}
1336
+ treeData={treeData}
1337
+ multiple
1338
+ filterTreeNode
1339
+ checkRelation='unRelated'
1340
+ defaultExpandAll
1341
+ style={style}
1342
+ defaultValue='China'
1343
+ />
1344
+ <br /><br />
1345
+ <div>checkRelation='unRelated' + defaultValue 为 China + 开启搜索 + searchBox in trigger + showClear</div>
1346
+ <TreeSelect
1347
+ dropdownStyle={dropdownStyle}
1348
+ treeData={treeData}
1349
+ multiple
1350
+ filterTreeNode
1351
+ showClear
1352
+ checkRelation='unRelated'
1353
+ defaultExpandAll
1354
+ style={style}
1355
+ searchPosition='trigger'
1356
+ defaultValue='China'
1357
+ />
1358
+ <br /><br />
1359
+ <div>checkRelation='unRelated' + 受控 + value 初始为 China</div>
1360
+ <TreeSelect
1361
+ dropdownStyle={dropdownStyle}
1362
+ treeData={treeData}
1363
+ multiple
1364
+ checkRelation='unRelated'
1365
+ defaultExpandAll
1366
+ style={style}
1367
+ value={value}
1368
+ onChange={handleChange}
1369
+ />
1370
+ <br /><br />
1371
+ <div>checkRelation='unRelated' + 受控 + onChangeWithObject</div>
1372
+ <TreeSelect
1373
+ dropdownStyle={dropdownStyle}
1374
+ treeData={treeData}
1375
+ multiple
1376
+ checkRelation='unRelated'
1377
+ defaultExpandAll
1378
+ style={style}
1379
+ value={value2}
1380
+ onChangeWithObject
1381
+ onChange={handleChange2}
1382
+ />
1383
+ <br /><br />
1384
+ <div>checkRelation='unRelated' + 受控 + leafOnly,此时 leafOnly 失效</div>
1385
+ <TreeSelect
1386
+ dropdownStyle={dropdownStyle}
1387
+ leafOnly
1388
+ treeData={treeData}
1389
+ multiple
1390
+ checkRelation='unRelated'
1391
+ defaultExpandAll
1392
+ style={style}
1393
+ value={value3}
1394
+ onChange={handleChange3}
1395
+ />
1396
+ <br /><br />
1397
+ <div>checkRelation='unRelated' + onSelect </div>
1398
+ <TreeSelect
1399
+ dropdownStyle={dropdownStyle}
1400
+ treeData={treeData}
1401
+ multiple
1402
+ checkRelation='unRelated'
1403
+ defaultExpandAll
1404
+ style={style}
1405
+ onSelect={(value,status,node)=>console.log('select', value, status, node)}
1406
+ />
1407
+ </>
1408
+ );
1409
+ };
@@ -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';
@@ -83,22 +84,22 @@ export type RenderSelectedItemInMultiple = (
83
84
  export type RenderSelectedItem = RenderSelectedItemInSingle | RenderSelectedItemInMultiple;
84
85
 
85
86
  export type OverrideCommonProps =
86
- 'renderFullLabel'
87
- | 'renderLabel'
88
- | 'defaultValue'
89
- | 'emptyContent'
90
- | 'filterTreeNode'
91
- | 'style'
92
- | 'treeData'
93
- | 'value'
94
- | 'onExpand';
87
+ 'renderFullLabel'
88
+ | 'renderLabel'
89
+ | 'defaultValue'
90
+ | 'emptyContent'
91
+ | 'filterTreeNode'
92
+ | 'style'
93
+ | 'treeData'
94
+ | 'value'
95
+ | 'onExpand';
95
96
 
96
97
  /**
97
98
  * Type definition description:
98
99
  * TreeSelectProps inherits some properties from BasicTreeSelectProps (from foundation) and TreeProps (from semi-ui-react).
99
100
  */
100
101
  // eslint-disable-next-line max-len
101
- export interface TreeSelectProps extends Omit<BasicTreeSelectProps, OverrideCommonProps | 'validateStatus' | 'searchRender'>, Pick<TreeProps, OverrideCommonProps>{
102
+ export interface TreeSelectProps extends Omit<BasicTreeSelectProps, OverrideCommonProps | 'validateStatus' | 'searchRender'>, Pick<TreeProps, OverrideCommonProps> {
102
103
  'aria-describedby'?: React.AriaAttributes['aria-describedby'];
103
104
  'aria-errormessage'?: React.AriaAttributes['aria-errormessage'];
104
105
  'aria-invalid'?: React.AriaAttributes['aria-invalid'];
@@ -145,10 +146,10 @@ export interface TreeSelectProps extends Omit<BasicTreeSelectProps, OverrideComm
145
146
  }
146
147
 
147
148
  export type OverrideCommonState =
148
- 'keyEntities'
149
- | 'treeData'
150
- | 'disabledKeys'
151
- | 'flattenNodes';
149
+ 'keyEntities'
150
+ | 'treeData'
151
+ | 'disabledKeys'
152
+ | 'flattenNodes';
152
153
 
153
154
  // eslint-disable-next-line max-len
154
155
  export interface TreeSelectState extends Omit<BasicTreeSelectInnerData, OverrideCommonState | 'prevProps'>, Pick<TreeState, OverrideCommonState> {
@@ -241,7 +242,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
241
242
  outerBottomSlot: PropTypes.node,
242
243
  outerTopSlot: PropTypes.node,
243
244
  onVisibleChange: PropTypes.func,
244
- expandAction: PropTypes.oneOf(['click' as const, 'doubleClick' as const, false as const]),
245
+ expandAction: PropTypes.oneOf(['click' as const, 'doubleClick' as const, false as const]),
245
246
  searchPosition: PropTypes.oneOf([strings.SEARCH_POSITION_DROPDOWN, strings.SEARCH_POSITION_TRIGGER]),
246
247
  clickToHide: PropTypes.bool,
247
248
  renderLabel: PropTypes.func,
@@ -250,6 +251,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
250
251
  optionListStyle: PropTypes.object,
251
252
  searchRender: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),
252
253
  renderSelectedItem: PropTypes.func,
254
+ checkRelation: PropTypes.string,
253
255
  'aria-label': PropTypes.string,
254
256
  };
255
257
 
@@ -279,6 +281,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
279
281
  expandAction: false,
280
282
  clickToHide: true,
281
283
  searchAutoFocus: false,
284
+ checkRelation: 'related',
282
285
  'aria-label': 'TreeSelect'
283
286
  };
284
287
  inputRef: React.RefObject<typeof Input>;
@@ -307,6 +310,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
307
310
  selectedKeys: [],
308
311
  checkedKeys: new Set(),
309
312
  halfCheckedKeys: new Set(),
313
+ realCheckedKeys: new Set([]),
310
314
  disabledKeys: new Set(),
311
315
  motionKeys: new Set([]),
312
316
  motionType: 'hide',
@@ -362,7 +366,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
362
366
  if (
363
367
  treeData &&
364
368
  props.motion &&
365
- !isEqual(new Set(Object.keys(newState.keyEntities)), new Set(Object.keys(prevState.keyEntities)))
369
+ !isEqual(Object.keys(newState.keyEntities), Object.keys(prevState.keyEntities))
366
370
  ) {
367
371
  if (prevProps && props.motion) {
368
372
  newState.motionKeys = new Set([]);
@@ -432,11 +436,15 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
432
436
  );
433
437
  } else if (treeData) {
434
438
  // If `treeData` changed, we also need check it
435
- newState.selectedKeys = findKeysForValues(
436
- normalizeValue(props.value, withObject) || '',
437
- valueEntities,
438
- isMultiple
439
- );
439
+ if (props.value) {
440
+ newState.selectedKeys = findKeysForValues(
441
+ normalizeValue(props.value, withObject) || '',
442
+ valueEntities,
443
+ isMultiple
444
+ );
445
+ } else {
446
+ newState.selectedKeys = updateKeys(prevState.selectedKeys, keyEntities);
447
+ }
440
448
  }
441
449
  } else {
442
450
  // checkedKeys: multiple mode controlled || data changed
@@ -456,18 +464,26 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
456
464
  );
457
465
  } else if (treeData) {
458
466
  // If `treeData` changed, we also need check it
459
- checkedKeyValues = findKeysForValues(
460
- normalizeValue(props.value, withObject) || [],
461
- valueEntities,
462
- isMultiple
463
- );
467
+ if (props.value) {
468
+ checkedKeyValues = findKeysForValues(
469
+ normalizeValue(props.value, withObject) || [],
470
+ valueEntities,
471
+ isMultiple
472
+ );
473
+ } else {
474
+ checkedKeyValues = updateKeys(prevState.checkedKeys, keyEntities);
475
+ }
464
476
  }
465
477
 
466
478
  if (checkedKeyValues) {
467
- const { checkedKeys, halfCheckedKeys } = calcCheckedKeys(checkedKeyValues, keyEntities);
479
+ if (props.checkRelation === 'unRelated') {
480
+ newState.realCheckedKeys = new Set(checkedKeyValues);
481
+ } else if (props.checkRelation === 'related') {
482
+ const { checkedKeys, halfCheckedKeys } = calcCheckedKeys(checkedKeyValues, keyEntities);
468
483
 
469
- newState.checkedKeys = checkedKeys;
470
- newState.halfCheckedKeys = halfCheckedKeys;
484
+ newState.checkedKeys = checkedKeys;
485
+ newState.halfCheckedKeys = halfCheckedKeys;
486
+ }
471
487
  }
472
488
  }
473
489
 
@@ -482,7 +498,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
482
498
  }
483
499
 
484
500
  // ================ disableStrictly =================
485
- if (treeData && props.disableStrictly) {
501
+ if (treeData && props.disableStrictly && props.checkRelation === 'related') {
486
502
  newState.disabledKeys = calcDisabledKeys(keyEntities);
487
503
  }
488
504
 
@@ -566,7 +582,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
566
582
  this.foundation.handleNodeLoad(loadedKeys, loadingKeys, data, resolve));
567
583
  },
568
584
  updateState: states => {
569
- this.setState({ ...states });
585
+ this.setState({ ...states } as TreeSelectState);
570
586
  },
571
587
  openMenu: () => {
572
588
  this.setState({ isOpen: true }, () => {
@@ -607,7 +623,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
607
623
  toggleHovering: bool => {
608
624
  this.setState({ isHovering: bool });
609
625
  },
610
- updateInputFocus: bool => {} // eslint-disable-line
626
+ updateInputFocus: bool => { } // eslint-disable-line
611
627
  };
612
628
  }
613
629
 
@@ -667,24 +683,39 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
667
683
  this.foundation.handleSelectionEnterPress(e);
668
684
  };
669
685
 
686
+ hasValue = (): boolean => {
687
+ const { multiple, checkRelation } = this.props;
688
+ const { realCheckedKeys, checkedKeys, selectedKeys } = this.state;
689
+ let hasValue = false;
690
+ if (multiple) {
691
+ if (checkRelation === 'related') {
692
+ hasValue = Boolean(checkedKeys.size);
693
+ } else if (checkRelation === 'unRelated') {
694
+ hasValue = Boolean(realCheckedKeys.size);
695
+ }
696
+ } else {
697
+ hasValue = Boolean(selectedKeys.length);
698
+ }
699
+ return hasValue;
700
+ }
701
+
670
702
  showClearBtn = () => {
671
- const { searchPosition } = this.props;
672
- const { inputValue } = this.state;
703
+ const { showClear, disabled, searchPosition } = this.props;
704
+ const { inputValue, isOpen, isHovering } = this.state;
673
705
  const triggerSearchHasInputValue = searchPosition === strings.SEARCH_POSITION_TRIGGER && inputValue;
674
- const { showClear, disabled, multiple } = this.props;
675
- const { selectedKeys, checkedKeys, isOpen, isHovering } = this.state;
676
- const hasValue = multiple ? Boolean(checkedKeys.size) : Boolean(selectedKeys.length);
677
- return showClear && (hasValue || triggerSearchHasInputValue) && !disabled && (isOpen || isHovering);
706
+
707
+ return showClear && (this.hasValue() || triggerSearchHasInputValue) && !disabled && (isOpen || isHovering);
678
708
  };
679
709
 
680
710
  renderTagList = () => {
681
- const { checkedKeys, keyEntities, disabledKeys } = this.state;
711
+ const { checkedKeys, keyEntities, disabledKeys, realCheckedKeys } = this.state;
682
712
  const {
683
713
  treeNodeLabelProp,
684
714
  leafOnly,
685
715
  disabled,
686
716
  disableStrictly,
687
717
  size,
718
+ checkRelation,
688
719
  renderSelectedItem: propRenderSelectedItem
689
720
  } = this.props;
690
721
  const renderSelectedItem = isFunction(propRenderSelectedItem) ?
@@ -693,7 +724,12 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
693
724
  isRenderInTag: true,
694
725
  content: get(item, treeNodeLabelProp, null)
695
726
  });
696
- const renderKeys = normalizeKeyList([...checkedKeys], keyEntities, leafOnly);
727
+ let renderKeys = [];
728
+ if (checkRelation === 'related') {
729
+ renderKeys = normalizeKeyList([...checkedKeys], keyEntities, leafOnly);
730
+ } else if (checkRelation === 'unRelated') {
731
+ renderKeys = [...realCheckedKeys];
732
+ }
697
733
  const tagList: Array<React.ReactNode> = [];
698
734
  // eslint-disable-next-line @typescript-eslint/no-shadow
699
735
  renderKeys.forEach((key: TreeNodeData['key']) => {
@@ -769,15 +805,13 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
769
805
  searchPosition,
770
806
  filterTreeNode,
771
807
  } = this.props;
772
- const { selectedKeys, checkedKeys } = this.state;
773
- const hasValue = multiple ? Boolean(checkedKeys.size) : Boolean(selectedKeys.length);
774
808
  const isTriggerPositionSearch = filterTreeNode && searchPosition === strings.SEARCH_POSITION_TRIGGER;
775
809
  // searchPosition = trigger
776
810
  if (isTriggerPositionSearch) {
777
811
  return multiple ? this.renderTagInput() : this.renderSingleTriggerSearch();
778
812
  }
779
813
  // searchPosition = dropdown and single seleciton
780
- if (!multiple || !hasValue) {
814
+ if (!multiple || !this.hasValue()) {
781
815
  const renderText = this.foundation.getRenderTextInSingle();
782
816
  const spanCls = cls({
783
817
  [`${prefixcls}-selection-placeholder`]: !renderText,
@@ -837,11 +871,11 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
837
871
  const clearCls = cls(`${prefixcls}-clearbtn`);
838
872
  if (showClearBtn) {
839
873
  return (
840
- <div
874
+ <div
841
875
  role='button'
842
- tabIndex={0}
843
- aria-label="Clear TreeSelect value"
844
- className={clearCls}
876
+ tabIndex={0}
877
+ aria-label="Clear TreeSelect value"
878
+ className={clearCls}
845
879
  onClick={this.handleClear}
846
880
  onKeyPress={this.handleClearEnterPress}
847
881
  >
@@ -953,7 +987,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
953
987
  onKeyPress={this.handleSelectionEnterPress}
954
988
  aria-invalid={this.props['aria-invalid']}
955
989
  aria-errormessage={this.props['aria-errormessage']}
956
- aria-label={this.props['aria-label']}
990
+ aria-label={this.props['aria-label']}
957
991
  aria-labelledby={this.props['aria-labelledby']}
958
992
  aria-describedby={this.props['aria-describedby']}
959
993
  aria-required={this.props['aria-required']}
@@ -1005,7 +1039,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
1005
1039
  });
1006
1040
  if (isFunction(renderSelectedItem)) {
1007
1041
  const { content, isRenderInTag } = treeNodeLabelProp in item && item ?
1008
- (renderSelectedItem as RenderSelectedItemInMultiple)(item, { index: idx, onClose }):
1042
+ (renderSelectedItem as RenderSelectedItemInMultiple)(item, { index: idx, onClose }) :
1009
1043
  null;
1010
1044
  if (isRenderInTag) {
1011
1045
  return <Tag {...tagProps}>{content}</Tag>;
@@ -1028,13 +1062,20 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
1028
1062
  searchAutoFocus,
1029
1063
  placeholder,
1030
1064
  maxTagCount,
1065
+ checkRelation,
1031
1066
  } = this.props;
1032
1067
  const {
1033
1068
  keyEntities,
1034
1069
  checkedKeys,
1035
- inputValue
1070
+ inputValue,
1071
+ realCheckedKeys,
1036
1072
  } = this.state;
1037
- const keyList = normalizeKeyList(checkedKeys, keyEntities, leafOnly);
1073
+ let keyList = [];
1074
+ if (checkRelation === 'related') {
1075
+ keyList = normalizeKeyList(checkedKeys, keyEntities, leafOnly);
1076
+ } else if (checkRelation === 'unRelated') {
1077
+ keyList = [...realCheckedKeys];
1078
+ }
1038
1079
  return (
1039
1080
  <TagInput
1040
1081
  maxTagCount={maxTagCount}
@@ -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
 
@@ -63,7 +63,6 @@ const getRenderText = (
63
63
 
64
64
  // clean up css overflow
65
65
  ellipsisContainer.style.textOverflow = 'clip';
66
- ellipsisContainer.style.whiteSpace = 'normal';
67
66
  ellipsisContainer.style.webkitLineClamp = 'none';
68
67
 
69
68
  // Render fake container
@@ -2,7 +2,7 @@
2
2
  import React, { useState } from 'react';
3
3
  import { Upload, Button, Toast, Icon } from '@douyinfe/semi-ui/index';
4
4
  import { withField, Form } from '../../form/index';
5
- import { IconPlus, IconFile, IconUpload } from '@douyinfe/semi-icons';
5
+ import { IconPlus, IconFile, IconUpload, IconEyeOpened, IconDownload, IconDelete } from '@douyinfe/semi-icons';
6
6
 
7
7
  import FileCard from '../fileCard';
8
8
 
@@ -50,7 +50,7 @@ let commonProps = {
50
50
  let url = fileItem.url;
51
51
  console.log(fileItem);
52
52
  window.open(url);
53
- },
53
+ }
54
54
  };
55
55
 
56
56
  export const BasicUsage = () => (
@@ -270,7 +270,7 @@ const defaultFileList = [
270
270
  'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bf8647bffab13c38772c9ff94bf91a9d.jpg',
271
271
  },
272
272
  {
273
- uid: '5',
273
+ uid: '3',
274
274
  name: 'jiafang3.jpeg',
275
275
  status: 'uploading',
276
276
  percent: 50,
@@ -279,7 +279,7 @@ const defaultFileList = [
279
279
  'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bf8647bffab13c38772c9ff94bf91a9d.jpg',
280
280
  },
281
281
  {
282
- uid: '5',
282
+ uid: '4',
283
283
  name: 'jiafang3.jpeg',
284
284
  status: 'validateFail',
285
285
  validateMessage: '文件过大',
@@ -288,7 +288,7 @@ const defaultFileList = [
288
288
  'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bf8647bffab13c38772c9ff94bf91a9d.jpg',
289
289
  },
290
290
  {
291
- uid: '4',
291
+ uid: '5',
292
292
  name: 'jiafang4.jpeg',
293
293
  status: 'validating',
294
294
  validateMessage: '校验中',
@@ -399,11 +399,12 @@ PictureListType.story = {
399
399
  export const PictureListTypeWithDefaultFileList = () => (
400
400
  <>
401
401
  <Upload
402
- showReplace
403
402
  {...commonProps}
403
+ showReplace={false}
404
404
  action={action}
405
405
  listType="picture"
406
406
  accept="image/*"
407
+ renderPicPreviewIcon={()=><IconEyeOpened style={{color: 'var(--semi-color-white)',fontSize: 24}} />}
407
408
  defaultFileList={defaultFileList}
408
409
  >
409
410
  <React.Fragment>
@@ -941,3 +942,18 @@ export const _ForbiddenRemove = () => <ForbiddenRemove />;
941
942
  _ForbiddenRemove.story = {
942
943
  name: 'forbidden remove',
943
944
  };
945
+
946
+ export const CustomListOperation = () => {
947
+ const renderFileOperation = (fileItem)=>{
948
+ return <div style={{display: 'flex',columnGap: 8, padding: '0 8px'}}>
949
+ <Button icon={<IconEyeOpened></IconEyeOpened>} type="tertiary" theme="borderless" size="small"></Button>
950
+ <Button icon={<IconDownload></IconDownload>} type="tertiary" theme="borderless" size="small"></Button>
951
+ <Button onClick={e=>fileItem.onRemove()} icon={<IconDelete></IconDelete>} type="tertiary" theme="borderless" size="small"></Button>
952
+ </div>
953
+ }
954
+ return <Upload defaultFileList={defaultFileList} itemStyle={{width: 300}} renderFileOperation={renderFileOperation}><Button icon={<IconUpload />} theme="light">点击上传</Button></Upload>
955
+ }
956
+
957
+ CustomListOperation.story = {
958
+ name: 'custom list operation',
959
+ }