@douyinfe/semi-ui 2.17.1 → 2.18.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 (149) hide show
  1. package/anchor/index.tsx +1 -1
  2. package/anchor/link.tsx +3 -4
  3. package/autoComplete/__test__/autoComplete.test.js +6 -6
  4. package/autoComplete/index.tsx +1 -1
  5. package/autoComplete/option.tsx +164 -0
  6. package/calendar/__test__/calendar.test.js +21 -2
  7. package/calendar/_story/calendar.stories.js +31 -0
  8. package/calendar/index.tsx +3 -1
  9. package/calendar/interface.ts +2 -1
  10. package/carousel/index.tsx +5 -5
  11. package/dist/css/semi.css +160 -22
  12. package/dist/css/semi.min.css +1 -1
  13. package/dist/umd/semi-ui.js +332 -74
  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/FieldProps/labelOptional.jsx +30 -0
  18. package/form/_story/form.stories.js +7 -0
  19. package/form/hoc/withField.tsx +1 -0
  20. package/form/label.tsx +21 -7
  21. package/gulpfile.js +3 -1
  22. package/lib/cjs/_base/base.css +35 -0
  23. package/lib/cjs/anchor/index.js +2 -1
  24. package/lib/cjs/anchor/link.d.ts +1 -1
  25. package/lib/cjs/anchor/link.js +9 -5
  26. package/lib/cjs/autoComplete/index.d.ts +1 -1
  27. package/lib/cjs/autoComplete/index.js +1 -1
  28. package/lib/cjs/autoComplete/option.d.ts +50 -0
  29. package/lib/cjs/autoComplete/option.js +218 -0
  30. package/lib/cjs/calendar/index.d.ts +2 -0
  31. package/lib/cjs/calendar/index.js +3 -1
  32. package/lib/cjs/calendar/interface.d.ts +2 -1
  33. package/lib/cjs/carousel/index.js +2 -2
  34. package/lib/cjs/form/hoc/withField.js +2 -1
  35. package/lib/cjs/form/label.d.ts +8 -5
  36. package/lib/cjs/form/label.js +15 -4
  37. package/lib/cjs/locale/interface.d.ts +3 -0
  38. package/lib/cjs/locale/source/ar.js +3 -0
  39. package/lib/cjs/locale/source/de.js +3 -0
  40. package/lib/cjs/locale/source/en_GB.js +3 -0
  41. package/lib/cjs/locale/source/en_US.js +3 -0
  42. package/lib/cjs/locale/source/es.js +3 -0
  43. package/lib/cjs/locale/source/fr.js +3 -0
  44. package/lib/cjs/locale/source/id_ID.js +3 -0
  45. package/lib/cjs/locale/source/it.js +3 -0
  46. package/lib/cjs/locale/source/ja_JP.js +3 -0
  47. package/lib/cjs/locale/source/ko_KR.js +3 -0
  48. package/lib/cjs/locale/source/ms_MY.js +3 -0
  49. package/lib/cjs/locale/source/pt_BR.js +3 -0
  50. package/lib/cjs/locale/source/ru_RU.js +3 -0
  51. package/lib/cjs/locale/source/th_TH.js +3 -0
  52. package/lib/cjs/locale/source/tr_TR.js +3 -0
  53. package/lib/cjs/locale/source/vi_VN.js +3 -0
  54. package/lib/cjs/locale/source/zh_CN.js +3 -0
  55. package/lib/cjs/locale/source/zh_TW.js +3 -0
  56. package/lib/cjs/modal/Modal.js +0 -8
  57. package/lib/cjs/modal/ModalContent.js +4 -1
  58. package/lib/cjs/tag/group.d.ts +3 -0
  59. package/lib/cjs/tag/group.js +24 -6
  60. package/lib/cjs/tag/index.d.ts +2 -1
  61. package/lib/cjs/tag/index.js +7 -5
  62. package/lib/cjs/tag/interface.d.ts +2 -1
  63. package/lib/cjs/tree/index.d.ts +3 -1
  64. package/lib/cjs/tree/index.js +23 -0
  65. package/lib/cjs/tree/interface.d.ts +4 -0
  66. package/lib/es/_base/base.css +35 -0
  67. package/lib/es/anchor/index.js +2 -1
  68. package/lib/es/anchor/link.d.ts +1 -1
  69. package/lib/es/anchor/link.js +9 -5
  70. package/lib/es/autoComplete/index.d.ts +1 -1
  71. package/lib/es/autoComplete/index.js +1 -1
  72. package/lib/es/autoComplete/option.d.ts +50 -0
  73. package/lib/es/autoComplete/option.js +188 -0
  74. package/lib/es/calendar/index.d.ts +2 -0
  75. package/lib/es/calendar/index.js +3 -1
  76. package/lib/es/calendar/interface.d.ts +2 -1
  77. package/lib/es/carousel/index.js +2 -2
  78. package/lib/es/form/hoc/withField.js +2 -1
  79. package/lib/es/form/label.d.ts +8 -5
  80. package/lib/es/form/label.js +13 -4
  81. package/lib/es/locale/interface.d.ts +3 -0
  82. package/lib/es/locale/source/ar.js +3 -0
  83. package/lib/es/locale/source/de.js +3 -0
  84. package/lib/es/locale/source/en_GB.js +3 -0
  85. package/lib/es/locale/source/en_US.js +3 -0
  86. package/lib/es/locale/source/es.js +3 -0
  87. package/lib/es/locale/source/fr.js +3 -0
  88. package/lib/es/locale/source/id_ID.js +3 -0
  89. package/lib/es/locale/source/it.js +3 -0
  90. package/lib/es/locale/source/ja_JP.js +3 -0
  91. package/lib/es/locale/source/ko_KR.js +3 -0
  92. package/lib/es/locale/source/ms_MY.js +3 -0
  93. package/lib/es/locale/source/pt_BR.js +3 -0
  94. package/lib/es/locale/source/ru_RU.js +3 -0
  95. package/lib/es/locale/source/th_TH.js +3 -0
  96. package/lib/es/locale/source/tr_TR.js +3 -0
  97. package/lib/es/locale/source/vi_VN.js +3 -0
  98. package/lib/es/locale/source/zh_CN.js +3 -0
  99. package/lib/es/locale/source/zh_TW.js +3 -0
  100. package/lib/es/modal/Modal.js +0 -8
  101. package/lib/es/modal/ModalContent.js +4 -1
  102. package/lib/es/tag/group.d.ts +3 -0
  103. package/lib/es/tag/group.js +24 -6
  104. package/lib/es/tag/index.d.ts +2 -1
  105. package/lib/es/tag/index.js +7 -5
  106. package/lib/es/tag/interface.d.ts +2 -1
  107. package/lib/es/tree/index.d.ts +3 -1
  108. package/lib/es/tree/index.js +22 -0
  109. package/lib/es/tree/interface.d.ts +4 -0
  110. package/locale/interface.ts +3 -0
  111. package/locale/source/ar.ts +3 -0
  112. package/locale/source/de.ts +3 -0
  113. package/locale/source/en_GB.ts +3 -0
  114. package/locale/source/en_US.ts +3 -0
  115. package/locale/source/es.ts +3 -0
  116. package/locale/source/fr.ts +3 -0
  117. package/locale/source/id_ID.ts +3 -0
  118. package/locale/source/it.ts +3 -0
  119. package/locale/source/ja_JP.ts +3 -0
  120. package/locale/source/ko_KR.ts +3 -0
  121. package/locale/source/ms_MY.ts +3 -0
  122. package/locale/source/pt_BR.ts +3 -0
  123. package/locale/source/ru_RU.ts +3 -0
  124. package/locale/source/th_TH.ts +3 -0
  125. package/locale/source/tr_TR.ts +4 -1
  126. package/locale/source/vi_VN.ts +3 -0
  127. package/locale/source/zh_CN.ts +3 -0
  128. package/locale/source/zh_TW.ts +3 -0
  129. package/modal/Modal.tsx +0 -6
  130. package/modal/ModalContent.tsx +4 -1
  131. package/modal/__test__/modal.test.js +1 -1
  132. package/modal/_story/__snapshots__/modal.stories.tsx.snap +203 -0
  133. package/package.json +7 -7
  134. package/radio/_story/radio.stories.js +2 -2
  135. package/rating/__test__/rating.test.js +1 -1
  136. package/select/__test__/select.test.js +11 -17
  137. package/select/_story/select.stories.js +6 -6
  138. package/steps/_story/steps.stories.js +3 -3
  139. package/switch/_story/switch.stories.js +4 -4
  140. package/switch/_story/switch.stories.tsx +4 -4
  141. package/tag/_story/tag.stories.js +57 -1
  142. package/tag/group.tsx +20 -3
  143. package/tag/index.tsx +6 -5
  144. package/tag/interface.ts +2 -1
  145. package/transfer/_story/transfer.stories.js +2 -2
  146. package/tree/_story/tree.stories.js +152 -3
  147. package/tree/index.tsx +16 -1
  148. package/tree/interface.ts +6 -0
  149. package/upload/_story/upload.stories.js +2 -2
@@ -0,0 +1,203 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`模态框-点击遮罩层不可关闭 1`] = `
4
+ <DialogComponent
5
+ maskClosable={false}
6
+ >
7
+ <Button
8
+ onClick={[Function]}
9
+ >
10
+ <Button
11
+ block={false}
12
+ disabled={false}
13
+ htmlType="button"
14
+ onClick={[Function]}
15
+ onMouseDown={[Function]}
16
+ onMouseEnter={[Function]}
17
+ onMouseLeave={[Function]}
18
+ prefixCls="semi-button"
19
+ size="default"
20
+ theme="light"
21
+ type="primary"
22
+ >
23
+ <button
24
+ aria-disabled={false}
25
+ className="semi-button semi-button-primary semi-button-light"
26
+ disabled={false}
27
+ onClick={[Function]}
28
+ onMouseDown={[Function]}
29
+ onMouseEnter={[Function]}
30
+ onMouseLeave={[Function]}
31
+ type="button"
32
+ >
33
+ <span
34
+ className="semi-button-content"
35
+ onClick={[Function]}
36
+ x-semi-prop="children"
37
+ >
38
+ show dialog
39
+ </span>
40
+ </button>
41
+ </Button>
42
+ </Button>
43
+ <Button
44
+ onClick={[Function]}
45
+ >
46
+ <Button
47
+ block={false}
48
+ disabled={false}
49
+ htmlType="button"
50
+ onClick={[Function]}
51
+ onMouseDown={[Function]}
52
+ onMouseEnter={[Function]}
53
+ onMouseLeave={[Function]}
54
+ prefixCls="semi-button"
55
+ size="default"
56
+ theme="light"
57
+ type="primary"
58
+ >
59
+ <button
60
+ aria-disabled={false}
61
+ className="semi-button semi-button-primary semi-button-light"
62
+ disabled={false}
63
+ onClick={[Function]}
64
+ onMouseDown={[Function]}
65
+ onMouseEnter={[Function]}
66
+ onMouseLeave={[Function]}
67
+ type="button"
68
+ >
69
+ <span
70
+ className="semi-button-content"
71
+ onClick={[Function]}
72
+ x-semi-prop="children"
73
+ >
74
+ 静态调用
75
+ </span>
76
+ </button>
77
+ </Button>
78
+ </Button>
79
+ <Modal
80
+ afterClose={[Function]}
81
+ cancelLoading={false}
82
+ centered={false}
83
+ closable={true}
84
+ closeOnEsc={true}
85
+ confirmLoading={false}
86
+ fullScreen={false}
87
+ hasCancel={true}
88
+ keepDOM={false}
89
+ lazyRender={true}
90
+ mask={true}
91
+ maskClosable={false}
92
+ maskFixed={false}
93
+ motion={true}
94
+ okType="primary"
95
+ onCancel={[Function]}
96
+ onOk={[Function]}
97
+ size="small"
98
+ title="对话框标题"
99
+ visible={false}
100
+ zIndex={1000}
101
+ />
102
+ </DialogComponent>
103
+ `;
104
+
105
+ exports[`模态框默认 1`] = `
106
+ <DialogComponent>
107
+ <Button
108
+ onClick={[Function]}
109
+ >
110
+ <Button
111
+ block={false}
112
+ disabled={false}
113
+ htmlType="button"
114
+ onClick={[Function]}
115
+ onMouseDown={[Function]}
116
+ onMouseEnter={[Function]}
117
+ onMouseLeave={[Function]}
118
+ prefixCls="semi-button"
119
+ size="default"
120
+ theme="light"
121
+ type="primary"
122
+ >
123
+ <button
124
+ aria-disabled={false}
125
+ className="semi-button semi-button-primary semi-button-light"
126
+ disabled={false}
127
+ onClick={[Function]}
128
+ onMouseDown={[Function]}
129
+ onMouseEnter={[Function]}
130
+ onMouseLeave={[Function]}
131
+ type="button"
132
+ >
133
+ <span
134
+ className="semi-button-content"
135
+ onClick={[Function]}
136
+ x-semi-prop="children"
137
+ >
138
+ show dialog
139
+ </span>
140
+ </button>
141
+ </Button>
142
+ </Button>
143
+ <Button
144
+ onClick={[Function]}
145
+ >
146
+ <Button
147
+ block={false}
148
+ disabled={false}
149
+ htmlType="button"
150
+ onClick={[Function]}
151
+ onMouseDown={[Function]}
152
+ onMouseEnter={[Function]}
153
+ onMouseLeave={[Function]}
154
+ prefixCls="semi-button"
155
+ size="default"
156
+ theme="light"
157
+ type="primary"
158
+ >
159
+ <button
160
+ aria-disabled={false}
161
+ className="semi-button semi-button-primary semi-button-light"
162
+ disabled={false}
163
+ onClick={[Function]}
164
+ onMouseDown={[Function]}
165
+ onMouseEnter={[Function]}
166
+ onMouseLeave={[Function]}
167
+ type="button"
168
+ >
169
+ <span
170
+ className="semi-button-content"
171
+ onClick={[Function]}
172
+ x-semi-prop="children"
173
+ >
174
+ 静态调用
175
+ </span>
176
+ </button>
177
+ </Button>
178
+ </Button>
179
+ <Modal
180
+ afterClose={[Function]}
181
+ cancelLoading={false}
182
+ centered={false}
183
+ closable={true}
184
+ closeOnEsc={true}
185
+ confirmLoading={false}
186
+ fullScreen={false}
187
+ hasCancel={true}
188
+ keepDOM={false}
189
+ lazyRender={true}
190
+ mask={true}
191
+ maskClosable={true}
192
+ maskFixed={false}
193
+ motion={true}
194
+ okType="primary"
195
+ onCancel={[Function]}
196
+ onOk={[Function]}
197
+ size="small"
198
+ title="对话框标题"
199
+ visible={false}
200
+ zIndex={1000}
201
+ />
202
+ </DialogComponent>
203
+ `;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@douyinfe/semi-ui",
3
- "version": "2.17.1",
3
+ "version": "2.18.0-beta.0",
4
4
  "description": "",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/es/index.js",
@@ -15,11 +15,11 @@
15
15
  "dependencies": {
16
16
  "@babel/runtime-corejs3": "^7.15.4",
17
17
  "@douyinfe/semi-animation": "2.12.0",
18
- "@douyinfe/semi-animation-react": "2.17.1",
19
- "@douyinfe/semi-foundation": "2.17.1",
20
- "@douyinfe/semi-icons": "2.17.1",
18
+ "@douyinfe/semi-animation-react": "2.18.0-beta.0",
19
+ "@douyinfe/semi-foundation": "2.18.0-beta.0",
20
+ "@douyinfe/semi-icons": "2.18.0-beta.0",
21
21
  "@douyinfe/semi-illustrations": "2.15.0",
22
- "@douyinfe/semi-theme-default": "2.17.1",
22
+ "@douyinfe/semi-theme-default": "2.18.0-beta.0",
23
23
  "async-validator": "^3.5.0",
24
24
  "classnames": "^2.2.6",
25
25
  "copy-text-to-clipboard": "^2.1.1",
@@ -66,13 +66,13 @@
66
66
  ],
67
67
  "author": "",
68
68
  "license": "MIT",
69
- "gitHead": "e2dfadcc7f24b9af6cab08b64ac0ead052219961",
69
+ "gitHead": "d390ac3fde2f62a63087a9ab8ea1dd1166432069",
70
70
  "devDependencies": {
71
71
  "@babel/plugin-proposal-decorators": "^7.15.8",
72
72
  "@babel/plugin-transform-runtime": "^7.15.8",
73
73
  "@babel/preset-env": "^7.15.8",
74
74
  "@babel/preset-react": "^7.14.5",
75
- "@douyinfe/semi-scss-compile": "2.17.1",
75
+ "@douyinfe/semi-scss-compile": "2.18.0-beta.0",
76
76
  "@storybook/addon-knobs": "^6.3.1",
77
77
  "@types/lodash": "^4.14.176",
78
78
  "@types/react": ">=16.0.0",
@@ -196,7 +196,7 @@ const RadioGroup1 = () => {
196
196
  </div>
197
197
  );
198
198
  };
199
- class RadioWithControled extends React.Component {
199
+ class RadioWithControlled extends React.Component {
200
200
  constructor(props) {
201
201
  super(props);
202
202
  this.state = {
@@ -240,7 +240,7 @@ export const _RadioGroup = () => {
240
240
  </RadioGroup>
241
241
  <br />
242
242
  value+onchange
243
- <RadioWithControled />
243
+ <RadioWithControlled />
244
244
  <br />
245
245
  联动
246
246
  <RadioGroup1 />
@@ -85,7 +85,7 @@ describe('Rating', () => {
85
85
  expect(spyOnChange.calledWithMatch(1)).toBe(true);
86
86
  });
87
87
 
88
- it('controled value', () => {
88
+ it('controlled value', () => {
89
89
  const R = getRating({ value: 2 });
90
90
  expect(R.state().value).toEqual(2);
91
91
  expect(R.find(`.${BASE_CLASS_PREFIX}-rating-star-full`).length).toEqual(2);
@@ -20,7 +20,7 @@ function getOption(list = defaultList) {
20
20
  let commonProps = {
21
21
  // Select use Popup Layer to show candidate option,
22
22
  // but all Popup Layer which extends from Tooltip (eg Popover, Dropdown) have animation and delay.
23
- // Turn off animation and delay during testing, to avoid wating (something like setTimeOut/balabala...) in the test code
23
+ // Turn off animation and delay during testing, to avoid waiting (something like setTimeOut/balabala...) in the test code
24
24
  motion: false,
25
25
  mouseEnterDelay: 0,
26
26
  mouseLeaveDelay: 0,
@@ -467,7 +467,7 @@ describe('Select', () => {
467
467
  const props = { disabled: true };
468
468
  const select = getSelect(props);
469
469
  expect(select.exists(`.${BASE_CLASS_PREFIX}-select-disabled`)).toEqual(true);
470
- // Does not respond click events when disbaled is true
470
+ // Does not respond click events when disabled is true
471
471
  select.find(`.${BASE_CLASS_PREFIX}-select`).simulate('click', {});
472
472
  expect(select.exists(`.${BASE_CLASS_PREFIX}-select-option-list`)).toEqual(false);
473
473
  });
@@ -556,12 +556,6 @@ describe('Select', () => {
556
556
  select.unmount();
557
557
  // when click clear button, should trigger onSearch
558
558
  // TODO
559
- let scProps = {
560
- showClear: true,
561
- filter: true,
562
- defaultValue: 'tikok',
563
- };
564
- const scSelect = getSelect(props);
565
559
  });
566
560
 
567
561
  it('emptyContent', () => {
@@ -718,7 +712,7 @@ describe('Select', () => {
718
712
  });
719
713
 
720
714
  it('onDeselect', () => {
721
- // trigger onDeselect when option is deselectd
715
+ // trigger onDeselect when option is deselected
722
716
  let onDeselect = (value, option) => {};
723
717
  let spyOnDeselect = sinon.spy(onDeselect);
724
718
  let props = {
@@ -916,7 +910,7 @@ describe('Select', () => {
916
910
  });
917
911
 
918
912
  it('【autoFocus】 & onBlur when autoFocus = true', () => {
919
- // autoFocus should trigger onBlur when click ohter element directly (dropdown not open)
913
+ // autoFocus should trigger onBlur when click other element directly (dropdown not open)
920
914
  let spyOnBlur = sinon.spy((value, option) => {
921
915
  });
922
916
  let props = {
@@ -936,7 +930,7 @@ describe('Select', () => {
936
930
  expect(spyOnBlur.callCount).toEqual(1);
937
931
  });
938
932
 
939
- it('vitrual', () => {
933
+ it('virtual', () => {
940
934
  let spyOnChange = sinon.spy((value) => {
941
935
  });
942
936
  let optionList = Array.from({ length: 100 }, (v, i) => ({ label: `option-${i}`, value: i }));
@@ -1048,7 +1042,7 @@ describe('Select', () => {
1048
1042
  it('customTrigger', () => {
1049
1043
  const triggerRender = ({ value, ...rest }) => {
1050
1044
  return (
1051
- <div className="custom-triger">
1045
+ <div className="custom-trigger">
1052
1046
  trigger
1053
1047
  </div>
1054
1048
  );
@@ -1057,7 +1051,7 @@ describe('Select', () => {
1057
1051
  triggerRender,
1058
1052
  };
1059
1053
  let select = getSelect(props);
1060
- let trigger = select.find('.custom-triger');
1054
+ let trigger = select.find('.custom-trigger');
1061
1055
  expect(trigger.length).toEqual(1);
1062
1056
  expect(trigger.at(0).text()).toEqual('trigger');
1063
1057
  trigger.at(0).simulate('click')
@@ -1186,7 +1180,7 @@ describe('Select', () => {
1186
1180
  expect(singleSelect.state().selections.size).toEqual(0);
1187
1181
  });
1188
1182
 
1189
- it('props optionList update after choose some option, uncontroled mode', () => {
1183
+ it('props optionList update after choose some option, uncontrolled mode', () => {
1190
1184
 
1191
1185
  let props = {
1192
1186
  defaultActiveFirstOption: true,
@@ -1234,7 +1228,7 @@ describe('Select', () => {
1234
1228
  expect(selections2[0][0]).toEqual('abc');
1235
1229
  });
1236
1230
 
1237
- it('click tag close when multiple, controled mode', () => {
1231
+ it('click tag close when multiple, controlled mode', () => {
1238
1232
  let spyOnChange = sinon.spy((value) => {
1239
1233
  });
1240
1234
  let spyOnDeselect = sinon.spy((option) => {
@@ -1303,8 +1297,8 @@ describe('Select', () => {
1303
1297
  expect(inputValue).toEqual(keyword);
1304
1298
  });
1305
1299
  // TODO ref selectAll \deselectAll when onChangeWithObject is true
1306
- // TODO when loading is true, do not response any keyborard event
1307
- // TODO can't remove tag when option is diabled
1300
+ // TODO when loading is true, do not response any keyboard event
1301
+ // TODO can't remove tag when option is disabled
1308
1302
  // it('allowCreate-renderCreateItem', ()=>{})
1309
1303
  // it('autoAdjustOverflow', ()=>{})
1310
1304
  // it('remote', ()=>{})
@@ -1183,7 +1183,7 @@ RenderSelectedItem.parameters = {
1183
1183
  chromatic: { disableSnapshot: false },
1184
1184
  };
1185
1185
 
1186
- const ControledSelect = () => {
1186
+ const ControlledSelect = () => {
1187
1187
  const [value, setValue] = useState('nick');
1188
1188
  const [value2, setValue2] = useState('jerry');
1189
1189
  const [value3, setValue3] = useState();
@@ -1277,13 +1277,13 @@ const ControledSelect = () => {
1277
1277
  );
1278
1278
  };
1279
1279
 
1280
- export const Controlled = () => <ControledSelect></ControledSelect>;
1280
+ export const Controlled = () => <ControlledSelect></ControlledSelect>;
1281
1281
 
1282
1282
  Controlled.story = {
1283
1283
  name: 'controlled',
1284
1284
  };
1285
1285
 
1286
- const UnControledSelect = () => {
1286
+ const UnControlledSelect = () => {
1287
1287
  const onChange = value => {
1288
1288
  console.log(value);
1289
1289
  };
@@ -1318,8 +1318,8 @@ const UnControledSelect = () => {
1318
1318
  );
1319
1319
  };
1320
1320
 
1321
- export { UnControledSelect };
1322
- UnControledSelect.story = {
1321
+ export { UnControlledSelect };
1322
+ UnControlledSelect.story = {
1323
1323
  name: '非受控组件'
1324
1324
  };
1325
1325
 
@@ -1800,7 +1800,7 @@ AllowCreateCustomRender.story = {
1800
1800
  name: 'allowCreate custom render',
1801
1801
  };
1802
1802
 
1803
- let AllowCreateControledDemo = () => {
1803
+ let AllowCreateControlledDemo = () => {
1804
1804
  let [value, setValue] = useState();
1805
1805
  const optionList = [
1806
1806
  {
@@ -199,12 +199,12 @@ class StepsDemo extends React.Component {
199
199
  }
200
200
  }
201
201
 
202
- export const StepsWithControled = () => {
202
+ export const StepsWithControlled = () => {
203
203
  return <StepsDemo></StepsDemo>;
204
204
  };
205
205
 
206
- StepsWithControled.story = {
207
- name: 'steps with controled',
206
+ StepsWithControlled.story = {
207
+ name: 'steps with controlled',
208
208
  };
209
209
 
210
210
  class StepsWithonChange extends React.Component {
@@ -65,17 +65,17 @@ SwitchDisabled.story = {
65
65
  name: 'switch disabled',
66
66
  };
67
67
 
68
- const ControledSwitch = () => {
68
+ const ControlledSwitch = () => {
69
69
  const [checked, onChange] = useState(true);
70
70
  return <Switch checked={checked} onChange={(v, e) => onChange(v)} aria-label='power-switch'/>;
71
71
  };
72
- export const SwitchCheckedOnChange = () => <ControledSwitch />;
72
+ export const SwitchCheckedOnChange = () => <ControlledSwitch />;
73
73
 
74
74
  SwitchCheckedOnChange.story = {
75
75
  name: 'switch checked + onChange',
76
76
  };
77
77
 
78
- const UnControledSwitch = () => {
78
+ const UnControlledSwitch = () => {
79
79
  const onChange = checked => {
80
80
  console.log(checked);
81
81
  };
@@ -86,7 +86,7 @@ const UnControledSwitch = () => {
86
86
  </>
87
87
  );
88
88
  };
89
- export const SwitchDefaultCheckedOnChange = () => <UnControledSwitch />;
89
+ export const SwitchDefaultCheckedOnChange = () => <UnControlledSwitch />;
90
90
 
91
91
  SwitchDefaultCheckedOnChange.story = {
92
92
  name: 'switch defaultChecked + onChange',
@@ -57,15 +57,15 @@ stories.add('switch disabled', () => (
57
57
  ));
58
58
 
59
59
 
60
- const ControledSwitch = () => {
60
+ const ControlledSwitch = () => {
61
61
  const [checked, onChange] = useState(true);
62
62
  return (
63
63
  <Switch checked={checked} onChange={(v, e) => onChange(v)} />
64
64
  );
65
65
  };
66
- stories.add('switch checked + onChange', () => <ControledSwitch/>);
66
+ stories.add('switch checked + onChange', () => <ControlledSwitch/>);
67
67
 
68
- const UnControledSwitch = () => {
68
+ const UnControlledSwitch = () => {
69
69
  const onChange = checked => {
70
70
  console.log(checked);
71
71
  };
@@ -76,7 +76,7 @@ const UnControledSwitch = () => {
76
76
  </>
77
77
  );
78
78
  };
79
- stories.add('switch defaultChecked + onChange', () => <UnControledSwitch/>);
79
+ stories.add('switch defaultChecked + onChange', () => <UnControlledSwitch/>);
80
80
 
81
81
  class LoadingDemo extends React.Component {
82
82
  constructor(props) {
@@ -1,5 +1,5 @@
1
1
  /* argus-disable unPkgSensitiveInfo */
2
- import React from 'react';
2
+ import React, { useCallback, useState } from 'react';
3
3
  import withPropsCombinations from 'react-storybook-addon-props-combinations';
4
4
  import { BASE_CLASS_PREFIX } from '../../../semi-foundation/base/constants';
5
5
 
@@ -232,3 +232,59 @@ export const AvatarTagGroup = () => <AvatarTagGroupDemo />;
232
232
  AvatarTagGroup.story = {
233
233
  name: 'avatar tagGroup',
234
234
  };
235
+
236
+ class TagGroupCloseableDemo extends React.Component {
237
+ constructor(props){
238
+ super(props);
239
+ this.state = {
240
+ tagList: [
241
+ { tagKey: '1', color: 'white', children: '抖音', closable: true,},
242
+ { tagKey: '2',color: 'white', children: '火山小视频', closable: true,},
243
+ { tagKey: '3',color: 'white', children: '剪映', closable: true,},
244
+ { tagKey: '4',color: 'white', children: '皮皮虾', closable: true,},
245
+ ]
246
+ };
247
+ this.tagListClick = this.tagListClick.bind(this);
248
+ }
249
+
250
+ tagListClick(value, e, tagKey){
251
+ const newTagList = [...this.state.tagList];
252
+ const closeTagIndex = newTagList.findIndex(t => t.tagKey === tagKey);
253
+ newTagList.splice(closeTagIndex, 1);
254
+ this.setState({
255
+ tagList: newTagList,
256
+ });
257
+ }
258
+
259
+ render() {
260
+ return (
261
+ <div style={ {
262
+ backgroundColor: 'var(--semi-color-fill-0)',
263
+ height: 35,
264
+ width: 300,
265
+ display: 'flex',
266
+ alignItems: 'center',
267
+ padding: '0 10px',
268
+ marginBottom: 30,
269
+ }}>
270
+ <TagGroup
271
+ maxTagCount={3}
272
+ style={ {
273
+ display: 'flex',
274
+ alignItems: 'center',
275
+ width: 350,
276
+ }}
277
+ tagList={this.state.tagList}
278
+ size='large'
279
+ onTagClose={this.tagListClick}
280
+ />
281
+ </div>
282
+ );
283
+ }
284
+ }
285
+
286
+ export const TagGroupCloseable = () => <TagGroupCloseableDemo />;
287
+
288
+ TagGroupCloseable.story = {
289
+ name: 'tagGroup closable',
290
+ }
package/tag/group.tsx CHANGED
@@ -21,6 +21,7 @@ export interface TagGroupProps<T> {
21
21
  popoverProps?: PopoverProps;
22
22
  avatarShape?: AvatarShape;
23
23
  mode?: string;
24
+ onTagClose: (tagChildren: React.ReactNode, event: React.MouseEvent<HTMLElement>, tagKey: string | number) => void;
24
25
  }
25
26
 
26
27
  export default class TagGroup<T> extends PureComponent<TagGroupProps<T>> {
@@ -29,6 +30,7 @@ export default class TagGroup<T> extends PureComponent<TagGroupProps<T>> {
29
30
  className: '',
30
31
  size: tagSize[0],
31
32
  avatarShape: 'square',
33
+ onTagClose: () => undefined,
32
34
  };
33
35
 
34
36
  static propTypes = {
@@ -40,6 +42,7 @@ export default class TagGroup<T> extends PureComponent<TagGroupProps<T>> {
40
42
  tagList: PropTypes.array,
41
43
  size: PropTypes.oneOf(tagSize),
42
44
  mode: PropTypes.string,
45
+ onTagClose: PropTypes.func,
43
46
  showPopover: PropTypes.bool,
44
47
  popoverProps: PropTypes.object,
45
48
  avatarShape: PropTypes.oneOf(avatarShapeSet),
@@ -95,18 +98,32 @@ export default class TagGroup<T> extends PureComponent<TagGroupProps<T>> {
95
98
  }
96
99
 
97
100
  renderAllTags() {
98
- const { tagList, size, mode, avatarShape } = this.props;
99
- const renderTags = tagList.map((tag, index): (Tag | React.ReactNode) => {
101
+ const { tagList, size, mode, avatarShape, onTagClose } = this.props;
102
+ const renderTags = tagList.map((tag): (Tag | React.ReactNode) => {
100
103
  if (mode === 'custom') {
101
104
  return tag as React.ReactNode;
102
105
  }
103
106
  if (!(tag as TagProps).size) {
104
107
  (tag as TagProps).size = size;
105
108
  }
109
+
106
110
  if (!(tag as TagProps).avatarShape) {
107
111
  (tag as TagProps).avatarShape = avatarShape;
108
112
  }
109
- return <Tag key={`${index}-tag`} {...(tag as TagProps)} />;
113
+
114
+ if (!(tag as TagProps).tagKey) {
115
+ if (typeof (tag as TagProps).children === 'string' || typeof (tag as TagProps).children === 'number') {
116
+ (tag as TagProps).tagKey = (tag as TagProps).children as string | number;
117
+ } else {
118
+ (tag as TagProps).tagKey = Math.random();
119
+ }
120
+ }
121
+ return <Tag {...(tag as TagProps)} key={(tag as TagProps).tagKey} onClose={(tagChildren, e, tagKey) => {
122
+ if ((tag as TagProps).onClose) {
123
+ (tag as TagProps).onClose(tagChildren, e, tagKey);
124
+ }
125
+ onTagClose && onTagClose(tagChildren, e, tagKey);
126
+ }} />;
110
127
  });
111
128
  return renderTags;
112
129
  }
package/tag/index.tsx CHANGED
@@ -40,6 +40,7 @@ export default class Tag extends Component<TagProps, TagState> {
40
40
 
41
41
  static propTypes = {
42
42
  children: PropTypes.node,
43
+ tagKey: PropTypes.oneOf([PropTypes.string, PropTypes.number]),
43
44
  size: PropTypes.oneOf(tagSize),
44
45
  color: PropTypes.oneOf(tagColors),
45
46
  type: PropTypes.oneOf(tagType),
@@ -79,11 +80,11 @@ export default class Tag extends Component<TagProps, TagState> {
79
80
  }
80
81
  }
81
82
 
82
- close(e: React.MouseEvent<HTMLElement>, value: React.ReactNode) {
83
+ close(e: React.MouseEvent<HTMLElement>, value: React.ReactNode, tagKey: string | number) {
83
84
  const { onClose } = this.props;
84
85
  e.stopPropagation();
85
86
  e.nativeEvent.stopImmediatePropagation();
86
- onClose && onClose(value, e);
87
+ onClose && onClose(value, e, tagKey);
87
88
  // when user call e.preventDefault() in onClick callback, tag will not hidden
88
89
  if (e.defaultPrevented) {
89
90
  return;
@@ -96,7 +97,7 @@ export default class Tag extends Component<TagProps, TagState> {
96
97
  switch (event.key) {
97
98
  case "Backspace":
98
99
  case "Delete":
99
- closable && this.close(event, this.props.children);
100
+ closable && this.close(event, this.props.children, this.props.tagKey);
100
101
  handlePrevent(event);
101
102
  break;
102
103
  case "Enter":
@@ -119,7 +120,7 @@ export default class Tag extends Component<TagProps, TagState> {
119
120
  }
120
121
 
121
122
  render() {
122
- const { children, size, color, closable, visible, onClose, onClick, className, type, avatarSrc, avatarShape, tabIndex, ...attr } = this.props;
123
+ const { tagKey, children, size, color, closable, visible, onClose, onClick, className, type, avatarSrc, avatarShape, tabIndex, ...attr } = this.props;
123
124
  const { visible: isVisible } = this.state;
124
125
  const clickable = onClick !== Tag.defaultProps.onClick || closable;
125
126
  // only when the Tag is clickable or closable, the value of tabIndex is allowed to be passed in.
@@ -145,7 +146,7 @@ export default class Tag extends Component<TagProps, TagState> {
145
146
  const wrapProps = clickable ? ({ ...baseProps, ...a11yProps }) : baseProps;
146
147
  const closeIcon = closable ? (
147
148
  // eslint-disable-next-line jsx-a11y/click-events-have-key-events
148
- <div className={`${prefixCls}-close`} onClick={e => this.close(e, children)}>
149
+ <div className={`${prefixCls}-close`} onClick={e => this.close(e, children, tagKey)}>
149
150
  <IconClose size="small" />
150
151
  </div>
151
152
  ) : null;
package/tag/interface.ts CHANGED
@@ -22,12 +22,13 @@ export type AvatarShape = 'circle' | 'square';
22
22
 
23
23
  export interface TagProps {
24
24
  children?: React.ReactNode;
25
+ tagKey?: string | number;
25
26
  size?: TagSize;
26
27
  color?: TagColor;
27
28
  type?: TagType;
28
29
  closable?: boolean;
29
30
  visible?: boolean;
30
- onClose?: (tagChildren: React.ReactNode, event: React.MouseEvent<HTMLElement>) => void;
31
+ onClose?: (tagChildren: React.ReactNode, event: React.MouseEvent<HTMLElement>, tagKey: string | number) => void;
31
32
  onClick?: React.MouseEventHandler<HTMLDivElement>;
32
33
  style?: React.CSSProperties;
33
34
  className?: string;