UNPKG

linkmore-design

Version:

🌈 πŸš€lmη»„δ»ΆεΊ“γ€‚πŸš€

379 lines (368 loc) β€’ 12.6 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.LIST_IGNORE = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _classnames = _interopRequireDefault(require("classnames")); var _rcUpload = _interopRequireDefault(require("rc-upload")); var _useMergedState = _interopRequireDefault(require("rc-util/lib/hooks/useMergedState")); var React = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _configProvider = require("../config-provider"); var _DisabledContext = _interopRequireDefault(require("../config-provider/DisabledContext")); var _LocaleReceiver = _interopRequireDefault(require("../locale-provider/LocaleReceiver")); var _default2 = _interopRequireDefault(require("../locale/default")); var _warning = _interopRequireDefault(require("../_util/warning")); var _UploadList = _interopRequireDefault(require("./UploadList")); var _utils = require("./utils"); const LIST_IGNORE = `__LIST_IGNORE_${Date.now()}__`; exports.LIST_IGNORE = LIST_IGNORE; const InternalUpload = (props, ref) => { const { fileList, defaultFileList, onRemove, showUploadList = true, listType = 'text', onPreview, onDownload, onChange, onDrop, previewFile, disabled: customDisabled, locale: propLocale, iconRender, isImageUrl, progress, prefixCls: customizePrefixCls, className, type = 'select', children, style, itemRender, maxCount, data = {}, multiple = false, action = '', accept = '', supportServerRender = true } = props; // ===================== Disabled ===================== const disabled = React.useContext(_DisabledContext.default); const mergedDisabled = customDisabled ?? disabled; const [mergedFileList, setMergedFileList] = (0, _useMergedState.default)(defaultFileList || [], { value: fileList, postState: list => list ?? [] }); const [dragState, setDragState] = React.useState('drop'); const upload = React.useRef(null); (0, _warning.default)('fileList' in props || !('value' in props), 'Upload', '`value` is not a valid prop, do you mean `fileList`?'); (0, _warning.default)(!('transformFile' in props), 'Upload', '`transformFile` is deprecated. Please use `beforeUpload` directly.'); // Control mode will auto fill file uid if not provided React.useMemo(() => { const timestamp = Date.now(); (fileList || []).forEach((file, index) => { if (!file.uid && !Object.isFrozen(file)) { file.uid = `__AUTO__${timestamp}_${index}__`; } }); }, [fileList]); const onInternalChange = (file, changedFileList, event) => { let cloneList = [...changedFileList]; // Cut to match count if (maxCount === 1) { cloneList = cloneList.slice(-1); } else if (maxCount) { cloneList = cloneList.slice(0, maxCount); } // Prevent React18 auto batch since input[upload] trigger process at same time // which makes fileList closure problem (0, _reactDom.flushSync)(() => { setMergedFileList(cloneList); }); const changeInfo = { file: file, fileList: cloneList }; if (event) { changeInfo.event = event; } onChange?.(changeInfo); }; const mergedBeforeUpload = async (file, fileListArgs) => { const { beforeUpload, transformFile } = props; let parsedFile = file; if (beforeUpload) { const result = await beforeUpload(file, fileListArgs); if (result === false) { return false; } // Hack for LIST_IGNORE, we add additional info to remove from the list delete file[LIST_IGNORE]; if (result === LIST_IGNORE) { Object.defineProperty(file, LIST_IGNORE, { value: true, configurable: true }); return false; } if (typeof result === 'object' && result) { parsedFile = result; } } if (transformFile) { parsedFile = await transformFile(parsedFile); } return parsedFile; }; const onBatchStart = batchFileInfoList => { // Skip file which marked as `LIST_IGNORE`, these file will not add to file list const filteredFileInfoList = batchFileInfoList.filter(info => !info.file[LIST_IGNORE]); // Nothing to do since no file need upload if (!filteredFileInfoList.length) { return; } const objectFileList = filteredFileInfoList.map(info => (0, _utils.file2Obj)(info.file)); // Concat new files with prev files let newFileList = [...mergedFileList]; objectFileList.forEach(fileObj => { // Replace file if exist newFileList = (0, _utils.updateFileList)(fileObj, newFileList); }); objectFileList.forEach((fileObj, index) => { // Repeat trigger `onChange` event for compatible let triggerFileObj = fileObj; if (!filteredFileInfoList[index].parsedFile) { // `beforeUpload` return false const { originFileObj } = fileObj; let clone; try { clone = new File([originFileObj], originFileObj.name, { type: originFileObj.type }); } catch (e) { clone = new Blob([originFileObj], { type: originFileObj.type }); clone.name = originFileObj.name; clone.lastModifiedDate = new Date(); clone.lastModified = new Date().getTime(); } clone.uid = fileObj.uid; triggerFileObj = clone; } else { // Inject `uploading` status fileObj.status = 'uploading'; } onInternalChange(triggerFileObj, newFileList); }); }; const onSuccess = (response, file, xhr) => { try { if (typeof response === 'string') { response = JSON.parse(response); } } catch (e) { /* do nothing */ } // removed if (!(0, _utils.getFileItem)(file, mergedFileList)) { return; } const targetItem = (0, _utils.file2Obj)(file); targetItem.status = 'done'; targetItem.percent = 100; targetItem.response = response; targetItem.xhr = xhr; const nextFileList = (0, _utils.updateFileList)(targetItem, mergedFileList); onInternalChange(targetItem, nextFileList); }; const onProgress = (e, file) => { // removed if (!(0, _utils.getFileItem)(file, mergedFileList)) { return; } const targetItem = (0, _utils.file2Obj)(file); targetItem.status = 'uploading'; targetItem.percent = e.percent; const nextFileList = (0, _utils.updateFileList)(targetItem, mergedFileList); onInternalChange(targetItem, nextFileList, e); }; const onError = (error, response, file) => { // removed if (!(0, _utils.getFileItem)(file, mergedFileList)) { return; } const targetItem = (0, _utils.file2Obj)(file); targetItem.error = error; targetItem.response = response; targetItem.status = 'error'; const nextFileList = (0, _utils.updateFileList)(targetItem, mergedFileList); onInternalChange(targetItem, nextFileList); }; const handleRemove = file => { let currentFile; Promise.resolve(typeof onRemove === 'function' ? onRemove(file) : onRemove).then(ret => { // Prevent removing file if (ret === false) { return; } const removedFileList = (0, _utils.removeFileItem)(file, mergedFileList); if (removedFileList) { currentFile = { ...file, status: 'removed' }; mergedFileList?.forEach(item => { const matchKey = currentFile.uid !== undefined ? 'uid' : 'name'; if (item[matchKey] === currentFile[matchKey] && !Object.isFrozen(item)) { item.status = 'removed'; } }); upload.current?.abort(currentFile); onInternalChange(currentFile, removedFileList); } }); }; const onFileDrop = e => { setDragState(e.type); if (e.type === 'drop') { onDrop?.(e); } }; // Test needs React.useImperativeHandle(ref, () => ({ onBatchStart, onSuccess, onProgress, onError, fileList: mergedFileList, upload: upload.current })); const { getPrefixCls, direction } = React.useContext(_configProvider.ConfigContext); const prefixCls = getPrefixCls('upload', customizePrefixCls); const rcUploadProps = { onBatchStart, onError, onProgress, onSuccess, ...props, data, multiple, action, accept, supportServerRender, prefixCls, disabled: mergedDisabled, beforeUpload: mergedBeforeUpload, onChange: undefined }; 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 || mergedDisabled) { delete rcUploadProps.id; } const renderUploadList = (button, buttonVisible) => showUploadList ? /*#__PURE__*/React.createElement(_LocaleReceiver.default, { componentName: "Upload", defaultLocale: _default2.default.Upload }, contextLocale => { const { showRemoveIcon, showPreviewIcon, showDownloadIcon, removeIcon, previewIcon, downloadIcon } = typeof showUploadList === 'boolean' ? {} : showUploadList; return /*#__PURE__*/React.createElement(_UploadList.default, { prefixCls: prefixCls, listType: listType, items: mergedFileList, previewFile: previewFile, onPreview: onPreview, onDownload: onDownload, onRemove: handleRemove, showRemoveIcon: !mergedDisabled && showRemoveIcon, showPreviewIcon: showPreviewIcon, showDownloadIcon: showDownloadIcon, removeIcon: removeIcon, previewIcon: previewIcon, downloadIcon: downloadIcon, iconRender: iconRender, locale: { ...contextLocale, ...propLocale }, isImageUrl: isImageUrl, progress: progress, appendAction: button, appendActionVisible: buttonVisible, itemRender: itemRender }); }) : button; if (type === 'drag') { const dragCls = (0, _classnames.default)(prefixCls, { [`${prefixCls}-drag`]: true, [`${prefixCls}-drag-uploading`]: mergedFileList.some(file => file.status === 'uploading'), [`${prefixCls}-drag-hover`]: dragState === 'dragover', [`${prefixCls}-disabled`]: mergedDisabled, [`${prefixCls}-rtl`]: direction === 'rtl' }, 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.default, (0, _extends2.default)({}, rcUploadProps, { ref: upload, className: `${prefixCls}-btn` }), /*#__PURE__*/React.createElement("div", { className: `${prefixCls}-drag-container` }, children))), renderUploadList()); } const uploadButtonCls = (0, _classnames.default)(prefixCls, { [`${prefixCls}-select`]: true, [`${prefixCls}-select-${listType}`]: true, [`${prefixCls}-disabled`]: mergedDisabled, [`${prefixCls}-rtl`]: direction === 'rtl' }); const renderUploadButton = uploadButtonStyle => /*#__PURE__*/React.createElement("div", { className: uploadButtonCls, style: uploadButtonStyle }, /*#__PURE__*/React.createElement(_rcUpload.default, (0, _extends2.default)({}, rcUploadProps, { ref: upload }))); const uploadButton = renderUploadButton(children ? undefined : { display: 'none' }); if (listType === 'picture-card') { return /*#__PURE__*/React.createElement("span", { className: (0, _classnames.default)(`${prefixCls}-picture-card-wrapper`, className) }, renderUploadList(uploadButton, !!children)); } return /*#__PURE__*/React.createElement("span", { className: className }, uploadButton, renderUploadList()); }; const Upload = /*#__PURE__*/React.forwardRef(InternalUpload); if (process.env.NODE_ENV !== 'production') { Upload.displayName = 'Upload'; } var _default = Upload; exports.default = _default;