@douyinfe/semi-ui 2.4.1 → 2.6.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 (138) hide show
  1. package/calendar/monthCalendar.tsx +14 -13
  2. package/cascader/__test__/cascader.test.js +24 -0
  3. package/cascader/_story/cascader.stories.js +73 -0
  4. package/cascader/index.tsx +26 -5
  5. package/cascader/item.tsx +25 -5
  6. package/datePicker/_story/v2/FixInputRangeFocus.jsx +25 -0
  7. package/datePicker/_story/v2/index.js +2 -1
  8. package/datePicker/dateInput.tsx +8 -5
  9. package/datePicker/datePicker.tsx +9 -1
  10. package/datePicker/month.tsx +14 -7
  11. package/datePicker/monthsGrid.tsx +17 -5
  12. package/datePicker/navigation.tsx +8 -4
  13. package/datePicker/quickControl.tsx +1 -0
  14. package/datePicker/yearAndMonth.tsx +1 -1
  15. package/dist/css/semi.css +71 -35
  16. package/dist/css/semi.min.css +1 -1
  17. package/dist/umd/semi-ui.js +696 -263
  18. package/dist/umd/semi-ui.js.map +1 -1
  19. package/dist/umd/semi-ui.min.js +1 -1
  20. package/dist/umd/semi-ui.min.js.map +1 -1
  21. package/form/__test__/formApi.test.js +182 -0
  22. package/form/_story/FormApi/arrayDemo.jsx +4 -7
  23. package/form/_story/Layout/slotDemo.jsx +2 -2
  24. package/form/_story/demo.jsx +18 -1
  25. package/form/_story/form.stories.js +6 -6
  26. package/form/baseForm.tsx +2 -2
  27. package/form/hoc/withField.tsx +1 -1
  28. package/lib/cjs/_base/base.css +5 -5
  29. package/lib/cjs/autoComplete/index.d.ts +1 -1
  30. package/lib/cjs/calendar/monthCalendar.js +21 -5
  31. package/lib/cjs/cascader/index.d.ts +9 -2
  32. package/lib/cjs/cascader/index.js +20 -1
  33. package/lib/cjs/cascader/item.d.ts +6 -2
  34. package/lib/cjs/cascader/item.js +33 -4
  35. package/lib/cjs/datePicker/dateInput.d.ts +0 -2
  36. package/lib/cjs/datePicker/dateInput.js +17 -6
  37. package/lib/cjs/datePicker/datePicker.js +19 -12
  38. package/lib/cjs/datePicker/month.d.ts +1 -0
  39. package/lib/cjs/datePicker/month.js +18 -2
  40. package/lib/cjs/datePicker/monthsGrid.js +16 -4
  41. package/lib/cjs/datePicker/navigation.js +8 -0
  42. package/lib/cjs/datePicker/quickControl.js +1 -0
  43. package/lib/cjs/datePicker/yearAndMonth.js +1 -0
  44. package/lib/cjs/dropdown/index.d.ts +1 -1
  45. package/lib/cjs/form/baseForm.d.ts +1 -1
  46. package/lib/cjs/form/baseForm.js +2 -2
  47. package/lib/cjs/form/field.d.ts +1 -1
  48. package/lib/cjs/form/hoc/withField.js +1 -1
  49. package/lib/cjs/scrollList/scrollItem.d.ts +2 -1
  50. package/lib/cjs/scrollList/scrollItem.js +13 -3
  51. package/lib/cjs/select/index.d.ts +3 -3
  52. package/lib/cjs/select/index.js +32 -28
  53. package/lib/cjs/select/option.js +2 -2
  54. package/lib/cjs/select/virtualRow.js +2 -2
  55. package/lib/cjs/table/Table.d.ts +1 -1
  56. package/lib/cjs/table/Table.js +8 -2
  57. package/lib/cjs/table/interface.d.ts +1 -0
  58. package/lib/cjs/tabs/interface.d.ts +1 -1
  59. package/lib/cjs/tooltip/index.d.ts +1 -1
  60. package/lib/cjs/tooltip/index.js +6 -2
  61. package/lib/cjs/tree/index.d.ts +2 -0
  62. package/lib/cjs/tree/index.js +15 -8
  63. package/lib/cjs/treeSelect/index.d.ts +2 -0
  64. package/lib/cjs/treeSelect/index.js +64 -27
  65. package/lib/cjs/upload/fileCard.js +31 -22
  66. package/lib/cjs/upload/index.d.ts +6 -0
  67. package/lib/cjs/upload/index.js +15 -8
  68. package/lib/cjs/upload/interface.d.ts +8 -6
  69. package/lib/es/_base/base.css +5 -5
  70. package/lib/es/autoComplete/index.d.ts +1 -1
  71. package/lib/es/calendar/monthCalendar.js +22 -5
  72. package/lib/es/cascader/index.d.ts +9 -2
  73. package/lib/es/cascader/index.js +19 -1
  74. package/lib/es/cascader/item.d.ts +6 -2
  75. package/lib/es/cascader/item.js +31 -4
  76. package/lib/es/datePicker/dateInput.d.ts +0 -2
  77. package/lib/es/datePicker/dateInput.js +17 -6
  78. package/lib/es/datePicker/datePicker.js +19 -12
  79. package/lib/es/datePicker/month.d.ts +1 -0
  80. package/lib/es/datePicker/month.js +18 -2
  81. package/lib/es/datePicker/monthsGrid.js +16 -4
  82. package/lib/es/datePicker/navigation.js +8 -0
  83. package/lib/es/datePicker/quickControl.js +2 -0
  84. package/lib/es/datePicker/yearAndMonth.js +1 -0
  85. package/lib/es/dropdown/index.d.ts +1 -1
  86. package/lib/es/form/baseForm.d.ts +1 -1
  87. package/lib/es/form/baseForm.js +2 -2
  88. package/lib/es/form/field.d.ts +1 -1
  89. package/lib/es/form/hoc/withField.js +1 -1
  90. package/lib/es/scrollList/scrollItem.d.ts +2 -1
  91. package/lib/es/scrollList/scrollItem.js +13 -3
  92. package/lib/es/select/index.d.ts +3 -3
  93. package/lib/es/select/index.js +30 -26
  94. package/lib/es/select/option.js +2 -2
  95. package/lib/es/select/virtualRow.js +2 -2
  96. package/lib/es/table/Table.d.ts +1 -1
  97. package/lib/es/table/Table.js +10 -2
  98. package/lib/es/table/interface.d.ts +1 -0
  99. package/lib/es/tabs/interface.d.ts +1 -1
  100. package/lib/es/tooltip/index.d.ts +1 -1
  101. package/lib/es/tooltip/index.js +6 -2
  102. package/lib/es/tree/index.d.ts +2 -0
  103. package/lib/es/tree/index.js +15 -8
  104. package/lib/es/treeSelect/index.d.ts +2 -0
  105. package/lib/es/treeSelect/index.js +64 -27
  106. package/lib/es/upload/fileCard.js +31 -24
  107. package/lib/es/upload/index.d.ts +6 -0
  108. package/lib/es/upload/index.js +14 -8
  109. package/lib/es/upload/interface.d.ts +8 -6
  110. package/package.json +9 -9
  111. package/scrollList/_story/ScrollList/index.js +3 -0
  112. package/scrollList/_story/WheelList/index.js +3 -0
  113. package/scrollList/scrollItem.tsx +30 -9
  114. package/select/index.tsx +18 -19
  115. package/select/option.tsx +2 -2
  116. package/select/virtualRow.tsx +2 -2
  117. package/table/Table.tsx +7 -2
  118. package/table/_story/Perf/Virtualized/index.jsx +6 -0
  119. package/table/_story/table.stories.js +1 -2
  120. package/table/_story/v2/FixedHeaderMerge/index.jsx +98 -0
  121. package/table/_story/v2/FixedResizable/index.jsx +114 -0
  122. package/table/_story/v2/defaultFilteredValue.tsx +114 -0
  123. package/table/_story/v2/index.js +5 -0
  124. package/table/interface.ts +1 -0
  125. package/tabs/interface.ts +1 -1
  126. package/tooltip/__test__/tooltip.test.js +48 -4
  127. package/tooltip/_story/tooltip.stories.js +83 -1
  128. package/tooltip/index.tsx +4 -4
  129. package/tree/__test__/treeMultiple.test.js +94 -0
  130. package/tree/_story/tree.stories.js +169 -0
  131. package/tree/index.tsx +12 -5
  132. package/treeSelect/__test__/treeMultiple.test.js +94 -0
  133. package/treeSelect/_story/treeSelect.stories.js +242 -0
  134. package/treeSelect/index.tsx +72 -40
  135. package/upload/_story/upload.stories.js +22 -6
  136. package/upload/fileCard.tsx +23 -23
  137. package/upload/index.tsx +15 -6
  138. package/upload/interface.ts +7 -5
@@ -678,4 +678,98 @@ describe('TreeSelect', () => {
678
678
  expect(treeSelect.find(`.${BASE_CLASS_PREFIX}-tree-option-highlight`).at(1).instance().textContent).toEqual('北');
679
679
 
680
680
  });
681
+
682
+ it('unRelated', () => {
683
+ const spyOnChange = sinon.spy(() => { });
684
+ const tree = getTreeSelect({
685
+ defaultExpandAll: true,
686
+ onChange: spyOnChange,
687
+ checkRelation: 'unRelated',
688
+ });
689
+ const nodelevel2 = tree.find(`.${BASE_CLASS_PREFIX}-tree-option.${BASE_CLASS_PREFIX}-tree-option-level-2`);
690
+ const selectedNode = nodelevel2.at(0);
691
+ selectedNode.simulate('click');
692
+ expect(spyOnChange.calledOnce).toBe(true);
693
+ expect(spyOnChange.calledWithMatch(['Zhongguo'])).toEqual(true);
694
+ // Note: selectedNode cannot be used directly here. selectedNode is the original node in the unselected state
695
+ expect(
696
+ tree
697
+ .find(`.${BASE_CLASS_PREFIX}-tree-option.${BASE_CLASS_PREFIX}-tree-option-level-2`)
698
+ .at(0)
699
+ .exists(`.${BASE_CLASS_PREFIX}-checkbox-checked`)
700
+ ).toEqual(true);
701
+ const nodelevel3 = tree.find(`.${BASE_CLASS_PREFIX}-tree-option.${BASE_CLASS_PREFIX}-tree-option-level-3`);
702
+ expect(
703
+ nodelevel3
704
+ .exists(`.${BASE_CLASS_PREFIX}-checkbox-unChecked` )
705
+ ).toEqual(true);
706
+ expect(
707
+ nodelevel3
708
+ .at(1)
709
+ .exists(`.${BASE_CLASS_PREFIX}-checkbox-unChecked` )
710
+ ).toEqual(true);
711
+ });
712
+
713
+ it('unRelated + value', () => {
714
+ const tree = getTreeSelect({
715
+ defaultExpandAll: true,
716
+ checkRelation: 'unRelated',
717
+ value: 'Zhongguo'
718
+ });
719
+ expect(
720
+ tree
721
+ .find(`.${BASE_CLASS_PREFIX}-tree-option.${BASE_CLASS_PREFIX}-tree-option-level-2`)
722
+ .at(0)
723
+ .exists(`.${BASE_CLASS_PREFIX}-checkbox-checked`)
724
+ ).toEqual(true);
725
+ const nodelevel3 = tree.find(`.${BASE_CLASS_PREFIX}-tree-option.${BASE_CLASS_PREFIX}-tree-option-level-3`);
726
+ expect(
727
+ nodelevel3
728
+ .exists(`.${BASE_CLASS_PREFIX}-checkbox-unChecked` )
729
+ ).toEqual(true);
730
+ expect(
731
+ nodelevel3
732
+ .at(1)
733
+ .exists(`.${BASE_CLASS_PREFIX}-checkbox-unChecked` )
734
+ ).toEqual(true);
735
+ });
736
+
737
+ it('unRelated + defaultValue', () => {
738
+ const tree = getTreeSelect({
739
+ defaultExpandAll: true,
740
+ checkRelation: 'unRelated',
741
+ defaultValue: 'Zhongguo'
742
+ });
743
+ expect(
744
+ tree
745
+ .find(`.${BASE_CLASS_PREFIX}-tree-option.${BASE_CLASS_PREFIX}-tree-option-level-2`)
746
+ .at(0)
747
+ .exists(`.${BASE_CLASS_PREFIX}-checkbox-checked`)
748
+ ).toEqual(true);
749
+ const nodelevel3 = tree.find(`.${BASE_CLASS_PREFIX}-tree-option.${BASE_CLASS_PREFIX}-tree-option-level-3`);
750
+ expect(
751
+ nodelevel3
752
+ .exists(`.${BASE_CLASS_PREFIX}-checkbox-unChecked` )
753
+ ).toEqual(true);
754
+ expect(
755
+ nodelevel3
756
+ .at(1)
757
+ .exists(`.${BASE_CLASS_PREFIX}-checkbox-unChecked` )
758
+ ).toEqual(true);
759
+ });
760
+
761
+ it('unRelated + onSelect', () => {
762
+ const spyOnSelect = sinon.spy(() => { });
763
+ const tree = getTreeSelect({
764
+ defaultExpandAll: true,
765
+ onSelect: spyOnSelect,
766
+ checkRelation: 'unRelated',
767
+ });
768
+ const nodelevel2 = tree.find(`.${BASE_CLASS_PREFIX}-tree-option.${BASE_CLASS_PREFIX}-tree-option-level-2`);
769
+ const selectedNode = nodelevel2.at(0);
770
+ selectedNode.simulate('click');
771
+ expect(spyOnSelect.calledOnce).toBe(true);
772
+ // onSelect first args is key, not value
773
+ expect(spyOnSelect.calledWithMatch('zhongguo')).toEqual(true);
774
+ });
681
775
  })
@@ -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
+ };
@@ -84,22 +84,22 @@ export type RenderSelectedItemInMultiple = (
84
84
  export type RenderSelectedItem = RenderSelectedItemInSingle | RenderSelectedItemInMultiple;
85
85
 
86
86
  export type OverrideCommonProps =
87
- 'renderFullLabel'
88
- | 'renderLabel'
89
- | 'defaultValue'
90
- | 'emptyContent'
91
- | 'filterTreeNode'
92
- | 'style'
93
- | 'treeData'
94
- | 'value'
95
- | 'onExpand';
87
+ 'renderFullLabel'
88
+ | 'renderLabel'
89
+ | 'defaultValue'
90
+ | 'emptyContent'
91
+ | 'filterTreeNode'
92
+ | 'style'
93
+ | 'treeData'
94
+ | 'value'
95
+ | 'onExpand';
96
96
 
97
97
  /**
98
98
  * Type definition description:
99
99
  * TreeSelectProps inherits some properties from BasicTreeSelectProps (from foundation) and TreeProps (from semi-ui-react).
100
100
  */
101
101
  // eslint-disable-next-line max-len
102
- 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> {
103
103
  'aria-describedby'?: React.AriaAttributes['aria-describedby'];
104
104
  'aria-errormessage'?: React.AriaAttributes['aria-errormessage'];
105
105
  'aria-invalid'?: React.AriaAttributes['aria-invalid'];
@@ -146,10 +146,10 @@ export interface TreeSelectProps extends Omit<BasicTreeSelectProps, OverrideComm
146
146
  }
147
147
 
148
148
  export type OverrideCommonState =
149
- 'keyEntities'
150
- | 'treeData'
151
- | 'disabledKeys'
152
- | 'flattenNodes';
149
+ 'keyEntities'
150
+ | 'treeData'
151
+ | 'disabledKeys'
152
+ | 'flattenNodes';
153
153
 
154
154
  // eslint-disable-next-line max-len
155
155
  export interface TreeSelectState extends Omit<BasicTreeSelectInnerData, OverrideCommonState | 'prevProps'>, Pick<TreeState, OverrideCommonState> {
@@ -242,7 +242,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
242
242
  outerBottomSlot: PropTypes.node,
243
243
  outerTopSlot: PropTypes.node,
244
244
  onVisibleChange: PropTypes.func,
245
- 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]),
246
246
  searchPosition: PropTypes.oneOf([strings.SEARCH_POSITION_DROPDOWN, strings.SEARCH_POSITION_TRIGGER]),
247
247
  clickToHide: PropTypes.bool,
248
248
  renderLabel: PropTypes.func,
@@ -251,6 +251,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
251
251
  optionListStyle: PropTypes.object,
252
252
  searchRender: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),
253
253
  renderSelectedItem: PropTypes.func,
254
+ checkRelation: PropTypes.string,
254
255
  'aria-label': PropTypes.string,
255
256
  };
256
257
 
@@ -280,6 +281,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
280
281
  expandAction: false,
281
282
  clickToHide: true,
282
283
  searchAutoFocus: false,
284
+ checkRelation: 'related',
283
285
  'aria-label': 'TreeSelect'
284
286
  };
285
287
  inputRef: React.RefObject<typeof Input>;
@@ -308,6 +310,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
308
310
  selectedKeys: [],
309
311
  checkedKeys: new Set(),
310
312
  halfCheckedKeys: new Set(),
313
+ realCheckedKeys: new Set([]),
311
314
  disabledKeys: new Set(),
312
315
  motionKeys: new Set([]),
313
316
  motionType: 'hide',
@@ -473,10 +476,14 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
473
476
  }
474
477
 
475
478
  if (checkedKeyValues) {
476
- 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);
477
483
 
478
- newState.checkedKeys = checkedKeys;
479
- newState.halfCheckedKeys = halfCheckedKeys;
484
+ newState.checkedKeys = checkedKeys;
485
+ newState.halfCheckedKeys = halfCheckedKeys;
486
+ }
480
487
  }
481
488
  }
482
489
 
@@ -491,7 +498,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
491
498
  }
492
499
 
493
500
  // ================ disableStrictly =================
494
- if (treeData && props.disableStrictly) {
501
+ if (treeData && props.disableStrictly && props.checkRelation === 'related') {
495
502
  newState.disabledKeys = calcDisabledKeys(keyEntities);
496
503
  }
497
504
 
@@ -575,7 +582,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
575
582
  this.foundation.handleNodeLoad(loadedKeys, loadingKeys, data, resolve));
576
583
  },
577
584
  updateState: states => {
578
- this.setState({ ...states });
585
+ this.setState({ ...states } as TreeSelectState);
579
586
  },
580
587
  openMenu: () => {
581
588
  this.setState({ isOpen: true }, () => {
@@ -616,7 +623,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
616
623
  toggleHovering: bool => {
617
624
  this.setState({ isHovering: bool });
618
625
  },
619
- updateInputFocus: bool => {} // eslint-disable-line
626
+ updateInputFocus: bool => { } // eslint-disable-line
620
627
  };
621
628
  }
622
629
 
@@ -676,24 +683,39 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
676
683
  this.foundation.handleSelectionEnterPress(e);
677
684
  };
678
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
+
679
702
  showClearBtn = () => {
680
- const { searchPosition } = this.props;
681
- const { inputValue } = this.state;
703
+ const { showClear, disabled, searchPosition } = this.props;
704
+ const { inputValue, isOpen, isHovering } = this.state;
682
705
  const triggerSearchHasInputValue = searchPosition === strings.SEARCH_POSITION_TRIGGER && inputValue;
683
- const { showClear, disabled, multiple } = this.props;
684
- const { selectedKeys, checkedKeys, isOpen, isHovering } = this.state;
685
- const hasValue = multiple ? Boolean(checkedKeys.size) : Boolean(selectedKeys.length);
686
- return showClear && (hasValue || triggerSearchHasInputValue) && !disabled && (isOpen || isHovering);
706
+
707
+ return showClear && (this.hasValue() || triggerSearchHasInputValue) && !disabled && (isOpen || isHovering);
687
708
  };
688
709
 
689
710
  renderTagList = () => {
690
- const { checkedKeys, keyEntities, disabledKeys } = this.state;
711
+ const { checkedKeys, keyEntities, disabledKeys, realCheckedKeys } = this.state;
691
712
  const {
692
713
  treeNodeLabelProp,
693
714
  leafOnly,
694
715
  disabled,
695
716
  disableStrictly,
696
717
  size,
718
+ checkRelation,
697
719
  renderSelectedItem: propRenderSelectedItem
698
720
  } = this.props;
699
721
  const renderSelectedItem = isFunction(propRenderSelectedItem) ?
@@ -702,7 +724,12 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
702
724
  isRenderInTag: true,
703
725
  content: get(item, treeNodeLabelProp, null)
704
726
  });
705
- 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
+ }
706
733
  const tagList: Array<React.ReactNode> = [];
707
734
  // eslint-disable-next-line @typescript-eslint/no-shadow
708
735
  renderKeys.forEach((key: TreeNodeData['key']) => {
@@ -778,15 +805,13 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
778
805
  searchPosition,
779
806
  filterTreeNode,
780
807
  } = this.props;
781
- const { selectedKeys, checkedKeys } = this.state;
782
- const hasValue = multiple ? Boolean(checkedKeys.size) : Boolean(selectedKeys.length);
783
808
  const isTriggerPositionSearch = filterTreeNode && searchPosition === strings.SEARCH_POSITION_TRIGGER;
784
809
  // searchPosition = trigger
785
810
  if (isTriggerPositionSearch) {
786
811
  return multiple ? this.renderTagInput() : this.renderSingleTriggerSearch();
787
812
  }
788
813
  // searchPosition = dropdown and single seleciton
789
- if (!multiple || !hasValue) {
814
+ if (!multiple || !this.hasValue()) {
790
815
  const renderText = this.foundation.getRenderTextInSingle();
791
816
  const spanCls = cls({
792
817
  [`${prefixcls}-selection-placeholder`]: !renderText,
@@ -846,11 +871,11 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
846
871
  const clearCls = cls(`${prefixcls}-clearbtn`);
847
872
  if (showClearBtn) {
848
873
  return (
849
- <div
874
+ <div
850
875
  role='button'
851
- tabIndex={0}
852
- aria-label="Clear TreeSelect value"
853
- className={clearCls}
876
+ tabIndex={0}
877
+ aria-label="Clear TreeSelect value"
878
+ className={clearCls}
854
879
  onClick={this.handleClear}
855
880
  onKeyPress={this.handleClearEnterPress}
856
881
  >
@@ -962,7 +987,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
962
987
  onKeyPress={this.handleSelectionEnterPress}
963
988
  aria-invalid={this.props['aria-invalid']}
964
989
  aria-errormessage={this.props['aria-errormessage']}
965
- aria-label={this.props['aria-label']}
990
+ aria-label={this.props['aria-label']}
966
991
  aria-labelledby={this.props['aria-labelledby']}
967
992
  aria-describedby={this.props['aria-describedby']}
968
993
  aria-required={this.props['aria-required']}
@@ -1014,7 +1039,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
1014
1039
  });
1015
1040
  if (isFunction(renderSelectedItem)) {
1016
1041
  const { content, isRenderInTag } = treeNodeLabelProp in item && item ?
1017
- (renderSelectedItem as RenderSelectedItemInMultiple)(item, { index: idx, onClose }):
1042
+ (renderSelectedItem as RenderSelectedItemInMultiple)(item, { index: idx, onClose }) :
1018
1043
  null;
1019
1044
  if (isRenderInTag) {
1020
1045
  return <Tag {...tagProps}>{content}</Tag>;
@@ -1037,13 +1062,20 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
1037
1062
  searchAutoFocus,
1038
1063
  placeholder,
1039
1064
  maxTagCount,
1065
+ checkRelation,
1040
1066
  } = this.props;
1041
1067
  const {
1042
1068
  keyEntities,
1043
1069
  checkedKeys,
1044
- inputValue
1070
+ inputValue,
1071
+ realCheckedKeys,
1045
1072
  } = this.state;
1046
- 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
+ }
1047
1079
  return (
1048
1080
  <TagInput
1049
1081
  maxTagCount={maxTagCount}
@@ -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
+ }