@douyinfe/semi-ui 2.1.4 → 2.2.0-beta.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/_base/_story/a11y.jsx +1302 -0
- package/_base/_story/a11y.scss +49 -0
- package/_base/_story/index.stories.js +3 -1
- package/_utils/index.ts +9 -4
- package/button/Button.tsx +1 -0
- package/cascader/__test__/cascader.test.js +221 -0
- package/cascader/_story/cascader.stories.js +138 -0
- package/cascader/index.tsx +37 -21
- package/cascader/item.tsx +4 -2
- package/checkbox/checkbox.tsx +2 -0
- package/checkbox/checkboxGroup.tsx +3 -2
- package/datePicker/__test__/datePicker.test.js +85 -2
- package/datePicker/_story/datePicker.stories.js +29 -1
- package/datePicker/_story/v2/YearButton.jsx +17 -0
- package/datePicker/_story/v2/index.js +1 -0
- package/datePicker/monthsGrid.tsx +12 -1
- package/datePicker/navigation.tsx +55 -29
- package/descriptions/__test__/descriptions.test.js +27 -1
- package/descriptions/_story/descriptions.stories.js +52 -2
- package/descriptions/item.tsx +1 -1
- package/dist/css/semi.css +56 -32
- package/dist/css/semi.min.css +1 -1
- package/dist/umd/semi-ui.js +854 -258
- 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/empty/index.tsx +2 -2
- package/form/_story/form.stories.js +0 -67
- package/form/hoc/withField.tsx +1 -1
- package/gulpfile.js +2 -1
- package/lib/cjs/_base/base.css +2 -2
- package/lib/cjs/_utils/index.d.ts +1 -0
- package/lib/cjs/_utils/index.js +12 -5
- package/lib/cjs/button/Button.d.ts +1 -0
- package/lib/cjs/cascader/index.d.ts +7 -0
- package/lib/cjs/cascader/index.js +35 -22
- package/lib/cjs/cascader/item.d.ts +2 -0
- package/lib/cjs/cascader/item.js +4 -2
- package/lib/cjs/checkbox/checkbox.js +3 -1
- package/lib/cjs/checkbox/checkboxGroup.d.ts +1 -0
- package/lib/cjs/checkbox/checkboxGroup.js +3 -1
- package/lib/cjs/datePicker/monthsGrid.d.ts +1 -0
- package/lib/cjs/datePicker/monthsGrid.js +6 -0
- package/lib/cjs/datePicker/navigation.js +47 -7
- package/lib/cjs/descriptions/item.js +1 -1
- package/lib/cjs/empty/index.d.ts +2 -2
- package/lib/cjs/empty/index.js +19 -18
- package/lib/cjs/form/baseForm.d.ts +6 -0
- package/lib/cjs/form/field.d.ts +6 -0
- package/lib/cjs/form/hoc/withField.js +3 -1
- package/lib/cjs/locale/source/es.d.ts +7 -0
- package/lib/cjs/locale/source/es.js +168 -0
- package/lib/cjs/modal/Modal.d.ts +2 -2
- package/lib/cjs/modal/Modal.js +2 -2
- package/lib/cjs/modal/confirm.d.ts +10 -10
- package/lib/cjs/navigation/index.d.ts +2 -2
- package/lib/cjs/pagination/index.js +9 -4
- package/lib/cjs/rating/item.js +1 -1
- package/lib/cjs/select/index.d.ts +10 -0
- package/lib/cjs/select/index.js +15 -9
- package/lib/cjs/timeline/item.d.ts +5 -2
- package/lib/cjs/timeline/item.js +13 -7
- package/lib/cjs/tree/treeNode.js +0 -2
- package/lib/cjs/upload/fileCard.d.ts +2 -0
- package/lib/cjs/upload/fileCard.js +70 -45
- package/lib/cjs/upload/index.d.ts +23 -2
- package/lib/cjs/upload/index.js +133 -25
- package/lib/cjs/upload/interface.d.ts +3 -0
- package/lib/es/_base/base.css +2 -2
- package/lib/es/_utils/index.d.ts +1 -0
- package/lib/es/_utils/index.js +12 -5
- package/lib/es/button/Button.d.ts +1 -0
- package/lib/es/cascader/index.d.ts +7 -0
- package/lib/es/cascader/index.js +34 -25
- package/lib/es/cascader/item.d.ts +2 -0
- package/lib/es/cascader/item.js +4 -2
- package/lib/es/checkbox/checkbox.js +3 -1
- package/lib/es/checkbox/checkboxGroup.d.ts +1 -0
- package/lib/es/checkbox/checkboxGroup.js +3 -1
- package/lib/es/datePicker/monthsGrid.d.ts +1 -0
- package/lib/es/datePicker/monthsGrid.js +6 -0
- package/lib/es/datePicker/navigation.js +48 -8
- package/lib/es/descriptions/item.js +1 -1
- package/lib/es/empty/index.d.ts +2 -2
- package/lib/es/empty/index.js +19 -18
- package/lib/es/form/baseForm.d.ts +6 -0
- package/lib/es/form/field.d.ts +6 -0
- package/lib/es/form/hoc/withField.js +3 -1
- package/lib/es/locale/source/es.d.ts +7 -0
- package/lib/es/locale/source/es.js +157 -0
- package/lib/es/modal/Modal.d.ts +2 -2
- package/lib/es/modal/Modal.js +2 -2
- package/lib/es/modal/confirm.d.ts +10 -10
- package/lib/es/navigation/index.d.ts +2 -2
- package/lib/es/pagination/index.js +8 -4
- package/lib/es/rating/item.js +1 -1
- package/lib/es/select/index.d.ts +10 -0
- package/lib/es/select/index.js +19 -9
- package/lib/es/timeline/item.d.ts +5 -2
- package/lib/es/timeline/item.js +12 -7
- package/lib/es/tree/treeNode.js +0 -2
- package/lib/es/upload/fileCard.d.ts +2 -0
- package/lib/es/upload/fileCard.js +69 -44
- package/lib/es/upload/index.d.ts +23 -2
- package/lib/es/upload/index.js +133 -24
- package/lib/es/upload/interface.d.ts +3 -0
- package/locale/source/es.ts +160 -0
- package/modal/Modal.tsx +4 -4
- package/navigation/__test__/navigation.test.js +4 -4
- package/navigation/_story/AutoOpen/index.js +1 -1
- package/navigation/_story/WithChildren/index.js +1 -1
- package/navigation/_story/navigation.stories.js +1 -1
- package/navigation/_story/navigation.stories.tsx +4 -4
- package/navigation/index.tsx +2 -2
- package/package.json +17 -9
- package/pagination/_story/pagination.stories.js +11 -0
- package/pagination/index.tsx +9 -4
- package/popover/Arrow.tsx +1 -1
- package/radio/_story/radio.stories.js +12 -1
- package/rating/item.tsx +1 -1
- package/select/_story/select.stories.js +39 -14
- package/select/index.tsx +21 -7
- package/table/_story/DynamicFilters/index.js +13 -16
- package/timeline/__test__/timeline.test.js +17 -1
- package/timeline/_story/timeline.stories.js +70 -6
- package/timeline/item.tsx +11 -6
- package/tooltip/_story/tooltip.stories.js +1 -1
- package/tree/_story/tree.stories.js +2 -2
- package/tree/treeNode.tsx +0 -2
- package/upload/__test__/upload.test.js +50 -1
- package/upload/fileCard.tsx +110 -95
- package/upload/index.tsx +147 -53
- package/upload/interface.ts +3 -0
|
@@ -81,8 +81,21 @@ export const Mode = () => (
|
|
|
81
81
|
}}
|
|
82
82
|
>
|
|
83
83
|
<Timeline mode="alternate">
|
|
84
|
-
<Timeline.Item time="2015-09-01">创建服务现场</Timeline.Item>
|
|
85
|
-
<Timeline.Item time="2015-09-01">初步排除网络异常</Timeline.Item>
|
|
84
|
+
<Timeline.Item time="2015-09-01" dot={<IconAlertTriangle />}>创建服务现场</Timeline.Item>
|
|
85
|
+
<Timeline.Item time="2015-09-01" dot={<IconAlertTriangle />}>初步排除网络异常</Timeline.Item>
|
|
86
|
+
<Timeline.Item time="2015-09-01" dot={<IconAlertTriangle />}>技术测试异常</Timeline.Item>
|
|
87
|
+
<Timeline.Item time="2015-09-01" dot={<IconAlertTriangle />}>网络异常正在修复</Timeline.Item>
|
|
88
|
+
</Timeline>
|
|
89
|
+
</div>
|
|
90
|
+
<br />
|
|
91
|
+
<div
|
|
92
|
+
style={{
|
|
93
|
+
width: '300px',
|
|
94
|
+
}}
|
|
95
|
+
>
|
|
96
|
+
<Timeline mode="right">
|
|
97
|
+
<Timeline.Item time="2015-09-01" dot={<IconAlertTriangle />}>创建服务现场</Timeline.Item>
|
|
98
|
+
<Timeline.Item time="2015-09-01" dot={<IconAlertTriangle />}>初步排除网络异常</Timeline.Item>
|
|
86
99
|
<Timeline.Item time="2015-09-01">技术测试异常</Timeline.Item>
|
|
87
100
|
<Timeline.Item time="2015-09-01">网络异常正在修复</Timeline.Item>
|
|
88
101
|
</Timeline>
|
|
@@ -93,9 +106,9 @@ export const Mode = () => (
|
|
|
93
106
|
width: '300px',
|
|
94
107
|
}}
|
|
95
108
|
>
|
|
96
|
-
<Timeline mode="
|
|
97
|
-
<Timeline.Item time="2015-09-01">创建服务现场</Timeline.Item>
|
|
98
|
-
<Timeline.Item time="2015-09-01">初步排除网络异常</Timeline.Item>
|
|
109
|
+
<Timeline mode="left">
|
|
110
|
+
<Timeline.Item time="2015-09-01" dot={<IconAlertTriangle />}>创建服务现场</Timeline.Item>
|
|
111
|
+
<Timeline.Item time="2015-09-01" dot={<IconAlertTriangle />}>初步排除网络异常</Timeline.Item>
|
|
99
112
|
<Timeline.Item time="2015-09-01">技术测试异常</Timeline.Item>
|
|
100
113
|
<Timeline.Item time="2015-09-01">网络异常正在修复</Timeline.Item>
|
|
101
114
|
</Timeline>
|
|
@@ -108,7 +121,7 @@ export const Mode = () => (
|
|
|
108
121
|
>
|
|
109
122
|
<Timeline mode="center">
|
|
110
123
|
<Timeline.Item time="2015-09-01">创建服务现场</Timeline.Item>
|
|
111
|
-
<Timeline.Item time="2015-09-01">初步排除网络异常</Timeline.Item>
|
|
124
|
+
<Timeline.Item time="2015-09-01" dot={<IconAlertTriangle />}>初步排除网络异常</Timeline.Item>
|
|
112
125
|
<Timeline.Item time="2015-09-01">技术测试异常</Timeline.Item>
|
|
113
126
|
<Timeline.Item time="2015-09-01">网络异常正在修复</Timeline.Item>
|
|
114
127
|
</Timeline>
|
|
@@ -152,6 +165,7 @@ const data = [
|
|
|
152
165
|
time: '2019-05-09 09:12',
|
|
153
166
|
extra: '节点辅助说明信息',
|
|
154
167
|
content: '网络异常正在修复',
|
|
168
|
+
dot: <IconAlertTriangle />,
|
|
155
169
|
type: 'success',
|
|
156
170
|
},
|
|
157
171
|
];
|
|
@@ -169,3 +183,53 @@ export const DataSource = () => (
|
|
|
169
183
|
DataSource.story = {
|
|
170
184
|
name: 'dataSource',
|
|
171
185
|
};
|
|
186
|
+
|
|
187
|
+
const dataWithOnClick = [
|
|
188
|
+
{
|
|
189
|
+
time: '2019-07-14 10:35',
|
|
190
|
+
extra: '节点辅助说明信息',
|
|
191
|
+
content: '创建服务现场',
|
|
192
|
+
type: 'ongoing',
|
|
193
|
+
onClick: e => console.log(e, '创建服务现场'),
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
time: '2019-06-13 16:17',
|
|
197
|
+
extra: '节点辅助说明信息',
|
|
198
|
+
content: <span style={{ fontSize: '18px' }}>初步排除网络异常</span>,
|
|
199
|
+
color: 'pink',
|
|
200
|
+
onClick: e => console.log(e, '初步排除网络异常'),
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
time: '2019-05-14 18:34',
|
|
204
|
+
extra: '节点辅助说明信息',
|
|
205
|
+
dot: <Icon type="alert_triangle" />,
|
|
206
|
+
content: '技术测试异常',
|
|
207
|
+
type: 'warning',
|
|
208
|
+
onClick: e => console.log(e, '技术测试异常'),
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
time: '2019-05-09 09:12',
|
|
212
|
+
extra: '节点辅助说明信息',
|
|
213
|
+
content: '网络异常正在修复',
|
|
214
|
+
type: 'success',
|
|
215
|
+
onClick: e => console.log(e, '网络异常正在修复'),
|
|
216
|
+
}
|
|
217
|
+
];
|
|
218
|
+
|
|
219
|
+
export const OnClickDemo = () => (
|
|
220
|
+
<div style={{ width: '400px' }}>
|
|
221
|
+
<div style={{ width: '300px' }}>
|
|
222
|
+
<Timeline mode='center'>
|
|
223
|
+
<Timeline.Item time='2015-09-01' onClick={e=>console.log(e, '创建服务现场')}>创建服务现场</Timeline.Item>
|
|
224
|
+
<Timeline.Item time='2015-09-01' onClick={e=>console.log(e, '初步排除网络异常')}>初步排除网络异常</Timeline.Item>
|
|
225
|
+
<Timeline.Item time='2015-09-01' onClick={e=>console.log(e, '技术测试异常')}>技术测试异常</Timeline.Item>
|
|
226
|
+
<Timeline.Item time='2015-09-01' onClick={e=>console.log(e, '网络异常正在修复')}>网络异常正在修复</Timeline.Item>
|
|
227
|
+
</Timeline>
|
|
228
|
+
<Timeline mode='alternate' dataSource={dataWithOnClick} />
|
|
229
|
+
</div>
|
|
230
|
+
</div>
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
OnClickDemo.story = {
|
|
234
|
+
name: 'onClick',
|
|
235
|
+
};
|
package/timeline/item.tsx
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import React, { PureComponent } from 'react';
|
|
2
2
|
import cls from 'classnames';
|
|
3
|
+
import { noop } from 'lodash';
|
|
3
4
|
import PropTypes from 'prop-types';
|
|
4
5
|
import { cssClasses, strings } from '@douyinfe/semi-foundation/timeline/constants';
|
|
5
6
|
import '@douyinfe/semi-foundation/timeline/timeline.scss';
|
|
6
7
|
|
|
7
8
|
export interface TimelineItemProps {
|
|
8
9
|
color?: string;
|
|
9
|
-
time?:
|
|
10
|
+
time?: React.ReactNode;
|
|
10
11
|
type?: 'default' | 'ongoing' | 'success' | 'warning' | 'error';
|
|
11
12
|
dot?: React.ReactNode;
|
|
12
13
|
extra?: React.ReactNode;
|
|
13
14
|
position?: 'left' | 'right';
|
|
14
15
|
className?: string;
|
|
15
16
|
style?: React.CSSProperties;
|
|
17
|
+
onClick?: React.MouseEventHandler<HTMLLIElement>;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
const prefixCls = cssClasses.ITEM;
|
|
@@ -20,18 +22,20 @@ const prefixCls = cssClasses.ITEM;
|
|
|
20
22
|
export default class Item extends PureComponent<TimelineItemProps> {
|
|
21
23
|
static propTypes = {
|
|
22
24
|
color: PropTypes.string,
|
|
23
|
-
time: PropTypes.
|
|
25
|
+
time: PropTypes.node,
|
|
24
26
|
type: PropTypes.oneOf(strings.ITEM_TYPE),
|
|
25
27
|
dot: PropTypes.node,
|
|
26
28
|
extra: PropTypes.node,
|
|
27
29
|
position: PropTypes.oneOf(strings.ITEM_POS),
|
|
28
30
|
className: PropTypes.string,
|
|
29
31
|
style: PropTypes.object,
|
|
32
|
+
onClick: PropTypes.func,
|
|
30
33
|
};
|
|
31
34
|
|
|
32
35
|
static defaultProps = {
|
|
33
36
|
type: 'default',
|
|
34
37
|
time: '',
|
|
38
|
+
onClick: noop,
|
|
35
39
|
};
|
|
36
40
|
|
|
37
41
|
render() {
|
|
@@ -43,7 +47,8 @@ export default class Item extends PureComponent<TimelineItemProps> {
|
|
|
43
47
|
type,
|
|
44
48
|
style,
|
|
45
49
|
time,
|
|
46
|
-
extra
|
|
50
|
+
extra,
|
|
51
|
+
onClick,
|
|
47
52
|
} = this.props;
|
|
48
53
|
|
|
49
54
|
const itemCls = cls(prefixCls,
|
|
@@ -57,7 +62,7 @@ export default class Item extends PureComponent<TimelineItemProps> {
|
|
|
57
62
|
});
|
|
58
63
|
const dotStyle = color ? { style: { backgroundColor: color } } : null;
|
|
59
64
|
return (
|
|
60
|
-
<li className={itemCls} style={style}>
|
|
65
|
+
<li className={itemCls} style={style} onClick={onClick}>
|
|
61
66
|
<div className={`${prefixCls}-tail`} />
|
|
62
67
|
<div
|
|
63
68
|
className={dotCls}
|
|
@@ -67,8 +72,8 @@ export default class Item extends PureComponent<TimelineItemProps> {
|
|
|
67
72
|
</div>
|
|
68
73
|
<div className={`${prefixCls}-content`}>
|
|
69
74
|
{children}
|
|
70
|
-
{extra
|
|
71
|
-
<div className={`${prefixCls}-content-time`}>{time}</div>
|
|
75
|
+
{extra && <div className={`${prefixCls}-content-extra`}>{extra}</div>}
|
|
76
|
+
{time && <div className={`${prefixCls}-content-time`}>{time}</div>}
|
|
72
77
|
</div>
|
|
73
78
|
</li>
|
|
74
79
|
);
|
|
@@ -652,7 +652,7 @@ export const ShowArrow = () => {
|
|
|
652
652
|
return (
|
|
653
653
|
<div>
|
|
654
654
|
<h4>should show content and arrow when click</h4>
|
|
655
|
-
<Tooltip showArrow trigger=
|
|
655
|
+
<Tooltip style={{ maxWidth: 320 }} showArrow trigger='custom' visible content={'hi semi semi semi semi semi semi semi'} position='right'>
|
|
656
656
|
<Test />
|
|
657
657
|
</Tooltip>
|
|
658
658
|
</div>
|
|
@@ -251,7 +251,7 @@ export const SimpleTree = () => (
|
|
|
251
251
|
// onExpand={(e, { expanded, node }) => console.log('expand', e, expanded, node)}
|
|
252
252
|
// onSelect={(e, bool, node) => console.log('select', e, bool, node)}
|
|
253
253
|
// onChange={e => console.log('change', e)}
|
|
254
|
-
|
|
254
|
+
onContextMenu={(e, node) => console.log(e.currentTarget, node)}
|
|
255
255
|
onDoubleClick={(e, node) => console.log(e, node)}
|
|
256
256
|
motion={true}
|
|
257
257
|
/>
|
|
@@ -268,7 +268,7 @@ export const MultipleTree = () => (
|
|
|
268
268
|
labelInValue
|
|
269
269
|
// onExpand={(e, { expanded, node }) => console.log('expand', e, expanded, node)}
|
|
270
270
|
// onSelect={(e, bool) => console.log('select', e, bool)}
|
|
271
|
-
|
|
271
|
+
onContextMenu={(e, node) => console.log(e, node)}
|
|
272
272
|
onDoubleClick={(e, node) => console.log(e, node)}
|
|
273
273
|
onChange={e => console.log('change', e)}
|
|
274
274
|
/>
|
package/tree/treeNode.tsx
CHANGED
|
@@ -75,8 +75,6 @@ export default class TreeNode extends PureComponent<TreeNodeProps, TreeNodeState
|
|
|
75
75
|
|
|
76
76
|
onContextMenu = (e: React.MouseEvent) => {
|
|
77
77
|
const { onNodeRightClick } = this.context;
|
|
78
|
-
e.stopPropagation();
|
|
79
|
-
e.nativeEvent.stopImmediatePropagation();
|
|
80
78
|
onNodeRightClick(e, this.props);
|
|
81
79
|
};
|
|
82
80
|
|
|
@@ -869,7 +869,7 @@ describe('Upload', () => {
|
|
|
869
869
|
beforeClear: () => Promise.reject(),
|
|
870
870
|
onChange: spyOnChangeReject,
|
|
871
871
|
onClear: spyOnClearReject,
|
|
872
|
-
})
|
|
872
|
+
});
|
|
873
873
|
|
|
874
874
|
const clearBtn = upload.find(`.${BASE_CLASS_PREFIX}-upload-file-list-title-clear`).at(0);
|
|
875
875
|
const clearBtnPass = uploadPass.find(`.${BASE_CLASS_PREFIX}-upload-file-list-title-clear`).at(0);
|
|
@@ -893,4 +893,53 @@ describe('Upload', () => {
|
|
|
893
893
|
expect(spyOnClearReject.callCount).toEqual(0);
|
|
894
894
|
});
|
|
895
895
|
});
|
|
896
|
+
|
|
897
|
+
it('insert method', () => {
|
|
898
|
+
const props = {
|
|
899
|
+
defaultFileList: [],
|
|
900
|
+
};
|
|
901
|
+
const upload = getUpload(props);
|
|
902
|
+
const uploadInstance = upload.instance();
|
|
903
|
+
|
|
904
|
+
const file_0 = new File([new ArrayBuffer(1024)], 'chucknorris_0.png', { type: 'image/png' });
|
|
905
|
+
const file_1 = new File([new ArrayBuffer(1024)], 'chucknorris_1.png', { type: 'image/png' });
|
|
906
|
+
const file_2 = new File([new ArrayBuffer(1024)], 'chucknorris_2.png', { type: 'image/png' });
|
|
907
|
+
|
|
908
|
+
expect(uploadInstance instanceof Upload).toEqual(true);
|
|
909
|
+
expect(Object.prototype.hasOwnProperty.call(uploadInstance, 'insert')).toEqual(true);
|
|
910
|
+
|
|
911
|
+
/**
|
|
912
|
+
* test fileList state should be [] => [file_0] => [file_1, file_0] => [file_1, file_2, file_0]
|
|
913
|
+
*/
|
|
914
|
+
upload.instance().insert([file_0]);
|
|
915
|
+
upload.instance().insert([file_1], 0);
|
|
916
|
+
upload.instance().insert([file_2], 1);
|
|
917
|
+
|
|
918
|
+
expect(Array.isArray(upload.state('fileList'))).toEqual(true);
|
|
919
|
+
expect(upload.state('fileList').length).toEqual(3);
|
|
920
|
+
expect(upload.state('fileList')[0].name).toEqual('chucknorris_1.png');
|
|
921
|
+
expect(upload.state('fileList')[1].name).toEqual('chucknorris_2.png');
|
|
922
|
+
expect(upload.state('fileList')[2].name).toEqual('chucknorris_0.png');
|
|
923
|
+
});
|
|
924
|
+
|
|
925
|
+
it('showPicInfo works', () => {
|
|
926
|
+
const props = {
|
|
927
|
+
listType: 'picture',
|
|
928
|
+
defaultFileList: [
|
|
929
|
+
{
|
|
930
|
+
uid: '1',
|
|
931
|
+
name: 'jiafang1.jpeg',
|
|
932
|
+
status: 'success',
|
|
933
|
+
size: '130kb',
|
|
934
|
+
url: 'https://sf6-cdn-tos.douyinstatic.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/bf8647bffab13c38772c9ff94bf91a9d.jpg',
|
|
935
|
+
},
|
|
936
|
+
],
|
|
937
|
+
showPicInfo: true,
|
|
938
|
+
};
|
|
939
|
+
const upload = getUpload(props);
|
|
940
|
+
|
|
941
|
+
expect(upload.exists(`.${BASE_CLASS_PREFIX}-upload`)).toEqual(true);
|
|
942
|
+
expect(upload.exists(`.${BASE_CLASS_PREFIX}-upload-file-list-main`)).toEqual(true);
|
|
943
|
+
expect(upload.exists(`.${BASE_CLASS_PREFIX}-upload-picture-file-card-pic-info`)).toEqual(true);
|
|
944
|
+
});
|
|
896
945
|
});
|
package/upload/fileCard.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import cls from 'classnames';
|
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import { cssClasses, strings } from '@douyinfe/semi-foundation/upload/constants';
|
|
5
5
|
import { getFileSize } from '@douyinfe/semi-foundation/upload/utils';
|
|
6
|
-
import {
|
|
6
|
+
import { IconAlertCircle, IconClose, IconFile, IconRefresh } from '@douyinfe/semi-icons';
|
|
7
7
|
import LocaleConsumer from '../locale/localeConsumer';
|
|
8
8
|
import { Locale } from '../locale/interface';
|
|
9
9
|
|
|
@@ -13,7 +13,6 @@ import Tooltip from '../tooltip/index';
|
|
|
13
13
|
import Spin from '../spin/index';
|
|
14
14
|
import { isElement } from '../_base/reactUtils';
|
|
15
15
|
import { RenderFileItemProps } from './interface';
|
|
16
|
-
import { IconAlertCircle, IconClose, IconFile, IconRefresh } from '@douyinfe/semi-icons';
|
|
17
16
|
|
|
18
17
|
const prefixCls = cssClasses.PREFIX;
|
|
19
18
|
|
|
@@ -69,6 +68,7 @@ class FileCard extends PureComponent<FileCardProps> {
|
|
|
69
68
|
style: PropTypes.object,
|
|
70
69
|
url: PropTypes.string,
|
|
71
70
|
validateMessage: PropTypes.node,
|
|
71
|
+
index: PropTypes.number
|
|
72
72
|
};
|
|
73
73
|
|
|
74
74
|
static defaultProps = {
|
|
@@ -92,10 +92,10 @@ class FileCard extends PureComponent<FileCardProps> {
|
|
|
92
92
|
let content = null;
|
|
93
93
|
switch (true) {
|
|
94
94
|
case typeof validateMessage === 'string' && status === strings.FILE_STATUS_VALIDATING:
|
|
95
|
-
content = (<><Spin size="small" wrapperClassName={`${prefixCls
|
|
95
|
+
content = (<><Spin size="small" wrapperClassName={`${prefixCls}-file-card-icon-loading`} />{validateMessage}</>);
|
|
96
96
|
break;
|
|
97
97
|
case typeof validateMessage === 'string':
|
|
98
|
-
content = (<><IconAlertCircle className={`${prefixCls
|
|
98
|
+
content = (<><IconAlertCircle className={`${prefixCls}-file-card-icon-error`} />{validateMessage}</>);
|
|
99
99
|
break;
|
|
100
100
|
case isElement(validateMessage):
|
|
101
101
|
content = validateMessage;
|
|
@@ -111,10 +111,10 @@ class FileCard extends PureComponent<FileCardProps> {
|
|
|
111
111
|
let icon = null;
|
|
112
112
|
switch (true) {
|
|
113
113
|
case validateMessage && status === strings.FILE_STATUS_VALIDATING:
|
|
114
|
-
icon = (<Spin size="small" wrapperClassName={`${prefixCls
|
|
114
|
+
icon = (<Spin size="small" wrapperClassName={`${prefixCls}-picture-file-card-icon-loading`} />);
|
|
115
115
|
break;
|
|
116
116
|
case validateMessage && (status === strings.FILE_STATUS_VALID_FAIL || status === strings.FILE_STATUS_UPLOAD_FAIL):
|
|
117
|
-
icon = (<div className={`${prefixCls
|
|
117
|
+
icon = (<div className={`${prefixCls}-picture-file-card-icon-error`}><ErrorSvg /></div>);
|
|
118
118
|
break;
|
|
119
119
|
default:
|
|
120
120
|
break;
|
|
@@ -123,41 +123,50 @@ class FileCard extends PureComponent<FileCardProps> {
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
renderPic(locale: Locale['Upload']): ReactNode {
|
|
126
|
-
const { url, percent, status, disabled, style, onPreviewClick } = this.props;
|
|
127
|
-
const filePicCardCls = cls({
|
|
128
|
-
[`${prefixCls }-picture-file-card`]: true,
|
|
129
|
-
[`${prefixCls }-picture-file-card-disabled`]: disabled,
|
|
130
|
-
[`${prefixCls }-picture-file-card-show-pointer`]: typeof onPreviewClick !== 'undefined',
|
|
131
|
-
});
|
|
126
|
+
const { url, percent, status, disabled, style, onPreviewClick, showPicInfo, renderPicInfo, renderThumbnail, name, index } = this.props;
|
|
132
127
|
const showProgress = status === strings.FILE_STATUS_UPLOADING && percent !== 100;
|
|
133
128
|
const showRetry = status === strings.FILE_STATUS_UPLOAD_FAIL && this.props.showRetry;
|
|
134
129
|
const showReplace = status === strings.FILE_STATUS_SUCCESS && this.props.showReplace;
|
|
135
|
-
const
|
|
130
|
+
const filePicCardCls = cls({
|
|
131
|
+
[`${prefixCls}-picture-file-card`]: true,
|
|
132
|
+
[`${prefixCls}-picture-file-card-disabled`]: disabled,
|
|
133
|
+
[`${prefixCls}-picture-file-card-show-pointer`]: typeof onPreviewClick !== 'undefined',
|
|
134
|
+
[`${prefixCls}-picture-file-card-error`]: status === strings.FILE_STATUS_UPLOAD_FAIL,
|
|
135
|
+
[`${prefixCls}-picture-file-card-uploading`]: showProgress
|
|
136
|
+
});
|
|
137
|
+
const closeCls = `${prefixCls}-picture-file-card-close`;
|
|
136
138
|
const retry = (
|
|
137
139
|
<div
|
|
138
|
-
className={`${prefixCls
|
|
139
|
-
<IconRefresh className={`${prefixCls
|
|
140
|
+
className={`${prefixCls}-picture-file-card-retry`} onClick={e => this.onRetry(e)}>
|
|
141
|
+
<IconRefresh className={`${prefixCls}-picture-file-card-icon-retry`} />
|
|
140
142
|
</div>
|
|
141
143
|
);
|
|
142
144
|
const replace = (
|
|
143
145
|
<Tooltip trigger="hover" position="top" content={locale.replace} showArrow={false} spacing={4}>
|
|
144
146
|
<div
|
|
145
|
-
className={`${prefixCls
|
|
146
|
-
<ReplaceSvg className={`${prefixCls
|
|
147
|
+
className={`${prefixCls}-picture-file-card-replace`} onClick={(e): void => this.onReplace(e)}>
|
|
148
|
+
<ReplaceSvg className={`${prefixCls}-picture-file-card-icon-replace`} />
|
|
147
149
|
</div>
|
|
148
150
|
</Tooltip>
|
|
149
151
|
|
|
150
152
|
);
|
|
151
153
|
|
|
154
|
+
const picInfo = typeof renderPicInfo === 'function' ? renderPicInfo(this.props) : (
|
|
155
|
+
<div className={`${prefixCls }-picture-file-card-pic-info`}>{index + 1}</div>
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
const thumbnail = typeof renderThumbnail === 'function' ? renderThumbnail(this.props) : <img src={url} alt={`picture of ${name}`} />;
|
|
159
|
+
|
|
152
160
|
return (
|
|
153
161
|
<div className={filePicCardCls} style={style} onClick={onPreviewClick}>
|
|
154
|
-
|
|
162
|
+
{thumbnail}
|
|
155
163
|
{showProgress ? <Progress percent={percent} type="circle" size="small" orbitStroke={'#FFF'} /> : null}
|
|
156
164
|
{showRetry ? retry : null}
|
|
157
165
|
{showReplace && replace}
|
|
158
|
-
{
|
|
159
|
-
|
|
160
|
-
|
|
166
|
+
{showPicInfo && picInfo}
|
|
167
|
+
{!disabled && (
|
|
168
|
+
<div className={closeCls}>
|
|
169
|
+
<IconClose size="extra-small" onClick={e => this.onRemove(e)} />
|
|
161
170
|
</div>
|
|
162
171
|
)}
|
|
163
172
|
{this.renderPicValidateMsg()}
|
|
@@ -165,6 +174,77 @@ class FileCard extends PureComponent<FileCardProps> {
|
|
|
165
174
|
);
|
|
166
175
|
}
|
|
167
176
|
|
|
177
|
+
renderFile(locale: Locale["Upload"]) {
|
|
178
|
+
const { name, size, percent, url, showRetry: propsShowRetry, showReplace: propsShowReplace, preview, previewFile, status, style, onPreviewClick } = this.props;
|
|
179
|
+
const fileCardCls = cls({
|
|
180
|
+
[`${prefixCls}-file-card`]: true,
|
|
181
|
+
[`${prefixCls}-file-card-fail`]: status === strings.FILE_STATUS_VALID_FAIL || status === strings.FILE_STATUS_UPLOAD_FAIL,
|
|
182
|
+
[`${prefixCls}-file-card-show-pointer`]: typeof onPreviewClick !== 'undefined',
|
|
183
|
+
});
|
|
184
|
+
const previewCls = cls({
|
|
185
|
+
[`${prefixCls}-file-card-preview`]: true,
|
|
186
|
+
[`${prefixCls}-file-card-preview-placeholder`]: !preview || previewFile
|
|
187
|
+
});
|
|
188
|
+
const infoCls = `${prefixCls}-file-card-info`;
|
|
189
|
+
const closeCls = `${prefixCls}-file-card-close`;
|
|
190
|
+
const replaceCls = `${prefixCls}-file-card-replace`;
|
|
191
|
+
const showProgress = !(percent === 100 || typeof percent === 'undefined') && status === strings.FILE_STATUS_UPLOADING;
|
|
192
|
+
// only show retry when upload fail & showRetry is true, no need to show during validate fail
|
|
193
|
+
const showRetry = status === strings.FILE_STATUS_UPLOAD_FAIL && propsShowRetry;
|
|
194
|
+
const showReplace = status === strings.FILE_STATUS_SUCCESS && propsShowReplace;
|
|
195
|
+
const fileSize = this.transSize(size);
|
|
196
|
+
let previewContent: ReactNode = preview ? (<img src={url} />) : (<IconFile size="large" />);
|
|
197
|
+
if (previewFile) {
|
|
198
|
+
previewContent = previewFile(this.props);
|
|
199
|
+
}
|
|
200
|
+
return (
|
|
201
|
+
<div className={fileCardCls} style={style} onClick={onPreviewClick}>
|
|
202
|
+
<div className={previewCls}>
|
|
203
|
+
{previewContent}
|
|
204
|
+
</div>
|
|
205
|
+
<div className={`${infoCls}-main`}>
|
|
206
|
+
<div className={`${infoCls}-main-text`}>
|
|
207
|
+
<span className={`${infoCls}-name`}>
|
|
208
|
+
{name}
|
|
209
|
+
</span>
|
|
210
|
+
<span>
|
|
211
|
+
<span className={`${infoCls}-size`}>{fileSize}</span>
|
|
212
|
+
{showReplace && (
|
|
213
|
+
<Tooltip trigger="hover" position="top" showArrow={false} content={locale.replace}>
|
|
214
|
+
<IconButton
|
|
215
|
+
onClick={e => this.onReplace(e)}
|
|
216
|
+
type="tertiary"
|
|
217
|
+
theme="borderless"
|
|
218
|
+
size="small"
|
|
219
|
+
icon={<DirectorySvg />}
|
|
220
|
+
className={replaceCls}
|
|
221
|
+
/>
|
|
222
|
+
</Tooltip>
|
|
223
|
+
)}
|
|
224
|
+
|
|
225
|
+
</span>
|
|
226
|
+
|
|
227
|
+
</div>
|
|
228
|
+
{showProgress ? (<Progress percent={percent} style={{ width: '100%' }} />) : null}
|
|
229
|
+
<div className={`${infoCls}-main-control`}>
|
|
230
|
+
<span className={`${infoCls}-validate-message`}>
|
|
231
|
+
{this.renderValidateMessage()}
|
|
232
|
+
</span>
|
|
233
|
+
{showRetry ? <span className={`${infoCls}-retry`} onClick={e => this.onRetry(e)}>{locale.retry}</span> : null}
|
|
234
|
+
</div>
|
|
235
|
+
</div>
|
|
236
|
+
<IconButton
|
|
237
|
+
onClick={e => this.onRemove(e)}
|
|
238
|
+
type="tertiary"
|
|
239
|
+
icon={<IconClose />}
|
|
240
|
+
theme="borderless"
|
|
241
|
+
size="small"
|
|
242
|
+
className={closeCls}
|
|
243
|
+
/>
|
|
244
|
+
</div>
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
|
|
168
248
|
onRemove(e: MouseEvent): void {
|
|
169
249
|
e.stopPropagation();
|
|
170
250
|
this.props.onRemove(this.props, e);
|
|
@@ -181,89 +261,24 @@ class FileCard extends PureComponent<FileCardProps> {
|
|
|
181
261
|
}
|
|
182
262
|
|
|
183
263
|
render() {
|
|
184
|
-
const {
|
|
185
|
-
const fileCardCls = cls({
|
|
186
|
-
[`${prefixCls}-file-card`]: true,
|
|
187
|
-
[`${prefixCls}-file-card-fail`]: status === strings.FILE_STATUS_VALID_FAIL || status === strings.FILE_STATUS_UPLOAD_FAIL,
|
|
188
|
-
[`${prefixCls}-file-card-show-pointer`]: typeof onPreviewClick !== 'undefined',
|
|
189
|
-
});
|
|
190
|
-
const previewCls = cls({
|
|
191
|
-
[`${prefixCls}-file-card-preview`]: true,
|
|
192
|
-
[`${prefixCls}-file-card-preview-placeholder`]: !preview || previewFile
|
|
193
|
-
});
|
|
194
|
-
const infoCls = `${prefixCls}-file-card-info`;
|
|
195
|
-
const closeCls = `${prefixCls}-file-card-close`;
|
|
196
|
-
const replaceCls = `${prefixCls}-file-card-replace`;
|
|
197
|
-
const showProgress = !(percent === 100 || typeof percent === 'undefined') && status === strings.FILE_STATUS_UPLOADING;
|
|
198
|
-
// only show retry when upload fail & showRetry is true, no need to show during validate fail
|
|
199
|
-
const showRetry = status === strings.FILE_STATUS_UPLOAD_FAIL && this.props.showRetry;
|
|
200
|
-
const showReplace = status === strings.FILE_STATUS_SUCCESS && this.props.showReplace;
|
|
201
|
-
|
|
264
|
+
const { listType } = this.props;
|
|
202
265
|
if (listType === strings.FILE_LIST_PIC) {
|
|
203
266
|
return (
|
|
204
267
|
<LocaleConsumer componentName="Upload">
|
|
205
|
-
{(locale: Locale[
|
|
268
|
+
{(locale: Locale["Upload"]) => (this.renderPic(locale))}
|
|
206
269
|
</LocaleConsumer>
|
|
207
270
|
);
|
|
208
271
|
}
|
|
209
272
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
273
|
+
if (listType === strings.FILE_LIST_DEFAULT) {
|
|
274
|
+
return (
|
|
275
|
+
<LocaleConsumer componentName="Upload">
|
|
276
|
+
{(locale: Locale["Upload"]) => (this.renderFile(locale))}
|
|
277
|
+
</LocaleConsumer>
|
|
278
|
+
);
|
|
214
279
|
}
|
|
215
|
-
return (
|
|
216
|
-
<LocaleConsumer componentName="Upload">
|
|
217
|
-
{(locale: Locale['Upload']): ReactNode => (
|
|
218
|
-
<div className={fileCardCls} style={style} onClick={onPreviewClick}>
|
|
219
|
-
{/* <a target='_blank' href={url} className={infoCls} rel="noopener noreferrer"> */}
|
|
220
|
-
<div className={previewCls}>
|
|
221
|
-
{previewContent}
|
|
222
|
-
</div>
|
|
223
|
-
<div className={`${infoCls}-main`}>
|
|
224
|
-
<div className={`${infoCls}-main-text`}>
|
|
225
|
-
<span className={`${infoCls}-name`}>
|
|
226
|
-
{name}
|
|
227
|
-
</span>
|
|
228
|
-
<span>
|
|
229
|
-
<span className={`${infoCls}-size`}>{fileSize}</span>
|
|
230
|
-
{showReplace && (
|
|
231
|
-
<Tooltip trigger="hover" position="top" showArrow={false} content={locale.replace}>
|
|
232
|
-
<IconButton
|
|
233
|
-
onClick={(e): void => this.onReplace(e)}
|
|
234
|
-
type="tertiary"
|
|
235
|
-
theme="borderless"
|
|
236
|
-
size="small"
|
|
237
|
-
icon={<DirectorySvg />}
|
|
238
|
-
className={replaceCls}
|
|
239
|
-
/>
|
|
240
|
-
</Tooltip>
|
|
241
|
-
)}
|
|
242
280
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
</div>
|
|
246
|
-
{showProgress ? (<Progress percent={percent} style={{ width: '100%' }} />) : null}
|
|
247
|
-
<div className={`${infoCls}-main-control`}>
|
|
248
|
-
<span className={`${infoCls}-validate-message`}>
|
|
249
|
-
{this.renderValidateMessage()}
|
|
250
|
-
</span>
|
|
251
|
-
{showRetry ? <span className={`${infoCls}-retry`} onClick={e => this.onRetry(e)}>{locale.retry}</span> : null}
|
|
252
|
-
</div>
|
|
253
|
-
</div>
|
|
254
|
-
{/* </a> */}
|
|
255
|
-
<IconButton
|
|
256
|
-
onClick={(e): void => this.onRemove(e)}
|
|
257
|
-
type="tertiary"
|
|
258
|
-
icon={<IconClose />}
|
|
259
|
-
theme="borderless"
|
|
260
|
-
size="small"
|
|
261
|
-
className={closeCls}
|
|
262
|
-
/>
|
|
263
|
-
</div>
|
|
264
|
-
)}
|
|
265
|
-
</LocaleConsumer>
|
|
266
|
-
);
|
|
281
|
+
return null;
|
|
267
282
|
}
|
|
268
283
|
}
|
|
269
284
|
|