chowa
Version:
UI component library based on React
206 lines (205 loc) • 7.87 kB
JavaScript
/**
* @license chowa v1.1.3
*
* Copyright (c) Chowa Techonlogies Co.,Ltd.(http://www.chowa.cn).
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const React = require("react");
const PropTypes = require("prop-types");
const classnames_1 = require("classnames");
const utils_1 = require("../utils");
const request_1 = require("./request");
const select_1 = require("./select");
const drag_1 = require("./drag");
const file_item_1 = require("./file-item");
const tool_1 = require("./tool");
class Upload extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
uploadFiles: tool_1.completeFileStorage(props.value || props.defaultValue)
};
this.request = new request_1.default(this);
[
'chooseFile',
'onInputChangeHandler',
'removeFile',
'triggerChange',
'appendUploadFile'
].forEach((fn) => {
this[fn] = this[fn].bind(this);
});
}
componentDidUpdate(preProps) {
if (!utils_1.isEqual(preProps.value, this.props.value)) {
const value = [].concat(this.props.value);
const compare = [].concat(this.state.uploadFiles);
let uploadFiles = [];
compare.forEach((uploadFile) => {
const valueIndex = value.findIndex((storageFile) => uploadFile.name === storageFile.name);
if (valueIndex) {
value.splice(valueIndex, 1);
}
if (uploadFile.status !== 'success' || valueIndex >= 0) {
uploadFiles.push(uploadFile);
}
});
uploadFiles = uploadFiles.concat(tool_1.completeFileStorage(value));
this.setState({ uploadFiles });
}
}
componentWillUnmount() {
const { uploadFiles } = this.state;
uploadFiles.forEach((file) => {
if (file.status !== 'success') {
file.xhr.abort();
}
});
}
triggerChange() {
const { onChange } = this.props;
const { uploadFiles } = this.state;
if (!onChange) {
return;
}
const storageFiles = [];
uploadFiles.forEach((uploadFile) => {
if (uploadFile.progress !== 100) {
return;
}
storageFiles.push(tool_1.transformToStorageFile(uploadFile));
});
onChange(storageFiles);
}
chooseFile() {
if (this.props.disabled) {
return;
}
this.InputEle.click();
}
onInputChangeHandler(e) {
for (let i = 0; i < e.target.files.length; i++) {
const file = e.target.files[i];
this.appendUploadFile(file);
}
e.target.value = null;
}
appendUploadFile(file) {
return __awaiter(this, void 0, void 0, function* () {
const { onBeforeUpload, exts, size, onExtError, onSizeError } = this.props;
if (utils_1.isExist(exts) && !exts.includes(tool_1.computedFileExt(file))) {
if (onExtError) {
onExtError(file);
}
return;
}
if (size > 0 && file.size > size) {
if (onSizeError) {
onSizeError(file);
}
return;
}
if (!onBeforeUpload) {
return this.request.exec(file);
}
const before = onBeforeUpload(file);
if (before instanceof Promise) {
before.then(() => {
this.request.exec(file);
});
}
else if (before === true) {
this.request.exec(file);
}
});
}
removeFile(index) {
const uploadFiles = [].concat(this.state.uploadFiles);
const { onRemove } = this.props;
const [removeFile] = uploadFiles.splice(index, 1);
if (removeFile.status !== 'success') {
removeFile.xhr.abort();
}
if (onRemove) {
onRemove(removeFile);
}
this.setState({ uploadFiles }, this.triggerChange);
}
render() {
const { className, children, style, mode, disabled, accept, multiple, name, capture, formatter, directory, showUploadList } = this.props;
const { uploadFiles } = this.state;
const componentClass = classnames_1.default({
[utils_1.preClass('upload')]: true,
[className]: utils_1.isExist(className)
});
return (React.createElement("div", { className: componentClass, style: style },
React.createElement("input", { type: 'file', accept: accept, multiple: multiple, name: name, capture: capture, hidden: true, onChange: this.onInputChangeHandler, ref: (ele) => {
this.InputEle = ele;
} }),
!children && mode === 'select' &&
React.createElement(select_1.default, { disabled: disabled, triggerUpload: this.chooseFile }),
!children && mode === 'drag' &&
React.createElement(drag_1.default, { appendUploadFile: this.appendUploadFile, disabled: disabled, triggerUpload: this.chooseFile, directory: directory }),
children &&
React.createElement("div", { onClick: this.chooseFile }, children),
showUploadList &&
React.createElement("ul", { className: utils_1.preClass('upload-file-list') }, uploadFiles.map((uploadFile, key) => {
const { name, progress, status, uuid } = uploadFile;
if (formatter) {
return formatter(uploadFile);
}
return (React.createElement(file_item_1.default, { key: uuid, name: name, progress: progress, status: status, onRemove: this.removeFile.bind(this, key) }));
}))));
}
}
Upload.propTypes = {
className: PropTypes.string,
style: PropTypes.object,
mode: PropTypes.oneOf(['select', 'drag']),
accept: PropTypes.string.isRequired,
exts: PropTypes.array,
size: PropTypes.number,
action: PropTypes.string,
capture: PropTypes.bool,
multiple: PropTypes.bool,
disabled: PropTypes.bool,
directory: PropTypes.bool,
headers: PropTypes.object,
name: PropTypes.string,
data: PropTypes.object,
defaultValue: PropTypes.array,
value: PropTypes.array,
onChange: PropTypes.func,
onBeforeUpload: PropTypes.func,
onProgress: PropTypes.func,
onSuccess: PropTypes.func,
onRemove: PropTypes.func,
onError: PropTypes.func,
onExtError: PropTypes.func,
onSizeError: PropTypes.func,
formatter: PropTypes.func,
showUploadList: PropTypes.bool
};
Upload.defaultProps = {
name: 'file',
mode: 'select',
capture: false,
multiple: false,
accept: '*',
directory: true,
showUploadList: false
};
exports.default = Upload;