@ant-design/x
Version:
Craft AI-driven interfaces effortlessly
243 lines (234 loc) • 8.56 kB
JavaScript
;
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);