@ai-group/chat-sdk 3.7.1-alpha2 → 3.7.1-alpha4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/FileGallery/index.js +59 -40
- package/dist/cjs/components/FileGallery/index.js.map +2 -2
- package/dist/cjs/components/FileGallery/styles.d.ts +7 -0
- package/dist/cjs/components/FileGallery/styles.js +78 -0
- package/dist/cjs/components/FileGallery/styles.js.map +2 -2
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/index.d.ts +7 -1
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/index.js +82 -22
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/index.js.map +2 -2
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/styles.d.ts +3 -0
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/styles.js +39 -0
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/styles.js.map +2 -2
- package/dist/cjs/components/XAdkChatbot/index.js +35 -5
- package/dist/cjs/components/XAdkChatbot/index.js.map +2 -2
- package/dist/cjs/components/XAdkChatbot/styles.js +1 -1
- package/dist/cjs/components/XAdkChatbot/styles.js.map +1 -1
- package/dist/cjs/components/XAdkSender/InlineTagInput.d.ts +11 -5
- package/dist/cjs/components/XAdkSender/InlineTagInput.js +188 -113
- package/dist/cjs/components/XAdkSender/InlineTagInput.js.map +2 -2
- package/dist/cjs/components/XAdkSender/InputTags.d.ts +2 -2
- package/dist/cjs/components/XAdkSender/InputTags.js +8 -8
- package/dist/cjs/components/XAdkSender/InputTags.js.map +2 -2
- package/dist/cjs/components/XAdkSender/index.js +104 -64
- package/dist/cjs/components/XAdkSender/index.js.map +2 -2
- package/dist/cjs/components/XAdkSender/styles.d.ts +4 -0
- package/dist/cjs/components/XAdkSender/styles.js +34 -6
- package/dist/cjs/components/XAdkSender/styles.js.map +2 -2
- package/dist/cjs/index.d.ts +2 -1
- package/dist/cjs/index.js +7 -0
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/types/FileGallery.d.ts +3 -0
- package/dist/cjs/types/FileGallery.js.map +1 -1
- package/dist/cjs/types/XAdkChatbot.d.ts +15 -0
- package/dist/cjs/types/XAdkChatbot.js.map +1 -1
- package/dist/cjs/types/XAdkSender.d.ts +74 -23
- package/dist/cjs/types/XAdkSender.js.map +1 -1
- package/dist/cjs/utils/index.d.ts +1 -0
- package/dist/cjs/utils/index.js +3 -1
- package/dist/cjs/utils/index.js.map +2 -2
- package/dist/cjs/utils/markdownResource.d.ts +7 -0
- package/dist/cjs/utils/markdownResource.js +73 -0
- package/dist/cjs/utils/markdownResource.js.map +7 -0
- package/dist/esm/components/FileGallery/index.js +22 -16
- package/dist/esm/components/FileGallery/index.js.map +1 -1
- package/dist/esm/components/FileGallery/styles.d.ts +7 -0
- package/dist/esm/components/FileGallery/styles.js +24 -17
- package/dist/esm/components/FileGallery/styles.js.map +1 -1
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.d.ts +7 -1
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.js +57 -7
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.js.map +1 -1
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/styles.d.ts +3 -0
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/styles.js +5 -2
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/styles.js.map +1 -1
- package/dist/esm/components/XAdkChatbot/index.js +20 -6
- package/dist/esm/components/XAdkChatbot/index.js.map +1 -1
- package/dist/esm/components/XAdkChatbot/styles.js +1 -1
- package/dist/esm/components/XAdkChatbot/styles.js.map +1 -1
- package/dist/esm/components/XAdkSender/InlineTagInput.d.ts +11 -5
- package/dist/esm/components/XAdkSender/InlineTagInput.js +185 -117
- package/dist/esm/components/XAdkSender/InlineTagInput.js.map +1 -1
- package/dist/esm/components/XAdkSender/InputTags.d.ts +2 -2
- package/dist/esm/components/XAdkSender/InputTags.js +9 -9
- package/dist/esm/components/XAdkSender/InputTags.js.map +1 -1
- package/dist/esm/components/XAdkSender/index.js +124 -77
- package/dist/esm/components/XAdkSender/index.js.map +1 -1
- package/dist/esm/components/XAdkSender/styles.d.ts +4 -0
- package/dist/esm/components/XAdkSender/styles.js +29 -25
- package/dist/esm/components/XAdkSender/styles.js.map +1 -1
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/FileGallery.d.ts +3 -0
- package/dist/esm/types/FileGallery.js.map +1 -1
- package/dist/esm/types/XAdkChatbot.d.ts +15 -0
- package/dist/esm/types/XAdkChatbot.js.map +1 -1
- package/dist/esm/types/XAdkSender.d.ts +74 -23
- package/dist/esm/types/XAdkSender.js.map +1 -1
- package/dist/esm/utils/index.d.ts +1 -0
- package/dist/esm/utils/index.js +1 -0
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/esm/utils/markdownResource.d.ts +7 -0
- package/dist/esm/utils/markdownResource.js +33 -0
- package/dist/esm/utils/markdownResource.js.map +1 -0
- package/dist/umd/chat-sdk.min.js +1 -1
- package/package.json +1 -1
|
@@ -121,6 +121,7 @@ var ImageWithLoading = ({
|
|
|
121
121
|
preview,
|
|
122
122
|
fallback,
|
|
123
123
|
displayMode,
|
|
124
|
+
className,
|
|
124
125
|
styles
|
|
125
126
|
}) => {
|
|
126
127
|
const [loadState, setLoadState] = (0, import_react.useState)("loading");
|
|
@@ -133,35 +134,43 @@ var ImageWithLoading = ({
|
|
|
133
134
|
containerStyle.width = typeof width === "number" ? `${width}px` : width;
|
|
134
135
|
if (height)
|
|
135
136
|
containerStyle.height = typeof height === "number" ? `${height}px` : height;
|
|
136
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
137
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
138
|
+
"div",
|
|
139
|
+
{
|
|
140
|
+
className: `${modeClass} ${className || ""}`,
|
|
141
|
+
style: containerStyle,
|
|
142
|
+
children: [
|
|
143
|
+
loadState === "loading" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.imageLoadingSkeleton, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.PictureOutlined, { style: { fontSize: 20, color: "#d9d9d9" } }) }),
|
|
144
|
+
loadState === "error" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.imageErrorFallback, children: [
|
|
145
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.PictureOutlined, {}),
|
|
146
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "加载失败" })
|
|
147
|
+
] }),
|
|
148
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
149
|
+
import_antd.Image,
|
|
150
|
+
{
|
|
151
|
+
src,
|
|
152
|
+
alt,
|
|
153
|
+
fallback,
|
|
154
|
+
preview,
|
|
155
|
+
loading,
|
|
156
|
+
style: {
|
|
157
|
+
display: loadState === "error" ? "none" : "block",
|
|
158
|
+
opacity: loadState === "loading" ? 0 : 1,
|
|
159
|
+
transition: "opacity 0.3s ease",
|
|
160
|
+
...displayMode === "thumbnail" ? { width: "100%", height: "100%", objectFit: "cover" } : { maxWidth: "100%", objectFit: "contain" }
|
|
161
|
+
},
|
|
162
|
+
onLoad: () => setLoadState("loaded"),
|
|
163
|
+
onError: () => setLoadState("error")
|
|
164
|
+
}
|
|
165
|
+
)
|
|
166
|
+
]
|
|
167
|
+
}
|
|
168
|
+
);
|
|
161
169
|
};
|
|
162
170
|
var FileGallery = ({
|
|
163
171
|
file,
|
|
164
172
|
align = "left",
|
|
173
|
+
size = "default",
|
|
165
174
|
removable = false,
|
|
166
175
|
onRemove = () => {
|
|
167
176
|
},
|
|
@@ -201,6 +210,8 @@ var FileGallery = ({
|
|
|
201
210
|
const fileSize = getFileSize(file);
|
|
202
211
|
const fileId = getFileId(file);
|
|
203
212
|
const url = getFileUrl(file) || objectUrl;
|
|
213
|
+
const isSmall = size === "small";
|
|
214
|
+
const cardClassName = `${styles.fileCard} ${isSmall ? styles.fileCardSmall : ""} ${align === "right" ? "align-right" : ""} ${className || ""}`;
|
|
204
215
|
const fileType = (0, import_react.useMemo)(
|
|
205
216
|
() => customType || inferFileType(file),
|
|
206
217
|
[customType, file]
|
|
@@ -215,7 +226,7 @@ var FileGallery = ({
|
|
|
215
226
|
const renderRemoveBtn = () => removable ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
216
227
|
"button",
|
|
217
228
|
{
|
|
218
|
-
className: styles.fileRemoveBtn
|
|
229
|
+
className: `${styles.fileRemoveBtn} ${isSmall ? styles.fileRemoveBtnSmall : ""}`,
|
|
219
230
|
onClick: (e) => {
|
|
220
231
|
e.stopPropagation();
|
|
221
232
|
onRemove(fileId);
|
|
@@ -241,11 +252,18 @@ var FileGallery = ({
|
|
|
241
252
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
242
253
|
"div",
|
|
243
254
|
{
|
|
244
|
-
className:
|
|
255
|
+
className: cardClassName,
|
|
245
256
|
style: { ...style, cursor: onClick ? "pointer" : void 0 },
|
|
246
257
|
onClick: () => onClick == null ? void 0 : onClick(file),
|
|
247
258
|
children: [
|
|
248
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
259
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
260
|
+
"div",
|
|
261
|
+
{
|
|
262
|
+
className: `${styles.fileIcon} ${isSmall ? styles.fileIconSmall : ""}`,
|
|
263
|
+
style: { color },
|
|
264
|
+
children: icon
|
|
265
|
+
}
|
|
266
|
+
),
|
|
249
267
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.fileInfo, children: [
|
|
250
268
|
isExternalUrl && !onClick ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
251
269
|
"a",
|
|
@@ -254,9 +272,9 @@ var FileGallery = ({
|
|
|
254
272
|
target: "_blank",
|
|
255
273
|
rel: "noopener noreferrer",
|
|
256
274
|
className: styles.fileLink,
|
|
257
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_antd.Tooltip, { title: fileName, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.fileName
|
|
275
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_antd.Tooltip, { title: fileName, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `${styles.fileName} ${isSmall ? styles.fileNameSmall : ""}`, children: fileName.length > 15 ? `${fileName.substring(0, 15)}...` : fileName }) })
|
|
258
276
|
}
|
|
259
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_antd.Tooltip, { title: fileName, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.fileName
|
|
277
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_antd.Tooltip, { title: fileName, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `${styles.fileName} ${isSmall ? styles.fileNameSmall : ""}`, children: fileName.length > 15 ? `${fileName.substring(0, 15)}...` : fileName }) }),
|
|
260
278
|
file.status === "uploading" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
261
279
|
import_antd.Progress,
|
|
262
280
|
{
|
|
@@ -264,9 +282,9 @@ var FileGallery = ({
|
|
|
264
282
|
size: "small",
|
|
265
283
|
showInfo: false,
|
|
266
284
|
strokeColor: "#1677ff",
|
|
267
|
-
className: styles.progress
|
|
285
|
+
className: `${styles.progress} ${isSmall ? styles.progressSmall : ""}`
|
|
268
286
|
}
|
|
269
|
-
) : fileSize > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.fileSize, children: formatFileSize(fileSize) }),
|
|
287
|
+
) : !isSmall && fileSize > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.fileSize, children: formatFileSize(fileSize) }),
|
|
270
288
|
file.status === "error" && file.errorMessage && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
271
289
|
"div",
|
|
272
290
|
{
|
|
@@ -314,7 +332,7 @@ var FileGallery = ({
|
|
|
314
332
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
315
333
|
"div",
|
|
316
334
|
{
|
|
317
|
-
className:
|
|
335
|
+
className: cardClassName,
|
|
318
336
|
style: { ...style, cursor: onClick ? "pointer" : void 0 },
|
|
319
337
|
onClick: () => onClick == null ? void 0 : onClick(file),
|
|
320
338
|
children: [
|
|
@@ -323,26 +341,27 @@ var FileGallery = ({
|
|
|
323
341
|
{
|
|
324
342
|
src: url,
|
|
325
343
|
alt: imageAlt || fileName,
|
|
326
|
-
width: imageWidth,
|
|
327
|
-
height: imageHeight,
|
|
344
|
+
width: size === "small" ? 22 : imageWidth,
|
|
345
|
+
height: size === "small" ? 22 : imageHeight,
|
|
328
346
|
displayMode: "thumbnail",
|
|
329
347
|
loading: imageLoading,
|
|
330
348
|
preview: onClick ? false : { src: url },
|
|
331
349
|
fallback: FALLBACK_IMAGE,
|
|
332
|
-
styles
|
|
350
|
+
styles,
|
|
351
|
+
className: isSmall ? styles.imageThumbnailSmall : void 0
|
|
333
352
|
}
|
|
334
353
|
),
|
|
335
354
|
renderUploadOverlay(),
|
|
336
355
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.fileInfo, children: [
|
|
337
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_antd.Tooltip, { title: fileName, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.fileName
|
|
338
|
-
Number(file == null ? void 0 : file.size) > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.fileSize, children: formatFileSize(fileSize) })
|
|
356
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_antd.Tooltip, { title: fileName, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `${styles.fileName} ${isSmall ? styles.fileNameSmall : ""}`, children: fileName.length > 15 ? `${fileName.substring(0, 15)}...` : fileName }) }),
|
|
357
|
+
!isSmall && Number(file == null ? void 0 : file.size) > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.fileSize, children: formatFileSize(fileSize) })
|
|
339
358
|
] }),
|
|
340
359
|
renderRemoveBtn()
|
|
341
360
|
]
|
|
342
361
|
}
|
|
343
362
|
);
|
|
344
363
|
}
|
|
345
|
-
if (fileType === "audio") {
|
|
364
|
+
if (fileType === "audio" && size !== "small") {
|
|
346
365
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
347
366
|
"div",
|
|
348
367
|
{
|
|
@@ -366,7 +385,7 @@ var FileGallery = ({
|
|
|
366
385
|
}
|
|
367
386
|
);
|
|
368
387
|
}
|
|
369
|
-
if (fileType === "video") {
|
|
388
|
+
if (fileType === "video" && size !== "small") {
|
|
370
389
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
371
390
|
"div",
|
|
372
391
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/components/FileGallery/index.tsx"],
|
|
4
|
-
"sourcesContent": ["import React, { useState, useEffect, useMemo } from \"react\";\nimport { Image, Tooltip, Progress } from \"antd\";\nimport {\n FileOutlined,\n FilePdfOutlined,\n FileWordOutlined,\n FileExcelOutlined,\n FilePptOutlined,\n FileImageOutlined,\n CloseOutlined,\n AudioOutlined,\n FileZipOutlined,\n VideoCameraOutlined,\n FileMarkdownOutlined,\n PictureOutlined,\n} from \"@ant-design/icons\";\nimport {\n FileItem,\n FileGalleryProps,\n FileIconType,\n ImageDisplayMode,\n FileCardType,\n} from \"@/types\";\nimport { useStyles } from \"./styles\";\n\n// ==================== 工具函数 ====================\n\nconst getFileName = (file: FileItem): string =>\n file.displayName || file.name || \"\";\n\nconst getFileSize = (file: FileItem): number => file.size || 0;\n\nconst getMimeType = (file: FileItem): string =>\n file.mimeType || file.type || \"\";\n\nconst getFileUrl = (file: FileItem): string =>\n file.fileUri ||\n file.response?.fileUrl ||\n file.response?.tempUrl ||\n file.tempUrl ||\n \"\";\n\nconst getFileId = (file: FileItem): string => file.id || file.uid || \"\";\n\nconst getFileExtension = (filename: string): string => {\n const ext = filename.split(\".\").pop();\n return ext ? ext.toLowerCase() : \"\";\n};\n\nconst IMAGE_EXTS = [\"jpg\", \"jpeg\", \"png\", \"gif\", \"webp\", \"bmp\", \"svg\"];\nconst AUDIO_EXTS = [\"mp3\", \"wav\", \"m4a\", \"aac\", \"ogg\", \"flac\"];\nconst VIDEO_EXTS = [\"mp4\", \"mov\", \"webm\", \"mkv\", \"avi\"];\n\n/** 自动推断文件卡片类型 */\nconst inferFileType = (file: FileItem): FileCardType => {\n const mimeType = getMimeType(file);\n if (mimeType.startsWith(\"image/\")) return \"image\";\n if (mimeType.startsWith(\"audio/\")) return \"audio\";\n if (mimeType.startsWith(\"video/\")) return \"video\";\n\n const ext = getFileExtension(getFileName(file));\n if (IMAGE_EXTS.includes(ext)) return \"image\";\n if (AUDIO_EXTS.includes(ext)) return \"audio\";\n if (VIDEO_EXTS.includes(ext)) return \"video\";\n\n // URL 扩展名兜底\n const url = getFileUrl(file);\n const urlExtMatch = url.match(/\\.(\\w+)(\\?.*)?$/);\n if (urlExtMatch) {\n const urlExt = urlExtMatch[1].toLowerCase();\n if (IMAGE_EXTS.includes(urlExt)) return \"image\";\n if (AUDIO_EXTS.includes(urlExt)) return \"audio\";\n if (VIDEO_EXTS.includes(urlExt)) return \"video\";\n }\n\n return \"file\";\n};\n\n/** 根据扩展名获取文件图标类型 key */\nconst getFileIconType = (file: FileItem): FileIconType => {\n const ext = getFileExtension(getFileName(file));\n if (ext === \"pdf\") return \"pdf\";\n if ([\"doc\", \"docx\"].includes(ext)) return \"word\";\n if ([\"xls\", \"xlsx\", \"csv\"].includes(ext)) return \"excel\";\n if ([\"ppt\", \"pptx\"].includes(ext)) return \"ppt\";\n if (AUDIO_EXTS.includes(ext)) return \"audio\";\n if (VIDEO_EXTS.includes(ext)) return \"video\";\n if ([\"zip\", \"rar\", \"7z\", \"tar\", \"gz\", \"bz2\", \"xz\", \"tgz\"].includes(ext))\n return \"zip\";\n if ([\"md\", \"markdown\"].includes(ext)) return \"markdown\";\n if (IMAGE_EXTS.includes(ext)) return \"image\";\n return \"default\";\n};\n\n/** 默认图标映射 */\nconst DEFAULT_ICON_MAP: Record<\n FileIconType,\n { icon: React.ReactNode; color: string }\n> = {\n pdf: { icon: <FilePdfOutlined />, color: \"#ff4d4f\" },\n word: { icon: <FileWordOutlined />, color: \"#1677ff\" },\n excel: { icon: <FileExcelOutlined />, color: \"#22b35e\" },\n ppt: { icon: <FilePptOutlined />, color: \"#ff6e31\" },\n audio: { icon: <AudioOutlined />, color: \"#722ed1\" },\n video: { icon: <VideoCameraOutlined />, color: \"#fa8c16\" },\n zip: { icon: <FileZipOutlined />, color: \"#eb2f96\" },\n markdown: { icon: <FileMarkdownOutlined />, color: \"#13c2c2\" },\n image: { icon: <FileImageOutlined />, color: \"#8c8c8c\" },\n default: { icon: <FileOutlined />, color: \"#8c8c8c\" },\n};\n\nconst formatFileSize = (bytes: number): string => {\n if (bytes < 1024) return bytes + \" B\";\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + \" KB\";\n return (bytes / (1024 * 1024)).toFixed(1) + \" MB\";\n};\n\nconst FALLBACK_IMAGE =\n \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMIAAADDCAYAAADQvc6UAAABRWlDQ1BJQ0MgUHJvZmlsZQAAKJFjYGASSSwoyGFhYGDIzSspCnJ3UoiIjFJgf8LAwSDCIMogwMCcmFxc4BgQ4ANUwgCjUcG3awyMIPqyLsis7PPOq3QdDFcvjV3jOD1boQVTPQrgSkktTgbSf4A4LbmgqISBgTEFyFYuLykAsTuAbJEioKOA7DkgdjqEvQHEToKwj4DVhAQ5A9k3gGyB5IxEoBmML4BsnSQk8XQkNtReEOBxcfXxUQg1Mjc0dyHgXNJBSWpFCYh2zi+oLMpMzyhRcASGUqqCZ16yno6CkYGRAQMDKMwhqj/fAIcloxgHQqxAjIHBEugw5sUIsSQpBobtQPdLciLEVJYzMPBHMDBsayhILEqEO4DxG0txmrERhM29nYGBddr//5/DGRjYNRkY/l7////39v///y4Dmn+LgeHANwDrkl1AuO+pmgAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAwqADAAQAAAABAAAAwwAAAAD9b/HnAAAHlklEQVR4Ae3dP3PTWBSGcbGzM6GCKqlIBRV0dHRJFarQ0eUT8LH4BnRU0NHR0UEFVdIlFRV7TzRksomPY8uykTk/zewQfKw/9znv4yvJynLv4uLiV2dBoDiBf4qP3/ARuCRABEFAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghgg0Aj8i0JO4OzsrPv69Wv+hi2qPHr0qNvf39+iI97soRIh4f3z58/u7du3SXX7Xt7Z2enevHmzfQe+oSN2apSAPj09TSrb+XKI/f379+08+A0cNRE2ANkupk+ACNPvkSPcAAEibACyXUyfABGm3yNHuAECRNgAZLuYPgEirKlHu7u7XdyytGwHAd8jjNyng4OD7vnz51dbPT8/7z58+NB9+/bt6jU/TI+AGWHEnrx48eJ/EsSmHzx40L18+fLyzxF3ZVMjEyDCiEDjMYZZS5wiPXnyZFbJaxMhQIQRGzHvWR7XCyOCXsOmiDAi1HmPMMQjDpbpEiDCiL358eNHurW/5SnWdIBbXiDCiA38/Pnzrce2YyZ4//59F3ePLNMl4PbpiL2J0L979+7yDtHDhw8vtzzvdGnEXdvUigSIsCLAWavHp/+qM0BcXMd/q25n1vF57TYBp0a3mUzilePj4+7k5KSLb6gt6ydAhPUzXnoPR0dHl79WGTNCfBnn1uvSCJdegQhLI1vvCk+fPu2ePXt2tZOYEV6/fn31dz+shwAR1sP1cqvLntbEN9MxA9xcYjsxS1jWR4AIa2Ibzx0tc44fYX/16lV6NDFLXH+YL32jwiACRBiEbf5KcXoTIsQSpzXx4N28Ja4BQoK7rgXiydbHjx/P25TaQAJEGAguWy0+2Q8PD6/Ki4R8EVl+bzBOnZY95fq9rj9zAkTI2SxdidBHqG9+skdw43borCXO/ZcJdraPWdv22uIEiLA4q7nvvCug8WTqzQveOH26fodo7g6uFe/a17W3+nFBAkRYENRdb1vkkz1CH9cPsVy/jrhr27PqMYvENYNlHAIesRiBYwRy0V+8iXP8+/fvX11Mr7L7ECueb/r48eMqm7FuI2BGWDEG8cm+7G3NEOfmdcTQw4h9/55lhm7DekRYKQPZF2ArbXTAyu4kDYB2YxUzwg0gi/41ztHnfQG26HbGel/crVrm7tNY+/1btkOEAZ2M05r4FB7r9GbAIdxaZYrHdOsgJ/wCEQY0J74TmOKnbxxT9n3FgGGWWsVdowHtjt9Nnvf7yQM2aZU/TIAIAxrw6dOnAWtZZcoEnBpNuTuObWMEiLAx1HY0ZQJEmHJ3HNvGCBBhY6jtaMoEiJB0Z29vL6ls58vxPcO8/zfrdo5qvKO+d3Fx8Wu8zf1dW4p/cPzLly/dtv9Ts/EbcvGAHhHyfBIhZ6NSiIBTo0LNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiEC/wGgKKC4YMA4TAAAAABJRU5ErkJggg==\";\n\n// ==================== 子组件:图片加载状态管理 ====================\n\nconst ImageWithLoading: React.FC<{\n src: string;\n alt: string;\n width?: number | string;\n height?: number | string;\n loading?: \"lazy\" | \"eager\";\n preview?: false | { src: string };\n fallback?: string;\n displayMode: ImageDisplayMode;\n styles: ReturnType<typeof useStyles>;\n}> = ({\n src,\n alt,\n width,\n height,\n loading,\n preview,\n fallback,\n displayMode,\n styles,\n}) => {\n const [loadState, setLoadState] = useState<\n \"loading\" | \"loaded\" | \"error\"\n >(\"loading\");\n\n useEffect(() => {\n setLoadState(\"loading\");\n }, [src]);\n\n const modeClass =\n displayMode === \"full\"\n ? styles.imageFullMode\n : displayMode === \"preview\"\n ? styles.imagePreviewMode\n : styles.imageThumbnail;\n\n const containerStyle: React.CSSProperties = {};\n if (width)\n containerStyle.width = typeof width === \"number\" ? `${width}px` : width;\n if (height)\n containerStyle.height = typeof height === \"number\" ? `${height}px` : height;\n\n return (\n <div className={modeClass} style={containerStyle}>\n {loadState === \"loading\" && (\n <div className={styles.imageLoadingSkeleton}>\n <PictureOutlined style={{ fontSize: 20, color: \"#d9d9d9\" }} />\n </div>\n )}\n\n {loadState === \"error\" && (\n <div className={styles.imageErrorFallback}>\n <PictureOutlined />\n <span>加载失败</span>\n </div>\n )}\n\n <Image\n src={src}\n alt={alt}\n fallback={fallback}\n preview={preview}\n loading={loading}\n style={{\n display: loadState === \"error\" ? \"none\" : \"block\",\n opacity: loadState === \"loading\" ? 0 : 1,\n transition: \"opacity 0.3s ease\",\n ...(displayMode === \"thumbnail\"\n ? { width: \"100%\", height: \"100%\", objectFit: \"cover\" }\n : { maxWidth: \"100%\", objectFit: \"contain\" }),\n }}\n onLoad={() => setLoadState(\"loaded\")}\n onError={() => setLoadState(\"error\")}\n />\n </div>\n );\n};\n\n// ==================== 主组件 ====================\n\nconst FileGallery: React.FC<FileGalleryProps> = ({\n file,\n align = \"left\",\n removable = false,\n onRemove = () => {},\n className,\n style,\n onClick,\n type: customType,\n // 图片相关\n imageDisplayMode = \"thumbnail\",\n imageWidth,\n imageHeight,\n imageLoading = \"eager\",\n imageAlt,\n // 音视频相关\n mediaAutoPlay = false,\n mediaLoop = false,\n mediaMuted = false,\n mediaPoster,\n videoProps,\n audioProps,\n // 自定义图标\n iconMap,\n customIcon,\n}) => {\n const styles = useStyles();\n const [objectUrl, setObjectUrl] = useState(\"\");\n\n useEffect(() => {\n if (!file?.file) return;\n const url = URL.createObjectURL(file.file);\n setObjectUrl(url);\n return () => URL.revokeObjectURL(url);\n }, [file?.file]);\n\n if (!file) return null;\n\n const fileName = getFileName(file);\n const fileSize = getFileSize(file);\n const fileId = getFileId(file);\n const url = getFileUrl(file) || objectUrl;\n\n // 核心逻辑:type prop 决定渲染方式(参考 file-card)\n // - 不传 type:自动推断,图片/音频/视频用原生渲染\n // - type=\"file\":强制附件卡片(音视频不可播放)\n // - type=\"image\"/\"audio\"/\"video\":强制指定类型\n const fileType = useMemo<FileCardType>(\n () => customType || inferFileType(file),\n [customType, file],\n );\n\n /** 获取图标(支持自定义) */\n const getIcon = (\n iconType: FileIconType,\n ): { icon: React.ReactNode; color: string } => {\n if (customIcon) return { icon: customIcon, color: \"inherit\" };\n if (iconMap?.[iconType])\n return { icon: iconMap[iconType]!, color: \"inherit\" };\n return DEFAULT_ICON_MAP[iconType];\n };\n\n // ==================== 渲染删除按钮 ====================\n const renderRemoveBtn = () =>\n removable ? (\n <button\n className={styles.fileRemoveBtn}\n onClick={(e) => {\n e.stopPropagation();\n onRemove(fileId);\n }}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n ) : null;\n\n // ==================== 渲染上传进度遮罩 ====================\n const renderUploadOverlay = () =>\n file.status === \"uploading\" ? (\n <div className={styles.imageOverlay}>\n <Progress\n type=\"circle\"\n percent={file.progress}\n size={30}\n strokeColor=\"#1677ff\"\n />\n </div>\n ) : null;\n\n // ==================== 附件卡片渲染(type=\"file\" 或普通文档) ====================\n const renderFileCard = () => {\n const iconType = getFileIconType(file);\n const { icon, color } = getIcon(iconType);\n const isExternalUrl = url && url.startsWith(\"http\");\n\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={{ ...style, cursor: onClick ? \"pointer\" : undefined }}\n onClick={() => onClick?.(file)}\n >\n <div className={styles.fileIcon} style={{ color }}>\n {icon}\n </div>\n\n <div className={styles.fileInfo}>\n {isExternalUrl && !onClick ? (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={styles.fileLink}\n >\n <Tooltip title={fileName}>\n <div className={styles.fileName}>\n {fileName.length > 15\n ? `${fileName.substring(0, 15)}...`\n : fileName}\n </div>\n </Tooltip>\n </a>\n ) : (\n <Tooltip title={fileName}>\n <div className={styles.fileName}>\n {fileName.length > 15\n ? `${fileName.substring(0, 15)}...`\n : fileName}\n </div>\n </Tooltip>\n )}\n\n {file.status === \"uploading\" ? (\n <Progress\n percent={file.progress}\n size=\"small\"\n showInfo={false}\n strokeColor=\"#1677ff\"\n className={styles.progress}\n />\n ) : (\n fileSize > 0 && (\n <div className={styles.fileSize}>\n {formatFileSize(fileSize)}\n </div>\n )\n )}\n\n {file.status === \"error\" && file.errorMessage && (\n <div\n style={{ fontSize: \"11px\", color: \"#ff4d4f\", marginTop: \"2px\" }}\n >\n {file.errorMessage}\n </div>\n )}\n </div>\n\n {renderRemoveBtn()}\n </div>\n );\n };\n\n // ==================== 图片渲染 ====================\n if (fileType === \"image\") {\n // full / preview 模式:独立展示\n if (imageDisplayMode === \"full\" || imageDisplayMode === \"preview\") {\n const containerStyle: React.CSSProperties = { ...style };\n if (imageWidth)\n containerStyle.width =\n typeof imageWidth === \"number\" ? `${imageWidth}px` : imageWidth;\n if (imageHeight)\n containerStyle.height =\n typeof imageHeight === \"number\" ? `${imageHeight}px` : imageHeight;\n\n return (\n <div\n className={`${imageDisplayMode === \"full\" ? styles.imageFullMode : styles.imagePreviewMode} ${className || \"\"}`}\n style={containerStyle}\n >\n <ImageWithLoading\n src={url}\n alt={imageAlt || fileName}\n displayMode={imageDisplayMode}\n loading={imageLoading}\n preview={onClick ? false : { src: url }}\n fallback={FALLBACK_IMAGE}\n styles={styles}\n />\n {renderUploadOverlay()}\n {renderRemoveBtn()}\n </div>\n );\n }\n\n // thumbnail 模式:卡片形式\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={{ ...style, cursor: onClick ? \"pointer\" : undefined }}\n onClick={() => onClick?.(file)}\n >\n <ImageWithLoading\n src={url}\n alt={imageAlt || fileName}\n width={imageWidth}\n height={imageHeight}\n displayMode=\"thumbnail\"\n loading={imageLoading}\n preview={onClick ? false : { src: url }}\n fallback={FALLBACK_IMAGE}\n styles={styles}\n />\n {renderUploadOverlay()}\n\n <div className={styles.fileInfo}>\n <Tooltip title={fileName}>\n <div className={styles.fileName}>\n {fileName.length > 15\n ? `${fileName.substring(0, 15)}...`\n : fileName}\n </div>\n </Tooltip>\n {Number(file?.size) > 0 && (\n <div className={styles.fileSize}>{formatFileSize(fileSize)}</div>\n )}\n </div>\n\n {renderRemoveBtn()}\n </div>\n );\n }\n\n // ==================== 音频渲染(原生播放器,无卡片包裹) ====================\n if (fileType === \"audio\") {\n return (\n <div\n className={`file-gallery-audio ${className || \"\"}`}\n style={{ position: \"relative\", width: 268, ...style }}\n >\n <audio\n src={url}\n controls\n autoPlay={mediaAutoPlay}\n loop={mediaLoop}\n muted={mediaMuted}\n style={{ width: \"100%\" }}\n {...audioProps}\n />\n {renderRemoveBtn()}\n </div>\n );\n }\n\n // ==================== 视频渲染(原生播放器,无卡片包裹) ====================\n if (fileType === \"video\") {\n return (\n <div\n className={`file-gallery-video ${className || \"\"}`}\n style={{ position: \"relative\", width: 268, ...style }}\n >\n <video\n src={url}\n controls\n autoPlay={mediaAutoPlay}\n loop={mediaLoop}\n muted={mediaMuted}\n poster={mediaPoster}\n style={{\n width: \"100%\",\n aspectRatio: \"16 / 9\",\n borderRadius: 8,\n background: \"#000\",\n }}\n {...videoProps}\n />\n {renderRemoveBtn()}\n </div>\n );\n }\n\n // ==================== 其他文件(附件卡片) ====================\n return renderFileCard();\n};\n\nexport default FileGallery;\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import React, { useState, useEffect, useMemo } from \"react\";\nimport { Image, Tooltip, Progress } from \"antd\";\nimport {\n FileOutlined,\n FilePdfOutlined,\n FileWordOutlined,\n FileExcelOutlined,\n FilePptOutlined,\n FileImageOutlined,\n CloseOutlined,\n AudioOutlined,\n FileZipOutlined,\n VideoCameraOutlined,\n FileMarkdownOutlined,\n PictureOutlined,\n} from \"@ant-design/icons\";\nimport {\n FileItem,\n FileGalleryProps,\n FileIconType,\n ImageDisplayMode,\n FileCardType,\n} from \"@/types\";\nimport { useStyles } from \"./styles\";\n\n// ==================== 工具函数 ====================\n\nconst getFileName = (file: FileItem): string =>\n file.displayName || file.name || \"\";\n\nconst getFileSize = (file: FileItem): number => file.size || 0;\n\nconst getMimeType = (file: FileItem): string =>\n file.mimeType || file.type || \"\";\n\nconst getFileUrl = (file: FileItem): string =>\n file.fileUri ||\n file.response?.fileUrl ||\n file.response?.tempUrl ||\n file.tempUrl ||\n \"\";\n\nconst getFileId = (file: FileItem): string => file.id || file.uid || \"\";\n\nconst getFileExtension = (filename: string): string => {\n const ext = filename.split(\".\").pop();\n return ext ? ext.toLowerCase() : \"\";\n};\n\nconst IMAGE_EXTS = [\"jpg\", \"jpeg\", \"png\", \"gif\", \"webp\", \"bmp\", \"svg\"];\nconst AUDIO_EXTS = [\"mp3\", \"wav\", \"m4a\", \"aac\", \"ogg\", \"flac\"];\nconst VIDEO_EXTS = [\"mp4\", \"mov\", \"webm\", \"mkv\", \"avi\"];\n\n/** 自动推断文件卡片类型 */\nconst inferFileType = (file: FileItem): FileCardType => {\n const mimeType = getMimeType(file);\n if (mimeType.startsWith(\"image/\")) return \"image\";\n if (mimeType.startsWith(\"audio/\")) return \"audio\";\n if (mimeType.startsWith(\"video/\")) return \"video\";\n\n const ext = getFileExtension(getFileName(file));\n if (IMAGE_EXTS.includes(ext)) return \"image\";\n if (AUDIO_EXTS.includes(ext)) return \"audio\";\n if (VIDEO_EXTS.includes(ext)) return \"video\";\n\n // URL 扩展名兜底\n const url = getFileUrl(file);\n const urlExtMatch = url.match(/\\.(\\w+)(\\?.*)?$/);\n if (urlExtMatch) {\n const urlExt = urlExtMatch[1].toLowerCase();\n if (IMAGE_EXTS.includes(urlExt)) return \"image\";\n if (AUDIO_EXTS.includes(urlExt)) return \"audio\";\n if (VIDEO_EXTS.includes(urlExt)) return \"video\";\n }\n\n return \"file\";\n};\n\n/** 根据扩展名获取文件图标类型 key */\nconst getFileIconType = (file: FileItem): FileIconType => {\n const ext = getFileExtension(getFileName(file));\n if (ext === \"pdf\") return \"pdf\";\n if ([\"doc\", \"docx\"].includes(ext)) return \"word\";\n if ([\"xls\", \"xlsx\", \"csv\"].includes(ext)) return \"excel\";\n if ([\"ppt\", \"pptx\"].includes(ext)) return \"ppt\";\n if (AUDIO_EXTS.includes(ext)) return \"audio\";\n if (VIDEO_EXTS.includes(ext)) return \"video\";\n if ([\"zip\", \"rar\", \"7z\", \"tar\", \"gz\", \"bz2\", \"xz\", \"tgz\"].includes(ext))\n return \"zip\";\n if ([\"md\", \"markdown\"].includes(ext)) return \"markdown\";\n if (IMAGE_EXTS.includes(ext)) return \"image\";\n return \"default\";\n};\n\n/** 默认图标映射 */\nconst DEFAULT_ICON_MAP: Record<\n FileIconType,\n { icon: React.ReactNode; color: string }\n> = {\n pdf: { icon: <FilePdfOutlined />, color: \"#ff4d4f\" },\n word: { icon: <FileWordOutlined />, color: \"#1677ff\" },\n excel: { icon: <FileExcelOutlined />, color: \"#22b35e\" },\n ppt: { icon: <FilePptOutlined />, color: \"#ff6e31\" },\n audio: { icon: <AudioOutlined />, color: \"#722ed1\" },\n video: { icon: <VideoCameraOutlined />, color: \"#fa8c16\" },\n zip: { icon: <FileZipOutlined />, color: \"#eb2f96\" },\n markdown: { icon: <FileMarkdownOutlined />, color: \"#13c2c2\" },\n image: { icon: <FileImageOutlined />, color: \"#8c8c8c\" },\n default: { icon: <FileOutlined />, color: \"#8c8c8c\" },\n};\n\nconst formatFileSize = (bytes: number): string => {\n if (bytes < 1024) return bytes + \" B\";\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + \" KB\";\n return (bytes / (1024 * 1024)).toFixed(1) + \" MB\";\n};\n\nconst FALLBACK_IMAGE =\n \"data:image/png;base64,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\";\n\n// ==================== 子组件:图片加载状态管理 ====================\n\nconst ImageWithLoading: React.FC<{\n src: string;\n alt: string;\n width?: number | string;\n height?: number | string;\n loading?: \"lazy\" | \"eager\";\n preview?: false | { src: string };\n fallback?: string;\n displayMode: ImageDisplayMode;\n className?: string;\n styles: ReturnType<typeof useStyles>;\n}> = ({\n src,\n alt,\n width,\n height,\n loading,\n preview,\n fallback,\n displayMode,\n className,\n styles,\n}) => {\n const [loadState, setLoadState] = useState<\n \"loading\" | \"loaded\" | \"error\"\n >(\"loading\");\n\n useEffect(() => {\n setLoadState(\"loading\");\n }, [src]);\n\n const modeClass =\n displayMode === \"full\"\n ? styles.imageFullMode\n : displayMode === \"preview\"\n ? styles.imagePreviewMode\n : styles.imageThumbnail;\n\n const containerStyle: React.CSSProperties = {};\n if (width)\n containerStyle.width = typeof width === \"number\" ? `${width}px` : width;\n if (height)\n containerStyle.height = typeof height === \"number\" ? `${height}px` : height;\n\n return (\n <div\n className={`${modeClass} ${className || \"\"}`}\n style={containerStyle}\n >\n {loadState === \"loading\" && (\n <div className={styles.imageLoadingSkeleton}>\n <PictureOutlined style={{ fontSize: 20, color: \"#d9d9d9\" }} />\n </div>\n )}\n\n {loadState === \"error\" && (\n <div className={styles.imageErrorFallback}>\n <PictureOutlined />\n <span>加载失败</span>\n </div>\n )}\n\n <Image\n src={src}\n alt={alt}\n fallback={fallback}\n preview={preview}\n loading={loading}\n style={{\n display: loadState === \"error\" ? \"none\" : \"block\",\n opacity: loadState === \"loading\" ? 0 : 1,\n transition: \"opacity 0.3s ease\",\n ...(displayMode === \"thumbnail\"\n ? { width: \"100%\", height: \"100%\", objectFit: \"cover\" }\n : { maxWidth: \"100%\", objectFit: \"contain\" }),\n }}\n onLoad={() => setLoadState(\"loaded\")}\n onError={() => setLoadState(\"error\")}\n />\n </div>\n );\n};\n\n// ==================== 主组件 ====================\n\nconst FileGallery: React.FC<FileGalleryProps> = ({\n file,\n align = \"left\",\n size = \"default\",\n removable = false,\n onRemove = () => {},\n className,\n style,\n onClick,\n type: customType,\n // 图片相关\n imageDisplayMode = \"thumbnail\",\n imageWidth,\n imageHeight,\n imageLoading = \"eager\",\n imageAlt,\n // 音视频相关\n mediaAutoPlay = false,\n mediaLoop = false,\n mediaMuted = false,\n mediaPoster,\n videoProps,\n audioProps,\n // 自定义图标\n iconMap,\n customIcon,\n}) => {\n const styles = useStyles();\n const [objectUrl, setObjectUrl] = useState(\"\");\n\n useEffect(() => {\n if (!file?.file) return;\n const url = URL.createObjectURL(file.file);\n setObjectUrl(url);\n return () => URL.revokeObjectURL(url);\n }, [file?.file]);\n\n if (!file) return null;\n\n const fileName = getFileName(file);\n const fileSize = getFileSize(file);\n const fileId = getFileId(file);\n const url = getFileUrl(file) || objectUrl;\n const isSmall = size === \"small\";\n const cardClassName = `${styles.fileCard} ${isSmall ? styles.fileCardSmall : \"\"} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`;\n\n // 核心逻辑:type prop 决定渲染方式(参考 file-card)\n // - 不传 type:自动推断,图片/音频/视频用原生渲染\n // - type=\"file\":强制附件卡片(音视频不可播放)\n // - type=\"image\"/\"audio\"/\"video\":强制指定类型\n const fileType = useMemo<FileCardType>(\n () => customType || inferFileType(file),\n [customType, file],\n );\n\n /** 获取图标(支持自定义) */\n const getIcon = (\n iconType: FileIconType,\n ): { icon: React.ReactNode; color: string } => {\n if (customIcon) return { icon: customIcon, color: \"inherit\" };\n if (iconMap?.[iconType])\n return { icon: iconMap[iconType]!, color: \"inherit\" };\n return DEFAULT_ICON_MAP[iconType];\n };\n\n // ==================== 渲染删除按钮 ====================\n const renderRemoveBtn = () =>\n removable ? (\n <button\n className={`${styles.fileRemoveBtn} ${isSmall ? styles.fileRemoveBtnSmall : \"\"}`}\n onClick={(e) => {\n e.stopPropagation();\n onRemove(fileId);\n }}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n ) : null;\n\n // ==================== 渲染上传进度遮罩 ====================\n const renderUploadOverlay = () =>\n file.status === \"uploading\" ? (\n <div className={styles.imageOverlay}>\n <Progress\n type=\"circle\"\n percent={file.progress}\n size={30}\n strokeColor=\"#1677ff\"\n />\n </div>\n ) : null;\n\n // ==================== 附件卡片渲染(type=\"file\" 或普通文档) ====================\n const renderFileCard = () => {\n const iconType = getFileIconType(file);\n const { icon, color } = getIcon(iconType);\n const isExternalUrl = url && url.startsWith(\"http\");\n\n return (\n <div\n className={cardClassName}\n style={{ ...style, cursor: onClick ? \"pointer\" : undefined }}\n onClick={() => onClick?.(file)}\n >\n <div\n className={`${styles.fileIcon} ${isSmall ? styles.fileIconSmall : \"\"}`}\n style={{ color }}\n >\n {icon}\n </div>\n\n <div className={styles.fileInfo}>\n {isExternalUrl && !onClick ? (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={styles.fileLink}\n >\n <Tooltip title={fileName}>\n <div className={`${styles.fileName} ${isSmall ? styles.fileNameSmall : \"\"}`}>\n {fileName.length > 15\n ? `${fileName.substring(0, 15)}...`\n : fileName}\n </div>\n </Tooltip>\n </a>\n ) : (\n <Tooltip title={fileName}>\n <div className={`${styles.fileName} ${isSmall ? styles.fileNameSmall : \"\"}`}>\n {fileName.length > 15\n ? `${fileName.substring(0, 15)}...`\n : fileName}\n </div>\n </Tooltip>\n )}\n\n {file.status === \"uploading\" ? (\n <Progress\n percent={file.progress}\n size=\"small\"\n showInfo={false}\n strokeColor=\"#1677ff\"\n className={`${styles.progress} ${isSmall ? styles.progressSmall : \"\"}`}\n />\n ) : (\n !isSmall && fileSize > 0 && (\n <div className={styles.fileSize}>\n {formatFileSize(fileSize)}\n </div>\n )\n )}\n\n {file.status === \"error\" && file.errorMessage && (\n <div\n style={{ fontSize: \"11px\", color: \"#ff4d4f\", marginTop: \"2px\" }}\n >\n {file.errorMessage}\n </div>\n )}\n </div>\n\n {renderRemoveBtn()}\n </div>\n );\n };\n\n // ==================== 图片渲染 ====================\n if (fileType === \"image\") {\n // full / preview 模式:独立展示\n if (imageDisplayMode === \"full\" || imageDisplayMode === \"preview\") {\n const containerStyle: React.CSSProperties = { ...style };\n if (imageWidth)\n containerStyle.width =\n typeof imageWidth === \"number\" ? `${imageWidth}px` : imageWidth;\n if (imageHeight)\n containerStyle.height =\n typeof imageHeight === \"number\" ? `${imageHeight}px` : imageHeight;\n\n return (\n <div\n className={`${imageDisplayMode === \"full\" ? styles.imageFullMode : styles.imagePreviewMode} ${className || \"\"}`}\n style={containerStyle}\n >\n <ImageWithLoading\n src={url}\n alt={imageAlt || fileName}\n displayMode={imageDisplayMode}\n loading={imageLoading}\n preview={onClick ? false : { src: url }}\n fallback={FALLBACK_IMAGE}\n styles={styles}\n />\n {renderUploadOverlay()}\n {renderRemoveBtn()}\n </div>\n );\n }\n\n // thumbnail 模式:卡片形式\n return (\n <div\n className={cardClassName}\n style={{ ...style, cursor: onClick ? \"pointer\" : undefined }}\n onClick={() => onClick?.(file)}\n >\n <ImageWithLoading\n src={url}\n alt={imageAlt || fileName}\n width={size === \"small\" ? 22 : imageWidth}\n height={size === \"small\" ? 22 : imageHeight}\n displayMode=\"thumbnail\"\n loading={imageLoading}\n preview={onClick ? false : { src: url }}\n fallback={FALLBACK_IMAGE}\n styles={styles}\n className={isSmall ? styles.imageThumbnailSmall : undefined}\n />\n {renderUploadOverlay()}\n\n <div className={styles.fileInfo}>\n <Tooltip title={fileName}>\n <div className={`${styles.fileName} ${isSmall ? styles.fileNameSmall : \"\"}`}>\n {fileName.length > 15\n ? `${fileName.substring(0, 15)}...`\n : fileName}\n </div>\n </Tooltip>\n {!isSmall && Number(file?.size) > 0 && (\n <div className={styles.fileSize}>{formatFileSize(fileSize)}</div>\n )}\n </div>\n\n {renderRemoveBtn()}\n </div>\n );\n }\n\n // ==================== 音频渲染(原生播放器,无卡片包裹) ====================\n if (fileType === \"audio\" && size !== \"small\") {\n return (\n <div\n className={`file-gallery-audio ${className || \"\"}`}\n style={{ position: \"relative\", width: 268, ...style }}\n >\n <audio\n src={url}\n controls\n autoPlay={mediaAutoPlay}\n loop={mediaLoop}\n muted={mediaMuted}\n style={{ width: \"100%\" }}\n {...audioProps}\n />\n {renderRemoveBtn()}\n </div>\n );\n }\n\n // ==================== 视频渲染(原生播放器,无卡片包裹) ====================\n if (fileType === \"video\" && size !== \"small\") {\n return (\n <div\n className={`file-gallery-video ${className || \"\"}`}\n style={{ position: \"relative\", width: 268, ...style }}\n >\n <video\n src={url}\n controls\n autoPlay={mediaAutoPlay}\n loop={mediaLoop}\n muted={mediaMuted}\n poster={mediaPoster}\n style={{\n width: \"100%\",\n aspectRatio: \"16 / 9\",\n borderRadius: 8,\n background: \"#000\",\n }}\n {...videoProps}\n />\n {renderRemoveBtn()}\n </div>\n );\n }\n\n // ==================== 其他文件(附件卡片) ====================\n return renderFileCard();\n};\n\nexport default FileGallery;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["url"]
|
|
7
7
|
}
|
|
@@ -2,14 +2,21 @@ export declare const useStyles: () => {
|
|
|
2
2
|
container: string;
|
|
3
3
|
fileList: string;
|
|
4
4
|
fileCard: string;
|
|
5
|
+
fileCardSmall: string;
|
|
5
6
|
imageThumbnail: string;
|
|
7
|
+
imageThumbnailSmall: string;
|
|
6
8
|
imageOverlay: string;
|
|
7
9
|
fileIcon: string;
|
|
10
|
+
fileIconSmall: string;
|
|
8
11
|
fileInfo: string;
|
|
9
12
|
fileName: string;
|
|
13
|
+
fileNameSmall: string;
|
|
10
14
|
fileSize: string;
|
|
15
|
+
fileSizeSmall: string;
|
|
11
16
|
progress: string;
|
|
17
|
+
progressSmall: string;
|
|
12
18
|
fileRemoveBtn: string;
|
|
19
|
+
fileRemoveBtnSmall: string;
|
|
13
20
|
fileLink: string;
|
|
14
21
|
mediaWrapper: string;
|
|
15
22
|
imagePreviewMode: string;
|
|
@@ -65,6 +65,30 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
|
|
|
65
65
|
&.align-right {
|
|
66
66
|
flex-direction: row-reverse;
|
|
67
67
|
}
|
|
68
|
+
|
|
69
|
+
`,
|
|
70
|
+
fileCardSmall: import_css.css`
|
|
71
|
+
gap: 6px;
|
|
72
|
+
min-width: 0;
|
|
73
|
+
max-width: 260px;
|
|
74
|
+
width: auto;
|
|
75
|
+
height: 32px;
|
|
76
|
+
min-height: 32px;
|
|
77
|
+
margin: 0;
|
|
78
|
+
padding: 4px 10px 4px 8px;
|
|
79
|
+
border-radius: 7px;
|
|
80
|
+
background: #f5f5f5;
|
|
81
|
+
border-color: transparent;
|
|
82
|
+
box-sizing: border-box;
|
|
83
|
+
|
|
84
|
+
&:hover {
|
|
85
|
+
background: #eeeeee;
|
|
86
|
+
border-color: transparent;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.ant-progress-line {
|
|
90
|
+
width: auto;
|
|
91
|
+
}
|
|
68
92
|
`,
|
|
69
93
|
imageThumbnail: import_css.css`
|
|
70
94
|
position: relative;
|
|
@@ -90,6 +114,12 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
|
|
|
90
114
|
object-fit: cover !important;
|
|
91
115
|
display: block !important;
|
|
92
116
|
}
|
|
117
|
+
|
|
118
|
+
`,
|
|
119
|
+
imageThumbnailSmall: import_css.css`
|
|
120
|
+
width: 22px;
|
|
121
|
+
height: 22px;
|
|
122
|
+
border-radius: 5px;
|
|
93
123
|
`,
|
|
94
124
|
imageOverlay: import_css.css`
|
|
95
125
|
position: absolute;
|
|
@@ -111,6 +141,12 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
|
|
|
111
141
|
display: flex;
|
|
112
142
|
align-items: center;
|
|
113
143
|
justify-content: center;
|
|
144
|
+
|
|
145
|
+
`,
|
|
146
|
+
fileIconSmall: import_css.css`
|
|
147
|
+
width: 20px;
|
|
148
|
+
height: 20px;
|
|
149
|
+
font-size: 16px;
|
|
114
150
|
`,
|
|
115
151
|
fileInfo: import_css.css`
|
|
116
152
|
flex: 1;
|
|
@@ -125,10 +161,21 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
|
|
|
125
161
|
overflow: hidden;
|
|
126
162
|
text-overflow: ellipsis;
|
|
127
163
|
white-space: nowrap;
|
|
164
|
+
|
|
165
|
+
`,
|
|
166
|
+
fileNameSmall: import_css.css`
|
|
167
|
+
max-width: 190px;
|
|
168
|
+
margin-bottom: 0;
|
|
169
|
+
font-size: 12px;
|
|
170
|
+
line-height: 20px;
|
|
128
171
|
`,
|
|
129
172
|
fileSize: import_css.css`
|
|
130
173
|
font-size: 11px;
|
|
131
174
|
color: #8c8c8c;
|
|
175
|
+
|
|
176
|
+
`,
|
|
177
|
+
fileSizeSmall: import_css.css`
|
|
178
|
+
display: none;
|
|
132
179
|
`,
|
|
133
180
|
progress: import_css.css`
|
|
134
181
|
margin-top: 4px;
|
|
@@ -140,6 +187,30 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
|
|
|
140
187
|
.ant-progress-bg {
|
|
141
188
|
height: 4px !important;
|
|
142
189
|
}
|
|
190
|
+
|
|
191
|
+
`,
|
|
192
|
+
progressSmall: import_css.css`
|
|
193
|
+
position: absolute;
|
|
194
|
+
left: 34px;
|
|
195
|
+
right: 10px;
|
|
196
|
+
bottom: 3px;
|
|
197
|
+
margin-top: 0;
|
|
198
|
+
line-height: 0;
|
|
199
|
+
|
|
200
|
+
.ant-progress-outer {
|
|
201
|
+
display: block;
|
|
202
|
+
width: 100%;
|
|
203
|
+
padding-inline-end: 0 !important;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.ant-progress-inner {
|
|
207
|
+
height: 3px !important;
|
|
208
|
+
background: rgba(22, 119, 255, 0.12);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.ant-progress-bg {
|
|
212
|
+
height: 3px !important;
|
|
213
|
+
}
|
|
143
214
|
`,
|
|
144
215
|
fileRemoveBtn: import_css.css`
|
|
145
216
|
position: absolute;
|
|
@@ -170,6 +241,13 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
|
|
|
170
241
|
cursor: not-allowed;
|
|
171
242
|
}
|
|
172
243
|
`,
|
|
244
|
+
fileRemoveBtnSmall: import_css.css`
|
|
245
|
+
top: -5px;
|
|
246
|
+
right: -5px;
|
|
247
|
+
width: 14px;
|
|
248
|
+
height: 14px;
|
|
249
|
+
font-size: 8px;
|
|
250
|
+
`,
|
|
173
251
|
fileLink: import_css.css`
|
|
174
252
|
display: flex;
|
|
175
253
|
align-items: center;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/components/FileGallery/styles.tsx"],
|
|
4
|
-
"sourcesContent": ["import { css } from \"@emotion/css\";\nimport { withBasicStyles } from \"@/styles/common\";\n\nexport const useStyles = withBasicStyles(() => ({\n container: css`\n padding: 12px 0;\n display: flex;\n flex-direction: column;\n gap: 12px;\n\n &.align-right {\n align-items: flex-end;\n }\n `,\n\n fileList: css`\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n `,\n\n fileCard: css`\n position: relative;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 12px;\n margin: 8px 0;\n background: #fafafa;\n border: 1px solid #f0f0f0;\n border-radius: 8px;\n min-width: 260px;\n max-width: 280px;\n min-height: 64px;\n transition: all 0.2s ease;\n\n &:hover {\n background: #f5f5f5;\n border-color: #e0e0e0;\n }\n\n /* align=right 时图标在右侧 */\n &.align-right {\n flex-direction: row-reverse;\n }\n `,\n\n imageThumbnail: css`\n position: relative;\n width: 44px;\n height: 44px;\n flex-shrink: 0;\n border-radius: 4px;\n overflow: hidden;\n background-color: #f5f5f5;\n border: 1px solid rgba(0, 0, 0, 0.06);\n\n .ant-image {\n width: 100% !important;\n height: 100% !important;\n display: flex !important;\n justify-content: center;\n align-items: center;\n }\n\n img {\n width: 100% !important;\n height: 100% !important;\n object-fit: cover !important;\n display: block !important;\n }\n `,\n\n imageOverlay: css`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.05);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n `,\n\n fileIcon: css`\n font-size: 24px;\n flex-shrink: 0;\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n `,\n\n fileInfo: css`\n flex: 1;\n min-width: 0;\n overflow: hidden;\n `,\n\n fileName: css`\n font-size: 13px;\n font-weight: 500;\n color: #262626;\n margin-bottom: 4px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n `,\n\n fileSize: css`\n font-size: 11px;\n color: #8c8c8c;\n `,\n\n progress: css`\n margin-top: 4px;\n\n .ant-progress-inner {\n height: 4px !important;\n }\n\n .ant-progress-bg {\n height: 4px !important;\n }\n `,\n\n fileRemoveBtn: css`\n position: absolute;\n top: -6px;\n right: -6px;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.75);\n color: #fff;\n border: none;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n z-index: 1;\n padding: 0;\n font-size: 10px;\n transition: all 0.2s ease;\n\n &:hover {\n background: rgba(0, 0, 0, 0.9);\n transform: scale(1.1);\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n `,\n\n fileLink: css`\n display: flex;\n align-items: center;\n gap: 8px;\n color: rgba(0, 0, 0, 0.85);\n text-decoration: none;\n font-size: 13px;\n\n &:hover {\n color: #1677ff;\n }\n `,\n\n mediaWrapper: css`\n margin-top: 6px;\n\n audio {\n width: 100%;\n height: 32px;\n outline: none;\n }\n\n video {\n width: 100%;\n max-height: 240px;\n border-radius: 4px;\n outline: none;\n background: #000;\n }\n `,\n\n // ========== 图片展示模式 ==========\n imagePreviewMode: css`\n position: relative;\n border-radius: 8px;\n overflow: hidden;\n background-color: #f5f5f5;\n border: 1px solid rgba(0, 0, 0, 0.06);\n\n .ant-image {\n display: flex !important;\n justify-content: center;\n align-items: center;\n }\n\n img {\n display: block !important;\n object-fit: contain !important;\n }\n `,\n\n imageFullMode: css`\n position: relative;\n border-radius: 8px;\n overflow: hidden;\n background-color: #f5f5f5;\n border: 1px solid rgba(0, 0, 0, 0.06);\n width: 100%;\n\n .ant-image {\n width: 100% !important;\n display: flex !important;\n }\n\n img {\n width: 100% !important;\n display: block !important;\n object-fit: contain !important;\n }\n `,\n\n // ========== 图片加载状态 ==========\n imageLoadingSkeleton: css`\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(90deg, #f5f5f5 25%, #e8e8e8 50%, #f5f5f5 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n\n @keyframes shimmer {\n 0% {\n background-position: 200% 0;\n }\n 100% {\n background-position: -200% 0;\n }\n }\n `,\n\n imageErrorFallback: css`\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n background: #fafafa;\n color: #bfbfbf;\n font-size: 20px;\n gap: 4px;\n\n span {\n font-size: 11px;\n color: #bfbfbf;\n }\n `,\n\n // ========== Media Card 模式 ==========\n mediaCardPlayIcon: css`\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.5);\n color: #fff;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n z-index: 2;\n `,\n}));\n\nexport default useStyles;\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAoB;AACpB,oBAAgC;AAEzB,IAAM,gBAAY,+BAAgB,OAAO;AAAA,EAC9C,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWX,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,EAMV,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,
|
|
4
|
+
"sourcesContent": ["import { css } from \"@emotion/css\";\nimport { withBasicStyles } from \"@/styles/common\";\n\nexport const useStyles = withBasicStyles(() => ({\n container: css`\n padding: 12px 0;\n display: flex;\n flex-direction: column;\n gap: 12px;\n\n &.align-right {\n align-items: flex-end;\n }\n `,\n\n fileList: css`\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n `,\n\n fileCard: css`\n position: relative;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 12px;\n margin: 8px 0;\n background: #fafafa;\n border: 1px solid #f0f0f0;\n border-radius: 8px;\n min-width: 260px;\n max-width: 280px;\n min-height: 64px;\n transition: all 0.2s ease;\n\n &:hover {\n background: #f5f5f5;\n border-color: #e0e0e0;\n }\n\n /* align=right 时图标在右侧 */\n &.align-right {\n flex-direction: row-reverse;\n }\n\n `,\n\n fileCardSmall: css`\n gap: 6px;\n min-width: 0;\n max-width: 260px;\n width: auto;\n height: 32px;\n min-height: 32px;\n margin: 0;\n padding: 4px 10px 4px 8px;\n border-radius: 7px;\n background: #f5f5f5;\n border-color: transparent;\n box-sizing: border-box;\n\n &:hover {\n background: #eeeeee;\n border-color: transparent;\n }\n\n .ant-progress-line {\n width: auto;\n }\n `,\n\n imageThumbnail: css`\n position: relative;\n width: 44px;\n height: 44px;\n flex-shrink: 0;\n border-radius: 4px;\n overflow: hidden;\n background-color: #f5f5f5;\n border: 1px solid rgba(0, 0, 0, 0.06);\n\n .ant-image {\n width: 100% !important;\n height: 100% !important;\n display: flex !important;\n justify-content: center;\n align-items: center;\n }\n\n img {\n width: 100% !important;\n height: 100% !important;\n object-fit: cover !important;\n display: block !important;\n }\n\n `,\n\n imageThumbnailSmall: css`\n width: 22px;\n height: 22px;\n border-radius: 5px;\n `,\n\n imageOverlay: css`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.05);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n `,\n\n fileIcon: css`\n font-size: 24px;\n flex-shrink: 0;\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n\n `,\n\n fileIconSmall: css`\n width: 20px;\n height: 20px;\n font-size: 16px;\n `,\n\n fileInfo: css`\n flex: 1;\n min-width: 0;\n overflow: hidden;\n `,\n\n fileName: css`\n font-size: 13px;\n font-weight: 500;\n color: #262626;\n margin-bottom: 4px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n\n `,\n\n fileNameSmall: css`\n max-width: 190px;\n margin-bottom: 0;\n font-size: 12px;\n line-height: 20px;\n `,\n\n fileSize: css`\n font-size: 11px;\n color: #8c8c8c;\n\n `,\n\n fileSizeSmall: css`\n display: none;\n `,\n\n progress: css`\n margin-top: 4px;\n\n .ant-progress-inner {\n height: 4px !important;\n }\n\n .ant-progress-bg {\n height: 4px !important;\n }\n\n `,\n\n progressSmall: css`\n position: absolute;\n left: 34px;\n right: 10px;\n bottom: 3px;\n margin-top: 0;\n line-height: 0;\n\n .ant-progress-outer {\n display: block;\n width: 100%;\n padding-inline-end: 0 !important;\n }\n\n .ant-progress-inner {\n height: 3px !important;\n background: rgba(22, 119, 255, 0.12);\n }\n\n .ant-progress-bg {\n height: 3px !important;\n }\n `,\n\n fileRemoveBtn: css`\n position: absolute;\n top: -6px;\n right: -6px;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.75);\n color: #fff;\n border: none;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n z-index: 1;\n padding: 0;\n font-size: 10px;\n transition: all 0.2s ease;\n\n &:hover {\n background: rgba(0, 0, 0, 0.9);\n transform: scale(1.1);\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n `,\n\n fileRemoveBtnSmall: css`\n top: -5px;\n right: -5px;\n width: 14px;\n height: 14px;\n font-size: 8px;\n `,\n\n fileLink: css`\n display: flex;\n align-items: center;\n gap: 8px;\n color: rgba(0, 0, 0, 0.85);\n text-decoration: none;\n font-size: 13px;\n\n &:hover {\n color: #1677ff;\n }\n `,\n\n mediaWrapper: css`\n margin-top: 6px;\n\n audio {\n width: 100%;\n height: 32px;\n outline: none;\n }\n\n video {\n width: 100%;\n max-height: 240px;\n border-radius: 4px;\n outline: none;\n background: #000;\n }\n `,\n\n // ========== 图片展示模式 ==========\n imagePreviewMode: css`\n position: relative;\n border-radius: 8px;\n overflow: hidden;\n background-color: #f5f5f5;\n border: 1px solid rgba(0, 0, 0, 0.06);\n\n .ant-image {\n display: flex !important;\n justify-content: center;\n align-items: center;\n }\n\n img {\n display: block !important;\n object-fit: contain !important;\n }\n `,\n\n imageFullMode: css`\n position: relative;\n border-radius: 8px;\n overflow: hidden;\n background-color: #f5f5f5;\n border: 1px solid rgba(0, 0, 0, 0.06);\n width: 100%;\n\n .ant-image {\n width: 100% !important;\n display: flex !important;\n }\n\n img {\n width: 100% !important;\n display: block !important;\n object-fit: contain !important;\n }\n `,\n\n // ========== 图片加载状态 ==========\n imageLoadingSkeleton: css`\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(90deg, #f5f5f5 25%, #e8e8e8 50%, #f5f5f5 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n\n @keyframes shimmer {\n 0% {\n background-position: 200% 0;\n }\n 100% {\n background-position: -200% 0;\n }\n }\n `,\n\n imageErrorFallback: css`\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n background: #fafafa;\n color: #bfbfbf;\n font-size: 20px;\n gap: 4px;\n\n span {\n font-size: 11px;\n color: #bfbfbf;\n }\n `,\n\n // ========== Media Card 模式 ==========\n mediaCardPlayIcon: css`\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.5);\n color: #fff;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n z-index: 2;\n `,\n}));\n\nexport default useStyles;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import "@ant-design/x-markdown/themes/light.css";
|
|
3
|
-
import type { FileItem } from "../../../../types";
|
|
3
|
+
import type { FileItem, MarkdownResourceLink, RenderMarkdownResourceLink } from "../../../../types";
|
|
4
4
|
export interface MarkdownRenderProps {
|
|
5
5
|
text: string;
|
|
6
|
+
/** 紧凑布局,适合用户消息气泡等内联场景 */
|
|
7
|
+
compact?: boolean;
|
|
6
8
|
/** 点击 Markdown 中识别到的文件链接的回调 */
|
|
7
9
|
onFileClick?: (file: FileItem) => void;
|
|
10
|
+
/** 点击 Markdown 中识别到的资源链接标签,如 [@skill](skill://xxx) */
|
|
11
|
+
onResourceLinkClick?: (link: MarkdownResourceLink) => void;
|
|
12
|
+
/** 自定义资源链接渲染,返回 null 时使用默认标签样式 */
|
|
13
|
+
renderResourceLink?: RenderMarkdownResourceLink;
|
|
8
14
|
}
|
|
9
15
|
declare const MarkdownRender: React.FC<MarkdownRenderProps>;
|
|
10
16
|
export default MarkdownRender;
|