antd
Version:
An enterprise-class UI design language and React components implementation
336 lines (288 loc) • 10.5 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _extends from "@babel/runtime/helpers/extends";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import * as React from 'react';
import RcUpload from 'rc-upload';
import classNames from 'classnames';
import Dragger from './Dragger';
import UploadList from './UploadList';
import { T, fileToObject, getFileItem, removeFileItem } from './utils';
import LocaleReceiver from '../locale-provider/LocaleReceiver';
import defaultLocale from '../locale/default';
import { ConfigContext } from '../config-provider';
import devWarning from '../_util/devWarning';
import useForceUpdate from '../_util/hooks/useForceUpdate';
import useFreshState from './useFreshState';
var InternalUpload = function InternalUpload(props, ref) {
var _classNames2;
var fileListProp = props.fileList,
defaultFileList = props.defaultFileList,
onRemove = props.onRemove,
showUploadList = props.showUploadList,
listType = props.listType,
onPreview = props.onPreview,
onDownload = props.onDownload,
previewFile = props.previewFile,
disabled = props.disabled,
propLocale = props.locale,
iconRender = props.iconRender,
isImageUrl = props.isImageUrl,
progress = props.progress,
customizePrefixCls = props.prefixCls,
className = props.className,
type = props.type,
children = props.children,
style = props.style,
itemRender = props.itemRender;
var _React$useState = React.useState('drop'),
_React$useState2 = _slicedToArray(_React$useState, 2),
dragState = _React$useState2[0],
setDragState = _React$useState2[1];
var forceUpdate = useForceUpdate(); // Refresh always use fresh data
var _useFreshState = useFreshState(fileListProp || defaultFileList || [], fileListProp),
_useFreshState2 = _slicedToArray(_useFreshState, 2),
getFileList = _useFreshState2[0],
setFileList = _useFreshState2[1];
var upload = React.useRef();
React.useEffect(function () {
devWarning('fileList' in props || !('value' in props), 'Upload', '`value` is not a valid prop, do you mean `fileList`?');
}, []);
var onChange = function onChange(info) {
setFileList(info.fileList);
var onChangeProp = props.onChange;
if (onChangeProp) {
onChangeProp(_extends(_extends({}, info), {
fileList: _toConsumableArray(info.fileList)
}));
}
};
var onStart = function onStart(file) {
var targetItem = fileToObject(file);
targetItem.status = 'uploading';
var nextFileList = getFileList().concat();
var fileIndex = nextFileList.findIndex(function (_ref) {
var uid = _ref.uid;
return uid === targetItem.uid;
});
if (fileIndex === -1) {
nextFileList.push(targetItem);
} else {
nextFileList[fileIndex] = targetItem;
}
onChange({
file: targetItem,
fileList: nextFileList
});
};
var onSuccess = function onSuccess(response, file, xhr) {
try {
if (typeof response === 'string') {
response = JSON.parse(response);
}
} catch (e) {
/* do nothing */
}
var targetItem = getFileItem(file, getFileList()); // removed
if (!targetItem) {
return;
}
targetItem.status = 'done';
targetItem.response = response;
targetItem.xhr = xhr;
onChange({
file: _extends({}, targetItem),
fileList: getFileList().concat()
});
};
var onProgress = function onProgress(e, file) {
var targetItem = getFileItem(file, getFileList()); // removed
if (!targetItem) {
return;
}
targetItem.percent = e.percent;
onChange({
event: e,
file: _extends({}, targetItem),
fileList: getFileList().concat()
});
};
var onError = function onError(error, response, file) {
var targetItem = getFileItem(file, getFileList()); // removed
if (!targetItem) {
return;
}
targetItem.error = error;
targetItem.response = response;
targetItem.status = 'error';
onChange({
file: _extends({}, targetItem),
fileList: getFileList().concat()
});
};
var handleRemove = function handleRemove(file) {
Promise.resolve(typeof onRemove === 'function' ? onRemove(file) : onRemove).then(function (ret) {
// Prevent removing file
if (ret === false) {
return;
}
var removedFileList = removeFileItem(file, getFileList());
if (removedFileList) {
file.status = 'removed';
if (upload.current) {
upload.current.abort(file);
}
onChange({
file: file,
fileList: removedFileList
});
}
});
};
var onFileDrop = function onFileDrop(e) {
setDragState(e.type);
};
var beforeUpload = function beforeUpload(file, fileListArgs) {
var beforeUploadProp = props.beforeUpload;
if (!beforeUploadProp) {
return true;
}
var result = beforeUploadProp(file, fileListArgs);
if (result === false) {
// Get unique file list
var uniqueList = [];
getFileList().concat(fileListArgs.map(fileToObject)).forEach(function (f) {
if (uniqueList.every(function (uf) {
return uf.uid !== f.uid;
})) {
uniqueList.push(f);
}
});
onChange({
file: file,
fileList: uniqueList
});
return false;
}
if (result && result.then) {
return result;
}
return true;
}; // Test needs
React.useImperativeHandle(ref, function () {
return {
onStart: onStart,
onSuccess: onSuccess,
onProgress: onProgress,
onError: onError,
fileList: getFileList(),
upload: upload.current,
forceUpdate: forceUpdate
};
});
var _React$useContext = React.useContext(ConfigContext),
getPrefixCls = _React$useContext.getPrefixCls,
direction = _React$useContext.direction;
var prefixCls = getPrefixCls('upload', customizePrefixCls);
var rcUploadProps = _extends(_extends({
onStart: onStart,
onError: onError,
onProgress: onProgress,
onSuccess: onSuccess
}, props), {
prefixCls: prefixCls,
beforeUpload: beforeUpload
});
delete rcUploadProps.className;
delete rcUploadProps.style; // Remove id to avoid open by label when trigger is hidden
// !children: https://github.com/ant-design/ant-design/issues/14298
// disabled: https://github.com/ant-design/ant-design/issues/16478
// https://github.com/ant-design/ant-design/issues/24197
if (!children || disabled) {
delete rcUploadProps.id;
}
var renderUploadList = function renderUploadList(button) {
return showUploadList ? /*#__PURE__*/React.createElement(LocaleReceiver, {
componentName: "Upload",
defaultLocale: defaultLocale.Upload
}, function (locale) {
var _ref2 = typeof showUploadList === 'boolean' ? {} : showUploadList,
showRemoveIcon = _ref2.showRemoveIcon,
showPreviewIcon = _ref2.showPreviewIcon,
showDownloadIcon = _ref2.showDownloadIcon,
removeIcon = _ref2.removeIcon,
downloadIcon = _ref2.downloadIcon;
return /*#__PURE__*/React.createElement(UploadList, {
listType: listType,
items: getFileList(true),
previewFile: previewFile,
onPreview: onPreview,
onDownload: onDownload,
onRemove: handleRemove,
showRemoveIcon: !disabled && showRemoveIcon,
showPreviewIcon: showPreviewIcon,
showDownloadIcon: showDownloadIcon,
removeIcon: removeIcon,
downloadIcon: downloadIcon,
iconRender: iconRender,
locale: _extends(_extends({}, locale), propLocale),
isImageUrl: isImageUrl,
progress: progress,
appendAction: button,
itemRender: itemRender
});
}) : button;
};
if (type === 'drag') {
var _classNames;
var dragCls = classNames(prefixCls, (_classNames = {}, _defineProperty(_classNames, "".concat(prefixCls, "-drag"), true), _defineProperty(_classNames, "".concat(prefixCls, "-drag-uploading"), getFileList().some(function (file) {
return file.status === 'uploading';
})), _defineProperty(_classNames, "".concat(prefixCls, "-drag-hover"), dragState === 'dragover'), _defineProperty(_classNames, "".concat(prefixCls, "-disabled"), disabled), _defineProperty(_classNames, "".concat(prefixCls, "-rtl"), direction === 'rtl'), _classNames), className);
return /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("div", {
className: dragCls,
onDrop: onFileDrop,
onDragOver: onFileDrop,
onDragLeave: onFileDrop,
style: style
}, /*#__PURE__*/React.createElement(RcUpload, _extends({}, rcUploadProps, {
ref: upload,
className: "".concat(prefixCls, "-btn")
}), /*#__PURE__*/React.createElement("div", {
className: "".concat(prefixCls, "-drag-container")
}, children))), renderUploadList());
}
var uploadButtonCls = classNames(prefixCls, (_classNames2 = {}, _defineProperty(_classNames2, "".concat(prefixCls, "-select"), true), _defineProperty(_classNames2, "".concat(prefixCls, "-select-").concat(listType), true), _defineProperty(_classNames2, "".concat(prefixCls, "-disabled"), disabled), _defineProperty(_classNames2, "".concat(prefixCls, "-rtl"), direction === 'rtl'), _classNames2));
var uploadButton = /*#__PURE__*/React.createElement("div", {
className: uploadButtonCls,
style: children ? undefined : {
display: 'none'
}
}, /*#__PURE__*/React.createElement(RcUpload, _extends({}, rcUploadProps, {
ref: upload
})));
if (listType === 'picture-card') {
return /*#__PURE__*/React.createElement("span", {
className: classNames("".concat(prefixCls, "-picture-card-wrapper"), className)
}, renderUploadList(uploadButton));
}
return /*#__PURE__*/React.createElement("span", {
className: className
}, uploadButton, renderUploadList());
};
var Upload = /*#__PURE__*/React.forwardRef(InternalUpload);
Upload.Dragger = Dragger;
Upload.displayName = 'Upload';
Upload.defaultProps = {
type: 'select',
multiple: false,
action: '',
data: {},
accept: '',
beforeUpload: T,
showUploadList: true,
listType: 'text',
className: '',
disabled: false,
supportServerRender: true
};
export default Upload;