Skip to content

Commit c13466e

Browse files
committed
merge
2 parents fe1b164 + 9812ea4 commit c13466e

25 files changed

+1875
-4
lines changed

components/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,6 @@ export { default as Tooltip } from './tooltip'
116116

117117
// export { default as Mention } from './mention'
118118

119-
// export { default as Upload } from './upload'
119+
export { default as Upload } from './upload'
120120

121121
export { default as version } from './version'

components/style.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,4 @@ import './timeline/style'
4141
import './input-number/style'
4242
import './transfer/style'
4343
import './tree/style'
44+
import './upload/style'

components/tooltip/Tooltip.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ export default {
148148
render (h) {
149149
const { $props, $data, $slots } = this
150150
const { prefixCls, openClassName, getPopupContainer } = $props
151-
const children = ($slots.default || []).filter(c => c.tag || c.text.trim() !== '')[0]
151+
const children = ($slots.default || []).filter(c => c.tag || c.text.trim() !== '')
152152
let sVisible = $data.sVisible
153153
// Hide tooltip when there is no title
154154
if (!hasProp(this, 'visible') && this.isNoTitle()) {

components/upload/Dragger.jsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { getOptionProps } from '../_util/props-util'
2+
import Upload from './Upload'
3+
import { UploadProps } from './interface'
4+
5+
export default {
6+
name: 'ADragger',
7+
props: UploadProps,
8+
render () {
9+
const props = getOptionProps(this)
10+
const draggerProps = {
11+
props: {
12+
...props,
13+
type: 'drag',
14+
},
15+
on: this.$listeners,
16+
style: { height: this.height },
17+
}
18+
return <Upload {...draggerProps} >{this.$slots.default}</Upload>
19+
},
20+
}

components/upload/Upload.jsx

Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
2+
import classNames from 'classnames'
3+
import uniqBy from 'lodash/uniqBy'
4+
import VcUpload from '../vc-upload'
5+
import BaseMixin from '../_util/BaseMixin'
6+
import { getOptionProps, initDefaultProps, hasProp } from '../_util/props-util'
7+
import LocaleReceiver from '../locale-provider/LocaleReceiver'
8+
import defaultLocale from '../locale-provider/default'
9+
import Dragger from './Dragger'
10+
import UploadList from './UploadList'
11+
import { UploadProps } from './interface'
12+
import { T, fileToObject, genPercentAdd, getFileItem, removeFileItem } from './utils'
13+
14+
export { UploadProps }
15+
16+
function noop () {}
17+
18+
export default {
19+
name: 'AUpload',
20+
Dragger: Dragger,
21+
mixins: [BaseMixin],
22+
props: initDefaultProps(UploadProps, {
23+
prefixCls: 'ant-upload',
24+
type: 'select',
25+
multiple: false,
26+
action: '',
27+
data: {},
28+
accept: '',
29+
beforeUpload: T,
30+
showUploadList: true,
31+
listType: 'text', // or pictrue
32+
disabled: false,
33+
supportServerRender: true,
34+
}),
35+
// recentUploadStatus: boolean | PromiseLike<any>;
36+
data () {
37+
this.progressTimer = null
38+
return {
39+
sFileList: this.fileList || this.defaultFileList || [],
40+
dragState: 'drop',
41+
}
42+
},
43+
beforeDestroy () {
44+
this.clearProgressTimer()
45+
},
46+
watch: {
47+
fileList (val) {
48+
this.sFileList = val
49+
},
50+
},
51+
methods: {
52+
onStart (file) {
53+
const nextFileList = this.sFileList.concat()
54+
const targetItem = fileToObject(file)
55+
targetItem.status = 'uploading'
56+
nextFileList.push(targetItem)
57+
this.onChange({
58+
file: targetItem,
59+
fileList: nextFileList,
60+
})
61+
// fix ie progress
62+
if (!window.FormData) {
63+
this.autoUpdateProgress(0, targetItem)
64+
}
65+
},
66+
autoUpdateProgress (_, file) {
67+
const getPercent = genPercentAdd()
68+
let curPercent = 0
69+
this.clearProgressTimer()
70+
this.progressTimer = setInterval(() => {
71+
curPercent = getPercent(curPercent)
72+
this.onProgress({
73+
percent: curPercent,
74+
}, file)
75+
}, 200)
76+
},
77+
onSuccess (response, file) {
78+
this.clearProgressTimer()
79+
try {
80+
if (typeof response === 'string') {
81+
response = JSON.parse(response)
82+
}
83+
} catch (e) { /* do nothing */
84+
}
85+
const fileList = this.sFileList
86+
const targetItem = getFileItem(file, fileList)
87+
// removed
88+
if (!targetItem) {
89+
return
90+
}
91+
targetItem.status = 'done'
92+
targetItem.response = response
93+
this.onChange({
94+
file: { ...targetItem },
95+
fileList,
96+
})
97+
},
98+
onProgress (e, file) {
99+
const fileList = this.sFileList
100+
const targetItem = getFileItem(file, fileList)
101+
// removed
102+
if (!targetItem) {
103+
return
104+
}
105+
targetItem.percent = e.percent
106+
this.onChange({
107+
event: e,
108+
file: { ...targetItem },
109+
fileList: this.sFileList,
110+
})
111+
},
112+
onError (error, response, file) {
113+
this.clearProgressTimer()
114+
const fileList = this.sFileList
115+
const targetItem = getFileItem(file, fileList)
116+
// removed
117+
if (!targetItem) {
118+
return
119+
}
120+
targetItem.error = error
121+
targetItem.response = response
122+
targetItem.status = 'error'
123+
this.onChange({
124+
file: { ...targetItem },
125+
fileList,
126+
})
127+
},
128+
handleRemove (file) {
129+
Promise.resolve(this.$emit('remove', file)).then(ret => {
130+
// Prevent removing file
131+
if (ret === false) {
132+
return
133+
}
134+
135+
const removedFileList = removeFileItem(file, this.sFileList)
136+
if (removedFileList) {
137+
this.onChange({
138+
file,
139+
fileList: removedFileList,
140+
})
141+
}
142+
})
143+
},
144+
handleManualRemove (file) {
145+
this.$refs.uploadRef.abort(file)
146+
file.status = 'removed' // eslint-disable-line
147+
this.handleRemove(file)
148+
},
149+
onChange (info) {
150+
if (!hasProp(this, 'fileList')) {
151+
this.setState({ sFileList: info.fileList })
152+
}
153+
this.$emit('change', info)
154+
},
155+
onFileDrop (e) {
156+
this.setState({
157+
dragState: e.type,
158+
})
159+
},
160+
reBeforeUpload (file, fileList) {
161+
if (!this.beforeUpload) {
162+
return true
163+
}
164+
const result = this.beforeUpload(file, fileList)
165+
if (result === false) {
166+
this.onChange({
167+
file,
168+
fileList: uniqBy(fileList.concat(this.sFileList), (item) => item.uid),
169+
})
170+
return false
171+
} else if (result && result.then) {
172+
return result
173+
}
174+
return true
175+
},
176+
clearProgressTimer () {
177+
clearInterval(this.progressTimer)
178+
},
179+
renderUploadList (locale) {
180+
const { showUploadList = {}, listType } = getOptionProps(this)
181+
const { showRemoveIcon, showPreviewIcon } = showUploadList
182+
const uploadListProps = {
183+
props: {
184+
listType,
185+
items: this.sFileList,
186+
showRemoveIcon,
187+
showPreviewIcon,
188+
locale: { ...locale, ...this.$props.locale },
189+
},
190+
on: {
191+
remove: this.handleManualRemove,
192+
preview: this.$listeners.preview || noop,
193+
},
194+
}
195+
return (
196+
<UploadList
197+
{...uploadListProps}
198+
/>
199+
)
200+
},
201+
},
202+
render () {
203+
const {
204+
prefixCls = '',
205+
showUploadList,
206+
listType,
207+
type,
208+
disabled,
209+
} = getOptionProps(this)
210+
211+
const vcUploadProps = {
212+
props: {
213+
...this.$props,
214+
beforeUpload: this.reBeforeUpload,
215+
},
216+
on: {
217+
// ...this.$listeners,
218+
start: this.onStart,
219+
error: this.onError,
220+
progress: this.onProgress,
221+
success: this.onSuccess,
222+
},
223+
ref: 'uploadRef',
224+
class: `${prefixCls}-btn`,
225+
}
226+
227+
const uploadList = showUploadList ? (
228+
<LocaleReceiver
229+
componentName='Upload'
230+
defaultLocale={defaultLocale.Upload}
231+
children={this.renderUploadList}
232+
>
233+
</LocaleReceiver>
234+
) : null
235+
236+
const children = this.$slots.default
237+
238+
if (type === 'drag') {
239+
const dragCls = classNames(prefixCls, {
240+
[`${prefixCls}-drag`]: true,
241+
[`${prefixCls}-drag-uploading`]: this.sFileList.some(file => file.status === 'uploading'),
242+
[`${prefixCls}-drag-hover`]: this.dragState === 'dragover',
243+
[`${prefixCls}-disabled`]: disabled,
244+
})
245+
return (
246+
<span>
247+
<div
248+
class={dragCls}
249+
onDrop={this.onFileDrop}
250+
onDragover={this.onFileDrop}
251+
onDragleave={this.onFileDrop}
252+
>
253+
<VcUpload {...vcUploadProps}>
254+
<div class={`${prefixCls}-drag-container`}>
255+
{children}
256+
</div>
257+
</VcUpload>
258+
</div>
259+
{uploadList}
260+
</span>
261+
)
262+
}
263+
264+
const uploadButtonCls = classNames(prefixCls, {
265+
[`${prefixCls}-select`]: true,
266+
[`${prefixCls}-select-${listType}`]: true,
267+
[`${prefixCls}-disabled`]: disabled,
268+
})
269+
const uploadButton = (
270+
<div class={uploadButtonCls} style={{ display: children ? '' : 'none' }}>
271+
<VcUpload {...vcUploadProps} >{children}</VcUpload>
272+
</div>
273+
)
274+
275+
if (listType === 'picture-card') {
276+
return (
277+
<span>
278+
{uploadList}
279+
{uploadButton}
280+
</span>
281+
)
282+
}
283+
return (
284+
<span>
285+
{uploadButton}
286+
{uploadList}
287+
</span>
288+
)
289+
},
290+
}

0 commit comments

Comments
 (0)