antd
Version:
An enterprise-class UI design language and React-based implementation
293 lines (278 loc) • 11.3 kB
JavaScript
import _defineProperty from 'babel-runtime/helpers/defineProperty';
import _extends from 'babel-runtime/helpers/extends';
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
import _createClass from 'babel-runtime/helpers/createClass';
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
import _inherits from 'babel-runtime/helpers/inherits';
import * as React from 'react';
import { polyfill } from 'react-lifecycles-compat';
import RcUpload from 'rc-upload';
import classNames from 'classnames';
import uniqBy from 'lodash/uniqBy';
import LocaleReceiver from '../locale-provider/LocaleReceiver';
import defaultLocale from '../locale-provider/default';
import UploadList from './UploadList';
import { T, fileToObject, genPercentAdd, getFileItem, removeFileItem } from './utils';
var Upload = function (_React$Component) {
_inherits(Upload, _React$Component);
function Upload(props) {
_classCallCheck(this, Upload);
var _this = _possibleConstructorReturn(this, (Upload.__proto__ || Object.getPrototypeOf(Upload)).call(this, props));
_this.onStart = function (file) {
var targetItem = void 0;
var nextFileList = _this.state.fileList.concat();
targetItem = fileToObject(file);
targetItem.status = 'uploading';
nextFileList.push(targetItem);
_this.onChange({
file: targetItem,
fileList: nextFileList
});
// fix ie progress
if (!window.FormData) {
_this.autoUpdateProgress(0, targetItem);
}
};
_this.onSuccess = function (response, file) {
_this.clearProgressTimer();
try {
if (typeof response === 'string') {
response = JSON.parse(response);
}
} catch (e) {/* do nothing */
}
var fileList = _this.state.fileList;
var targetItem = getFileItem(file, fileList);
// removed
if (!targetItem) {
return;
}
targetItem.status = 'done';
targetItem.response = response;
_this.onChange({
file: _extends({}, targetItem),
fileList: fileList
});
};
_this.onProgress = function (e, file) {
var fileList = _this.state.fileList;
var targetItem = getFileItem(file, fileList);
// removed
if (!targetItem) {
return;
}
targetItem.percent = e.percent;
_this.onChange({
event: e,
file: _extends({}, targetItem),
fileList: _this.state.fileList
});
};
_this.onError = function (error, response, file) {
_this.clearProgressTimer();
var fileList = _this.state.fileList;
var targetItem = getFileItem(file, fileList);
// removed
if (!targetItem) {
return;
}
targetItem.error = error;
targetItem.response = response;
targetItem.status = 'error';
_this.onChange({
file: _extends({}, targetItem),
fileList: fileList
});
};
_this.handleManualRemove = function (file) {
_this.upload.abort(file);
file.status = 'removed'; // eslint-disable-line
_this.handleRemove(file);
};
_this.onChange = function (info) {
if (!('fileList' in _this.props)) {
_this.setState({ fileList: info.fileList });
}
var onChange = _this.props.onChange;
if (onChange) {
onChange(info);
}
};
_this.onFileDrop = function (e) {
_this.setState({
dragState: e.type
});
};
_this.beforeUpload = function (file, fileList) {
if (!_this.props.beforeUpload) {
return true;
}
var result = _this.props.beforeUpload(file, fileList);
if (result === false) {
_this.onChange({
file: file,
fileList: uniqBy(_this.state.fileList.concat(fileList.map(fileToObject)), function (item) {
return item.uid;
})
});
return false;
} else if (result && result.then) {
return result;
}
return true;
};
_this.saveUpload = function (node) {
_this.upload = node;
};
_this.renderUploadList = function (locale) {
var _this$props = _this.props,
showUploadList = _this$props.showUploadList,
listType = _this$props.listType,
onPreview = _this$props.onPreview;
var showRemoveIcon = showUploadList.showRemoveIcon,
showPreviewIcon = showUploadList.showPreviewIcon;
return React.createElement(UploadList, { listType: listType, items: _this.state.fileList, onPreview: onPreview, onRemove: _this.handleManualRemove, showRemoveIcon: showRemoveIcon, showPreviewIcon: showPreviewIcon, locale: _extends({}, locale, _this.props.locale) });
};
_this.state = {
fileList: props.fileList || props.defaultFileList || [],
dragState: 'drop'
};
return _this;
}
_createClass(Upload, [{
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this.clearProgressTimer();
}
}, {
key: 'autoUpdateProgress',
value: function autoUpdateProgress(_, file) {
var _this2 = this;
var getPercent = genPercentAdd();
var curPercent = 0;
this.clearProgressTimer();
this.progressTimer = setInterval(function () {
curPercent = getPercent(curPercent);
_this2.onProgress({
percent: curPercent * 100
}, file);
}, 200);
}
}, {
key: 'handleRemove',
value: function handleRemove(file) {
var _this3 = this;
var onRemove = this.props.onRemove;
Promise.resolve(typeof onRemove === 'function' ? onRemove(file) : onRemove).then(function (ret) {
// Prevent removing file
if (ret === false) {
return;
}
var removedFileList = removeFileItem(file, _this3.state.fileList);
if (removedFileList) {
_this3.onChange({
file: file,
fileList: removedFileList
});
}
});
}
}, {
key: 'clearProgressTimer',
value: function clearProgressTimer() {
clearInterval(this.progressTimer);
}
}, {
key: 'render',
value: function render() {
var _classNames2;
var _props = this.props,
_props$prefixCls = _props.prefixCls,
prefixCls = _props$prefixCls === undefined ? '' : _props$prefixCls,
className = _props.className,
showUploadList = _props.showUploadList,
listType = _props.listType,
type = _props.type,
disabled = _props.disabled,
children = _props.children;
var rcUploadProps = _extends({ onStart: this.onStart, onError: this.onError, onProgress: this.onProgress, onSuccess: this.onSuccess }, this.props, { beforeUpload: this.beforeUpload });
delete rcUploadProps.className;
var uploadList = showUploadList ? React.createElement(
LocaleReceiver,
{ componentName: 'Upload', defaultLocale: defaultLocale.Upload },
this.renderUploadList
) : null;
if (type === 'drag') {
var _classNames;
var dragCls = classNames(prefixCls, (_classNames = {}, _defineProperty(_classNames, prefixCls + '-drag', true), _defineProperty(_classNames, prefixCls + '-drag-uploading', this.state.fileList.some(function (file) {
return file.status === 'uploading';
})), _defineProperty(_classNames, prefixCls + '-drag-hover', this.state.dragState === 'dragover'), _defineProperty(_classNames, prefixCls + '-disabled', disabled), _classNames));
return React.createElement(
'span',
{ className: className },
React.createElement(
'div',
{ className: dragCls, onDrop: this.onFileDrop, onDragOver: this.onFileDrop, onDragLeave: this.onFileDrop },
React.createElement(
RcUpload,
_extends({}, rcUploadProps, { ref: this.saveUpload, className: prefixCls + '-btn' }),
React.createElement(
'div',
{ className: prefixCls + '-drag-container' },
children
)
)
),
uploadList
);
}
var uploadButtonCls = classNames(prefixCls, (_classNames2 = {}, _defineProperty(_classNames2, prefixCls + '-select', true), _defineProperty(_classNames2, prefixCls + '-select-' + listType, true), _defineProperty(_classNames2, prefixCls + '-disabled', disabled), _classNames2));
var uploadButton = React.createElement(
'div',
{ className: uploadButtonCls, style: { display: children ? '' : 'none' } },
React.createElement(RcUpload, _extends({}, rcUploadProps, { ref: this.saveUpload }))
);
if (listType === 'picture-card') {
return React.createElement(
'span',
{ className: className },
uploadList,
uploadButton
);
}
return React.createElement(
'span',
{ className: className },
uploadButton,
uploadList
);
}
}], [{
key: 'getDerivedStateFromProps',
value: function getDerivedStateFromProps(nextProps) {
if ('fileList' in nextProps) {
return {
fileList: nextProps.fileList || []
};
}
return null;
}
}]);
return Upload;
}(React.Component);
Upload.defaultProps = {
prefixCls: 'ant-upload',
type: 'select',
multiple: false,
action: '',
data: {},
accept: '',
beforeUpload: T,
showUploadList: true,
listType: 'text',
className: '',
disabled: false,
supportServerRender: true
};
polyfill(Upload);
export default Upload;