UNPKG

@alifd/next

Version:

A configurable component library for web built on React.

346 lines (345 loc) 20 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var react_1 = tslib_1.__importStar(require("react")); var prop_types_1 = tslib_1.__importDefault(require("prop-types")); var classnames_1 = tslib_1.__importDefault(require("classnames")); var config_provider_1 = tslib_1.__importDefault(require("../config-provider")); var progress_1 = tslib_1.__importDefault(require("../progress")); var icon_1 = tslib_1.__importDefault(require("../icon")); var button_1 = tslib_1.__importDefault(require("../button")); var util_1 = require("../util"); var zh_cn_1 = tslib_1.__importDefault(require("../locale/zh-cn")); var util_2 = require("./util"); var transform_1 = tslib_1.__importDefault(require("./transform")); var selecter_1 = tslib_1.__importDefault(require("./runtime/selecter")); var isIE9 = util_1.env.ieVersion === 9; var List = /** @class */ (function (_super) { tslib_1.__extends(List, _super); function List() { var _this = _super.apply(this, tslib_1.__spreadArray([], tslib_1.__read(arguments), false)) || this; _this.handleClose = function (file) { var _a = _this.props, onRemove = _a.onRemove, uploader = _a.uploader; var remove = onRemove(file); util_1.func.promiseCall(remove, function () { uploader && uploader.removeFile(file); }); }; _this.handleCancel = function (file) { var _a = _this.props, onCancel = _a.onCancel, uploader = _a.uploader; var cancel = onCancel(file); util_1.func.promiseCall(cancel, function () { uploader && uploader.abort(file); }); }; _this.onImageError = function (file, obj) { obj.onerror = null; _this.props.onImageError(obj, file); }; _this.onSelect = function (oldfile, files) { var uploader = _this.props.uploader; uploader && files.length && uploader.replaceWithNewFile(oldfile, files[0]); }; return _this; } List.prototype.componentDidUpdate = function () { var _this = this; var _a = this.props, listType = _a.listType, useDataURL = _a.useDataURL, value = _a.value; if (listType !== 'image' && listType !== 'card') { return; } useDataURL && value.forEach(function (file) { if (typeof document === 'undefined' || typeof window === 'undefined' || !window.FileReader || !window.File || !(file.originFileObj instanceof File) || file.imgURL !== undefined) { return; } file.imgURL = ''; (0, util_2.previewFile)(file.originFileObj, function (previewDataUrl) { file.imgURL = previewDataUrl; _this.forceUpdate(); }); }); }; List.prototype.onPreview = function (file, e) { var onPreview = this.props.onPreview; if (!onPreview) { return; } // e.preventDefault(); return onPreview(file, e); }; List.prototype.getInfo = function (file) { var _a; var prefixCls = "".concat(this.props.prefix, "upload"); var downloadURL = file.downloadURL || file.url; var imgURL = file.imgURL || file.url; var size = this.sizeCaculator(file.size); var itemCls = (0, classnames_1.default)((_a = {}, _a["".concat(prefixCls, "-list-item")] = true, _a["".concat(prefixCls, "-list-item-").concat(file.state)] = file.state, _a["".concat(prefixCls, "-list-item-error-with-msg")] = file.state === 'error' && file.errorMsg, _a)); var alt = file.name || file.alt; return { prefixCls: prefixCls, downloadURL: downloadURL, imgURL: imgURL, size: size, itemCls: itemCls, alt: alt }; }; // transfer size from number to xx K/ XxxM / xxG List.prototype.sizeCaculator = function (size) { var fileSize = parseFloat(size); // fileSize 为浮点数 用 < 0.000001 替代 === 0 if (isNaN(fileSize) || fileSize < 0.0000001) { return 0; } var SIZE_SUFFIX = ['B', 'K', 'M', 'G', 'T', 'P']; var suffixIndex = 0; // 在Mac上实验发现 取1024造成显示的大小和实际大小不一致 // 因为单位制不同 见 https://superuser.com/questions/938234/size-of-files-in-windows-os-its-kb-or-kb var BIT_NUMBER_SYSTEM = 1024; while (fileSize >= BIT_NUMBER_SYSTEM && suffixIndex < SIZE_SUFFIX.length) { suffixIndex++; fileSize /= BIT_NUMBER_SYSTEM; } var suffix = SIZE_SUFFIX[suffixIndex]; fileSize = fileSize.toFixed(2); return "".concat(fileSize).concat(suffix); }; List.prototype.getTextList = function (file) { var _this = this; var _a = this.props, locale = _a.locale, extraRender = _a.extraRender, actionRender = _a.actionRender, progressProps = _a.progressProps, rtl = _a.rtl, fileNameRender = _a.fileNameRender, previewOnFileName = _a.previewOnFileName; var _b = this.getInfo(file), prefixCls = _b.prefixCls, downloadURL = _b.downloadURL, size = _b.size, itemCls = _b.itemCls; var onClick = function () { return file.state === 'uploading' ? _this.handleCancel(file) : _this.handleClose(file); }; var onKeyDown = function (e) { if (e.keyCode === util_1.KEYCODE.ENTER) { onClick(); } }; return (react_1.default.createElement("div", { className: itemCls, key: file.uid || file.name }, react_1.default.createElement("div", { className: "".concat(prefixCls, "-list-item-name-wrap") }, react_1.default.createElement("a", { onClick: previewOnFileName ? this.onPreview.bind(this, file) : util_1.func.noop, href: downloadURL, target: "_blank", style: { pointerEvents: (downloadURL ? '' : 'none') }, className: "".concat(prefixCls, "-list-item-name") }, react_1.default.createElement("span", null, fileNameRender(file)), !!size && (react_1.default.createElement("span", { className: "".concat(prefixCls, "-list-item-size"), dir: rtl ? 'rtl' : undefined }, "(", size, ")")), react_1.default.createElement("span", { className: "".concat(prefixCls, "-extra") }, extraRender(file)))), file.state === 'uploading' ? (react_1.default.createElement("div", { className: "".concat(prefixCls, "-list-item-progress") }, react_1.default.createElement(progress_1.default, tslib_1.__assign({ size: "medium", percent: file.percent, textRender: util_1.func.noop, rtl: rtl }, progressProps)))) : null, file.state === 'error' && file.errorMsg ? (react_1.default.createElement("div", { className: "".concat(prefixCls, "-list-item-error-msg") }, file.errorMsg)) : null, react_1.default.createElement("span", { className: "".concat(prefixCls, "-list-item-op") }, actionRender(file), this.props.closable ? (react_1.default.createElement(icon_1.default, { type: "close", size: "large", role: "button", "aria-label": locale.upload.delete, tabIndex: 0, onClick: onClick, onKeyDown: onKeyDown })) : null))); }; List.prototype.getImageList = function (file) { var _this = this; var _a = this.props, extraRender = _a.extraRender, actionRender = _a.actionRender, progressProps = _a.progressProps, rtl = _a.rtl, fileNameRender = _a.fileNameRender, previewOnFileName = _a.previewOnFileName, itemRender = _a.itemRender; var _b = this.getInfo(file), prefixCls = _b.prefixCls, downloadURL = _b.downloadURL, imgURL = _b.imgURL, size = _b.size, itemCls = _b.itemCls, alt = _b.alt; var img = null; var onClick = function () { return file.state === 'uploading' ? _this.handleCancel(file) : _this.handleClose(file); }; var onKeyDown = function (e) { if (e.keyCode === util_1.KEYCODE.ENTER) { onClick(); } }; if (file.state === 'uploading' || (file.state === 'selected' && !imgURL)) { img = react_1.default.createElement(icon_1.default, { type: "picture" }); } else if (file.state === 'error') { img = react_1.default.createElement(icon_1.default, { type: "cry" }); } else { /* eslint-disable no-lonely-if */ if (typeof itemRender === 'function') { img = itemRender(file); } else { img = (react_1.default.createElement("img", { src: imgURL, onError: this.onImageError.bind(this, file), tabIndex: 0, alt: alt, onClick: this.onPreview.bind(this, file) })); } } return (react_1.default.createElement("div", { className: itemCls, key: file.uid || file.name }, react_1.default.createElement("div", { className: "".concat(prefixCls, "-list-item-thumbnail") }, img), react_1.default.createElement("span", { className: "".concat(prefixCls, "-list-item-op") }, actionRender(file), this.props.closable ? (react_1.default.createElement(icon_1.default, { type: "close", size: "large", tabIndex: 0, role: "button", onClick: onClick, onKeyDown: onKeyDown })) : null), react_1.default.createElement("a", { onClick: previewOnFileName ? this.onPreview.bind(this, file) : util_1.func.noop, href: downloadURL, target: "_blank", style: { pointerEvents: (downloadURL ? '' : 'none') }, className: "".concat(prefixCls, "-list-item-name") }, react_1.default.createElement("span", null, fileNameRender(file)), !!size && (react_1.default.createElement("span", { className: "".concat(prefixCls, "-list-item-size"), dir: rtl ? 'rtl' : undefined }, "(", size, ")")), react_1.default.createElement("span", { className: "".concat(prefixCls, "-extra") }, extraRender(file))), file.state === 'uploading' ? (react_1.default.createElement("div", { className: "".concat(prefixCls, "-list-item-progress") }, react_1.default.createElement(progress_1.default, tslib_1.__assign({ size: "medium", percent: file.percent, textRender: util_1.func.noop }, progressProps)))) : null, file.state === 'error' && file.errorMsg ? (react_1.default.createElement("div", { className: "".concat(prefixCls, "-list-item-error-msg") }, file.errorMsg)) : null)); }; List.prototype.getPictureCardList = function (file, isPreview) { var _this = this; var _a = this.props, locale = _a.locale, progressProps = _a.progressProps, fileNameRender = _a.fileNameRender, itemRender = _a.itemRender, showDownload = _a.showDownload; var _b = this.getInfo(file), prefixCls = _b.prefixCls, downloadURL = _b.downloadURL, imgURL = _b.imgURL, itemCls = _b.itemCls, alt = _b.alt; var state = isPreview ? '' : file.state; var img = null; if (state === 'uploading' || (state === 'selected' && !imgURL)) { img = (react_1.default.createElement("div", { className: "".concat(prefixCls, "-list-item-handler") }, react_1.default.createElement(icon_1.default, { type: "picture" }), react_1.default.createElement(button_1.default, { text: true, onClick: function () { return _this.handleCancel(file); } }, locale.card.cancel))); } else if (state === 'error') { img = (react_1.default.createElement("div", { className: "".concat(prefixCls, "-list-item-handler") }, react_1.default.createElement(icon_1.default, { type: "cry" }))); } else { img = (react_1.default.createElement("img", { src: imgURL, tabIndex: 0, alt: alt, onError: this.onImageError.bind(this, file), onClick: this.onPreview.bind(this, file) })); } var onClose = function () { return _this.handleClose(file); }; var onKeyDownClose = function (e) { if (e.keyCode === util_1.KEYCODE.ENTER) { onClose(); } }; var item = null; if (state === 'uploading') { item = [ react_1.default.createElement("div", { className: "".concat(prefixCls, "-list-item-thumbnail"), key: "img" }, img), react_1.default.createElement("div", { className: "".concat(prefixCls, "-list-item-progress"), key: "progress" }, react_1.default.createElement(progress_1.default, tslib_1.__assign({ size: "medium", percent: file.percent, textRender: util_1.func.noop }, progressProps))), ]; } else { /* eslint-disable no-lonely-if */ if (typeof itemRender === 'function') { // 不处理上传态和选择态,太过复杂 item = itemRender(file, { remove: onClose }); } else { var Uploader = this.props.uploader || { props: {} }; var UploaderProps = Uploader.props; // TODO: 2.x 中逻辑会修改为,只要有 showDownload,那就有下载按钮(不管有没有 downloadURL) item = [ react_1.default.createElement("div", { className: "".concat(prefixCls, "-list-item-thumbnail"), key: "img" }, img), react_1.default.createElement("span", { key: "tool", className: "".concat(prefixCls, "-tool") }, state !== 'error' && showDownload && downloadURL ? (react_1.default.createElement("a", { href: downloadURL, target: "_blank", className: "".concat(prefixCls, "-tool-item ").concat(prefixCls, "-tool-download-link") }, react_1.default.createElement(icon_1.default, { type: "download", "aria-label": locale.card.download, className: "".concat(prefixCls, "-tool-download-icon") }))) : null, this.props.reUpload && !isPreview && !isIE9 ? (react_1.default.createElement(selecter_1.default, { className: "".concat(prefixCls, "-tool-item ").concat(prefixCls, "-tool-reupload"), accept: UploaderProps.accept, name: UploaderProps.fileKeyName, onSelect: this.onSelect.bind(this, file) }, react_1.default.createElement(icon_1.default, { type: "edit", className: "".concat(prefixCls, "-tool-reupload-icon") }))) : null, this.props.closable && !isPreview ? (react_1.default.createElement("span", { className: "".concat(prefixCls, "-tool-item ").concat(prefixCls, "-tool-close") }, react_1.default.createElement(icon_1.default, { type: "ashbin", "aria-label": locale.card.delete, tabIndex: 0, role: "button", onClick: onClose, onKeyDown: onKeyDownClose }))) : null), ]; } } return (react_1.default.createElement("div", { className: itemCls, key: file.uid || file.name }, react_1.default.createElement("div", { className: "".concat(prefixCls, "-list-item-wrapper") }, item), react_1.default.createElement("span", { className: "".concat(prefixCls, "-list-item-name") }, fileNameRender(file)))); }; List.prototype.render = function () { var _a, _b; var _this = this; var _c = this.props, listType = _c.listType, children = _c.children, prefix = _c.prefix, rtl = _c.rtl, className = _c.className, isPreview = _c.isPreview; var prefixCls = "".concat(prefix, "upload"); var list = []; if (isPreview) { var previewCls_1 = (0, classnames_1.default)((_a = {}, _a["".concat(prefix, "form-preview")] = true, _a[className] = !!className, _a)); list = this.props.value.map(function (file, index) { if (!file) { return null; } var downloadURL = file.downloadURL, name = file.name; if (listType === 'text') { return (react_1.default.createElement("div", { className: previewCls_1, key: index }, react_1.default.createElement("a", { href: downloadURL, target: "_blank" }, name))); } else if (listType === 'image' || listType === 'card') { return _this.getPictureCardList(file, true); } return null; }); } else { list = this.props.value.map(function (file) { if (!file) { return null; } if (listType === 'text') { return _this.getTextList(file); } else if (listType === 'image') { return _this.getImageList(file); } else if (listType === 'card') { return _this.getPictureCardList(file); } return null; }); } if (rtl && listType === 'card' && Array.isArray(list)) { list = list.reverse(); } var _listType = isPreview && listType === 'image' ? 'card' : this.props.listType; var listclassNames = (0, classnames_1.default)((_b = {}, _b["".concat(prefixCls, "-list")] = true, _b["".concat(prefixCls, "-list-").concat(_listType)] = true, _b["".concat(prefixCls, "-ie9")] = isIE9, _b), className); var others = util_1.obj.pickAttrsWith(this.props, 'data-'); return (react_1.default.createElement("div", tslib_1.__assign({}, others, { className: listclassNames, dir: rtl ? 'rtl' : undefined }), rtl ? children : list, rtl ? list : children)); }; List.propTypes = { prefix: prop_types_1.default.string, locale: prop_types_1.default.object, listType: prop_types_1.default.oneOf(['text', 'image', 'card']), value: prop_types_1.default.array, closable: prop_types_1.default.bool, onRemove: prop_types_1.default.func, onCancel: prop_types_1.default.func, onImageError: prop_types_1.default.func, onPreview: prop_types_1.default.func, previewOnFileName: prop_types_1.default.bool, extraRender: prop_types_1.default.func, actionRender: prop_types_1.default.func, itemRender: prop_types_1.default.func, progressProps: prop_types_1.default.object, children: prop_types_1.default.node, uploader: prop_types_1.default.any, showDownload: prop_types_1.default.bool, useDataURL: prop_types_1.default.bool, rtl: prop_types_1.default.bool, isPreview: prop_types_1.default.bool, fileNameRender: prop_types_1.default.func, }; List.defaultProps = { prefix: 'next-', listType: 'text', value: [], locale: zh_cn_1.default.Upload, closable: false, showDownload: true, onRemove: util_1.func.noop, onCancel: util_1.func.noop, extraRender: util_1.func.noop, actionRender: util_1.func.noop, onImageError: util_1.func.noop, progressProps: {}, fileNameRender: function (file) { return file.name; }, previewOnFileName: false, }; return List; }(react_1.Component)); // Wrap <List> with <ConfigProvider> to avoid context missing if it is // referenced by other internal modules. // https://github.com/alibaba-fusion/next/blob/build/1.13.9/src/upload/upload.jsx#L521 exports.default = config_provider_1.default.config(List, { componentName: 'Upload', // @ts-expect-error 类型不匹配 transform: transform_1.default, });