UNPKG

@ucloud-pccl/react-components

Version:
441 lines (439 loc) 19.6 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _newArrowCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/newArrowCheck")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _isArray2 = _interopRequireDefault(require("lodash/isArray")); var _uniqueId2 = _interopRequireDefault(require("lodash/uniqueId")); var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _generateError = _interopRequireDefault(require("../../utils/generateError")); var _localeConsumerDecorator = _interopRequireDefault(require("../../components/LocaleProvider/localeConsumerDecorator")); var _Modal = _interopRequireDefault(require("../../components/Modal")); var _deprecatedLog = _interopRequireDefault(require("../../utils/deprecatedLog")); var _Selector = _interopRequireDefault(require("./Selector")); var _List = _interopRequireDefault(require("./List")); var _Dropzone = _interopRequireDefault(require("./Dropzone")); var _zh_CN = _interopRequireDefault(require("./locale/zh_CN")); var _utils = require("./utils"); var _style = require("./style"); var _excluded = ["disabled", "multiple", "accept", "maxSize", "selector", "locale", "selectorBtnProps"]; var _dec, _class, _Upload, _this10 = void 0; function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } var fileShape = _propTypes.default.shape({ name: _propTypes.default.string.isRequired, uid: _propTypes.default.string.isRequired, size: _propTypes.default.number, type: _propTypes.default.string, status: _propTypes.default.string, previewUrl: _propTypes.default.string, thumbnailUrl: _propTypes.default.string }); /** * 文件上传控件 */ var Upload = (_dec = (0, _localeConsumerDecorator.default)({ defaultLocale: _zh_CN.default, localeName: 'Upload' }), _dec(_class = (_Upload = /*#__PURE__*/function (_PureComponent) { function Upload(props) { var _this2 = this; var _this; (0, _classCallCheck2.default)(this, Upload); _this = _callSuper(this, Upload, [props]); /** 判定组件是否为controlled */ _this.componentDidUpdate = function () { (0, _newArrowCheck2.default)(this, _this2); /** 检查props是否更改了controlled类型 */ /* eslint-disable no-console */ if (!_this.IS_CONTROLLED && _this.props.fileList !== undefined) { console.error('You are changing a uncontrolled Upload to be controlled, which may cause a lot of problem'); } else if (_this.IS_CONTROLLED && _this.props.fileList === undefined) { console.error('You are changing a controlled Upload to be uncontrolled, which may cause a lot of problem'); } /* eslint-enable no-console */ }.bind(this); /** 单选 */ _this.onSingleSelect = function (files) { var _this3 = this; (0, _newArrowCheck2.default)(this, _this2); var _this$props = _this.props, onAdd = _this$props.onAdd, onRemove = _this$props.onRemove; if (!files.length) return; var fileList = _this.getFileList(); if (fileList.length) { var file = fileList[0]; if (onRemove(file, 0) === false) { return; } } fileList = [files[0]]; if (onAdd(fileList) === false) { return; } _this.onChange(fileList, function () { (0, _newArrowCheck2.default)(this, _this3); return _this.handleFilesUpload(fileList); }.bind(this)); }.bind(this); /** 处理添加文件 */ _this.onAdd = function (files) { var _this4 = this; (0, _newArrowCheck2.default)(this, _this2); var _this$props2 = _this.props, maxCount = _this$props2.maxCount, onAdd = _this$props2.onAdd; if (onAdd(files) === false) { return; } var fileList = _this.getFileList(); if (fileList.length + files.length > maxCount) { _this.onMaxCountError(); } fileList = fileList.concat(files); if (maxCount > 0) fileList = fileList.slice(0, maxCount); _this.onChange(fileList, function () { (0, _newArrowCheck2.default)(this, _this4); return _this.handleFilesUpload(files); }.bind(this)); }.bind(this); /** 处理文件上传 */ _this.handleFilesUpload = function (files) { var _this5 = this; (0, _newArrowCheck2.default)(this, _this2); var handleUpload = _this.props.handleUpload; if (!handleUpload) return; files.forEach(function (file) { var _this6 = this; (0, _newArrowCheck2.default)(this, _this5); file.status = 'uploading'; handleUpload(file, function (progress) { (0, _newArrowCheck2.default)(this, _this6); file.progress = progress; _this.onChange(_this.getFileList()); }.bind(this)).then(function () { (0, _newArrowCheck2.default)(this, _this6); file.status = 'success'; }.bind(this)).catch(function (e) { (0, _newArrowCheck2.default)(this, _this6); file.status = 'error'; file.error = e; }.bind(this)).then(function () { (0, _newArrowCheck2.default)(this, _this6); _this.onChange(_this.getFileList()); }.bind(this)); }.bind(this)); _this.onChange(_this.getFileList()); }.bind(this); /** 处理删除文件 */ _this.onRemove = function (file, index) { (0, _newArrowCheck2.default)(this, _this2); var onRemove = _this.props.onRemove; if (onRemove(file, index) === false) { return; } var fileList = _this.getFileList(); fileList.splice(index, 1); _this.onChange(fileList); }.bind(this); /** 处理change */ _this.onChange = function (fileList, cb) { (0, _newArrowCheck2.default)(this, _this2); if (!_this.IS_CONTROLLED) { _this.onUncontrolledChange(fileList, cb); } else { _this.onControlledChange(fileList, cb); } }.bind(this); /** 非受控处理change */ _this.onUncontrolledChange = function (fileList, cb) { var _this7 = this; (0, _newArrowCheck2.default)(this, _this2); var onChange = _this.props.onChange; _this.setState({ fileList: fileList }, function () { (0, _newArrowCheck2.default)(this, _this7); onChange(fileList); cb && cb(); }.bind(this)); }.bind(this); /** 受控组件处理change */ _this.onControlledChange = function (fileList) { (0, _newArrowCheck2.default)(this, _this2); var onChange = _this.props.onChange; onChange(fileList); }.bind(this); /** 处理错误 */ _this.onError = function (error) { (0, _newArrowCheck2.default)(this, _this2); var onError = _this.props.onError; if (onError) { onError(error); } else { _this.onDefaultError(error); } }.bind(this); _this.onDefaultError = function (Error) { (0, _newArrowCheck2.default)(this, _this2); var locale = _this.props.locale; _Modal.default.alert({ title: locale.defaultErrorTipTitle }, /*#__PURE__*/_react.default.createElement(_style.ErrorTipWrap, null, Error === null || Error === void 0 ? void 0 : Error.message)); }.bind(this); _this.onMaxCountError = function () { (0, _newArrowCheck2.default)(this, _this2); var _this$props3 = _this.props, maxCount = _this$props3.maxCount, locale = _this$props3.locale; _this.onError((0, _generateError.default)(locale.maxCountErrorTip.replace('{maxCount}', maxCount), 'FileMaxCountError')); }.bind(this); _this.onFileError = function (e) { (0, _newArrowCheck2.default)(this, _this2); _this.onError(e); }.bind(this); _this.onFileSelect = function (files) { (0, _newArrowCheck2.default)(this, _this2); if (!files || !files.length) return; var _this$props4 = _this.props, accept = _this$props4.accept, maxSize = _this$props4.maxSize, multiple = _this$props4.multiple, locale = _this$props4.locale; files = [].slice.call(files); for (var index in files) { var file = files[index]; var checkResult = (0, _utils.checkFile)(file, accept, maxSize, locale); if (checkResult !== true) { _this.onFileError(checkResult); return; } file.uid = (0, _uniqueId2.default)('__file_uid_for_upload_components__'); } if (multiple) { _this.onAdd(files); } else { _this.onSingleSelect(files); } }.bind(this); /** 获取文件列表 */ _this.getFileList = function () { (0, _newArrowCheck2.default)(this, _this2); return (_this.props.fileList || _this.state.fileList).slice(); }.bind(this); _this.renderList = function () { var _this8 = this; (0, _newArrowCheck2.default)(this, _this2); var _this$props5 = _this.props, disabled = _this$props5.disabled, onPreview = _this$props5.onPreview, getPreviewableOfItem = _this$props5.getPreviewableOfItem, locale = _this$props5.locale; var listType = _this.props.listType; var fileList = _this.getFileList(); var listProps = { fileList: fileList, onRemove: _this.onRemove, onPreview: onPreview, getPreviewableOfItem: getPreviewableOfItem, handleReupload: function handleReupload(file) { (0, _newArrowCheck2.default)(this, _this8); return _this.handleFilesUpload([file]); }.bind(this), disabled: disabled, locale: locale }; if (!(0, _isArray2.default)(listType)) { listType = [listType]; } var _listType = listType, _listType2 = (0, _slicedToArray2.default)(_listType, 2), type = _listType2[0], option = _listType2[1]; switch (type) { case 'list': return /*#__PURE__*/_react.default.createElement(_List.default, (0, _extends2.default)({}, listProps, { card: option === 'card', thumbnail: option === 'thumbnail' })); case 'dropzone': return /*#__PURE__*/_react.default.createElement(_Dropzone.default, (0, _extends2.default)({}, listProps, { card: option === 'card', thumbnail: option === 'thumbnail', onSelect: _this.onFileSelect })); case 'none': return null; case 'text': default: return /*#__PURE__*/_react.default.createElement(_List.default, listProps); } }.bind(this); if (props.fileList !== undefined) { if (props.defaultFileList !== undefined) { // eslint-disable-next-line no-console console.error('You can only use one of fileList and defaultFileList'); } _this.IS_CONTROLLED = true; } if (props.listType === 'text') { (0, _deprecatedLog.default)('listType text', 'list'); } _this.state = { fileList: props.fileList || props.defaultFileList || [] }; return _this; } (0, _inherits2.default)(Upload, _PureComponent); return (0, _createClass2.default)(Upload, [{ key: "render", value: function render() { var _this9 = this; var _this$props6 = this.props, disabled = _this$props6.disabled, multiple = _this$props6.multiple, accept = _this$props6.accept, maxSize = _this$props6.maxSize, selector = _this$props6.selector, locale = _this$props6.locale, selectorBtnProps = _this$props6.selectorBtnProps, rest = (0, _objectWithoutProperties2.default)(_this$props6, _excluded); /** clean unused rest props for div */ ['maxCount', 'onChange', 'onAdd', 'onRemove', 'handleUpload', 'onError', 'defaultFileList', 'fileList', 'listType', 'onPreview'].forEach(function (key) { (0, _newArrowCheck2.default)(this, _this9); delete rest[key]; }.bind(this)); return /*#__PURE__*/_react.default.createElement(_style.UploadWrap, rest, /*#__PURE__*/_react.default.createElement(_Selector.default, { onSelect: this.onFileSelect, disabled: disabled, multiple: multiple, accept: accept, maxSize: maxSize, selector: selector, locale: locale, selectorBtnProps: selectorBtnProps }), this.renderList()); } }]); }(_react.PureComponent), _Upload.propTypes = { /** * 文件列表变化时的回调,如新增、删除、上传、上传完成、进度更新等操作 * @param {Object[]} fileList - 文件列表 * @param {string} fileList[].name - 文件名称 * @param {string} fileList[].uid - 文件 uid * @param {number} fileList[].size - 文件的大小 * @param {string} fileList[].type - 文件的类型,MIME * @param {string} fileList[].status - 文件的上传状态,只有传入 handleUpload 时才有的属性 [uploading,success,error] * @param {number} fileList[].progress - 文件的上传进度,只有 handleUpload 中上报了 progress 才会有 */ onChange: _propTypes.default.func, /** * 正在添加文件时的回调,可通过返回值控制添加行为 * @param {Object[]} fileList - 文件列表 * @returns 是否应用添加操作,返回 false 时不触发添加 */ onAdd: _propTypes.default.func, /** * 正在删除文件时的回调,可通过返回值控制添加行为 * @param {Object} file - 删除的文件 * @param {number} index - 删除文件的索引 * @returns 是否应用删除操作,返回 false 时不触发删除 */ onRemove: _propTypes.default.func, /** 自定义文件是否可删除,默认为 loading 时不可删除,如果需要都可删除可直接传入 () => true */ getRemovableOfItem: _propTypes.default.func, /** * 选中或读取文件错误回调,自定义错误处理,不传时默认行为会在报错时拦截文件进入列表并弹窗提示用户 * @param {Object} error - 错误信息 * @param {string} error.message - 错误的具体信息 * @param {string} error.name - 错误的类型,包括 FileTypeError - 文件类型错误、FileSizeError - 文件大小错误、FileMaxCountError - 文件数量错误,以及其他可能出现的原生错误 */ onError: _propTypes.default.func, /** * 预览操作,自定义预览操作,不传时默认为对图片可进行预览,点击会在新窗口打开图片,需要关闭默认行为可使用 null * @param {Object} file - 预览的文件 * @param {number} index - 预览文件的索引 */ onPreview: _propTypes.default.func, /** * 自定义预览操作时每个文件都会调用预览,可以使用这个函数来过滤不想出现预览的文件 * @param {Object} file - 检测的文件 */ getPreviewableOfItem: _propTypes.default.func, /** * 定义上传操作,受控组件中不起作用请自行处理 * 应交互需求,上传中某些样式下会有进度条,需要调用 handleProgress 来更新进度,如果不调用,将会出现一个假的进度条,😂 * @param {Object} file - 上传的文件 * @param {function} handleProgress - 上报上传的进度,(progress) => void,在上传过程中调用 handleProgress(progress) 来更新文件进度 */ handleUpload: _propTypes.default.func, /** 是否禁用 */ disabled: _propTypes.default.bool, /** 是否可以多选 */ multiple: _propTypes.default.bool, /** * 可接受的文件类型, MIME * [input accept](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) */ accept: _propTypes.default.string, /** 文件大小限制 */ maxSize: _propTypes.default.number, /** 文件数量限制 */ maxCount: _propTypes.default.number, /** 自定义选择控件,为 null 时隐藏*/ selector: _propTypes.default.node, /** * 文件列表展示类型,格式为 'list' | ['list', 'card'] | ['dropzone', 'thumbnail'] * none - 隐藏文件列表 * text - 展示文件名称列表 * list - 普通列表形式,可通过第二个参数设置 thumbnail 和 card * dropzone - 拖拽上传区域,可通过第二个参数设置 thumbnail 和 card */ listType: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.array]), /** 默认文件列表,非受控组件使用,初始化时才有效 */ defaultFileList: _propTypes.default.arrayOf(fileShape), /** 文件列表,传入后变为受控组件 */ fileList: _propTypes.default.arrayOf(fileShape), /** 自定义样式 */ customStyle: _propTypes.default.shape({ /** 列表的最大高度 */ listMaxHeight: _propTypes.default.string }), /** @ignore */ className: _propTypes.default.string, /** @ignore */ locale: _propTypes.default.object, /** 自定义选择按钮样式: styleType: string; icon: React.Node */ selectorBtnProps: _propTypes.default.object }, _Upload.defaultProps = { onChange: function onChange() { (0, _newArrowCheck2.default)(this, _this10); }.bind(void 0), onAdd: function onAdd() { (0, _newArrowCheck2.default)(this, _this10); }.bind(void 0), onRemove: function onRemove() { (0, _newArrowCheck2.default)(this, _this10); }.bind(void 0), listType: 'list', selectorBtnProps: {} }, _Upload)) || _class); var _default = exports.default = Upload;