UNPKG

@ant-design/x

Version:

Craft AI-driven interfaces effortlessly

243 lines (234 loc) 8.56 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _icons = require("@ant-design/icons"); var _antd = require("antd"); var _classnames = _interopRequireDefault(require("classnames")); var _react = _interopRequireDefault(require("react")); var _xProvider = require("../../x-provider"); var _context = require("../context"); var _style = _interopRequireDefault(require("../style")); var _util = require("../util"); var _AudioIcon = _interopRequireDefault(require("./AudioIcon")); var _Progress = _interopRequireDefault(require("./Progress")); var _VideoIcon = _interopRequireDefault(require("./VideoIcon")); const EMPTY = '\u00A0'; const DEFAULT_ICON_COLOR = '#8c8c8c'; const IMG_EXTS = ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp', 'svg']; const PRESET_FILE_ICONS = [{ key: 'default', icon: /*#__PURE__*/_react.default.createElement(_icons.FileTextFilled, null), color: DEFAULT_ICON_COLOR, ext: [] }, { key: 'excel', icon: /*#__PURE__*/_react.default.createElement(_icons.FileExcelFilled, null), color: '#22b35e', ext: ['xlsx', 'xls'] }, { key: 'image', icon: /*#__PURE__*/_react.default.createElement(_icons.FileImageFilled, null), color: DEFAULT_ICON_COLOR, ext: IMG_EXTS }, { key: 'markdown', icon: /*#__PURE__*/_react.default.createElement(_icons.FileMarkdownFilled, null), color: DEFAULT_ICON_COLOR, ext: ['md', 'mdx'] }, { key: 'pdf', icon: /*#__PURE__*/_react.default.createElement(_icons.FilePdfFilled, null), color: '#ff4d4f', ext: ['pdf'] }, { key: 'ppt', icon: /*#__PURE__*/_react.default.createElement(_icons.FilePptFilled, null), color: '#ff6e31', ext: ['ppt', 'pptx'] }, { key: 'word', icon: /*#__PURE__*/_react.default.createElement(_icons.FileWordFilled, null), color: '#1677ff', ext: ['doc', 'docx'] }, { key: 'zip', icon: /*#__PURE__*/_react.default.createElement(_icons.FileZipFilled, null), color: '#fab714', ext: ['zip', 'rar', '7z', 'tar', 'gz'] }, { key: 'video', icon: /*#__PURE__*/_react.default.createElement(_VideoIcon.default, null), color: '#ff4d4f', ext: ['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv'] }, { key: 'audio', icon: /*#__PURE__*/_react.default.createElement(_AudioIcon.default, null), color: '#8c8c8c', ext: ['mp3', 'wav', 'flac', 'ape', 'aac', 'ogg'] }]; function matchExt(suffix, ext) { return ext.some(e => suffix.toLowerCase() === `.${e}`); } function getSize(size) { let retSize = size; const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB']; let unitIndex = 0; while (retSize >= 1024 && unitIndex < units.length - 1) { retSize /= 1024; unitIndex++; } return `${retSize.toFixed(0)} ${units[unitIndex]}`; } function FileListCard(props, ref) { const { prefixCls: customizePrefixCls, item, onRemove, className, style, imageProps, type, icon } = props; const context = _react.default.useContext(_context.AttachmentContext); const { disabled } = context || {}; const { name, size, percent, status = 'done', description } = item; // ============================= Prefix ============================= const { getPrefixCls } = (0, _xProvider.useXProviderContext)(); const prefixCls = getPrefixCls('attachment', customizePrefixCls); const cardCls = `${prefixCls}-list-card`; // ============================= Style ============================== const [wrapCSSVar, hashId, cssVarCls] = (0, _style.default)(prefixCls); // ============================== Name ============================== const [namePrefix, nameSuffix] = _react.default.useMemo(() => { const nameStr = name || ''; const match = nameStr.match(/^(.*)\.[^.]+$/); return match ? [match[1], nameStr.slice(match[1].length)] : [nameStr, '']; }, [name]); const isImg = _react.default.useMemo(() => matchExt(nameSuffix, IMG_EXTS), [nameSuffix]); // ============================== Desc ============================== const desc = _react.default.useMemo(() => { if (description) { return description; } if (status === 'uploading') { return `${percent || 0}%`; } if (status === 'error') { return item.response || EMPTY; } return size ? getSize(size) : EMPTY; }, [status, percent]); // ============================== Icon ============================== const [finalIcon, iconColor] = _react.default.useMemo(() => { if (icon) { if (typeof icon === 'string') { const presetIcon = PRESET_FILE_ICONS.find(preset => preset.key === icon); if (presetIcon) { return [presetIcon.icon, presetIcon.color]; } } else { return [icon, undefined]; } } for (const { ext, icon: presetIcon, color } of PRESET_FILE_ICONS) { if (matchExt(nameSuffix, ext)) { return [presetIcon, color]; } } return [/*#__PURE__*/_react.default.createElement(_icons.FileTextFilled, { key: "defaultIcon" }), DEFAULT_ICON_COLOR]; }, [nameSuffix, icon]); // ========================== ImagePreview ========================== const [previewImg, setPreviewImg] = _react.default.useState(); _react.default.useEffect(() => { if (item.originFileObj) { let synced = true; (0, _util.previewImage)(item.originFileObj).then(url => { if (synced) { setPreviewImg(url); } }); return () => { synced = false; }; } setPreviewImg(undefined); }, [item.originFileObj]); // ============================= Render ============================= let content = null; const previewUrl = item.thumbUrl || item.url || previewImg; // 根据 type 属性或文件类型决定是否显示图片预览 const shouldShowImagePreview = type === 'image' || type !== 'file' && isImg && (item.originFileObj || previewUrl); if (shouldShowImagePreview) { // Preview Image style content = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, previewUrl && /*#__PURE__*/_react.default.createElement(_antd.Image, (0, _extends2.default)({ alt: "preview", src: previewUrl }, imageProps)), status !== 'done' && /*#__PURE__*/_react.default.createElement("div", { className: `${cardCls}-img-mask` }, status === 'uploading' && percent !== undefined && /*#__PURE__*/_react.default.createElement(_Progress.default, { percent: percent, prefixCls: cardCls }), status === 'error' && /*#__PURE__*/_react.default.createElement("div", { className: `${cardCls}-desc` }, /*#__PURE__*/_react.default.createElement("div", { className: `${cardCls}-ellipsis-prefix` }, desc)))); } else { // Preview Card style content = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", { className: `${cardCls}-icon`, style: iconColor ? { color: iconColor } : undefined }, finalIcon), /*#__PURE__*/_react.default.createElement("div", { className: `${cardCls}-content` }, /*#__PURE__*/_react.default.createElement("div", { className: `${cardCls}-name` }, /*#__PURE__*/_react.default.createElement("div", { className: `${cardCls}-ellipsis-prefix` }, namePrefix ?? EMPTY), /*#__PURE__*/_react.default.createElement("div", { className: `${cardCls}-ellipsis-suffix` }, nameSuffix)), /*#__PURE__*/_react.default.createElement("div", { className: `${cardCls}-desc` }, /*#__PURE__*/_react.default.createElement("div", { className: `${cardCls}-ellipsis-prefix` }, desc)))); } return wrapCSSVar( /*#__PURE__*/_react.default.createElement("div", { className: (0, _classnames.default)(cardCls, { [`${cardCls}-status-${status}`]: status, [`${cardCls}-type-preview`]: shouldShowImagePreview, [`${cardCls}-type-overview`]: !shouldShowImagePreview }, className, hashId, cssVarCls), style: style, ref: ref }, content, !disabled && onRemove && /*#__PURE__*/_react.default.createElement("button", { type: "button", className: `${cardCls}-remove`, onClick: () => { onRemove(item); } }, /*#__PURE__*/_react.default.createElement(_icons.CloseCircleFilled, null)))); } var _default = exports.default = /*#__PURE__*/_react.default.forwardRef(FileListCard);