@douyinfe/semi-ui 2.17.1 → 2.19.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/anchor/index.tsx +1 -1
- package/anchor/link.tsx +3 -4
- package/autoComplete/__test__/autoComplete.test.js +6 -6
- package/autoComplete/index.tsx +1 -1
- package/autoComplete/option.tsx +164 -0
- package/calendar/__test__/calendar.test.js +21 -2
- package/calendar/_story/calendar.stories.js +31 -0
- package/calendar/index.tsx +3 -1
- package/calendar/interface.ts +2 -1
- package/carousel/index.tsx +5 -5
- package/checkbox/checkbox.tsx +10 -2
- package/checkbox/checkboxGroup.tsx +2 -0
- package/dist/css/semi.css +160 -22
- package/dist/css/semi.min.css +1 -1
- package/dist/umd/semi-ui.js +15144 -16407
- package/dist/umd/semi-ui.js.map +1 -1
- package/dist/umd/semi-ui.min.js +1 -1
- package/dist/umd/semi-ui.min.js.map +1 -1
- package/form/_story/FieldProps/labelOptional.jsx +30 -0
- package/form/_story/form.stories.js +7 -0
- package/form/hoc/withField.tsx +1 -0
- package/form/label.tsx +21 -7
- package/gulpfile.js +3 -1
- package/lib/cjs/_base/base.css +35 -0
- package/lib/cjs/anchor/index.js +2 -1
- package/lib/cjs/anchor/link.d.ts +1 -1
- package/lib/cjs/anchor/link.js +9 -5
- package/lib/cjs/autoComplete/index.d.ts +1 -1
- package/lib/cjs/autoComplete/index.js +1 -1
- package/lib/cjs/autoComplete/option.d.ts +50 -0
- package/lib/cjs/autoComplete/option.js +218 -0
- package/lib/cjs/calendar/index.d.ts +2 -0
- package/lib/cjs/calendar/index.js +3 -1
- package/lib/cjs/calendar/interface.d.ts +2 -1
- package/lib/cjs/carousel/index.js +2 -2
- package/lib/cjs/checkbox/checkbox.d.ts +4 -0
- package/lib/cjs/checkbox/checkbox.js +9 -3
- package/lib/cjs/checkbox/checkboxGroup.js +4 -2
- package/lib/cjs/form/baseForm.d.ts +1 -1
- package/lib/cjs/form/field.d.ts +1 -1
- package/lib/cjs/form/hoc/withField.js +2 -1
- package/lib/cjs/form/label.d.ts +8 -5
- package/lib/cjs/form/label.js +15 -4
- package/lib/cjs/locale/interface.d.ts +3 -0
- package/lib/cjs/locale/source/ar.js +3 -0
- package/lib/cjs/locale/source/de.js +3 -0
- package/lib/cjs/locale/source/en_GB.js +3 -0
- package/lib/cjs/locale/source/en_US.js +3 -0
- package/lib/cjs/locale/source/es.js +3 -0
- package/lib/cjs/locale/source/fr.js +3 -0
- package/lib/cjs/locale/source/id_ID.js +3 -0
- package/lib/cjs/locale/source/it.js +3 -0
- package/lib/cjs/locale/source/ja_JP.js +3 -0
- package/lib/cjs/locale/source/ko_KR.js +3 -0
- package/lib/cjs/locale/source/ms_MY.js +3 -0
- package/lib/cjs/locale/source/pt_BR.js +3 -0
- package/lib/cjs/locale/source/ru_RU.js +3 -0
- package/lib/cjs/locale/source/th_TH.js +3 -0
- package/lib/cjs/locale/source/tr_TR.js +3 -0
- package/lib/cjs/locale/source/vi_VN.js +3 -0
- package/lib/cjs/locale/source/zh_CN.js +3 -0
- package/lib/cjs/locale/source/zh_TW.js +3 -0
- package/lib/cjs/modal/Modal.js +0 -8
- package/lib/cjs/modal/ModalContent.js +4 -1
- package/lib/cjs/radio/radio.d.ts +2 -0
- package/lib/cjs/radio/radio.js +33 -8
- package/lib/cjs/radio/radioGroup.js +4 -2
- package/lib/cjs/tag/group.d.ts +3 -0
- package/lib/cjs/tag/group.js +24 -6
- package/lib/cjs/tag/index.d.ts +2 -1
- package/lib/cjs/tag/index.js +7 -5
- package/lib/cjs/tag/interface.d.ts +2 -1
- package/lib/cjs/tree/index.d.ts +3 -1
- package/lib/cjs/tree/index.js +23 -0
- package/lib/cjs/tree/interface.d.ts +4 -0
- package/lib/cjs/typography/title.d.ts +1 -1
- package/lib/es/_base/base.css +35 -0
- package/lib/es/anchor/index.js +2 -1
- package/lib/es/anchor/link.d.ts +1 -1
- package/lib/es/anchor/link.js +9 -5
- package/lib/es/autoComplete/index.d.ts +1 -1
- package/lib/es/autoComplete/index.js +1 -1
- package/lib/es/autoComplete/option.d.ts +50 -0
- package/lib/es/autoComplete/option.js +188 -0
- package/lib/es/calendar/index.d.ts +2 -0
- package/lib/es/calendar/index.js +3 -1
- package/lib/es/calendar/interface.d.ts +2 -1
- package/lib/es/carousel/index.js +2 -2
- package/lib/es/checkbox/checkbox.d.ts +4 -0
- package/lib/es/checkbox/checkbox.js +10 -4
- package/lib/es/checkbox/checkboxGroup.js +4 -2
- package/lib/es/form/baseForm.d.ts +1 -1
- package/lib/es/form/field.d.ts +1 -1
- package/lib/es/form/hoc/withField.js +2 -1
- package/lib/es/form/label.d.ts +8 -5
- package/lib/es/form/label.js +13 -4
- package/lib/es/locale/interface.d.ts +3 -0
- package/lib/es/locale/source/ar.js +3 -0
- package/lib/es/locale/source/de.js +3 -0
- package/lib/es/locale/source/en_GB.js +3 -0
- package/lib/es/locale/source/en_US.js +3 -0
- package/lib/es/locale/source/es.js +3 -0
- package/lib/es/locale/source/fr.js +3 -0
- package/lib/es/locale/source/id_ID.js +3 -0
- package/lib/es/locale/source/it.js +3 -0
- package/lib/es/locale/source/ja_JP.js +3 -0
- package/lib/es/locale/source/ko_KR.js +3 -0
- package/lib/es/locale/source/ms_MY.js +3 -0
- package/lib/es/locale/source/pt_BR.js +3 -0
- package/lib/es/locale/source/ru_RU.js +3 -0
- package/lib/es/locale/source/th_TH.js +3 -0
- package/lib/es/locale/source/tr_TR.js +3 -0
- package/lib/es/locale/source/vi_VN.js +3 -0
- package/lib/es/locale/source/zh_CN.js +3 -0
- package/lib/es/locale/source/zh_TW.js +3 -0
- package/lib/es/modal/Modal.js +0 -8
- package/lib/es/modal/ModalContent.js +4 -1
- package/lib/es/radio/radio.d.ts +2 -0
- package/lib/es/radio/radio.js +31 -8
- package/lib/es/radio/radioGroup.js +4 -2
- package/lib/es/tag/group.d.ts +3 -0
- package/lib/es/tag/group.js +24 -6
- package/lib/es/tag/index.d.ts +2 -1
- package/lib/es/tag/index.js +7 -5
- package/lib/es/tag/interface.d.ts +2 -1
- package/lib/es/tree/index.d.ts +3 -1
- package/lib/es/tree/index.js +22 -0
- package/lib/es/tree/interface.d.ts +4 -0
- package/lib/es/typography/title.d.ts +1 -1
- package/locale/interface.ts +3 -0
- package/locale/source/ar.ts +3 -0
- package/locale/source/de.ts +3 -0
- package/locale/source/en_GB.ts +3 -0
- package/locale/source/en_US.ts +3 -0
- package/locale/source/es.ts +3 -0
- package/locale/source/fr.ts +3 -0
- package/locale/source/id_ID.ts +3 -0
- package/locale/source/it.ts +3 -0
- package/locale/source/ja_JP.ts +3 -0
- package/locale/source/ko_KR.ts +3 -0
- package/locale/source/ms_MY.ts +3 -0
- package/locale/source/pt_BR.ts +3 -0
- package/locale/source/ru_RU.ts +3 -0
- package/locale/source/th_TH.ts +3 -0
- package/locale/source/tr_TR.ts +4 -1
- package/locale/source/vi_VN.ts +3 -0
- package/locale/source/zh_CN.ts +3 -0
- package/locale/source/zh_TW.ts +3 -0
- package/modal/Modal.tsx +0 -6
- package/modal/ModalContent.tsx +4 -1
- package/modal/__test__/modal.test.js +1 -1
- package/modal/_story/__snapshots__/modal.stories.tsx.snap +203 -0
- package/package.json +7 -7
- package/radio/_story/radio.stories.js +2 -2
- package/radio/radio.tsx +27 -5
- package/radio/radioGroup.tsx +2 -0
- package/rating/__test__/rating.test.js +1 -1
- package/select/__test__/select.test.js +11 -17
- package/select/_story/select.stories.js +6 -6
- package/steps/_story/steps.stories.js +3 -3
- package/switch/_story/switch.stories.js +4 -4
- package/switch/_story/switch.stories.tsx +4 -4
- package/tag/_story/tag.stories.js +57 -1
- package/tag/group.tsx +20 -3
- package/tag/index.tsx +6 -5
- package/tag/interface.ts +2 -1
- package/transfer/_story/transfer.stories.js +2 -2
- package/tree/_story/tree.stories.js +152 -3
- package/tree/index.tsx +16 -1
- package/tree/interface.ts +6 -0
- package/upload/_story/upload.stories.js +2 -2
- package/webpack.config.js +10 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@douyinfe/semi-ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.19.0-alpha.1",
|
|
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.
|
|
19
|
-
"@douyinfe/semi-foundation": "2.
|
|
20
|
-
"@douyinfe/semi-icons": "2.
|
|
18
|
+
"@douyinfe/semi-animation-react": "2.19.0-alpha.1",
|
|
19
|
+
"@douyinfe/semi-foundation": "2.19.0-alpha.1",
|
|
20
|
+
"@douyinfe/semi-icons": "2.19.0-alpha.1",
|
|
21
21
|
"@douyinfe/semi-illustrations": "2.15.0",
|
|
22
|
-
"@douyinfe/semi-theme-default": "2.
|
|
22
|
+
"@douyinfe/semi-theme-default": "2.19.0-alpha.1",
|
|
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": "
|
|
69
|
+
"gitHead": "d1dbf82734b2187cc74c4bd674ba2c22c199d823",
|
|
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.
|
|
75
|
+
"@douyinfe/semi-scss-compile": "2.19.0-alpha.1",
|
|
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
|
|
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
|
-
<
|
|
243
|
+
<RadioWithControlled />
|
|
244
244
|
<br />
|
|
245
245
|
联动
|
|
246
246
|
<RadioGroup1 />
|
package/radio/radio.tsx
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import cls from 'classnames';
|
|
5
|
-
import { noop } from 'lodash';
|
|
5
|
+
import { noop, isUndefined, isBoolean } from 'lodash';
|
|
6
6
|
|
|
7
7
|
import RadioFoundation, { RadioAdapter } from '@douyinfe/semi-foundation/radio/radioFoundation';
|
|
8
8
|
import { RadioChangeEvent } from '@douyinfe/semi-foundation/radio/radioInnerFoundation';
|
|
@@ -52,6 +52,7 @@ export interface RadioState {
|
|
|
52
52
|
addonId?: string;
|
|
53
53
|
extraId?: string;
|
|
54
54
|
focusVisible?: boolean;
|
|
55
|
+
checked?: boolean;
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
export { RadioChangeEvent };
|
|
@@ -104,11 +105,22 @@ class Radio extends BaseComponent<RadioProps, RadioState> {
|
|
|
104
105
|
hover: false,
|
|
105
106
|
addonId: props.addonId,
|
|
106
107
|
extraId: props.extraId,
|
|
108
|
+
checked: props.checked || props.defaultChecked || false,
|
|
107
109
|
};
|
|
108
110
|
this.foundation = new RadioFoundation(this.adapter);
|
|
109
111
|
this.radioEntity = null;
|
|
110
112
|
}
|
|
111
113
|
|
|
114
|
+
componentDidUpdate(prevProps: RadioProps) {
|
|
115
|
+
if (this.props.checked !== prevProps.checked) {
|
|
116
|
+
if (isUndefined(this.props.checked)) {
|
|
117
|
+
this.foundation.setChecked(false);
|
|
118
|
+
} else if (isBoolean(this.props.checked)) {
|
|
119
|
+
this.foundation.setChecked(this.props.checked);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
112
124
|
get adapter(): RadioAdapter {
|
|
113
125
|
return {
|
|
114
126
|
...super.adapter,
|
|
@@ -118,6 +130,9 @@ class Radio extends BaseComponent<RadioProps, RadioState> {
|
|
|
118
130
|
setAddonId: () => {
|
|
119
131
|
this.setState({ addonId: getUuidShort({ prefix: 'addon' }) });
|
|
120
132
|
},
|
|
133
|
+
setChecked: (checked: boolean) => {
|
|
134
|
+
this.setState({ checked });
|
|
135
|
+
},
|
|
121
136
|
setExtraId: () => {
|
|
122
137
|
this.setState({ extraId: getUuidShort({ prefix: 'extra' }) });
|
|
123
138
|
},
|
|
@@ -146,6 +161,7 @@ class Radio extends BaseComponent<RadioProps, RadioState> {
|
|
|
146
161
|
const { radioGroup } = this.context;
|
|
147
162
|
radioGroup.onChange && radioGroup.onChange(e);
|
|
148
163
|
}
|
|
164
|
+
!('checked' in this.props) && this.foundation.setChecked(e.target.checked);
|
|
149
165
|
onChange && onChange(e);
|
|
150
166
|
};
|
|
151
167
|
|
|
@@ -171,7 +187,6 @@ class Radio extends BaseComponent<RadioProps, RadioState> {
|
|
|
171
187
|
const {
|
|
172
188
|
addonClassName,
|
|
173
189
|
addonStyle,
|
|
174
|
-
checked,
|
|
175
190
|
disabled,
|
|
176
191
|
style,
|
|
177
192
|
className,
|
|
@@ -194,8 +209,11 @@ class Radio extends BaseComponent<RadioProps, RadioState> {
|
|
|
194
209
|
isButtonRadioComponent,
|
|
195
210
|
buttonSize,
|
|
196
211
|
realPrefixCls;
|
|
197
|
-
const { hover: isHover, addonId, extraId, focusVisible } = this.state;
|
|
198
|
-
|
|
212
|
+
const { hover: isHover, addonId, extraId, focusVisible, checked, } = this.state;
|
|
213
|
+
const props: Record<string, any> = {
|
|
214
|
+
checked,
|
|
215
|
+
disabled,
|
|
216
|
+
};
|
|
199
217
|
|
|
200
218
|
if (this.isInGroup()) {
|
|
201
219
|
realChecked = this.context.radioGroup.value === propValue;
|
|
@@ -206,13 +224,17 @@ class Radio extends BaseComponent<RadioProps, RadioState> {
|
|
|
206
224
|
isPureCardRadioGroup = this.context.radioGroup.isPureCardRadio;
|
|
207
225
|
buttonSize = this.context.radioGroup.buttonSize;
|
|
208
226
|
realPrefixCls = prefixCls || this.context.radioGroup.prefixCls;
|
|
209
|
-
props =
|
|
227
|
+
props.checked = realChecked;
|
|
228
|
+
props.disabled = isDisabled;
|
|
210
229
|
} else {
|
|
211
230
|
realChecked = checked;
|
|
212
231
|
isDisabled = disabled;
|
|
213
232
|
realMode = mode;
|
|
214
233
|
isButtonRadioComponent = type === 'button';
|
|
215
234
|
realPrefixCls = prefixCls;
|
|
235
|
+
isButtonRadioGroup = type === strings.TYPE_BUTTON;
|
|
236
|
+
isPureCardRadioGroup = type === strings.TYPE_PURECARD;
|
|
237
|
+
isCardRadioGroup = type === strings.TYPE_CARD || isPureCardRadioGroup;
|
|
216
238
|
}
|
|
217
239
|
const isButtonRadio = typeof isButtonRadioGroup === 'undefined' ? isButtonRadioComponent : isButtonRadioGroup;
|
|
218
240
|
|
package/radio/radioGroup.tsx
CHANGED
|
@@ -177,6 +177,7 @@ class RadioGroup extends BaseComponent<RadioGroupProps, RadioGroupState> {
|
|
|
177
177
|
key={index}
|
|
178
178
|
disabled={this.props.disabled}
|
|
179
179
|
value={option}
|
|
180
|
+
type={type}
|
|
180
181
|
>
|
|
181
182
|
{option}
|
|
182
183
|
</Radio>
|
|
@@ -190,6 +191,7 @@ class RadioGroup extends BaseComponent<RadioGroupProps, RadioGroupState> {
|
|
|
190
191
|
extra={option.extra}
|
|
191
192
|
className={option.className}
|
|
192
193
|
style={option.style}
|
|
194
|
+
type={type}
|
|
193
195
|
>
|
|
194
196
|
{option.label}
|
|
195
197
|
</Radio>
|
|
@@ -85,7 +85,7 @@ describe('Rating', () => {
|
|
|
85
85
|
expect(spyOnChange.calledWithMatch(1)).toBe(true);
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
-
it('
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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('
|
|
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-
|
|
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-
|
|
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,
|
|
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,
|
|
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
|
|
1307
|
-
// TODO can't remove tag when option is
|
|
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
|
|
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 = () => <
|
|
1280
|
+
export const Controlled = () => <ControlledSelect></ControlledSelect>;
|
|
1281
1281
|
|
|
1282
1282
|
Controlled.story = {
|
|
1283
1283
|
name: 'controlled',
|
|
1284
1284
|
};
|
|
1285
1285
|
|
|
1286
|
-
const
|
|
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 {
|
|
1322
|
-
|
|
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
|
|
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
|
|
202
|
+
export const StepsWithControlled = () => {
|
|
203
203
|
return <StepsDemo></StepsDemo>;
|
|
204
204
|
};
|
|
205
205
|
|
|
206
|
-
|
|
207
|
-
name: 'steps with
|
|
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
|
|
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 = () => <
|
|
72
|
+
export const SwitchCheckedOnChange = () => <ControlledSwitch />;
|
|
73
73
|
|
|
74
74
|
SwitchCheckedOnChange.story = {
|
|
75
75
|
name: 'switch checked + onChange',
|
|
76
76
|
};
|
|
77
77
|
|
|
78
|
-
const
|
|
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 = () => <
|
|
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
|
|
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', () => <
|
|
66
|
+
stories.add('switch checked + onChange', () => <ControlledSwitch/>);
|
|
67
67
|
|
|
68
|
-
const
|
|
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', () => <
|
|
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
|
|
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
|
-
|
|
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
|
|
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;
|
|
@@ -195,7 +195,7 @@ TransferDraggableAndDisabled.story = {
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
|
|
198
|
-
const
|
|
198
|
+
const ControlledTransfer = () => {
|
|
199
199
|
const [value, setValue] = useState([2, 3]);
|
|
200
200
|
|
|
201
201
|
const handleChange = value => {
|
|
@@ -209,7 +209,7 @@ const ControledTransfer = () => {
|
|
|
209
209
|
);
|
|
210
210
|
};
|
|
211
211
|
|
|
212
|
-
export const ControlledTransfer = () => <
|
|
212
|
+
export const ControlledTransfer = () => <ControlledTransfer />;
|
|
213
213
|
|
|
214
214
|
ControlledTransfer.story = {
|
|
215
215
|
name: '受控Transfer',
|