UNPKG

tdesign-react

Version:
473 lines (469 loc) 23.3 kB
/** * tdesign v1.15.1 * (c) 2025 tdesign * @license MIT */ import { _ as _toConsumableArray } from '../../_chunks/dep-87d110df.js'; import { _ as _defineProperty } from '../../_chunks/dep-cb0a3966.js'; import { _ as _slicedToArray } from '../../_chunks/dep-48805ab8.js'; import React, { useState, useMemo } from 'react'; import classNames from 'classnames'; import { isFunction, isObject } from 'lodash-es'; import { BrowseIcon, DeleteIcon, CheckCircleFilledIcon, ErrorCircleFilledIcon, TimeFilledIcon, FileExcelIcon, FilePdfIcon, FileWordIcon, FilePowerpointIcon, FileIcon, VideoIcon } from 'tdesign-icons-react'; import { a as abridgeName, r as returnFileSize, I as IMAGE_REGEXP, F as FILE_PDF_REGEXP, b as FILE_EXCEL_REGEXP, c as FILE_WORD_REGEXP, d as FILE_PPT_REGEXP, V as VIDEO_REGEXP } from '../../_chunks/dep-f83e4452.js'; import useGlobalIcon from '../../hooks/useGlobalIcon.js'; import { ImageViewer } from '../../image-viewer/index.js'; import { Button } from '../../button/index.js'; import useDrag from '../hooks/useDrag.js'; import { Loading } from '../../loading/index.js'; import { Link } from '../../link/index.js'; import parseTNode from '../../_util/parseTNode.js'; import { Image } from '../../image/index.js'; import '../../_chunks/dep-026a4c6b.js'; import '../../_chunks/dep-eca3a3de.js'; import '../../_chunks/dep-b908e1fe.js'; import '../../hooks/useConfig.js'; import '../../config-provider/ConfigContext.js'; import '../../_chunks/dep-f97636ce.js'; import '../../_chunks/dep-9dbbf468.js'; import 'dayjs'; import '../../image-viewer/ImageViewer.js'; import 'react-dom'; import '../../_chunks/dep-6a010af7.js'; import '../../_chunks/dep-6b660ef0.js'; import '../../_chunks/dep-52ff3837.js'; import '../../_chunks/dep-76b39920.js'; import '../../hooks/useImagePreviewUrl.js'; import '../../locale/LocalReceiver.js'; import '../../config-provider/ConfigProvider.js'; import '../../tooltip/index.js'; import '../../tooltip/Tooltip.js'; import '../../popup/index.js'; import '../../popup/Popup.js'; import 'react-transition-group'; import '../../_util/ref.js'; import 'react-is'; import '../../_util/isFragment.js'; import '../../_chunks/dep-3a09424a.js'; import '../../common/Portal.js'; import '../../hooks/useLayoutEffect.js'; import '../../hooks/useAnimation.js'; import '../../hooks/useAttach.js'; import '../../hooks/useControlled.js'; import '../../_util/noop.js'; import '../../hooks/useDefaultProps.js'; import '../../hooks/useMutationObserver.js'; import '../../hooks/useLatest.js'; import '../../hooks/usePopper.js'; import '@popperjs/core'; import 'react-fast-compare'; import '../../hooks/useWindowSize.js'; import '../../popup/defaultProps.js'; import '../../popup/hooks/useTrigger.js'; import '../../_util/composeRefs.js'; import '../../_util/listener.js'; import '../../popup/utils/transition.js'; import '../../popup/PopupPlugin.js'; import '../../_util/react-render.js'; import '../../common/PluginContainer.js'; import '../../tooltip/defaultProps.js'; import '../../tooltip/TooltipLite.js'; import '../../hooks/useSwitch.js'; import '../../hooks/usePersistFn.js'; import '../../dialog/index.js'; import '../../dialog/Dialog.js'; import '../../hooks/useDeepEffect.js'; import '../../hooks/useSetState.js'; import '../../dialog/defaultProps.js'; import '../../dialog/DialogCard.js'; import '../../button/Button.js'; import '../../hooks/useDomRefCallback.js'; import '../../hooks/useRipple.js'; import '../../_chunks/dep-c48e2ca1.js'; import '../../button/defaultProps.js'; import '../../loading/Loading.js'; import '../../loading/gradient.js'; import '../../_chunks/dep-6af6bc60.js'; import '../../loading/defaultProps.js'; import '../../loading/plugin.js'; import '../../dialog/hooks/useDialogDrag.js'; import '../../hooks/useMouseEvent.js'; import '../../dialog/hooks/useDialogEsc.js'; import '../../dialog/hooks/useDialogPosition.js'; import '../../dialog/hooks/useLockStyle.js'; import '../../_chunks/dep-51092aec.js'; import '../../dialog/utils.js'; import '../../dialog/plugin.js'; import '../../image-viewer/hooks/useIconMap.js'; import '../../image-viewer/hooks/useIndex.js'; import '../../image-viewer/hooks/useMirror.js'; import '../../image-viewer/hooks/usePosition.js'; import '../../image-viewer/hooks/useRotate.js'; import '../../image-viewer/hooks/useScale.js'; import '../../image-viewer/utils.js'; import '../../image-viewer/defaultProps.js'; import '../../image-viewer/hooks/useImageScale.js'; import '../../image-viewer/hooks/useList.js'; import '../../image-viewer/hooks/useViewerScale.js'; import '../../image/Image.js'; import '../../_chunks/dep-4450afc0.js'; import '../../image/defaultProps.js'; import '../../space/index.js'; import '../../space/Space.js'; import '../../space/defaultProps.js'; import '../../link/Link.js'; import '../../link/defaultProps.js'; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } var ImageFlowList = function ImageFlowList(props) { var _props$draggable = props.draggable, draggable = _props$draggable === void 0 ? true : _props$draggable, accept = props.accept, showThumbnail = props.showThumbnail, cancelUploadButton = props.cancelUploadButton, uploadButton = props.uploadButton, onPreview = props.onPreview; var locale = props.locale, uploading = props.uploading, disabled = props.disabled, displayFiles = props.displayFiles, classPrefix = props.classPrefix; var uploadPrefix = "".concat(classPrefix, "-upload"); var _useState = useState([]), _useState2 = _slicedToArray(_useState, 2), currentPreviewFile = _useState2[0], setCurrentPreviewFile = _useState2[1]; var _useState3 = useState(0), _useState4 = _slicedToArray(_useState3, 2), previewIndex = _useState4[0], setPreviewIndex = _useState4[1]; var _useGlobalIcon = useGlobalIcon({ BrowseIcon: BrowseIcon, DeleteIcon: DeleteIcon, CheckCircleFilledIcon: CheckCircleFilledIcon, ErrorCircleFilledIcon: ErrorCircleFilledIcon, TimeFilledIcon: TimeFilledIcon, FileExcelIcon: FileExcelIcon, FilePdfIcon: FilePdfIcon, FileWordIcon: FileWordIcon, FilePowerpointIcon: FilePowerpointIcon, FileIcon: FileIcon, VideoIcon: VideoIcon }), BrowseIcon$1 = _useGlobalIcon.BrowseIcon, DeleteIcon$1 = _useGlobalIcon.DeleteIcon, CheckCircleFilledIcon$1 = _useGlobalIcon.CheckCircleFilledIcon, ErrorCircleFilledIcon$1 = _useGlobalIcon.ErrorCircleFilledIcon, TimeFilledIcon$1 = _useGlobalIcon.TimeFilledIcon, FileExcelIcon$1 = _useGlobalIcon.FileExcelIcon, FilePdfIcon$1 = _useGlobalIcon.FilePdfIcon, FileWordIcon$1 = _useGlobalIcon.FileWordIcon, FilePowerpointIcon$1 = _useGlobalIcon.FilePowerpointIcon, FileIcon$1 = _useGlobalIcon.FileIcon, VideoIcon$1 = _useGlobalIcon.VideoIcon; var drag = useDrag(_objectSpread(_objectSpread({}, props.dragEvents), {}, { accept: accept })); var uploadText = useMemo(function () { if (uploading) return "".concat(locale.progress.uploadingText); return locale.triggerUploadText.normal; }, [locale, uploading]); var innerDragEvents = draggable ? { onDrop: drag.handleDrop, onDragEnter: drag.handleDragenter, onDragOver: drag.handleDragover, onDragLeave: drag.handleDragleave } : {}; var browseIconClick = function browseIconClick(_ref) { var e = _ref.e, index = _ref.index, file = _ref.file, viewFiles = _ref.viewFiles; setPreviewIndex(index); setCurrentPreviewFile(viewFiles); onPreview === null || onPreview === void 0 || onPreview({ file: file, index: index, e: e }); }; var previewIndexChange = function previewIndexChange(index) { setPreviewIndex(index); }; var closePreview = function closePreview() { setCurrentPreviewFile([]); }; var getStatusMap = function getStatusMap() { var _locale$progress, _locale$progress2, _locale$progress3, _locale$progress4; var iconMap = { success: /* @__PURE__ */React.createElement(CheckCircleFilledIcon$1, null), fail: /* @__PURE__ */React.createElement(ErrorCircleFilledIcon$1, null), progress: /* @__PURE__ */React.createElement(Loading, null), waiting: /* @__PURE__ */React.createElement(TimeFilledIcon$1, null) }; var textMap = { success: (_locale$progress = locale.progress) === null || _locale$progress === void 0 ? void 0 : _locale$progress.successText, fail: (_locale$progress2 = locale.progress) === null || _locale$progress2 === void 0 ? void 0 : _locale$progress2.failText, progress: (_locale$progress3 = locale.progress) === null || _locale$progress3 === void 0 ? void 0 : _locale$progress3.uploadingText, waiting: (_locale$progress4 = locale.progress) === null || _locale$progress4 === void 0 ? void 0 : _locale$progress4.waitingText }; return { iconMap: iconMap, textMap: textMap }; }; var renderEmpty = function renderEmpty() { return /* @__PURE__ */React.createElement("div", { className: "".concat(uploadPrefix, "__flow-empty") }, drag.dragActive ? locale.dragger.dragDropText : locale.dragger.clickAndDragText); }; var renderImgItem = function renderImgItem(file, index) { var _file$response; var _getStatusMap = getStatusMap(), iconMap = _getStatusMap.iconMap, textMap = _getStatusMap.textMap; var fileName = props.abridgeName && file.name ? abridgeName.apply(void 0, [file.name].concat(_toConsumableArray(props.abridgeName))) : file.name; return /* @__PURE__ */React.createElement("li", { className: "".concat(uploadPrefix, "__card-item"), key: file.name + index + file.percent + file.status }, /* @__PURE__ */React.createElement("div", { className: classNames(["".concat(uploadPrefix, "__card-content"), _defineProperty({}, "".concat(classPrefix, "-is-bordered"), file.status !== "waiting")]) }, file.status === "progress" && /* @__PURE__ */React.createElement("div", { className: "".concat(uploadPrefix, "__card-status-wrap ").concat(uploadPrefix, "__").concat(props.theme, "-progress") }, iconMap[file.status], /* @__PURE__ */React.createElement("p", null, textMap[file.status], props.showUploadProgress && " ".concat(file.percent, "%"))), file.status === "fail" && /* @__PURE__ */React.createElement("div", { className: "".concat(uploadPrefix, "__card-status-wrap ").concat(uploadPrefix, "__").concat(props.theme, "-fail") }, iconMap[file.status], /* @__PURE__ */React.createElement("p", null, ((_file$response = file.response) === null || _file$response === void 0 ? void 0 : _file$response.error) || textMap[file.status])), (["waiting", "success"].includes(file.status) || !file.status && file.url) && /* @__PURE__ */React.createElement(Image, { className: "".concat(uploadPrefix, "__card-image"), fit: "contain", src: file.url || file.raw, error: "", loading: "" }), /* @__PURE__ */React.createElement("div", { className: "".concat(uploadPrefix, "__card-mask") }, (file.url || file.raw) && !["progress", "fail"].includes(file.status) && /* @__PURE__ */React.createElement("span", { className: "".concat(uploadPrefix, "__card-mask-item") }, /* @__PURE__ */React.createElement(BrowseIcon$1, { onClick: function onClick(event) { var e = event.type ? event : event.e; browseIconClick({ e: e, index: index, file: file, viewFiles: displayFiles }); } }), /* @__PURE__ */React.createElement("span", { className: "".concat(uploadPrefix, "__card-mask-item-divider") })), !disabled && /* @__PURE__ */React.createElement("span", { className: "".concat(uploadPrefix, "__card-mask-item ").concat(uploadPrefix, "__delete"), onClick: function onClick(e) { return props.onRemove({ e: e, index: index, file: file }); } }, /* @__PURE__ */React.createElement(DeleteIcon$1, null)))), props.showImageFileName && /* @__PURE__ */React.createElement("p", { className: classNames(["".concat(uploadPrefix, "__card-name"), "".concat(uploadPrefix, "__flow-status")]) }, ["success", "waiting"].includes(file.status) && iconMap[file.status], fileName)); }; var renderStatus = function renderStatus(file) { var _file$response2; var _getStatusMap2 = getStatusMap(), iconMap = _getStatusMap2.iconMap, textMap = _getStatusMap2.textMap; return /* @__PURE__ */React.createElement("div", { className: "".concat(uploadPrefix, "__flow-status") }, iconMap[file.status], /* @__PURE__ */React.createElement("span", { className: "".concat(uploadPrefix, "__").concat(props.theme, "-").concat(file.status) }, (_file$response2 = file.response) !== null && _file$response2 !== void 0 && _file$response2.error ? file.response.error || textMap[file.status] : textMap[file.status], props.showUploadProgress && file.status === "progress" ? " ".concat(file.percent || 0, "%") : "")); }; var renderNormalActionCol = function renderNormalActionCol(file, index) { var _locale$triggerUpload; return /* @__PURE__ */React.createElement("td", null, /* @__PURE__ */React.createElement(Link, { theme: "primary", hover: "color", className: "".concat(uploadPrefix, "__delete"), onClick: function onClick(e) { return props.onRemove({ e: e, index: index, file: file }); } }, locale === null || locale === void 0 || (_locale$triggerUpload = locale.triggerUploadText) === null || _locale$triggerUpload === void 0 ? void 0 : _locale$triggerUpload["delete"])); }; function getFileThumbnailIcon(fileType) { if (FILE_PDF_REGEXP.test(fileType)) { return /* @__PURE__ */React.createElement(FilePdfIcon$1, null); } if (FILE_EXCEL_REGEXP.test(fileType)) { return /* @__PURE__ */React.createElement(FileExcelIcon$1, null); } if (FILE_WORD_REGEXP.test(fileType)) { return /* @__PURE__ */React.createElement(FileWordIcon$1, null); } if (FILE_PPT_REGEXP.test(fileType)) { return /* @__PURE__ */React.createElement(FilePowerpointIcon$1, null); } if (VIDEO_REGEXP.test(fileType)) { return /* @__PURE__ */React.createElement(VideoIcon$1, null); } return /* @__PURE__ */React.createElement(FileIcon$1, null); } function renderFileThumbnail(file) { if (!file || !file.raw && file.url) return null; var fileType = file.raw.type; var className = "".concat(uploadPrefix, "__file-thumbnail"); if (IMAGE_REGEXP.test(fileType) && (file.url || file.raw)) { return /* @__PURE__ */React.createElement(Image, { className: className, src: file.url || file.raw, fit: "scale-down", error: "", loading: "", onClick: function onClick(e) { e.preventDefault(); browseIconClick({ e: e, index: 0, file: file, viewFiles: [file] }); } }); } return /* @__PURE__ */React.createElement("div", { className: className }, getFileThumbnailIcon(fileType)); } var renderBatchActionCol = function renderBatchActionCol(index) { var _locale$triggerUpload2; return index === 0 ? /* @__PURE__ */React.createElement("td", { rowSpan: displayFiles.length, className: "".concat(uploadPrefix, "__flow-table__batch-row") }, /* @__PURE__ */React.createElement(Link, { theme: "primary", hover: "color", className: "".concat(uploadPrefix, "__delete"), onClick: function onClick(e) { return props.onRemove({ e: e, index: -1, file: void 0 }); } }, locale === null || locale === void 0 || (_locale$triggerUpload2 = locale.triggerUploadText) === null || _locale$triggerUpload2 === void 0 ? void 0 : _locale$triggerUpload2["delete"])) : null; }; var renderFileList = function renderFileList() { var _locale$file, _locale$file2, _locale$file3, _locale$file4; if (props.fileListDisplay === null) return null; if (props.fileListDisplay) { return parseTNode(props.fileListDisplay, { cancelUpload: props.cancelUpload, uploadFiles: props.uploadFiles, onPreview: props.onPreview, onRemove: props.onRemove, toUploadFiles: props.toUploadFiles, sizeOverLimitMessage: props.sizeOverLimitMessage, locale: props.locale, files: displayFiles, dragEvents: innerDragEvents }); } return /* @__PURE__ */React.createElement("table", _objectSpread({ className: "".concat(uploadPrefix, "__flow-table") }, innerDragEvents), /* @__PURE__ */React.createElement("thead", null, /* @__PURE__ */React.createElement("tr", null, /* @__PURE__ */React.createElement("th", null, (_locale$file = locale.file) === null || _locale$file === void 0 ? void 0 : _locale$file.fileNameText), /* @__PURE__ */React.createElement("th", null, (_locale$file2 = locale.file) === null || _locale$file2 === void 0 ? void 0 : _locale$file2.fileSizeText), /* @__PURE__ */React.createElement("th", null, (_locale$file3 = locale.file) === null || _locale$file3 === void 0 ? void 0 : _locale$file3.fileStatusText), disabled ? null : /* @__PURE__ */React.createElement("th", null, (_locale$file4 = locale.file) === null || _locale$file4 === void 0 ? void 0 : _locale$file4.fileOperationText))), /* @__PURE__ */React.createElement("tbody", null, !displayFiles.length && /* @__PURE__ */React.createElement("tr", null, /* @__PURE__ */React.createElement("td", { colSpan: 4 }, renderEmpty())), displayFiles.map(function (file, index) { var _props$abridgeName; var showBatchUploadAction = props.isBatchUpload; var deleteNode = showBatchUploadAction && displayFiles.every(function (item) { return item.status === "success" || !item.status; }) ? renderBatchActionCol(index) : renderNormalActionCol(file, index); var fileName = (_props$abridgeName = props.abridgeName) !== null && _props$abridgeName !== void 0 && _props$abridgeName.length ? abridgeName.apply(void 0, [file.name].concat(_toConsumableArray(props.abridgeName))) : file.name; var thumbnailNode = showThumbnail ? /* @__PURE__ */React.createElement("div", { className: "".concat(uploadPrefix, "__file-info") }, renderFileThumbnail(file), fileName) : fileName; var fileNameNode = file.url ? /* @__PURE__ */React.createElement(Link, { href: file.url, target: "_blank", hover: "color" }, thumbnailNode) : thumbnailNode; return /* @__PURE__ */React.createElement("tr", { key: file.name + index }, /* @__PURE__ */React.createElement("td", { className: "".concat(uploadPrefix, "__file-name") }, fileNameNode), /* @__PURE__ */React.createElement("td", null, returnFileSize(file.size)), /* @__PURE__ */React.createElement("td", null, renderStatus(file)), disabled ? null : deleteNode); }))); }; var renderImageList = function renderImageList() { if (props.fileListDisplay) { return parseTNode(props.fileListDisplay, _objectSpread(_objectSpread({}, props), {}, { files: displayFiles, dragEvents: innerDragEvents })); } return /* @__PURE__ */React.createElement("ul", { className: "".concat(uploadPrefix, "__card clearfix") }, displayFiles.map(function (file, index) { return renderImgItem(file, index); })); }; var renderCancelUploadButton = function renderCancelUploadButton() { if (cancelUploadButton === null) return null; if (isFunction(cancelUploadButton)) return parseTNode(cancelUploadButton); var cancelButtonProps = isObject(cancelUploadButton) ? cancelUploadButton : void 0; return /* @__PURE__ */React.createElement(Button, _objectSpread({ theme: "default", disabled: disabled || !uploading, className: "".concat(uploadPrefix, "__cancel"), onClick: function onClick(e) { var _props$cancelUpload; return (_props$cancelUpload = props.cancelUpload) === null || _props$cancelUpload === void 0 ? void 0 : _props$cancelUpload.call(props, { e: e }); } }, cancelButtonProps), locale === null || locale === void 0 ? void 0 : locale.cancelUploadText); }; var renderUploadButton = function renderUploadButton() { if (uploadButton === null) return null; if (isFunction(uploadButton)) return parseTNode(uploadButton); var uploadButtonProps = isObject(uploadButton) ? uploadButton : void 0; return /* @__PURE__ */React.createElement(Button, _objectSpread({ disabled: disabled || uploading || !displayFiles.length, theme: "primary", loading: uploading, className: "".concat(uploadPrefix, "__continue"), onClick: function onClick() { var _props$uploadFiles; return (_props$uploadFiles = props.uploadFiles) === null || _props$uploadFiles === void 0 ? void 0 : _props$uploadFiles.call(props); } }, uploadButtonProps), uploadText); }; var cardClassName = "".concat(uploadPrefix, "__flow-card-area"); return /* @__PURE__ */React.createElement("div", { className: "".concat(uploadPrefix, "__flow ").concat(uploadPrefix, "__flow-").concat(props.theme) }, /* @__PURE__ */React.createElement("div", { className: "".concat(uploadPrefix, "__flow-op") }, props.children, props.placeholder && /* @__PURE__ */React.createElement("small", { className: "".concat(uploadPrefix, "__flow-placeholder ").concat(uploadPrefix, "__placeholder") }, props.placeholder)), props.theme === "image-flow" && /* @__PURE__ */React.createElement("div", _objectSpread({ className: cardClassName }, innerDragEvents), displayFiles.length ? renderImageList() : renderEmpty()), props.theme === "file-flow" && (displayFiles.length ? renderFileList() : /* @__PURE__ */React.createElement("div", _objectSpread({ className: cardClassName }, innerDragEvents), renderEmpty())), !props.autoUpload && /* @__PURE__ */React.createElement("div", { className: "".concat(uploadPrefix, "__flow-bottom") }, renderCancelUploadButton(), renderUploadButton()), /* @__PURE__ */React.createElement(ImageViewer, _objectSpread({ images: currentPreviewFile.map(function (t) { return t.url || t.raw; }), visible: !!currentPreviewFile.length, onClose: closePreview, index: previewIndex, onIndexChange: previewIndexChange }, props.imageViewerProps))); }; ImageFlowList.displayName = "ImageFlowList"; export { ImageFlowList as default }; //# sourceMappingURL=MultipleFlowList.js.map