rsuite
Version:
A suite of react components
423 lines (360 loc) • 13.3 kB
JavaScript
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
import _extends from "@babel/runtime/helpers/esm/extends";
import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized";
import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose";
import _find from "lodash/find";
import * as React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { compose } from 'recompose';
import IntlContext from '../IntlProvider/IntlContext';
import withLocale from '../IntlProvider/withLocale';
import FileItem from './UploadFileItem';
import UploadTrigger from './UploadTrigger';
import { prefix, ajaxUpload, defaultProps, getUnhandledProps } from '../utils';
import { getFiles, guid } from './utils';
var Uploader =
/*#__PURE__*/
function (_React$Component) {
_inheritsLoose(Uploader, _React$Component);
function Uploader(props) {
var _this;
_this = _React$Component.call(this, props) || this;
_this.inputRef = void 0;
_this.handleRemoveFile = function (fileKey) {
var _this$props$onRemove, _this$props, _this$props$onChange, _this$props2;
var fileList = _this.getFileList();
var file = _find(fileList, function (f) {
return f.fileKey === fileKey;
});
var nextFileList = fileList.filter(function (f) {
return f.fileKey !== fileKey;
});
if (_this.xhrs[file.fileKey] && _this.xhrs[file.fileKey].readyState !== 4) {
_this.xhrs[file.fileKey].abort();
}
_this.setState({
fileList: nextFileList
});
(_this$props$onRemove = (_this$props = _this.props).onRemove) === null || _this$props$onRemove === void 0 ? void 0 : _this$props$onRemove.call(_this$props, file);
(_this$props$onChange = (_this$props2 = _this.props).onChange) === null || _this$props$onChange === void 0 ? void 0 : _this$props$onChange.call(_this$props2, nextFileList);
_this.cleanInputValue();
};
_this.handleUploadTriggerChange = function (event) {
var _this$props3 = _this.props,
autoUpload = _this$props3.autoUpload,
shouldQueueUpdate = _this$props3.shouldQueueUpdate,
onChange = _this$props3.onChange;
var fileList = _this.getFileList();
var files = getFiles(event);
var newFileList = [];
Array.from(files).forEach(function (file) {
newFileList.push({
blobFile: file,
name: file.name,
status: 'inited',
fileKey: guid()
});
});
var nextFileList = [].concat(fileList, newFileList);
var checkState = shouldQueueUpdate === null || shouldQueueUpdate === void 0 ? void 0 : shouldQueueUpdate(nextFileList, newFileList);
var upload = function upload() {
onChange === null || onChange === void 0 ? void 0 : onChange(nextFileList);
_this.setState({
fileList: nextFileList
}, function () {
autoUpload && _this.handleAjaxUpload();
});
};
if (checkState instanceof Promise) {
checkState.then(function (res) {
if (res) {
upload();
}
});
return;
} else if (checkState === false) {
_this.cleanInputValue();
return;
}
upload();
};
_this.handleAjaxUploadSuccess = function (file, response, event, xhr) {
var nextFile = _extends({}, file, {
status: 'finished',
progress: 100
});
_this.updateFileList(nextFile, function () {
var _this$props$onSuccess, _this$props4;
(_this$props$onSuccess = (_this$props4 = _this.props).onSuccess) === null || _this$props$onSuccess === void 0 ? void 0 : _this$props$onSuccess.call(_this$props4, response, nextFile, event, xhr);
});
};
_this.handleAjaxUploadError = function (file, status, event, xhr) {
var nextFile = _extends({}, file, {
status: 'error'
});
_this.updateFileList(nextFile, function () {
var _this$props$onError, _this$props5;
(_this$props$onError = (_this$props5 = _this.props).onError) === null || _this$props$onError === void 0 ? void 0 : _this$props$onError.call(_this$props5, status, nextFile, event, xhr);
});
};
_this.handleAjaxUploadProgress = function (file, percent, event, xhr) {
var nextFile = _extends({}, file, {
status: 'uploading',
progress: percent
});
_this.updateFileList(nextFile, function () {
var _this$props$onProgres, _this$props6;
(_this$props$onProgres = (_this$props6 = _this.props).onProgress) === null || _this$props$onProgres === void 0 ? void 0 : _this$props$onProgres.call(_this$props6, percent, nextFile, event, xhr);
});
};
_this.handleUploadFile = function (file) {
var _this$props7 = _this.props,
name = _this$props7.name,
action = _this$props7.action,
headers = _this$props7.headers,
withCredentials = _this$props7.withCredentials,
timeout = _this$props7.timeout,
data = _this$props7.data,
onUpload = _this$props7.onUpload;
var xhr = ajaxUpload({
name: name,
timeout: timeout,
headers: headers,
data: data,
withCredentials: withCredentials,
file: file.blobFile,
url: action,
onError: _this.handleAjaxUploadError.bind(_assertThisInitialized(_this), file),
onSuccess: _this.handleAjaxUploadSuccess.bind(_assertThisInitialized(_this), file),
onProgress: _this.handleAjaxUploadProgress.bind(_assertThisInitialized(_this), file)
});
_this.updateFileList(_extends({}, file, {
status: 'uploading'
}));
_this.xhrs[file.fileKey] = xhr;
onUpload === null || onUpload === void 0 ? void 0 : onUpload(file);
};
_this.handleReupload = function (file) {
var _this$props8 = _this.props,
onReupload = _this$props8.onReupload,
autoUpload = _this$props8.autoUpload;
autoUpload && _this.handleUploadFile(file);
onReupload === null || onReupload === void 0 ? void 0 : onReupload(file);
};
_this.createFile = function (file) {
var fileKey = file.fileKey;
return _extends({}, file, {
fileKey: fileKey || guid(),
progress: 0
});
};
_this.addPrefix = function (name) {
return prefix(_this.props.classPrefix)(name);
};
_this.progressTimer = void 0;
_this.xhrs = {};
_this.uploadTrigger = null;
var _props$defaultFileLis = props.defaultFileList,
defaultFileList = _props$defaultFileLis === void 0 ? [] : _props$defaultFileLis;
var _fileList = defaultFileList.map(_this.createFile);
_this.state = {
fileList: _fileList,
fileMap: {}
};
_this.inputRef = React.createRef();
return _this;
} // public API
var _proto = Uploader.prototype;
_proto.start = function start(file) {
if (file) {
this.handleUploadFile(file);
return;
}
this.handleAjaxUpload();
};
_proto.getFileList = function getFileList() {
var fileList = this.props.fileList;
var fileMap = this.state.fileMap;
if (typeof fileList !== 'undefined') {
return fileList.map(function (file) {
return _extends({}, file, {}, fileMap[file.fileKey]);
});
}
return this.state.fileList;
};
_proto.cleanInputValue = function cleanInputValue() {
if (this.inputRef.current) {
this.inputRef.current.getInputInstance().value = '';
}
};
_proto.handleAjaxUpload = function handleAjaxUpload() {
var _this2 = this;
var shouldUpload = this.props.shouldUpload;
var fileList = this.getFileList();
fileList.forEach(function (file) {
var checkState = shouldUpload === null || shouldUpload === void 0 ? void 0 : shouldUpload(file);
if (checkState instanceof Promise) {
checkState.then(function (res) {
if (res) {
_this2.handleUploadFile(file);
}
});
return;
} else if (checkState === false) {
return;
}
if (file.status === 'inited') {
_this2.handleUploadFile(file);
}
});
this.cleanInputValue();
};
_proto.updateFileList = function updateFileList(nextFile, callback) {
var fileList = this.getFileList();
var nextFileList = fileList.map(function (file) {
return file.fileKey === nextFile.fileKey ? nextFile : file;
});
var nextState = {
fileList: nextFileList
};
if (nextFile.progress) {
var fileMap = this.state.fileMap;
fileMap[nextFile.fileKey] = {
progress: nextFile.progress,
status: nextFile.status
};
nextState.fileMap = fileMap;
}
this.setState(nextState, callback);
};
_proto.renderFileItems = function renderFileItems() {
var _this3 = this;
var _this$props9 = this.props,
disabledFileItem = _this$props9.disabledFileItem,
listType = _this$props9.listType,
onPreview = _this$props9.onPreview,
maxPreviewFileSize = _this$props9.maxPreviewFileSize,
renderFileInfo = _this$props9.renderFileInfo,
removable = _this$props9.removable;
var fileList = this.getFileList();
return React.createElement("div", {
key: "items",
className: this.addPrefix('file-items')
}, fileList.map(function (file, index) {
return React.createElement(FileItem, {
key: file.fileKey || index,
file: file,
maxPreviewFileSize: maxPreviewFileSize,
listType: listType,
disabled: disabledFileItem,
onPreview: onPreview,
onReupload: _this3.handleReupload,
onCancel: _this3.handleRemoveFile,
renderFileInfo: renderFileInfo,
removable: removable
});
}));
};
_proto.renderUploadTrigger = function renderUploadTrigger() {
var _this$props10 = this.props,
name = _this$props10.name,
multiple = _this$props10.multiple,
disabled = _this$props10.disabled,
accept = _this$props10.accept,
children = _this$props10.children,
toggleComponentClass = _this$props10.toggleComponentClass,
draggable = _this$props10.draggable,
rest = _objectWithoutPropertiesLoose(_this$props10, ["name", "multiple", "disabled", "accept", "children", "toggleComponentClass", "draggable"]);
var unhandled = getUnhandledProps(Uploader, rest);
return React.createElement(UploadTrigger, _extends({}, unhandled, {
name: name,
key: "trigger",
multiple: multiple,
draggable: draggable,
disabled: disabled,
accept: accept,
ref: this.inputRef,
onChange: this.handleUploadTriggerChange,
componentClass: toggleComponentClass
}), children);
};
_proto.render = function render() {
var _classNames;
var _this$props11 = this.props,
classPrefix = _this$props11.classPrefix,
className = _this$props11.className,
listType = _this$props11.listType,
fileListVisible = _this$props11.fileListVisible,
locale = _this$props11.locale,
style = _this$props11.style,
draggable = _this$props11.draggable;
var classes = classNames(className, classPrefix, this.addPrefix(listType), (_classNames = {}, _classNames[this.addPrefix('draggable')] = draggable, _classNames));
var renderList = [this.renderUploadTrigger()];
if (fileListVisible) {
renderList.push(this.renderFileItems());
}
if (listType === 'picture') {
renderList.reverse();
}
return React.createElement(IntlContext.Provider, {
value: locale
}, React.createElement("div", {
className: classes,
style: style
}, renderList));
};
return Uploader;
}(React.Component);
Uploader.propTypes = {
action: PropTypes.string,
accept: PropTypes.string,
autoUpload: PropTypes.bool,
children: PropTypes.node,
className: PropTypes.string,
classPrefix: PropTypes.string,
defaultFileList: PropTypes.array,
fileList: PropTypes.array,
data: PropTypes.object,
multiple: PropTypes.bool,
disabled: PropTypes.bool,
disabledFileItem: PropTypes.bool,
name: PropTypes.string,
timeout: PropTypes.number,
withCredentials: PropTypes.bool,
headers: PropTypes.object,
locale: PropTypes.object,
listType: PropTypes.oneOf(['text', 'picture-text', 'picture']),
shouldQueueUpdate: PropTypes.func,
shouldUpload: PropTypes.func,
onChange: PropTypes.func,
onUpload: PropTypes.func,
onReupload: PropTypes.func,
onPreview: PropTypes.func,
onError: PropTypes.func,
onSuccess: PropTypes.func,
onProgress: PropTypes.func,
onRemove: PropTypes.func,
maxPreviewFileSize: PropTypes.number,
style: PropTypes.object,
toggleComponentClass: PropTypes.elementType,
renderFileInfo: PropTypes.func,
removable: PropTypes.bool,
fileListVisible: PropTypes.bool,
draggable: PropTypes.bool
};
Uploader.defaultProps = {
autoUpload: true,
timeout: 0,
name: 'file',
multiple: false,
disabled: false,
withCredentials: false,
data: {},
listType: 'text',
removable: true,
fileListVisible: true
};
export default compose(withLocale(['Uploader']), defaultProps({
classPrefix: 'uploader'
}))(Uploader);