feat: add upload component

This commit is contained in:
玄寂 2015-08-08 23:37:35 +08:00
parent 2507bba7a4
commit 63cf7bb742
10 changed files with 397 additions and 3 deletions

View File

@ -0,0 +1,30 @@
# 点击上传
- order: 2
经典款式
---
````jsx
var Upload = antd.Upload;
var props = {
type: 'uploadClickStyle',
description: '支持扩展名为: .rar .zip ...',
action: '/upload.do',
data: {},
accept: '',
uploadTip: '',
start: function(file){
console.log(file.name)
},
error: function() {},
success: function() {},
progress: function() {}
};
React.render(
<Upload {...props} />,
document.getElementById('components-upload-demo-click')
);
````

View File

@ -0,0 +1,33 @@
# 拖拽上传
- order: 0
款式1
---
````jsx
var Upload = antd.Upload;
var props = {
type: 'uploadDragStyleWithPicAndWords',
name: 'file',
action: '/upload.do',
data: {},
accept: 'i',
uploadTip: '',
error: function(err) {
console.log(err)
},
success: function() {},
progress: function() {},
start: function(file){
console.log(file)
}
};
React.render(
<Upload {...props} />,
document.getElementById('components-upload-demo-dragstyle1')
);
````

View File

@ -0,0 +1,31 @@
# 拖拽上传
- order: 1
款式2
---
````jsx
var Upload = antd.Upload;
var props = {
type: 'uploadDragStyleSimple',
name: 'file',
action: '/upload.do',
data: {},
accept: '',
uploadTip: '',
error: function() {},
success: function() {},
progress: function() {},
start: function(){
}
};
React.render(
<Upload {...props} />,
document.getElementById('components-upload-demo-dragstyle2')
);
````

140
components/upload/index.jsx Normal file
View File

@ -0,0 +1,140 @@
import React from 'react';
import Upload from 'rc-upload';
import assign from 'object-assign';
import Message from '../message';
const prefixCls = 'ant-upload';
var DownloadList = React.createClass({
handleClose(e) {
e.target.parentNode.style.display = 'none';
},
render() {
var downloadItem = function(file){
var statusIcon = file.status === 'done' ? <i className='anticon anticon-check upload-success-icon'></i> : <i className='anticon anticon-loading'></i>;
var closeIcon = file.status === 'done' ? <i className='anticon anticon-cross' ref='theCloseBtn' onClick={this.handleClose}></i> : '';
return (
<div className='upload-list-item' key={file.id}>
{statusIcon}
<b className='upload-item-name'>{file.filename}</b>
{closeIcon}
</div>
);
}.bind(this);
return <div className='upload-list'>{this.props.items.map(downloadItem)}</div>;
}
});
export default React.createClass({
getInitialState() {
return {
downloadList: []
};
},
handleStart(file) {
var i = this.state.downloadList.length + 1;
var nextDownloadList = this.state.downloadList.concat([{id: i, uid: file.uid || '', filename: file.name, status: 'downloading' }]);
this.setState({downloadList: nextDownloadList});
},
handleSuccess(ret, file) {
var matchWay = file.uid === '' ? 'byName' : 'byUid';
Message.success(file.name + '上传完成');
for (var i = 0; i < this.state.downloadList.length; i++){
if(matchWay === 'byName'){
if(this.state.downloadList[i].filename === file.name){
this.state.downloadList[i].status = 'done';
}
}else{
if(this.state.downloadList[i].uid === file.uid){
this.state.downloadList[i].status = 'done';
}
}
}
this.setState({downloadList: this.state.downloadList});
},
handleProgress() {
//console.log('handleProcess ', file);
},
handleError() {
//console.log('err ',err)
Message.error('上传失败');
},
getDefaultProps() {
return {
type: 'uploadClickStyle',
name: 'ooxx',
multipart: false,
action: '',
data: {},
accept: '',
uploadTip: '',
start: function() {},
error: function() {},
success: function() {},
progress: function() {}
};
},
render() {
var type = this.props.type;
var props = assign({}, this.props);
props.onStart = (file) => {
this.handleStart(file);
props.start.call(this, file);
};
props.onSuccess = (ret, file) => {
this.handleSuccess(ret, file);
props.success.call(this, ret, file);
};
props.onProgress = (step) => {
this.handleProgress(step);
props.progress.call(this, step);
};
props.onError = (err) => {
this.handleError(err);
props.error.call(this, err);
};
if (type === 'uploadDragStyleWithPicAndWords') {
return (
<div className={prefixCls + '-container'}>
<Upload {...props}>
<div className={prefixCls + '-method-drag-picwords'}>
<p className='upload-drag-icon'>
<i className='anticon anticon-inbox'></i>
</p>
<p className='upload-tip-one'>点击或将文件拖拽到此区域上传</p>
<p className='upload-tip-two'>支持单个或批量上传,严谨上传公司内部资料及其他违禁文件</p>
</div>
</Upload>
</div>
);
} else if (type === 'uploadDragStyleSimple') {
return (
<div className={prefixCls + '-method-drag-cross'}>
<Upload {...props}>
<div className='upload-drag-area'>
<i className='anticon anticon-plus'></i>
</div>
</Upload>
</div>
);
} else if (type === 'uploadClickStyle') {
return (
<div className={prefixCls + '-method-click'}>
<Upload {...props}>
<div className='upload-btn'>
<i className='anticon anticon-upload'></i>
<button>点击上传</button>
</div>
</Upload>
<div className='upload-text-tip'>{this.props.description}</div>
<DownloadList items={this.state.downloadList} />
</div>
);
}
}
});

View File

@ -5,4 +5,18 @@
--- ---
## 关于上传
- 上传是将信息从个人计算机(本地计算机)传递到中央计算机(远程计算机)系统上,让网络上的人都能看到.将制作好的网页、文字、图片、视频通过网页或者上传工具软件发布到互联网上的服务器系统上去,以便让其他人浏览、欣赏。这一过程称为上传。
## API
| 参数 | 说明 | 类型 | 默认值 |
|----------- |--------------------------------------------------------- | ---------- |-------|
| name | 可选参数, 上传的文件 | String | file |
| action | 必选参数, 上传的地址 | String | 无 |
| data | 可选参数, 上传所需参数 | Object | 无 |
| accept | 可选参数, 接受上传的文件类型, 详见input accept Attribute | String | 无 |
| onError | 可选参数, error callback |Function | 无 |
| onSuccess | 可选参数, success callback | Function | 无 |
| onProgress | 可选参数, progress callback, 现代浏览器有效 | Function | 无 |

View File

@ -30,7 +30,8 @@ var antd = {
RadioGroup: require('./components/radio/group'), RadioGroup: require('./components/radio/group'),
Alert: require('./components/alert'), Alert: require('./components/alert'),
Validation: require('./components/validation'), Validation: require('./components/validation'),
Tree: require('./components/Tree') Tree: require('./components/Tree'),
Upload: require('./components/upload')
}; };
module.exports = antd; module.exports = antd;

32
nico.js
View File

@ -1,6 +1,8 @@
var path = require('path'); var path = require('path');
var package = require('./package'); var package = require('./package');
var webpack = require('webpack'); var webpack = require('webpack');
var inspect = require('util').inspect;
var Busboy = require('busboy');
var webpackMiddleware = require('webpack-dev-middleware'); var webpackMiddleware = require('webpack-dev-middleware');
var webpackConfig = require('./webpack.config'); var webpackConfig = require('./webpack.config');
var webpackCompiler = webpack(webpackConfig); var webpackCompiler = webpack(webpackConfig);
@ -31,7 +33,35 @@ exports.ignorefilter = function(filepath, subdir) {
} }
return true; return true;
}; };
exports.middlewares = [{ exports.middlewares = [
{
name: 'upload',
filter: /upload\.do?$/,
handle: function(req, res, next) {
if (req.method === 'POST') {
var busboy = new Busboy({headers: req.headers});
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
console.log('File [' + fieldname + ']: filename: ' + filename + ', encoding: ' + encoding + ', mimetype: ' + mimetype);
file.on('data', function(data) {
console.log('File [' + fieldname + '] got ' + data.length + ' bytes');
});
file.on('end', function() {
console.log('File [' + fieldname + '] Finished');
});
});
busboy.on('field', function(fieldname, val, fieldnameTruncated, valTruncated) {
console.log('Field [' + fieldname + ']: value: ' + inspect(val));
});
busboy.on('finish', function() {
console.log('Done parsing form!');
//res.writeHead(303, { Connection: 'close', Location: '/' });
res.end('success');
});
req.pipe(busboy);
}
}
},
{
name: 'webpackDevMiddleware', name: 'webpackDevMiddleware',
filter: /\.(js|css)(\.map)?$/, filter: /\.(js|css)(\.map)?$/,
handle: function(req, res, next) { handle: function(req, res, next) {

View File

@ -57,6 +57,7 @@
"rc-tabs": "~5.2.0", "rc-tabs": "~5.2.0",
"rc-tooltip": "~2.4.0", "rc-tooltip": "~2.4.0",
"rc-tree": "~0.10.0", "rc-tree": "~0.10.0",
"rc-upload": "~1.2.4-beta2",
"rc-util": "~2.0.3", "rc-util": "~2.0.3",
"react-slick": "~0.6.4" "react-slick": "~0.6.4"
}, },
@ -78,7 +79,8 @@
"nico-jsx": "~0.5.8", "nico-jsx": "~0.5.8",
"precommit-hook": "^1.0.7", "precommit-hook": "^1.0.7",
"webpack": "^1.10.1", "webpack": "^1.10.1",
"webpack-dev-middleware": "^1.2.0" "webpack-dev-middleware": "^1.2.0",
"busboy": "~0.2.9"
}, },
"scripts": { "scripts": {
"babel": "babel components --out-dir lib", "babel": "babel components --out-dir lib",

View File

@ -28,3 +28,4 @@
@import "tree"; @import "tree";
@import "carousel/slick"; @import "carousel/slick";
@import "carousel/slick-theme"; @import "carousel/slick-theme";
@import "upload";

View File

@ -0,0 +1,112 @@
@prefixUploadClass: ant-upload;
.@{prefixUploadClass} {
font-size: 12px;
&-container{
width: 100%;
padding: 0 42px;
}
&-method-drag-picwords {
border: 1px dashed #d9d9d9;
border-radius: @border-radius-base;
text-align: center;
min-width: 100px;
height: 209px;
p.upload-drag-icon{
.anticon {
font-size: 80px;
margin-top: -30px;
color: #2db7f5;
}
height: 60px;
margin: 44px auto 24px auto;
}
p.upload-tip-one{
font-size: 14px;
color: #666;
}
p.upload-tip-two{
font-size: 12px;
color: #666;
margin-top: 5px;
}
}
&-method-drag-cross {
border: 1px dashed #d9d9d9;
border-radius: @border-radius-base;
text-align: center;
line-height: 146px;
width: 246px;
height: 146px;
.anticon {
color: #2db7f5;
font-size: 30px;
}
.upload-drag-area{
width: 100%;
height: 100%;
}
}
&-method-click {
.upload-btn{
height: 22px;
line-height: 22px;
position: relative;
margin-bottom: 8px;
button{
position: absolute;
top: 0;
left: 0;
padding-left: 20px;
text-align: left;
height: 22px;
line-height: 22px;
width: 76px;
border: 1px solid #d9d9d9;
background-color: #fff;
border-radius: 8px;
color: #666;
font-size: 12px;
outline: none;
}
.anticon{
position: absolute;
top: 5px;
z-index: 10;
font-size: 10px;
margin: -4px 0 0 8px;
}
}
.upload-list {
margin-left: 4px;
}
.upload-list-item {
margin-bottom: 4px;
height: 22px;
overflow: hidden;
.anticon {
margin-top: -2px;
}
}
.upload-item-name {
font-size: 12px;
color: #666;
margin-left: 4px;
margin-right: 8px;
font-weight: normal;
}
.anticon {
font-size: 10px;
color: #999;
}
.upload-success-icon {
color: #87d068;
}
.upload-text-tip {
font-size: 12px;
color: #999;
}
}
}