@ai-group/chat-sdk 3.0.4 → 3.0.6

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.
Files changed (96) hide show
  1. package/dist/cjs/components/FileGallery/FileGallery.stories.d.ts +6 -0
  2. package/dist/cjs/components/FileGallery/FileGallery.stories.js +143 -0
  3. package/dist/cjs/components/FileGallery/FileGallery.stories.js.map +7 -0
  4. package/dist/cjs/components/FileGallery/index.d.ts +13 -12
  5. package/dist/cjs/components/FileGallery/index.js +165 -159
  6. package/dist/cjs/components/FileGallery/index.js.map +2 -2
  7. package/dist/cjs/components/FileGallery/styles.js +5 -0
  8. package/dist/cjs/components/FileGallery/styles.js.map +2 -2
  9. package/dist/cjs/components/XAdkChatbot/XAdkChatbot.stories.js +28 -9
  10. package/dist/cjs/components/XAdkChatbot/XAdkChatbot.stories.js.map +2 -2
  11. package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/index.d.ts +1 -0
  12. package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/index.js +2 -0
  13. package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/index.js.map +2 -2
  14. package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/styles.js +7 -1
  15. package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/styles.js.map +2 -2
  16. package/dist/cjs/components/XAdkChatbot/index.js +29 -4
  17. package/dist/cjs/components/XAdkChatbot/index.js.map +2 -2
  18. package/dist/cjs/components/XAdkChatbot/styles.d.ts +1 -0
  19. package/dist/cjs/components/XAdkChatbot/styles.js +7 -0
  20. package/dist/cjs/components/XAdkChatbot/styles.js.map +2 -2
  21. package/dist/cjs/components/XAdkProvider/XAdkProvider.stories.js +2 -2
  22. package/dist/cjs/components/XAdkProvider/XAdkProvider.stories.js.map +1 -1
  23. package/dist/cjs/components/XAdkProvider/compound/Messages.js +63 -9
  24. package/dist/cjs/components/XAdkProvider/compound/Messages.js.map +3 -3
  25. package/dist/cjs/components/XAdkProvider/context/ChatActionContext.d.ts +5 -0
  26. package/dist/cjs/components/XAdkProvider/context/ChatActionContext.js.map +2 -2
  27. package/dist/cjs/components/XAdkProvider/context/ChatStateContext.d.ts +2 -0
  28. package/dist/cjs/components/XAdkProvider/context/ChatStateContext.js.map +2 -2
  29. package/dist/cjs/components/XAdkProvider/index.js +11 -5
  30. package/dist/cjs/components/XAdkProvider/index.js.map +2 -2
  31. package/dist/cjs/components/XAdkSender/XAdkSender.stories.d.ts +2 -2
  32. package/dist/cjs/components/XAdkSender/XAdkSender.stories.js.map +2 -2
  33. package/dist/cjs/components/XAdkSender/index.js +9 -1
  34. package/dist/cjs/components/XAdkSender/index.js.map +2 -2
  35. package/dist/cjs/hooks/useADKChat.d.ts +4 -0
  36. package/dist/cjs/hooks/useADKChat.js +24 -2
  37. package/dist/cjs/hooks/useADKChat.js.map +2 -2
  38. package/dist/cjs/types/ChatHook.d.ts +6 -1
  39. package/dist/cjs/types/ChatHook.js.map +1 -1
  40. package/dist/cjs/types/FileGallery.d.ts +1 -21
  41. package/dist/cjs/types/FileGallery.js.map +1 -1
  42. package/dist/cjs/types/XAdkChatbot.d.ts +1 -1
  43. package/dist/cjs/types/XAdkChatbot.js.map +1 -1
  44. package/dist/cjs/types/XAdkProvider.d.ts +5 -0
  45. package/dist/cjs/types/XAdkProvider.js.map +1 -1
  46. package/dist/cjs/types/XAdkSender.js.map +1 -1
  47. package/dist/esm/components/FileGallery/FileGallery.stories.d.ts +6 -0
  48. package/dist/esm/components/FileGallery/FileGallery.stories.js +48 -0
  49. package/dist/esm/components/FileGallery/FileGallery.stories.js.map +1 -0
  50. package/dist/esm/components/FileGallery/index.d.ts +13 -12
  51. package/dist/esm/components/FileGallery/index.js +48 -69
  52. package/dist/esm/components/FileGallery/index.js.map +1 -1
  53. package/dist/esm/components/FileGallery/styles.js +1 -1
  54. package/dist/esm/components/FileGallery/styles.js.map +1 -1
  55. package/dist/esm/components/XAdkChatbot/XAdkChatbot.stories.js +25 -13
  56. package/dist/esm/components/XAdkChatbot/XAdkChatbot.stories.js.map +1 -1
  57. package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.d.ts +1 -0
  58. package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.js +2 -0
  59. package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.js.map +1 -1
  60. package/dist/esm/components/XAdkChatbot/components/MarkdownRender/styles.js +1 -1
  61. package/dist/esm/components/XAdkChatbot/components/MarkdownRender/styles.js.map +1 -1
  62. package/dist/esm/components/XAdkChatbot/index.js +49 -11
  63. package/dist/esm/components/XAdkChatbot/index.js.map +1 -1
  64. package/dist/esm/components/XAdkChatbot/styles.d.ts +1 -0
  65. package/dist/esm/components/XAdkChatbot/styles.js +21 -20
  66. package/dist/esm/components/XAdkChatbot/styles.js.map +1 -1
  67. package/dist/esm/components/XAdkProvider/XAdkProvider.stories.js +2 -2
  68. package/dist/esm/components/XAdkProvider/XAdkProvider.stories.js.map +1 -1
  69. package/dist/esm/components/XAdkProvider/compound/Messages.js +124 -11
  70. package/dist/esm/components/XAdkProvider/compound/Messages.js.map +1 -1
  71. package/dist/esm/components/XAdkProvider/context/ChatActionContext.d.ts +5 -0
  72. package/dist/esm/components/XAdkProvider/context/ChatActionContext.js.map +1 -1
  73. package/dist/esm/components/XAdkProvider/context/ChatStateContext.d.ts +2 -0
  74. package/dist/esm/components/XAdkProvider/context/ChatStateContext.js.map +1 -1
  75. package/dist/esm/components/XAdkProvider/index.js +23 -5
  76. package/dist/esm/components/XAdkProvider/index.js.map +1 -1
  77. package/dist/esm/components/XAdkSender/XAdkSender.stories.d.ts +2 -2
  78. package/dist/esm/components/XAdkSender/XAdkSender.stories.js +13 -13
  79. package/dist/esm/components/XAdkSender/XAdkSender.stories.js.map +1 -1
  80. package/dist/esm/components/XAdkSender/index.js +14 -4
  81. package/dist/esm/components/XAdkSender/index.js.map +1 -1
  82. package/dist/esm/hooks/useADKChat.d.ts +4 -0
  83. package/dist/esm/hooks/useADKChat.js +79 -28
  84. package/dist/esm/hooks/useADKChat.js.map +1 -1
  85. package/dist/esm/types/ChatHook.d.ts +6 -1
  86. package/dist/esm/types/ChatHook.js.map +1 -1
  87. package/dist/esm/types/FileGallery.d.ts +1 -21
  88. package/dist/esm/types/FileGallery.js.map +1 -1
  89. package/dist/esm/types/XAdkChatbot.d.ts +1 -1
  90. package/dist/esm/types/XAdkChatbot.js.map +1 -1
  91. package/dist/esm/types/XAdkProvider.d.ts +5 -0
  92. package/dist/esm/types/XAdkProvider.js.map +1 -1
  93. package/dist/esm/types/XAdkSender.js.map +1 -1
  94. package/dist/umd/chat-sdk.min.css +1 -1
  95. package/dist/umd/chat-sdk.min.js +1 -1
  96. package/package.json +1 -1
@@ -214,7 +214,7 @@ export interface XAdkChatbotProps extends Partial<XAdkSenderProps> {
214
214
  welcome?: React.ReactNode;
215
215
  /** 显示函数调用详情 */
216
216
  showFnCallDetail?: boolean;
217
- /** 是否初始化 */
217
+ /** 是否初始化完成,初始化完成后自动滚动到最新消息 */
218
218
  initialized?: boolean;
219
219
  /** 提交回调 */
220
220
  onSubmit?: ({ text, files }: SendContent) => void;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/types/XAdkChatbot.ts"],
4
- "sourcesContent": ["import { JSX, ReactNode } from \"react\";\nimport { type XAdkSenderProps } from \"./XAdkSender\";\nimport { type SendContent } from \"./XAiSender\";\n\n/**\n * 消息分组接口\n */\nexport interface ChatGroup {\n id: string;\n role: \"user\" | \"bot\";\n msgs: IMessage[];\n invocationId?: string;\n allFiles: any[];\n /** 点赞状态: 1=赞, -1=踩, 0=未反馈 */\n isLike?: number;\n}\n\nexport interface IInvocation {\n id: string;\n name: string;\n spanId: string;\n traceId: string;\n parentSpanId: string;\n startTime: number;\n endTime: number;\n sessionId: string;\n invocationId: string;\n duration: number;\n attributes: Record<string, string>;\n botName: string;\n workspaceNo: string;\n status: number;\n agentName: string;\n agentNo: string;\n agentVersionNo: string;\n userId: string;\n}\n\nexport interface AgentRunRequest {\n stream?: boolean;\n sessionId: string | undefined;\n content: {\n parts: Array<{\n text?: string;\n functionResponse?: {\n id?: string;\n name?: string;\n response?: any;\n };\n }>;\n role: string;\n };\n files?: Array<{\n fileName: string;\n fileId?: string;\n tempUrl: string;\n type?: string;\n mimeType: string;\n }>;\n stateDelta?: any;\n}\nexport interface Blob {\n displayName?: string;\n mimeType?: string;\n data: string;\n}\n\nexport interface FunctionCall {\n id?: string;\n name: string;\n args: { [key: string]: any };\n}\n\nexport interface FunctionResponse {\n id?: string;\n name: string;\n response: { [key: string]: any };\n}\n\nexport interface FileData {\n displayName: string;\n mimeType: string;\n fileUri: string;\n}\n\nexport interface ExecutableCode {\n language: \"UNKNOWN\" | \"PYTHON\";\n code: string;\n}\n\nexport interface CodeExecutionResult {\n outcome: \"UNKNOWN\" | \"OK\" | \"FAILED\" | \"DEADLINE_EXCEEDED\";\n output: string;\n}\n\nexport interface Part {\n text?: string;\n inlineData?: Blob;\n functionCall?: FunctionCall;\n functionResponse?: FunctionResponse;\n thought?: boolean;\n fileData?: FileData;\n executableCode?: ExecutableCode;\n codeExecutionResult?: CodeExecutionResult;\n errorMessage?: string;\n}\n\nexport interface GenAiContent {\n role: string;\n parts: Part[];\n}\n\nexport interface LlmRequest {\n contents: GenAiContent[];\n}\n\nexport interface LlmResponse {\n partial?: boolean;\n content: GenAiContent;\n error?: string;\n errorMessage?: string;\n errorCode?: string;\n longRunningToolIds?: string[];\n}\n\nexport interface EventActions {\n message?: string;\n artifactDelta?: any;\n functionCall?: FunctionCall;\n functionResponse?: FunctionResponse;\n finishReason?: string;\n}\n\nexport interface Event extends LlmResponse {\n id?: string;\n author?: string;\n invocationId?: string;\n actions?: EventActions;\n longRunningToolIds?: string[];\n branch?: string;\n timestamp?: number;\n evalStatus?: any;\n failedMetric?: any;\n evalScore?: any;\n evalThreshold?: any;\n groundingMetadata?: {\n searchEntryPoint?: {\n renderedContent?: any;\n };\n };\n isLike?: number;\n sessionId?: string;\n}\n\nexport interface SessionState {\n [key: string]: unknown;\n}\n\nexport interface Session {\n id?: string;\n appName?: string;\n userId?: string;\n state?: SessionState;\n events?: Event[];\n lastUpdateTime?: number;\n}\n\nexport interface TimeTick {\n position: number;\n label: string;\n}\n\nexport interface IMessage {\n /** 前端生成的唯一标识 */\n id: string;\n /** 单次请求的唯一标识 */\n invocationId?: string;\n /** 单个Event的唯一标识,一个event里有可能有多个parts的消息 */\n eventId?: string;\n /** 消息发起人:智能体名称、user */\n author?: string;\n role: \"bot\" | \"user\";\n /** 时间戳 */\n timestamp?: number;\n isLoading?: boolean;\n /** 函数调用 */\n functionCall?: FunctionCall;\n /** 函数调用结果 */\n functionResponse?: FunctionResponse;\n /** 文件上传 */\n inlineData?: Blob;\n /** 文本消息 */\n text?: string;\n /** 文件信息 */\n fileData?: FileData[];\n /** 思考 */\n thought?: boolean;\n executableCode?: ExecutableCode;\n codeExecutionResult?: CodeExecutionResult;\n renderedContent?: any;\n /** 原始数据 */\n raw?: any;\n // 下面暂时没有用到\n evalStatus?: any;\n failedMetric?: any;\n evalScore?: any;\n evalThreshold?: any;\n invocationIndex?: any;\n finalResponsePartIndex?: any;\n toolUseIndex?: any;\n /** 是否赞/踩 */\n isLike?: number;\n}\n\nexport type ActionProps = (data: {\n message: ChatGroup;\n isLastBotMsg: boolean;\n}) => JSX.Element | null;\n\nexport interface XAdkChatbotProps extends Partial<XAdkSenderProps> {\n className?: string;\n style?: React.CSSProperties;\n // 加载状态\n loading?: boolean;\n /** 消息列表 */\n messages: IMessage[];\n /** 开场白 */\n prologue?: string;\n /** 建议回复 */\n suggestions?: string[];\n /** 欢迎页面 */\n welcome?: React.ReactNode;\n /** 显示函数调用详情 */\n showFnCallDetail?: boolean;\n /** 是否初始化 */\n initialized?: boolean;\n /** 提交回调 */\n onSubmit?: ({ text, files }: SendContent) => void;\n /** 函数调用确认回调 */\n onConfirm?: (fnCall: FunctionCall, confirmed: boolean) => void;\n /** 停止回调 */\n onStop?: () => void;\n /** 清除回调 */\n onClear?: () => void;\n /** 建议回复回调 */\n onSuggest?: (text: string) => void;\n\n // ========== 新增功能 ==========\n\n /** Agent 名称 (欢迎页面) */\n agentName?: string;\n /** Agent 图标 (欢迎页面) */\n agentIcon?: string;\n /** Agent 描述 (欢迎页面) */\n description?: string;\n\n /** 是否显示重试按钮 */\n showRetry?: boolean;\n /** 是否显示复制按钮 */\n showCopy?: boolean;\n /** 是否显示日志按钮 */\n showLog?: boolean;\n\n /** 重试回调 */\n onRetry?: () => void;\n /** 复制回调 */\n onCopy?: (text: string) => void;\n /** 查看日志回调 */\n onShowLog?: (invocationId: string, timestamp?: number) => void;\n\n /** 是否启用消息分组 (默认 true) */\n enableGrouping?: boolean;\n\n /** 是否自动解析 process 内容并展示思维链 (默认 true) */\n enableProcessParsing?: boolean;\n\n /** 消息功能区 */\n actions?: ActionProps;\n\n /**\n * Process 解析选项\n * @example\n * // 业务项目格式 (注释模式)\n * parseOptions={{ mode: 'comment' }}\n *\n * @example\n * // 自定义格式\n * parseOptions={{\n * mode: 'custom',\n * customPatterns: [\n * { regex: /\\[REASONING\\]([\\s\\S]*?)\\[\\/REASONING\\]/g, type: 'reasoning' }\n * ]\n * }}\n */\n parseOptions?: {\n mode?: \"xml\" | \"comment\" | \"custom\";\n customPatterns?: Array<{ regex: RegExp; type: string }>;\n finalMarker?: string;\n };\n\n /** 是否禁用输入 */\n disabled?: boolean;\n\n /** 是否流式响应 */\n stream?: boolean;\n}\n"],
4
+ "sourcesContent": ["import { JSX } from \"react\";\nimport { type XAdkSenderProps } from \"./XAdkSender\";\nimport { type SendContent } from \"./XAiSender\";\n\n/**\n * 消息分组接口\n */\nexport interface ChatGroup {\n id: string;\n role: \"user\" | \"bot\";\n msgs: IMessage[];\n invocationId?: string;\n allFiles: any[];\n /** 点赞状态: 1=赞, -1=踩, 0=未反馈 */\n isLike?: number;\n}\n\nexport interface IInvocation {\n id: string;\n name: string;\n spanId: string;\n traceId: string;\n parentSpanId: string;\n startTime: number;\n endTime: number;\n sessionId: string;\n invocationId: string;\n duration: number;\n attributes: Record<string, string>;\n botName: string;\n workspaceNo: string;\n status: number;\n agentName: string;\n agentNo: string;\n agentVersionNo: string;\n userId: string;\n}\n\nexport interface AgentRunRequest {\n stream?: boolean;\n sessionId: string | undefined;\n content: {\n parts: Array<{\n text?: string;\n functionResponse?: {\n id?: string;\n name?: string;\n response?: any;\n };\n }>;\n role: string;\n };\n files?: Array<{\n fileName: string;\n fileId?: string;\n tempUrl: string;\n type?: string;\n mimeType: string;\n }>;\n stateDelta?: any;\n}\nexport interface Blob {\n displayName?: string;\n mimeType?: string;\n data: string;\n}\n\nexport interface FunctionCall {\n id?: string;\n name: string;\n args: { [key: string]: any };\n}\n\nexport interface FunctionResponse {\n id?: string;\n name: string;\n response: { [key: string]: any };\n}\n\nexport interface FileData {\n displayName: string;\n mimeType: string;\n fileUri: string;\n}\n\nexport interface ExecutableCode {\n language: \"UNKNOWN\" | \"PYTHON\";\n code: string;\n}\n\nexport interface CodeExecutionResult {\n outcome: \"UNKNOWN\" | \"OK\" | \"FAILED\" | \"DEADLINE_EXCEEDED\";\n output: string;\n}\n\nexport interface Part {\n text?: string;\n inlineData?: Blob;\n functionCall?: FunctionCall;\n functionResponse?: FunctionResponse;\n thought?: boolean;\n fileData?: FileData;\n executableCode?: ExecutableCode;\n codeExecutionResult?: CodeExecutionResult;\n errorMessage?: string;\n}\n\nexport interface GenAiContent {\n role: string;\n parts: Part[];\n}\n\nexport interface LlmRequest {\n contents: GenAiContent[];\n}\n\nexport interface LlmResponse {\n partial?: boolean;\n content: GenAiContent;\n error?: string;\n errorMessage?: string;\n errorCode?: string;\n longRunningToolIds?: string[];\n}\n\nexport interface EventActions {\n message?: string;\n artifactDelta?: any;\n functionCall?: FunctionCall;\n functionResponse?: FunctionResponse;\n finishReason?: string;\n}\n\nexport interface Event extends LlmResponse {\n id?: string;\n author?: string;\n invocationId?: string;\n actions?: EventActions;\n longRunningToolIds?: string[];\n branch?: string;\n timestamp?: number;\n evalStatus?: any;\n failedMetric?: any;\n evalScore?: any;\n evalThreshold?: any;\n groundingMetadata?: {\n searchEntryPoint?: {\n renderedContent?: any;\n };\n };\n isLike?: number;\n sessionId?: string;\n}\n\nexport interface SessionState {\n [key: string]: unknown;\n}\n\nexport interface Session {\n id?: string;\n appName?: string;\n userId?: string;\n state?: SessionState;\n events?: Event[];\n lastUpdateTime?: number;\n}\n\nexport interface TimeTick {\n position: number;\n label: string;\n}\n\nexport interface IMessage {\n /** 前端生成的唯一标识 */\n id: string;\n /** 单次请求的唯一标识 */\n invocationId?: string;\n /** 单个Event的唯一标识,一个event里有可能有多个parts的消息 */\n eventId?: string;\n /** 消息发起人:智能体名称、user */\n author?: string;\n role: \"bot\" | \"user\";\n /** 时间戳 */\n timestamp?: number;\n isLoading?: boolean;\n /** 函数调用 */\n functionCall?: FunctionCall;\n /** 函数调用结果 */\n functionResponse?: FunctionResponse;\n /** 文件上传 */\n inlineData?: Blob;\n /** 文本消息 */\n text?: string;\n /** 文件信息 */\n fileData?: FileData[];\n /** 思考 */\n thought?: boolean;\n executableCode?: ExecutableCode;\n codeExecutionResult?: CodeExecutionResult;\n renderedContent?: any;\n /** 原始数据 */\n raw?: any;\n // 下面暂时没有用到\n evalStatus?: any;\n failedMetric?: any;\n evalScore?: any;\n evalThreshold?: any;\n invocationIndex?: any;\n finalResponsePartIndex?: any;\n toolUseIndex?: any;\n /** 是否赞/踩 */\n isLike?: number;\n}\n\nexport type ActionProps = (data: {\n message: ChatGroup;\n isLastBotMsg: boolean;\n}) => JSX.Element | null;\n\nexport interface XAdkChatbotProps extends Partial<XAdkSenderProps> {\n className?: string;\n style?: React.CSSProperties;\n // 加载状态\n loading?: boolean;\n /** 消息列表 */\n messages: IMessage[];\n /** 开场白 */\n prologue?: string;\n /** 建议回复 */\n suggestions?: string[];\n /** 欢迎页面 */\n welcome?: React.ReactNode;\n /** 显示函数调用详情 */\n showFnCallDetail?: boolean;\n /** 是否初始化完成,初始化完成后自动滚动到最新消息 */\n initialized?: boolean;\n /** 提交回调 */\n onSubmit?: ({ text, files }: SendContent) => void;\n /** 函数调用确认回调 */\n onConfirm?: (fnCall: FunctionCall, confirmed: boolean) => void;\n /** 停止回调 */\n onStop?: () => void;\n /** 清除回调 */\n onClear?: () => void;\n /** 建议回复回调 */\n onSuggest?: (text: string) => void;\n\n // ========== 新增功能 ==========\n\n /** Agent 名称 (欢迎页面) */\n agentName?: string;\n /** Agent 图标 (欢迎页面) */\n agentIcon?: string;\n /** Agent 描述 (欢迎页面) */\n description?: string;\n\n /** 是否显示重试按钮 */\n showRetry?: boolean;\n /** 是否显示复制按钮 */\n showCopy?: boolean;\n /** 是否显示日志按钮 */\n showLog?: boolean;\n\n /** 重试回调 */\n onRetry?: () => void;\n /** 复制回调 */\n onCopy?: (text: string) => void;\n /** 查看日志回调 */\n onShowLog?: (invocationId: string, timestamp?: number) => void;\n\n /** 是否启用消息分组 (默认 true) */\n enableGrouping?: boolean;\n\n /** 是否自动解析 process 内容并展示思维链 (默认 true) */\n enableProcessParsing?: boolean;\n\n /** 消息功能区 */\n actions?: ActionProps;\n\n /**\n * Process 解析选项\n * @example\n * // 业务项目格式 (注释模式)\n * parseOptions={{ mode: 'comment' }}\n *\n * @example\n * // 自定义格式\n * parseOptions={{\n * mode: 'custom',\n * customPatterns: [\n * { regex: /\\[REASONING\\]([\\s\\S]*?)\\[\\/REASONING\\]/g, type: 'reasoning' }\n * ]\n * }}\n */\n parseOptions?: {\n mode?: \"xml\" | \"comment\" | \"custom\";\n customPatterns?: Array<{ regex: RegExp; type: string }>;\n finalMarker?: string;\n };\n\n /** 是否禁用输入 */\n disabled?: boolean;\n\n /** 是否流式响应 */\n stream?: boolean;\n}\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -97,6 +97,11 @@ export interface XAdkProviderConfig {
97
97
  appNo?: string;
98
98
  chatProps?: ChatConfig;
99
99
  debug?: boolean;
100
+ /**
101
+ * 是否展示点赞/点踩按钮
102
+ * @default true
103
+ */
104
+ showFeedback?: boolean;
100
105
  }
101
106
  /**
102
107
  * XAdkProvider Props
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/types/XAdkProvider.ts"],
4
- "sourcesContent": ["import { ReactNode } from \"react\";\nimport {\n IMessage,\n Success,\n Event,\n Error,\n SendContent,\n ThemeType,\n} from \"@/types\";\n\nexport interface DebugOptions {\n url: string;\n sessionId?: string;\n config: any;\n token: string;\n type?: \"agentDebug\" | \"appDebug\";\n /**\n * 是否启用 Hook\n * 当使用自定义 chatData 时,应设置为 false 以避免内部 Hook 初始化\n * @default true\n */\n enabled?: boolean;\n onError?: (error: Error) => void;\n onSuccess?: (data: Success) => void;\n onStream?: (data: Event) => void;\n onMessage?: (content: string, data: IMessage) => void;\n}\n\n/**\n * 事件状态码枚举\n * @enum {string}\n * @version 1.0.0\n */\nexport enum EventCode {\n /** 切换会话 */\n SESSION_SWITCH = \"SESSION_SWITCH\",\n /** 开启新会话 */\n SESSION_CREATE = \"SESSION_CREATE\",\n}\n\nexport type handleEvent = {\n code: EventCode;\n message: string;\n data?: any;\n};\n/**\n * renderFooter insert 参数说明\n */\nexport interface FooterRenderArgs {\n message: IMessage;\n isLastBotMsg: boolean;\n isLastMsg: boolean;\n}\n\n/**\n * Provider 可通过 ref 暴露的方法句柄\n */\nexport interface XAdkProviderHandle {\n startChat: (content: SendContent) => void;\n stopChat: () => void;\n clearChat: () => void;\n deleteSession: (id: string) => void;\n updateSession: (id: string, title: string) => void;\n getAppInfo: () => any;\n getMessages: () => IMessage[];\n getSessions: () => any[];\n setMessages: (msgs: IMessage[]) => void;\n setCurrentSessionDetail: (id: string) => void;\n}\n\n/**\n * config.chatProps 中的配置\n */\nexport interface ChatConfig {\n /**\n * 是否展示清空按钮\n * @type {boolean}\n * @default false\n */\n clearBtnShow?: boolean;\n /**\n * 是否展示输入框\n * @type {boolean}\n * @default true\n */\n inputShow?: boolean;\n /**\n * 打字机效果速度(单位:毫秒)\n * @type {number}\n * @default 60\n * @version 1.0.0\n */\n textSpeed?: number;\n}\n\n/**\n * Provider config 整体配置结构\n */\nexport interface XAdkProviderConfig {\n session?: {\n showSessionList?: boolean;\n };\n /**\n * 初始化后是否默认展示第一条会话内容\n * @type {boolean}\n * @default false\n */\n showFirstSession?: boolean;\n allowUpload?: boolean;\n appNo?: string;\n chatProps?: ChatConfig;\n debug?: boolean;\n}\n\n/**\n * XAdkProvider Props\n */\nexport interface XAdkProviderProps {\n /**\n * AI 服务基础地址\n */\n url: string;\n /**\n * 认证 token\n */\n token: string;\n /**\n * 组件功能配置\n */\n config?: XAdkProviderConfig;\n /**\n * Provider 唯一标识\n */\n providerId?: string;\n /**\n * 消息成功回调\n */\n onSuccess?: (success: any) => void;\n /**\n * 流式消息回调\n */\n onStream?: (data: Event) => void;\n /**\n * 错误回调\n */\n onError?: (err: any) => void;\n /**\n * 每条消息回调\n */\n onMessage?: (content: string, data: IMessage) => void;\n /**\n * 事件回调\n */\n onEvent?: (event: handleEvent) => void;\n /**\n * React 子元素 - 支持 Compound Components\n */\n children?: ReactNode;\n}\n\n// XAiSDKProps 继承 XAdkProviderProps\nexport interface XAdkSDKProps extends XAdkProviderProps {\n /**\n * 主题类型\n * @type {ThemeType}\n * @default 'default'\n * @version 1.0.0\n */\n theme?: ThemeType;\n\n /**\n * 组件属性配置\n * @type {object}\n * @default undefined\n * @version 1.0.0\n */\n componentProps?: {\n /**\n * 组件ID\n * @type {string}\n * @default undefined\n * @version 1.0.0\n */\n id?: string;\n /** 支持任意 CSS 属性 */\n [key: string]: any;\n };\n}\n"],
4
+ "sourcesContent": ["import { ReactNode } from \"react\";\nimport {\n IMessage,\n Success,\n Event,\n Error,\n SendContent,\n ThemeType,\n} from \"@/types\";\n\nexport interface DebugOptions {\n url: string;\n sessionId?: string;\n config: any;\n token: string;\n type?: \"agentDebug\" | \"appDebug\";\n /**\n * 是否启用 Hook\n * 当使用自定义 chatData 时,应设置为 false 以避免内部 Hook 初始化\n * @default true\n */\n enabled?: boolean;\n onError?: (error: Error) => void;\n onSuccess?: (data: Success) => void;\n onStream?: (data: Event) => void;\n onMessage?: (content: string, data: IMessage) => void;\n}\n\n/**\n * 事件状态码枚举\n * @enum {string}\n * @version 1.0.0\n */\nexport enum EventCode {\n /** 切换会话 */\n SESSION_SWITCH = \"SESSION_SWITCH\",\n /** 开启新会话 */\n SESSION_CREATE = \"SESSION_CREATE\",\n}\n\nexport type handleEvent = {\n code: EventCode;\n message: string;\n data?: any;\n};\n/**\n * renderFooter insert 参数说明\n */\nexport interface FooterRenderArgs {\n message: IMessage;\n isLastBotMsg: boolean;\n isLastMsg: boolean;\n}\n\n/**\n * Provider 可通过 ref 暴露的方法句柄\n */\nexport interface XAdkProviderHandle {\n startChat: (content: SendContent) => void;\n stopChat: () => void;\n clearChat: () => void;\n deleteSession: (id: string) => void;\n updateSession: (id: string, title: string) => void;\n getAppInfo: () => any;\n getMessages: () => IMessage[];\n getSessions: () => any[];\n setMessages: (msgs: IMessage[]) => void;\n setCurrentSessionDetail: (id: string) => void;\n}\n\n/**\n * config.chatProps 中的配置\n */\nexport interface ChatConfig {\n /**\n * 是否展示清空按钮\n * @type {boolean}\n * @default false\n */\n clearBtnShow?: boolean;\n /**\n * 是否展示输入框\n * @type {boolean}\n * @default true\n */\n inputShow?: boolean;\n /**\n * 打字机效果速度(单位:毫秒)\n * @type {number}\n * @default 60\n * @version 1.0.0\n */\n textSpeed?: number;\n}\n\n/**\n * Provider config 整体配置结构\n */\nexport interface XAdkProviderConfig {\n session?: {\n showSessionList?: boolean;\n };\n /**\n * 初始化后是否默认展示第一条会话内容\n * @type {boolean}\n * @default false\n */\n showFirstSession?: boolean;\n allowUpload?: boolean;\n appNo?: string;\n chatProps?: ChatConfig;\n debug?: boolean;\n /**\n * 是否展示点赞/点踩按钮\n * @default true\n */\n showFeedback?: boolean;\n}\n\n/**\n * XAdkProvider Props\n */\nexport interface XAdkProviderProps {\n /**\n * AI 服务基础地址\n */\n url: string;\n /**\n * 认证 token\n */\n token: string;\n /**\n * 组件功能配置\n */\n config?: XAdkProviderConfig;\n /**\n * Provider 唯一标识\n */\n providerId?: string;\n /**\n * 消息成功回调\n */\n onSuccess?: (success: any) => void;\n /**\n * 流式消息回调\n */\n onStream?: (data: Event) => void;\n /**\n * 错误回调\n */\n onError?: (err: any) => void;\n /**\n * 每条消息回调\n */\n onMessage?: (content: string, data: IMessage) => void;\n /**\n * 事件回调\n */\n onEvent?: (event: handleEvent) => void;\n /**\n * React 子元素 - 支持 Compound Components\n */\n children?: ReactNode;\n}\n\n// XAiSDKProps 继承 XAdkProviderProps\nexport interface XAdkSDKProps extends XAdkProviderProps {\n /**\n * 主题类型\n * @type {ThemeType}\n * @default 'default'\n * @version 1.0.0\n */\n theme?: ThemeType;\n\n /**\n * 组件属性配置\n * @type {object}\n * @default undefined\n * @version 1.0.0\n */\n componentProps?: {\n /**\n * 组件ID\n * @type {string}\n * @default undefined\n * @version 1.0.0\n */\n id?: string;\n /** 支持任意 CSS 属性 */\n [key: string]: any;\n };\n}\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAiCO,IAAK,YAAL,kBAAKA,eAAL;AAEL,EAAAA,WAAA,oBAAiB;AAEjB,EAAAA,WAAA,oBAAiB;AAJP,SAAAA;AAAA,GAAA;",
6
6
  "names": ["EventCode"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/types/XAdkSender.ts"],
4
- "sourcesContent": ["// types/XAdkSender.ts\nimport React from \"react\";\n\ninterface uploadRequestProps {\n (options: {\n file: File;\n onProgress?: (e: { percent: number }) => void;\n onSuccess?: (response: any) => void;\n onError?: (error: Error) => void;\n }): Promise<void> | void;\n}\n\nexport interface ServerFile {\n fileName: string;\n fileId: number;\n tempUrl: string;\n type: string;\n mimeType: string;\n}\n\nexport interface LocalFile {\n id: string;\n uid: string;\n name: string;\n file: File;\n size: number;\n type: string;\n progress: number;\n status: \"pending\" | \"uploading\" | \"success\" | \"error\";\n // 服务器返回字段\n fileId?: number;\n tempUrl?: string;\n response?: any;\n errorMessage?: string; // 上传错误信息\n}\n\nexport type FileValidator = (\n file: File,\n context: { files: LocalFile[] },\n) => string | null;\n\nexport interface ActionsComponents {\n SendButton: React.ComponentType<any>;\n UploadButton: React.ComponentType<any>;\n ClearButton: React.ComponentType<any>;\n}\n\nexport type SlotRenderFunction = (\n oriNode: React.ReactNode,\n info: { components: ActionsComponents },\n) => React.ReactNode | false;\n\n// 上传相关\nexport interface UploaderCoreProps {\n uploadRequest?: uploadRequestProps;\n\n maxFileSize?: number;\n allowedFileTypes?: string[];\n maxFiles?: number;\n\n validators?: FileValidator[]; // ⭐ 关键扩展点\n\n // ⭐ 数据层回调(比 onFilesChange 更底层)\n onFilesChange?: (files: LocalFile[]) => void;\n onUploadSuccess?: (file: LocalFile) => void;\n onUploadError?: (file: LocalFile, error: Error) => void;\n}\n\n// UI 相关\nexport interface SenderUIProps {\n clearBtnShow?: boolean;\n allowUpload?: boolean;\n loading?: boolean;\n disabled?: boolean; // 只读状态\n onClear?: () => void;\n onChange?: (value: string) => void;\n onSubmit?: (data: { text: string; files: ServerFile[] }) => void;\n onStop?: () => void;\n\n // UI插槽功能\n /** 后缀内容,默认展示操作按钮,设为 false 时不显示 */\n suffix?: React.ReactNode | false | SlotRenderFunction;\n /** 头部面板 */\n header?: React.ReactNode | false | SlotRenderFunction;\n /** 前缀内容 */\n prefix?: React.ReactNode | false | SlotRenderFunction;\n /** 底部内容 */\n footer?: React.ReactNode | false | SlotRenderFunction;\n}\n\nexport type XAdkSenderProps = SenderUIProps & UploaderCoreProps;\n"],
4
+ "sourcesContent": ["// types/XAdkSender.ts\nimport React from \"react\";\n\ninterface uploadRequestProps {\n (options: {\n file: File;\n onProgress?: (e: { percent: number }) => void;\n onSuccess?: (response: any) => void;\n onError?: (error: Error) => void;\n }): Promise<void> | void;\n}\n\nexport interface ServerFile {\n fileName: string;\n fileId: number;\n tempUrl: string;\n type: string;\n mimeType: string;\n}\n\nexport interface LocalFile {\n id: string;\n uid: string;\n name: string;\n file: File;\n size: number;\n type: string;\n progress: number;\n status: \"pending\" | \"uploading\" | \"success\" | \"error\";\n // 服务器返回字段\n fileId?: number;\n tempUrl?: string;\n response?: any;\n errorMessage?: string; // 上传错误信息\n}\n\nexport type FileValidator = (\n file: File,\n context: { files: LocalFile[] },\n) => string | null;\n\nexport interface ActionsComponents {\n SendButton: React.ComponentType<any>;\n UploadButton: React.ComponentType<any>;\n ClearButton: React.ComponentType<any>;\n}\n\nexport type SlotRenderFunction = (\n oriNode: React.ReactNode,\n info: { components: ActionsComponents },\n) => React.ReactNode | false;\n\n// 上传相关\nexport interface UploaderCoreProps {\n uploadRequest?: uploadRequestProps;\n\n maxFileSize?: number;\n allowedFileTypes?: string[];\n maxFiles?: number;\n\n validators?: FileValidator[];\n\n // 数据层回调\n onFilesChange?: (files: LocalFile[]) => void;\n onUploadSuccess?: (file: LocalFile) => void;\n onUploadError?: (file: LocalFile, error: Error) => void;\n}\n\n// UI 相关\nexport interface SenderUIProps {\n clearBtnShow?: boolean;\n allowUpload?: boolean;\n loading?: boolean;\n disabled?: boolean; // 只读状态\n onClear?: () => void;\n onChange?: (value: string) => void;\n onSubmit?: (data: { text: string; files: ServerFile[] }) => void;\n onStop?: () => void;\n\n // UI插槽功能\n /** 后缀内容,默认展示操作按钮,设为 false 时不显示 */\n suffix?: React.ReactNode | false | SlotRenderFunction;\n /** 头部面板 */\n header?: React.ReactNode | false | SlotRenderFunction;\n /** 前缀内容 */\n prefix?: React.ReactNode | false | SlotRenderFunction;\n /** 底部内容 */\n footer?: React.ReactNode | false | SlotRenderFunction;\n}\n\nexport type XAdkSenderProps = SenderUIProps & UploaderCoreProps;\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,6 @@
1
+ import type { Meta, StoryObj } from "@storybook/react-vite";
2
+ import FileGallery from "./index";
3
+ declare const meta: Meta<typeof FileGallery>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof meta>;
6
+ export declare const 基础用法: Story;
@@ -0,0 +1,48 @@
1
+ import FileGallery from "./index";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ var meta = {
4
+ title: "AI组件/FileGallery 附件卡片",
5
+ component: FileGallery,
6
+ parameters: {
7
+ layout: "padded",
8
+ docs: {
9
+ description: {
10
+ component: "\n\n\u4E00\u4E2A\u901A\u7528\u7684\u5355\u6587\u4EF6\u5C55\u793A\u7EC4\u4EF6\uFF0C\u7C7B\u4F3C antd-design-x \u7684\u8BBE\u8BA1\u98CE\u683C\uFF0C\u652F\u6301\u591A\u79CD\u6587\u4EF6\u7C7B\u578B\u7684\u5C55\u793A\u548C\u4EA4\u4E92\u3002\n\n## \u2728 \u7279\u6027\n\n- \uD83D\uDCC1 \u652F\u6301\u591A\u79CD\u6587\u4EF6\u7C7B\u578B\u5C55\u793A (\u56FE\u7247\u3001\u97F3\u9891\u3001\u89C6\u9891\u3001\u6587\u6863\u7B49)\n- \uD83D\uDDBC\uFE0F \u56FE\u7247\u652F\u6301\u9884\u89C8\u548C\u7F29\u7565\u56FE\n- \uD83C\uDFB5 \u97F3\u9891\u6587\u4EF6\u652F\u6301\u5185\u8054\u64AD\u653E\n- \uD83C\uDFAC \u89C6\u9891\u6587\u4EF6\u652F\u6301\u5185\u8054\u64AD\u653E\n- \uD83D\uDCCA \u663E\u793A\u6587\u4EF6\u5927\u5C0F\u3001\u7C7B\u578B\u56FE\u6807\n- \uD83D\uDDD1\uFE0F \u652F\u6301\u5220\u9664\u64CD\u4F5C\n- \uD83D\uDCE4 \u652F\u6301\u4E0A\u4F20\u8FDB\u5EA6\u663E\u793A\n- \uD83C\uDFAF \u5355\u6587\u4EF6\u8BBE\u8BA1\uFF0C\u5E03\u5C40\u7075\u6D3B\u53EF\u63A7\n- \uD83C\uDFA8 \u652F\u6301\u5361\u7247\u5185\u90E8\u5E03\u5C40\u63A7\u5236\uFF08\u56FE\u6807\u5728\u5DE6/\u53F3\uFF09\n\n## \uD83C\uDFA8 \u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B\n\n### \u56FE\u7247 (\u5E26\u9884\u89C8)\n\n- jpg, jpeg, png, gif, webp, bmp, svg\n\n### \u97F3\u9891 (\u5185\u8054\u64AD\u653E)\n\n- mp3, wav, m4a, aac, ogg, flac\n\n### \u89C6\u9891 (\u5185\u8054\u64AD\u653E)\n\n- mp4, mov, webm, mkv, avi\n\n### \u6587\u6863 (\u56FE\u6807\u5C55\u793A)\n\n- PDF: pdf\n- Word: doc, docx\n- Excel: xls, xlsx, csv\n- PowerPoint: ppt, pptx\n- \u5176\u4ED6: \u901A\u7528\u6587\u4EF6\u56FE\u6807\n\n## \uD83D\uDCDD Props \u8BF4\u660E\n\n| \u5C5E\u6027 | \u7C7B\u578B | \u9ED8\u8BA4\u503C | \u8BF4\u660E |\n| --------- | --------------------- | ------ | ------------------------------------------ |\n| file | FileItem | - | \u6587\u4EF6\u5BF9\u8C61\uFF08\u5FC5\u9700\uFF09 |\n| align | \"left\" | \"right\" | \"left\" | \u5361\u7247\u5185\u90E8\u5E03\u5C40\uFF1A\u56FE\u6807\u5728\u5DE6(left)\u6216\u53F3(right) |\n| removable | boolean | false | \u662F\u5426\u663E\u793A\u5220\u9664\u6309\u94AE |\n| onRemove | (id: string) => void | - | \u5220\u9664\u6587\u4EF6\u56DE\u8C03 |\n| className | string | - | \u81EA\u5B9A\u4E49\u6837\u5F0F\u7C7B\u540D |\n| style | React.CSSProperties | - | \u81EA\u5B9A\u4E49\u6837\u5F0F |\n\n\n## \uD83D\uDCA1 \u8BBE\u8BA1\u7406\u5FF5\n\n### \u4E3A\u4EC0\u4E48\u662F\u5355\u6587\u4EF6\u8BBE\u8BA1\uFF1F\n\n1. **\u5E03\u5C40\u7075\u6D3B\u6027**\uFF1A\u4E0A\u5C42\u7EC4\u4EF6\u53EF\u4EE5\u81EA\u7531\u63A7\u5236\u6587\u4EF6\u5217\u8868\u7684\u5E03\u5C40\u65B9\u5F0F\uFF08flex\u3001grid\u3001\u6C34\u5E73\u3001\u5782\u76F4\u7B49\uFF09\n2. **\u5BF9\u9F50\u63A7\u5236**\uFF1A\u901A\u8FC7\u5BB9\u5668\u7684 CSS \u63A7\u5236\u6574\u4E2A\u5217\u8868\u7684\u5BF9\u9F50\u65B9\u5F0F\uFF0C\u800C\u975E\u7EC4\u4EF6\u5185\u90E8\u63A7\u5236\n3. **\u8D23\u4EFB\u5355\u4E00**\uFF1A\u7EC4\u4EF6\u4E13\u6CE8\u4E8E\u5355\u4E2A\u6587\u4EF6\u7684\u5C55\u793A\uFF0C\u4E0D\u5173\u5FC3\u5217\u8868\u5E03\u5C40\n4. **\u6613\u4E8E\u6269\u5C55**\uFF1A\u53EF\u4EE5\u8F7B\u677E\u63D2\u5165\u5176\u4ED6\u5143\u7D20\uFF08\u5982\u5206\u9694\u7B26\u3001\u6807\u7B7E\u7B49\uFF09\n "
11
+ }
12
+ }
13
+ },
14
+ tags: ["autodocs"],
15
+ argTypes: {}
16
+ };
17
+ export default meta;
18
+ // ============================================
19
+ // 示例 1: 基础用法
20
+ // ============================================
21
+ export var 基础用法 = {
22
+ render: function render() {
23
+ var remoteFiles = [{
24
+ displayName: "report.xlsx",
25
+ mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
26
+ fileUri: "https://example.com/report.xlsx"
27
+ }, {
28
+ displayName: "photo.png",
29
+ mimeType: "image/png",
30
+ fileUri: "https://example.com/photo.png"
31
+ }];
32
+ return /*#__PURE__*/_jsx("div", {
33
+ style: {
34
+ display: "flex",
35
+ flexWrap: "wrap",
36
+ gap: "8px",
37
+ justifyContent: "flex-start"
38
+ },
39
+ children: remoteFiles.map(function (file, index) {
40
+ return /*#__PURE__*/_jsx(FileGallery, {
41
+ file: file,
42
+ align: "left"
43
+ }, index);
44
+ })
45
+ });
46
+ }
47
+ };
48
+ //# sourceMappingURL=FileGallery.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["FileGallery","jsx","_jsx","meta","title","component","parameters","layout","docs","description","tags","argTypes","基础用法","render","remoteFiles","displayName","mimeType","fileUri","style","display","flexWrap","gap","justifyContent","children","map","file","index","align"],"sources":["../../../../src/components/FileGallery/FileGallery.stories.tsx"],"sourcesContent":["import type { Meta, StoryObj } from \"@storybook/react-vite\";\nimport FileGallery from \"./index\";\n\nconst meta: Meta<typeof FileGallery> = {\n title: \"AI组件/FileGallery 附件卡片\",\n component: FileGallery,\n parameters: {\n layout: \"padded\",\n docs: {\n description: {\n component: `\n\n一个通用的单文件展示组件,类似 antd-design-x 的设计风格,支持多种文件类型的展示和交互。\n\n## ✨ 特性\n\n- 📁 支持多种文件类型展示 (图片、音频、视频、文档等)\n- 🖼️ 图片支持预览和缩略图\n- 🎵 音频文件支持内联播放\n- 🎬 视频文件支持内联播放\n- 📊 显示文件大小、类型图标\n- 🗑️ 支持删除操作\n- 📤 支持上传进度显示\n- 🎯 单文件设计,布局灵活可控\n- 🎨 支持卡片内部布局控制(图标在左/右)\n\n## 🎨 支持的文件类型\n\n### 图片 (带预览)\n\n- jpg, jpeg, png, gif, webp, bmp, svg\n\n### 音频 (内联播放)\n\n- mp3, wav, m4a, aac, ogg, flac\n\n### 视频 (内联播放)\n\n- mp4, mov, webm, mkv, avi\n\n### 文档 (图标展示)\n\n- PDF: pdf\n- Word: doc, docx\n- Excel: xls, xlsx, csv\n- PowerPoint: ppt, pptx\n- 其他: 通用文件图标\n\n## 📝 Props 说明\n\n| 属性 | 类型 | 默认值 | 说明 |\n| --------- | --------------------- | ------ | ------------------------------------------ |\n| file | FileItem | - | 文件对象(必需) |\n| align | \"left\" \\| \"right\" | \"left\" | 卡片内部布局:图标在左(left)或右(right) |\n| removable | boolean | false | 是否显示删除按钮 |\n| onRemove | (id: string) => void | - | 删除文件回调 |\n| className | string | - | 自定义样式类名 |\n| style | React.CSSProperties | - | 自定义样式 |\n\n\n## 💡 设计理念\n\n### 为什么是单文件设计?\n\n1. **布局灵活性**:上层组件可以自由控制文件列表的布局方式(flex、grid、水平、垂直等)\n2. **对齐控制**:通过容器的 CSS 控制整个列表的对齐方式,而非组件内部控制\n3. **责任单一**:组件专注于单个文件的展示,不关心列表布局\n4. **易于扩展**:可以轻松插入其他元素(如分隔符、标签等)\n `,\n },\n },\n },\n tags: [\"autodocs\"],\n argTypes: {},\n};\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\n// ============================================\n// 示例 1: 基础用法\n// ============================================\nexport const 基础用法: Story = {\n render: () => {\n const remoteFiles = [\n {\n displayName: \"report.xlsx\",\n mimeType:\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n fileUri: \"https://example.com/report.xlsx\",\n },\n {\n displayName: \"photo.png\",\n mimeType: \"image/png\",\n fileUri: \"https://example.com/photo.png\",\n },\n ];\n\n return (\n <div\n style={{\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: \"8px\",\n justifyContent: \"flex-start\",\n }}\n >\n {remoteFiles.map((file, index) => (\n <FileGallery key={index} file={file} align=\"left\" />\n ))}\n </div>\n );\n },\n};\n"],"mappings":"AACA,OAAOA,WAAW;AAAgB,SAAAC,GAAA,IAAAC,IAAA;AAElC,IAAMC,IAA8B,GAAG;EACrCC,KAAK,EAAE,uBAAuB;EAC9BC,SAAS,EAAEL,WAAW;EACtBM,UAAU,EAAE;IACVC,MAAM,EAAE,QAAQ;IAChBC,IAAI,EAAE;MACJC,WAAW,EAAE;QACXJ,SAAS;MA2DX;IACF;EACF,CAAC;EACDK,IAAI,EAAE,CAAC,UAAU,CAAC;EAClBC,QAAQ,EAAE,CAAC;AACb,CAAC;AAED,eAAeR,IAAI;AAGnB;AACA;AACA;AACA,OAAO,IAAMS,IAAW,GAAG;EACzBC,MAAM,EAAE,SAAAA,OAAA,EAAM;IACZ,IAAMC,WAAW,GAAG,CAClB;MACEC,WAAW,EAAE,aAAa;MAC1BC,QAAQ,EACN,mEAAmE;MACrEC,OAAO,EAAE;IACX,CAAC,EACD;MACEF,WAAW,EAAE,WAAW;MACxBC,QAAQ,EAAE,WAAW;MACrBC,OAAO,EAAE;IACX,CAAC,CACF;IAED,oBACEf,IAAA;MACEgB,KAAK,EAAE;QACLC,OAAO,EAAE,MAAM;QACfC,QAAQ,EAAE,MAAM;QAChBC,GAAG,EAAE,KAAK;QACVC,cAAc,EAAE;MAClB,CAAE;MAAAC,QAAA,EAEDT,WAAW,CAACU,GAAG,CAAC,UAACC,IAAI,EAAEC,KAAK;QAAA,oBAC3BxB,IAAA,CAACF,WAAW;UAAayB,IAAI,EAAEA,IAAK;UAACE,KAAK,EAAC;QAAM,GAA/BD,KAAiC,CAAC;MAAA,CACrD;IAAC,CACC,CAAC;EAEV;AACF,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import { FileGalleryProps } from "../../types";
3
3
  /**
4
- * FileGallery - 通用文件展示组件
4
+ * FileGallery - 单文件展示组件
5
5
  *
6
6
  * 功能特性:
7
7
  * - 📁 支持多种文件类型展示 (图片、音频、视频、文档等)
@@ -11,23 +11,24 @@ import { FileGalleryProps } from "../../types";
11
11
  * - 📊 显示文件大小、类型图标
12
12
  * - 🗑️ 支持删除操作
13
13
  * - 📤 支持上传进度显示
14
- * - 🎨 支持左右对齐
14
+ * - 🎨 支持卡片内部布局控制(align:图标和信息的排列方式)
15
15
  *
16
16
  * @example
17
17
  * // XAdkSender 场景 - 可删除的本地文件
18
- * <FileGallery
19
- * files={localFiles}
20
- * removable
21
- * onRemove={handleRemove}
22
- * align="left"
23
- * />
18
+ * {files.map(file => (
19
+ * <FileGallery
20
+ * key={file.id}
21
+ * file={file}
22
+ * removable
23
+ * onRemove={handleRemove}
24
+ * />
25
+ * ))}
24
26
  *
25
27
  * @example
26
28
  * // XadkChatbot 场景 - 只读的远程文件
27
- * <FileGallery
28
- * files={remoteFiles}
29
- * align="right"
30
- * />
29
+ * {files.map(file => (
30
+ * <FileGallery key={file.id} file={file} />
31
+ * ))}
31
32
  */
32
33
  declare const FileGallery: React.FC<FileGalleryProps>;
33
34
  export default FileGallery;
@@ -164,12 +164,46 @@ var formatFileSize = function formatFileSize(bytes) {
164
164
  };
165
165
  var styles = useStyles();
166
166
 
167
- // ==================== 子组件 ====================
168
-
169
- var FileItemComponent = function FileItemComponent(_ref) {
167
+ /**
168
+ * FileGallery - 单文件展示组件
169
+ *
170
+ * 功能特性:
171
+ * - 📁 支持多种文件类型展示 (图片、音频、视频、文档等)
172
+ * - 🖼️ 图片支持预览和缩略图
173
+ * - 🎵 音频文件支持内联播放
174
+ * - 🎬 视频文件支持内联播放
175
+ * - 📊 显示文件大小、类型图标
176
+ * - 🗑️ 支持删除操作
177
+ * - 📤 支持上传进度显示
178
+ * - 🎨 支持卡片内部布局控制(align:图标和信息的排列方式)
179
+ *
180
+ * @example
181
+ * // XAdkSender 场景 - 可删除的本地文件
182
+ * {files.map(file => (
183
+ * <FileGallery
184
+ * key={file.id}
185
+ * file={file}
186
+ * removable
187
+ * onRemove={handleRemove}
188
+ * />
189
+ * ))}
190
+ *
191
+ * @example
192
+ * // XadkChatbot 场景 - 只读的远程文件
193
+ * {files.map(file => (
194
+ * <FileGallery key={file.id} file={file} />
195
+ * ))}
196
+ */
197
+ var FileGallery = function FileGallery(_ref) {
170
198
  var file = _ref.file,
171
- removable = _ref.removable,
172
- onRemove = _ref.onRemove;
199
+ _ref$align = _ref.align,
200
+ align = _ref$align === void 0 ? "left" : _ref$align,
201
+ _ref$removable = _ref.removable,
202
+ removable = _ref$removable === void 0 ? false : _ref$removable,
203
+ _ref$onRemove = _ref.onRemove,
204
+ onRemove = _ref$onRemove === void 0 ? function () {} : _ref$onRemove,
205
+ className = _ref.className,
206
+ style = _ref.style;
173
207
  var _useState = useState(""),
174
208
  _useState2 = _slicedToArray(_useState, 2),
175
209
  objectUrl = _useState2[0],
@@ -182,6 +216,7 @@ var FileItemComponent = function FileItemComponent(_ref) {
182
216
  return URL.revokeObjectURL(url);
183
217
  };
184
218
  }, [file.file]);
219
+ if (!file) return null;
185
220
  var isImage = isImageFile(file);
186
221
  var isAudio = isAudioFile(file);
187
222
  var isVideo = isVideoFile(file);
@@ -193,7 +228,8 @@ var FileItemComponent = function FileItemComponent(_ref) {
193
228
  // 图片文件
194
229
  if (isImage) {
195
230
  return /*#__PURE__*/_jsxs("div", {
196
- className: styles.fileCard,
231
+ className: "".concat(styles.fileCard, " ").concat(align === "right" ? "align-right" : "", " ").concat(className || ""),
232
+ style: style,
197
233
  children: [/*#__PURE__*/_jsxs("div", {
198
234
  className: styles.imageThumbnail,
199
235
  children: [/*#__PURE__*/_jsx(Image, {
@@ -239,7 +275,8 @@ var FileItemComponent = function FileItemComponent(_ref) {
239
275
  // 音频文件
240
276
  if (isAudio) {
241
277
  return /*#__PURE__*/_jsxs("div", {
242
- className: styles.fileCard,
278
+ className: "".concat(styles.fileCard, " ").concat(align === "right" ? "align-right" : "", " ").concat(className || ""),
279
+ style: style,
243
280
  children: [/*#__PURE__*/_jsx("div", {
244
281
  className: styles.fileIcon,
245
282
  style: {
@@ -278,7 +315,8 @@ var FileItemComponent = function FileItemComponent(_ref) {
278
315
  // 视频文件
279
316
  if (isVideo) {
280
317
  return /*#__PURE__*/_jsxs("div", {
281
- className: styles.fileCard,
318
+ className: "".concat(styles.fileCard, " ").concat(align === "right" ? "align-right" : "", " ").concat(className || ""),
319
+ style: style,
282
320
  children: [/*#__PURE__*/_jsx("div", {
283
321
  className: styles.fileIcon,
284
322
  style: {
@@ -320,7 +358,8 @@ var FileItemComponent = function FileItemComponent(_ref) {
320
358
  color = _getFileIcon.color;
321
359
  var isExternalUrl = url && url.startsWith("http");
322
360
  return /*#__PURE__*/_jsxs("div", {
323
- className: styles.fileCard,
361
+ className: "".concat(styles.fileCard, " ").concat(align === "right" ? "align-right" : "", " ").concat(className || ""),
362
+ style: style,
324
363
  children: [/*#__PURE__*/_jsx("div", {
325
364
  className: styles.fileIcon,
326
365
  style: {
@@ -375,65 +414,5 @@ var FileItemComponent = function FileItemComponent(_ref) {
375
414
  })]
376
415
  });
377
416
  };
378
-
379
- // ==================== 主组件 ====================
380
-
381
- /**
382
- * FileGallery - 通用文件展示组件
383
- *
384
- * 功能特性:
385
- * - 📁 支持多种文件类型展示 (图片、音频、视频、文档等)
386
- * - 🖼️ 图片支持预览和缩略图
387
- * - 🎵 音频文件支持内联播放
388
- * - 🎬 视频文件支持内联播放
389
- * - 📊 显示文件大小、类型图标
390
- * - 🗑️ 支持删除操作
391
- * - 📤 支持上传进度显示
392
- * - 🎨 支持左右对齐
393
- *
394
- * @example
395
- * // XAdkSender 场景 - 可删除的本地文件
396
- * <FileGallery
397
- * files={localFiles}
398
- * removable
399
- * onRemove={handleRemove}
400
- * align="left"
401
- * />
402
- *
403
- * @example
404
- * // XadkChatbot 场景 - 只读的远程文件
405
- * <FileGallery
406
- * files={remoteFiles}
407
- * align="right"
408
- * />
409
- */
410
- var FileGallery = function FileGallery(_ref2) {
411
- var files = _ref2.files,
412
- _ref2$align = _ref2.align,
413
- align = _ref2$align === void 0 ? "left" : _ref2$align,
414
- _ref2$removable = _ref2.removable,
415
- removable = _ref2$removable === void 0 ? false : _ref2$removable,
416
- _ref2$onRemove = _ref2.onRemove,
417
- onRemove = _ref2$onRemove === void 0 ? function () {} : _ref2$onRemove,
418
- className = _ref2.className,
419
- style = _ref2.style;
420
- if (!files || files.length === 0) return null;
421
- return /*#__PURE__*/_jsx("div", {
422
- className: "".concat(styles.container, " ").concat(align === "right" ? "align-right" : "", " ").concat(className || ""),
423
- style: style,
424
- children: /*#__PURE__*/_jsx("div", {
425
- className: styles.fileList,
426
- children: /*#__PURE__*/_jsx(Image.PreviewGroup, {
427
- children: files.map(function (file, index) {
428
- return /*#__PURE__*/_jsx(FileItemComponent, {
429
- file: file,
430
- removable: removable,
431
- onRemove: onRemove
432
- }, getFileId(file) || index);
433
- })
434
- })
435
- })
436
- });
437
- };
438
417
  export default FileGallery;
439
418
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["React","useState","useEffect","Image","Tooltip","Progress","FileOutlined","FilePdfOutlined","FileWordOutlined","FileExcelOutlined","FilePptOutlined","FileImageOutlined","CloseOutlined","AudioOutlined","VideoCameraOutlined","useStyles","jsx","_jsx","jsxs","_jsxs","getFileName","file","displayName","name","getFileSize","size","getMimeType","mimeType","type","getFileUrl","_file$response","_file$response2","fileUri","response","fileUrl","tempUrl","getFileId","id","uid","isImageFile","startsWith","fileName","match","url","isAudioFile","isVideoFile","getFileExtension","filename","ext","split","pop","toLowerCase","getFileIcon","icon","color","includes","formatFileSize","bytes","toFixed","styles","FileItemComponent","_ref","removable","onRemove","_useState","_useState2","_slicedToArray","objectUrl","setObjectUrl","URL","createObjectURL","revokeObjectURL","isImage","isAudio","isVideo","fileSize","fileId","className","fileCard","children","imageThumbnail","src","alt","fallback","preview","status","imageOverlay","percent","progress","strokeColor","fileInfo","title","length","concat","substring","fileRemoveBtn","onClick","disabled","fileIcon","style","controls","mediaWrapper","width","height","_getFileIcon","isExternalUrl","href","target","rel","fileLink","showInfo","errorMessage","fontSize","marginTop","FileGallery","_ref2","files","_ref2$align","align","_ref2$removable","_ref2$onRemove","container","fileList","PreviewGroup","map","index"],"sources":["../../../../src/components/FileGallery/index.tsx"],"sourcesContent":["import React, { useState, useEffect } 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 VideoCameraOutlined,\n} from \"@ant-design/icons\";\nimport { FileItem, FileGalleryProps, FileItemComponentProps } from \"@/types\";\nimport { useStyles } from \"./styles\";\n\n// ==================== 工具函数 ====================\n\n/**\n * 获取文件名\n */\nconst getFileName = (file: FileItem): string => {\n return file.displayName || file.name || \"\";\n};\n\n/**\n * 获取文件大小\n */\nconst getFileSize = (file: FileItem): number => {\n return file.size || 0;\n};\n\n/**\n * 获取文件 MIME 类型\n */\nconst getMimeType = (file: FileItem): string => {\n return file.mimeType || file.type || \"\";\n};\n\n/**\n * 获取文件 URL\n */\nconst getFileUrl = (file: FileItem): string => {\n return (\n file.fileUri ||\n file.response?.fileUrl ||\n file.response?.tempUrl ||\n file.tempUrl ||\n \"\"\n );\n};\n\n/**\n * 获取文件唯一标识\n */\nconst getFileId = (file: FileItem): string => {\n return file.id || file.uid || \"\";\n};\n\n/**\n * 判断是否是图片文件\n */\nconst isImageFile = (file: FileItem): boolean => {\n const mimeType = getMimeType(file);\n if (mimeType && mimeType.startsWith(\"image/\")) return true;\n\n const fileName = getFileName(file);\n if (fileName && fileName.match(/\\.(jpg|jpeg|png|gif|webp|bmp|svg)$/i))\n return true;\n\n const url = getFileUrl(file);\n if (url && url.match(/\\.(jpg|jpeg|png|gif|webp|bmp|svg)(\\?.*)?$/i))\n return true;\n\n return false;\n};\n\n/**\n * 判断是否是音频文件\n */\nconst isAudioFile = (file: FileItem): boolean => {\n const mimeType = getMimeType(file);\n if (mimeType && mimeType.startsWith(\"audio/\")) return true;\n\n const fileName = getFileName(file);\n return !!fileName?.match(/\\.(mp3|wav|m4a|aac|ogg|flac)$/i);\n};\n\n/**\n * 判断是否是视频文件\n */\nconst isVideoFile = (file: FileItem): boolean => {\n const mimeType = getMimeType(file);\n if (mimeType && mimeType.startsWith(\"video/\")) return true;\n\n const fileName = getFileName(file);\n return !!fileName?.match(/\\.(mp4|mov|webm|mkv|avi)$/i);\n};\n\n/**\n * 获取文件扩展名\n */\nconst getFileExtension = (filename: string): string => {\n const ext = filename.split(\".\").pop();\n return ext ? ext.toLowerCase() : \"\";\n};\n\n/**\n * 获取文件图标和颜色\n */\nconst getFileIcon = (\n file: FileItem,\n): { icon: React.ReactNode; color: string } => {\n const ext = getFileExtension(getFileName(file));\n\n // PDF\n if (ext === \"pdf\") {\n return { icon: <FilePdfOutlined />, color: \"#ff4d4f\" };\n }\n\n // Word\n if ([\"doc\", \"docx\"].includes(ext)) {\n return { icon: <FileWordOutlined />, color: \"#1677ff\" };\n }\n\n // Excel\n if ([\"xls\", \"xlsx\", \"csv\"].includes(ext)) {\n return { icon: <FileExcelOutlined />, color: \"#22b35e\" };\n }\n\n // PPT\n if ([\"ppt\", \"pptx\"].includes(ext)) {\n return { icon: <FilePptOutlined />, color: \"#ff6e31\" };\n }\n\n // Audio\n if ([\"mp3\", \"wav\", \"m4a\", \"aac\", \"ogg\", \"flac\"].includes(ext)) {\n return { icon: <AudioOutlined />, color: \"#722ed1\" };\n }\n\n // Video\n if ([\"mp4\", \"mov\", \"webm\", \"mkv\", \"avi\"].includes(ext)) {\n return { icon: <VideoCameraOutlined />, color: \"#fa8c16\" };\n }\n\n // 图片\n if (isImageFile(file)) {\n return { icon: <FileImageOutlined />, color: \"#8c8c8c\" };\n }\n\n // 默认\n return { icon: <FileOutlined />, color: \"#8c8c8c\" };\n};\n\n/**\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 styles = useStyles();\n\n// ==================== 子组件 ====================\n\nconst FileItemComponent: React.FC<FileItemComponentProps> = ({\n file,\n removable,\n onRemove,\n}) => {\n const [objectUrl, setObjectUrl] = useState(\"\");\n\n useEffect(() => {\n if (!file.file) return;\n\n const url = URL.createObjectURL(file.file);\n setObjectUrl(url);\n\n return () => URL.revokeObjectURL(url);\n }, [file.file]);\n\n const isImage = isImageFile(file);\n const isAudio = isAudioFile(file);\n const isVideo = isVideoFile(file);\n const fileName = getFileName(file);\n const fileSize = getFileSize(file);\n const fileId = getFileId(file);\n const url = getFileUrl(file) || objectUrl;\n\n // 图片文件\n if (isImage) {\n return (\n <div className={styles.fileCard}>\n {/* 图片缩略图 */}\n <div className={styles.imageThumbnail}>\n <Image\n src={url}\n alt={fileName}\n fallback=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mN8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==\"\n preview={{\n src: url,\n }}\n />\n\n {/* 上传进度遮罩 */}\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 )}\n </div>\n\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 <div className={styles.fileSize}>{formatFileSize(fileSize)}</div>\n </div>\n\n {/* 删除按钮 */}\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n }\n\n // 音频文件\n if (isAudio) {\n return (\n <div className={styles.fileCard}>\n <div className={styles.fileIcon} style={{ color: \"#722ed1\" }}>\n <AudioOutlined />\n </div>\n\n <div className={styles.fileInfo}>\n <Tooltip title={fileName}>\n <div className={styles.fileName}>{fileName}</div>\n </Tooltip>\n\n <audio\n src={url}\n controls\n className={styles.mediaWrapper}\n style={{ width: \"100%\", height: 28 }}\n />\n </div>\n\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n }\n\n // 视频文件\n if (isVideo) {\n return (\n <div className={styles.fileCard}>\n <div className={styles.fileIcon} style={{ color: \"#fa8c16\" }}>\n <VideoCameraOutlined />\n </div>\n\n <div className={styles.fileInfo}>\n <Tooltip title={fileName}>\n <div className={styles.fileName}>{fileName}</div>\n </Tooltip>\n\n <video\n src={url}\n controls\n className={styles.mediaWrapper}\n style={{ width: \"100%\", height: 40 }}\n />\n </div>\n\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n }\n\n // 其他文件\n const { icon, color } = getFileIcon(file);\n const isExternalUrl = url && url.startsWith(\"http\");\n\n return (\n <div className={styles.fileCard}>\n <div className={styles.fileIcon} style={{ color }}>\n {icon}\n </div>\n\n <div className={styles.fileInfo}>\n {isExternalUrl ? (\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}>{formatFileSize(fileSize)}</div>\n )\n )}\n\n {file.status === \"error\" && file.errorMessage && (\n <div\n style={{\n fontSize: \"11px\",\n color: \"#ff4d4f\",\n marginTop: \"2px\",\n }}\n >\n {file.errorMessage}\n </div>\n )}\n </div>\n\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n};\n\n// ==================== 主组件 ====================\n\n/**\n * FileGallery - 通用文件展示组件\n *\n * 功能特性:\n * - 📁 支持多种文件类型展示 (图片、音频、视频、文档等)\n * - 🖼️ 图片支持预览和缩略图\n * - 🎵 音频文件支持内联播放\n * - 🎬 视频文件支持内联播放\n * - 📊 显示文件大小、类型图标\n * - 🗑️ 支持删除操作\n * - 📤 支持上传进度显示\n * - 🎨 支持左右对齐\n *\n * @example\n * // XAdkSender 场景 - 可删除的本地文件\n * <FileGallery\n * files={localFiles}\n * removable\n * onRemove={handleRemove}\n * align=\"left\"\n * />\n *\n * @example\n * // XadkChatbot 场景 - 只读的远程文件\n * <FileGallery\n * files={remoteFiles}\n * align=\"right\"\n * />\n */\nconst FileGallery: React.FC<FileGalleryProps> = ({\n files,\n align = \"left\",\n removable = false,\n onRemove = () => {},\n className,\n style,\n}) => {\n if (!files || files.length === 0) return null;\n\n return (\n <div\n className={`${styles.container} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={style}\n >\n <div className={styles.fileList}>\n <Image.PreviewGroup>\n {files.map((file, index) => (\n <FileItemComponent\n key={getFileId(file) || index}\n file={file}\n removable={removable}\n onRemove={onRemove}\n />\n ))}\n </Image.PreviewGroup>\n </div>\n </div>\n );\n};\n\nexport default FileGallery;\n"],"mappings":"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"}
1
+ {"version":3,"names":["React","useState","useEffect","Image","Tooltip","Progress","FileOutlined","FilePdfOutlined","FileWordOutlined","FileExcelOutlined","FilePptOutlined","FileImageOutlined","CloseOutlined","AudioOutlined","VideoCameraOutlined","useStyles","jsx","_jsx","jsxs","_jsxs","getFileName","file","displayName","name","getFileSize","size","getMimeType","mimeType","type","getFileUrl","_file$response","_file$response2","fileUri","response","fileUrl","tempUrl","getFileId","id","uid","isImageFile","startsWith","fileName","match","url","isAudioFile","isVideoFile","getFileExtension","filename","ext","split","pop","toLowerCase","getFileIcon","icon","color","includes","formatFileSize","bytes","toFixed","styles","FileGallery","_ref","_ref$align","align","_ref$removable","removable","_ref$onRemove","onRemove","className","style","_useState","_useState2","_slicedToArray","objectUrl","setObjectUrl","URL","createObjectURL","revokeObjectURL","isImage","isAudio","isVideo","fileSize","fileId","concat","fileCard","children","imageThumbnail","src","alt","fallback","preview","status","imageOverlay","percent","progress","strokeColor","fileInfo","title","length","substring","fileRemoveBtn","onClick","disabled","fileIcon","controls","mediaWrapper","width","height","_getFileIcon","isExternalUrl","href","target","rel","fileLink","showInfo","errorMessage","fontSize","marginTop"],"sources":["../../../../src/components/FileGallery/index.tsx"],"sourcesContent":["import React, { useState, useEffect } 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 VideoCameraOutlined,\n} from \"@ant-design/icons\";\nimport { FileItem, FileGalleryProps, FileItemComponentProps } from \"@/types\";\nimport { useStyles } from \"./styles\";\n\n// ==================== 工具函数 ====================\n\n/**\n * 获取文件名\n */\nconst getFileName = (file: FileItem): string => {\n return file.displayName || file.name || \"\";\n};\n\n/**\n * 获取文件大小\n */\nconst getFileSize = (file: FileItem): number => {\n return file.size || 0;\n};\n\n/**\n * 获取文件 MIME 类型\n */\nconst getMimeType = (file: FileItem): string => {\n return file.mimeType || file.type || \"\";\n};\n\n/**\n * 获取文件 URL\n */\nconst getFileUrl = (file: FileItem): string => {\n return (\n file.fileUri ||\n file.response?.fileUrl ||\n file.response?.tempUrl ||\n file.tempUrl ||\n \"\"\n );\n};\n\n/**\n * 获取文件唯一标识\n */\nconst getFileId = (file: FileItem): string => {\n return file.id || file.uid || \"\";\n};\n\n/**\n * 判断是否是图片文件\n */\nconst isImageFile = (file: FileItem): boolean => {\n const mimeType = getMimeType(file);\n if (mimeType && mimeType.startsWith(\"image/\")) return true;\n\n const fileName = getFileName(file);\n if (fileName && fileName.match(/\\.(jpg|jpeg|png|gif|webp|bmp|svg)$/i))\n return true;\n\n const url = getFileUrl(file);\n if (url && url.match(/\\.(jpg|jpeg|png|gif|webp|bmp|svg)(\\?.*)?$/i))\n return true;\n\n return false;\n};\n\n/**\n * 判断是否是音频文件\n */\nconst isAudioFile = (file: FileItem): boolean => {\n const mimeType = getMimeType(file);\n if (mimeType && mimeType.startsWith(\"audio/\")) return true;\n\n const fileName = getFileName(file);\n return !!fileName?.match(/\\.(mp3|wav|m4a|aac|ogg|flac)$/i);\n};\n\n/**\n * 判断是否是视频文件\n */\nconst isVideoFile = (file: FileItem): boolean => {\n const mimeType = getMimeType(file);\n if (mimeType && mimeType.startsWith(\"video/\")) return true;\n\n const fileName = getFileName(file);\n return !!fileName?.match(/\\.(mp4|mov|webm|mkv|avi)$/i);\n};\n\n/**\n * 获取文件扩展名\n */\nconst getFileExtension = (filename: string): string => {\n const ext = filename.split(\".\").pop();\n return ext ? ext.toLowerCase() : \"\";\n};\n\n/**\n * 获取文件图标和颜色\n */\nconst getFileIcon = (\n file: FileItem,\n): { icon: React.ReactNode; color: string } => {\n const ext = getFileExtension(getFileName(file));\n\n // PDF\n if (ext === \"pdf\") {\n return { icon: <FilePdfOutlined />, color: \"#ff4d4f\" };\n }\n\n // Word\n if ([\"doc\", \"docx\"].includes(ext)) {\n return { icon: <FileWordOutlined />, color: \"#1677ff\" };\n }\n\n // Excel\n if ([\"xls\", \"xlsx\", \"csv\"].includes(ext)) {\n return { icon: <FileExcelOutlined />, color: \"#22b35e\" };\n }\n\n // PPT\n if ([\"ppt\", \"pptx\"].includes(ext)) {\n return { icon: <FilePptOutlined />, color: \"#ff6e31\" };\n }\n\n // Audio\n if ([\"mp3\", \"wav\", \"m4a\", \"aac\", \"ogg\", \"flac\"].includes(ext)) {\n return { icon: <AudioOutlined />, color: \"#722ed1\" };\n }\n\n // Video\n if ([\"mp4\", \"mov\", \"webm\", \"mkv\", \"avi\"].includes(ext)) {\n return { icon: <VideoCameraOutlined />, color: \"#fa8c16\" };\n }\n\n // 图片\n if (isImageFile(file)) {\n return { icon: <FileImageOutlined />, color: \"#8c8c8c\" };\n }\n\n // 默认\n return { icon: <FileOutlined />, color: \"#8c8c8c\" };\n};\n\n/**\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 styles = useStyles();\n\n/**\n * FileGallery - 单文件展示组件\n *\n * 功能特性:\n * - 📁 支持多种文件类型展示 (图片、音频、视频、文档等)\n * - 🖼️ 图片支持预览和缩略图\n * - 🎵 音频文件支持内联播放\n * - 🎬 视频文件支持内联播放\n * - 📊 显示文件大小、类型图标\n * - 🗑️ 支持删除操作\n * - 📤 支持上传进度显示\n * - 🎨 支持卡片内部布局控制(align:图标和信息的排列方式)\n *\n * @example\n * // XAdkSender 场景 - 可删除的本地文件\n * {files.map(file => (\n * <FileGallery\n * key={file.id}\n * file={file}\n * removable\n * onRemove={handleRemove}\n * />\n * ))}\n *\n * @example\n * // XadkChatbot 场景 - 只读的远程文件\n * {files.map(file => (\n * <FileGallery key={file.id} file={file} />\n * ))}\n */\nconst FileGallery: React.FC<FileGalleryProps> = ({\n file,\n align = \"left\",\n removable = false,\n onRemove = () => {},\n className,\n style,\n}) => {\n const [objectUrl, setObjectUrl] = useState(\"\");\n\n useEffect(() => {\n if (!file.file) return;\n\n const url = URL.createObjectURL(file.file);\n setObjectUrl(url);\n\n return () => URL.revokeObjectURL(url);\n }, [file.file]);\n\n if (!file) return null;\n\n const isImage = isImageFile(file);\n const isAudio = isAudioFile(file);\n const isVideo = isVideoFile(file);\n const fileName = getFileName(file);\n const fileSize = getFileSize(file);\n const fileId = getFileId(file);\n const url = getFileUrl(file) || objectUrl;\n\n // 图片文件\n if (isImage) {\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={style}\n >\n {/* 图片缩略图 */}\n <div className={styles.imageThumbnail}>\n <Image\n src={url}\n alt={fileName}\n fallback=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mN8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==\"\n preview={{\n src: url,\n }}\n />\n\n {/* 上传进度遮罩 */}\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 )}\n </div>\n\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 <div className={styles.fileSize}>{formatFileSize(fileSize)}</div>\n </div>\n\n {/* 删除按钮 */}\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n }\n\n // 音频文件\n if (isAudio) {\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={style}\n >\n <div className={styles.fileIcon} style={{ color: \"#722ed1\" }}>\n <AudioOutlined />\n </div>\n\n <div className={styles.fileInfo}>\n <Tooltip title={fileName}>\n <div className={styles.fileName}>{fileName}</div>\n </Tooltip>\n\n <audio\n src={url}\n controls\n className={styles.mediaWrapper}\n style={{ width: \"100%\", height: 28 }}\n />\n </div>\n\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n }\n\n // 视频文件\n if (isVideo) {\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={style}\n >\n <div className={styles.fileIcon} style={{ color: \"#fa8c16\" }}>\n <VideoCameraOutlined />\n </div>\n\n <div className={styles.fileInfo}>\n <Tooltip title={fileName}>\n <div className={styles.fileName}>{fileName}</div>\n </Tooltip>\n\n <video\n src={url}\n controls\n className={styles.mediaWrapper}\n style={{ width: \"100%\", height: 40 }}\n />\n </div>\n\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n }\n\n // 其他文件\n const { icon, color } = getFileIcon(file);\n const isExternalUrl = url && url.startsWith(\"http\");\n\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={style}\n >\n <div className={styles.fileIcon} style={{ color }}>\n {icon}\n </div>\n\n <div className={styles.fileInfo}>\n {isExternalUrl ? (\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}>{formatFileSize(fileSize)}</div>\n )\n )}\n\n {file.status === \"error\" && file.errorMessage && (\n <div\n style={{\n fontSize: \"11px\",\n color: \"#ff4d4f\",\n marginTop: \"2px\",\n }}\n >\n {file.errorMessage}\n </div>\n )}\n </div>\n\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n};\n\nexport default FileGallery;\n"],"mappings":";AAAA,OAAOA,KAAK,IAAIC,QAAQ,EAAEC,SAAS,QAAQ,OAAO;AAClD,SAASC,KAAK,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,MAAM;AAC/C,SACEC,YAAY,EACZC,eAAe,EACfC,gBAAgB,EAChBC,iBAAiB,EACjBC,eAAe,EACfC,iBAAiB,EACjBC,aAAa,EACbC,aAAa,EACbC,mBAAmB,QACd,mBAAmB;AAE1B,SAASC,SAAS;;AAElB;;AAEA;AACA;AACA;AAFA,SAAAC,GAAA,IAAAC,IAAA;AAAA,SAAAC,IAAA,IAAAC,KAAA;AAGA,IAAMC,WAAW,GAAG,SAAdA,WAAWA,CAAIC,IAAc,EAAa;EAC9C,OAAOA,IAAI,CAACC,WAAW,IAAID,IAAI,CAACE,IAAI,IAAI,EAAE;AAC5C,CAAC;;AAED;AACA;AACA;AACA,IAAMC,WAAW,GAAG,SAAdA,WAAWA,CAAIH,IAAc,EAAa;EAC9C,OAAOA,IAAI,CAACI,IAAI,IAAI,CAAC;AACvB,CAAC;;AAED;AACA;AACA;AACA,IAAMC,WAAW,GAAG,SAAdA,WAAWA,CAAIL,IAAc,EAAa;EAC9C,OAAOA,IAAI,CAACM,QAAQ,IAAIN,IAAI,CAACO,IAAI,IAAI,EAAE;AACzC,CAAC;;AAED;AACA;AACA;AACA,IAAMC,UAAU,GAAG,SAAbA,UAAUA,CAAIR,IAAc,EAAa;EAAA,IAAAS,cAAA,EAAAC,eAAA;EAC7C,OACEV,IAAI,CAACW,OAAO,MAAAF,cAAA,GACZT,IAAI,CAACY,QAAQ,cAAAH,cAAA,uBAAbA,cAAA,CAAeI,OAAO,OAAAH,eAAA,GACtBV,IAAI,CAACY,QAAQ,cAAAF,eAAA,uBAAbA,eAAA,CAAeI,OAAO,KACtBd,IAAI,CAACc,OAAO,IACZ,EAAE;AAEN,CAAC;;AAED;AACA;AACA;AACA,IAAMC,SAAS,GAAG,SAAZA,SAASA,CAAIf,IAAc,EAAa;EAC5C,OAAOA,IAAI,CAACgB,EAAE,IAAIhB,IAAI,CAACiB,GAAG,IAAI,EAAE;AAClC,CAAC;;AAED;AACA;AACA;AACA,IAAMC,WAAW,GAAG,SAAdA,WAAWA,CAAIlB,IAAc,EAAc;EAC/C,IAAMM,QAAQ,GAAGD,WAAW,CAACL,IAAI,CAAC;EAClC,IAAIM,QAAQ,IAAIA,QAAQ,CAACa,UAAU,CAAC,QAAQ,CAAC,EAAE,OAAO,IAAI;EAE1D,IAAMC,QAAQ,GAAGrB,WAAW,CAACC,IAAI,CAAC;EAClC,IAAIoB,QAAQ,IAAIA,QAAQ,CAACC,KAAK,CAAC,qCAAqC,CAAC,EACnE,OAAO,IAAI;EAEb,IAAMC,GAAG,GAAGd,UAAU,CAACR,IAAI,CAAC;EAC5B,IAAIsB,GAAG,IAAIA,GAAG,CAACD,KAAK,CAAC,4CAA4C,CAAC,EAChE,OAAO,IAAI;EAEb,OAAO,KAAK;AACd,CAAC;;AAED;AACA;AACA;AACA,IAAME,WAAW,GAAG,SAAdA,WAAWA,CAAIvB,IAAc,EAAc;EAC/C,IAAMM,QAAQ,GAAGD,WAAW,CAACL,IAAI,CAAC;EAClC,IAAIM,QAAQ,IAAIA,QAAQ,CAACa,UAAU,CAAC,QAAQ,CAAC,EAAE,OAAO,IAAI;EAE1D,IAAMC,QAAQ,GAAGrB,WAAW,CAACC,IAAI,CAAC;EAClC,OAAO,CAAC,EAACoB,QAAQ,aAARA,QAAQ,eAARA,QAAQ,CAAEC,KAAK,CAAC,gCAAgC,CAAC;AAC5D,CAAC;;AAED;AACA;AACA;AACA,IAAMG,WAAW,GAAG,SAAdA,WAAWA,CAAIxB,IAAc,EAAc;EAC/C,IAAMM,QAAQ,GAAGD,WAAW,CAACL,IAAI,CAAC;EAClC,IAAIM,QAAQ,IAAIA,QAAQ,CAACa,UAAU,CAAC,QAAQ,CAAC,EAAE,OAAO,IAAI;EAE1D,IAAMC,QAAQ,GAAGrB,WAAW,CAACC,IAAI,CAAC;EAClC,OAAO,CAAC,EAACoB,QAAQ,aAARA,QAAQ,eAARA,QAAQ,CAAEC,KAAK,CAAC,4BAA4B,CAAC;AACxD,CAAC;;AAED;AACA;AACA;AACA,IAAMI,gBAAgB,GAAG,SAAnBA,gBAAgBA,CAAIC,QAAgB,EAAa;EACrD,IAAMC,GAAG,GAAGD,QAAQ,CAACE,KAAK,CAAC,GAAG,CAAC,CAACC,GAAG,CAAC,CAAC;EACrC,OAAOF,GAAG,GAAGA,GAAG,CAACG,WAAW,CAAC,CAAC,GAAG,EAAE;AACrC,CAAC;;AAED;AACA;AACA;AACA,IAAMC,WAAW,GAAG,SAAdA,WAAWA,CACf/B,IAAc,EAC+B;EAC7C,IAAM2B,GAAG,GAAGF,gBAAgB,CAAC1B,WAAW,CAACC,IAAI,CAAC,CAAC;;EAE/C;EACA,IAAI2B,GAAG,KAAK,KAAK,EAAE;IACjB,OAAO;MAAEK,IAAI,eAAEpC,IAAA,CAACV,eAAe,IAAE,CAAC;MAAE+C,KAAK,EAAE;IAAU,CAAC;EACxD;;EAEA;EACA,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAACC,QAAQ,CAACP,GAAG,CAAC,EAAE;IACjC,OAAO;MAAEK,IAAI,eAAEpC,IAAA,CAACT,gBAAgB,IAAE,CAAC;MAAE8C,KAAK,EAAE;IAAU,CAAC;EACzD;;EAEA;EACA,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAACC,QAAQ,CAACP,GAAG,CAAC,EAAE;IACxC,OAAO;MAAEK,IAAI,eAAEpC,IAAA,CAACR,iBAAiB,IAAE,CAAC;MAAE6C,KAAK,EAAE;IAAU,CAAC;EAC1D;;EAEA;EACA,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAACC,QAAQ,CAACP,GAAG,CAAC,EAAE;IACjC,OAAO;MAAEK,IAAI,eAAEpC,IAAA,CAACP,eAAe,IAAE,CAAC;MAAE4C,KAAK,EAAE;IAAU,CAAC;EACxD;;EAEA;EACA,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAACC,QAAQ,CAACP,GAAG,CAAC,EAAE;IAC7D,OAAO;MAAEK,IAAI,eAAEpC,IAAA,CAACJ,aAAa,IAAE,CAAC;MAAEyC,KAAK,EAAE;IAAU,CAAC;EACtD;;EAEA;EACA,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAACC,QAAQ,CAACP,GAAG,CAAC,EAAE;IACtD,OAAO;MAAEK,IAAI,eAAEpC,IAAA,CAACH,mBAAmB,IAAE,CAAC;MAAEwC,KAAK,EAAE;IAAU,CAAC;EAC5D;;EAEA;EACA,IAAIf,WAAW,CAAClB,IAAI,CAAC,EAAE;IACrB,OAAO;MAAEgC,IAAI,eAAEpC,IAAA,CAACN,iBAAiB,IAAE,CAAC;MAAE2C,KAAK,EAAE;IAAU,CAAC;EAC1D;;EAEA;EACA,OAAO;IAAED,IAAI,eAAEpC,IAAA,CAACX,YAAY,IAAE,CAAC;IAAEgD,KAAK,EAAE;EAAU,CAAC;AACrD,CAAC;;AAED;AACA;AACA;AACA,IAAME,cAAc,GAAG,SAAjBA,cAAcA,CAAIC,KAAa,EAAa;EAChD,IAAIA,KAAK,GAAG,IAAI,EAAE,OAAOA,KAAK,GAAG,IAAI;EACrC,IAAIA,KAAK,GAAG,IAAI,GAAG,IAAI,EAAE,OAAO,CAACA,KAAK,GAAG,IAAI,EAAEC,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK;EACjE,OAAO,CAACD,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,EAAEC,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK;AACnD,CAAC;AAED,IAAMC,MAAM,GAAG5C,SAAS,CAAC,CAAC;;AAE1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAM6C,WAAuC,GAAG,SAA1CA,WAAuCA,CAAAC,IAAA,EAOvC;EAAA,IANJxC,IAAI,GAAAwC,IAAA,CAAJxC,IAAI;IAAAyC,UAAA,GAAAD,IAAA,CACJE,KAAK;IAALA,KAAK,GAAAD,UAAA,cAAG,MAAM,GAAAA,UAAA;IAAAE,cAAA,GAAAH,IAAA,CACdI,SAAS;IAATA,SAAS,GAAAD,cAAA,cAAG,KAAK,GAAAA,cAAA;IAAAE,aAAA,GAAAL,IAAA,CACjBM,QAAQ;IAARA,QAAQ,GAAAD,aAAA,cAAG,YAAM,CAAC,CAAC,GAAAA,aAAA;IACnBE,SAAS,GAAAP,IAAA,CAATO,SAAS;IACTC,KAAK,GAAAR,IAAA,CAALQ,KAAK;EAEL,IAAAC,SAAA,GAAkCrE,QAAQ,CAAC,EAAE,CAAC;IAAAsE,UAAA,GAAAC,cAAA,CAAAF,SAAA;IAAvCG,SAAS,GAAAF,UAAA;IAAEG,YAAY,GAAAH,UAAA;EAE9BrE,SAAS,CAAC,YAAM;IACd,IAAI,CAACmB,IAAI,CAACA,IAAI,EAAE;IAEhB,IAAMsB,GAAG,GAAGgC,GAAG,CAACC,eAAe,CAACvD,IAAI,CAACA,IAAI,CAAC;IAC1CqD,YAAY,CAAC/B,GAAG,CAAC;IAEjB,OAAO;MAAA,OAAMgC,GAAG,CAACE,eAAe,CAAClC,GAAG,CAAC;IAAA;EACvC,CAAC,EAAE,CAACtB,IAAI,CAACA,IAAI,CAAC,CAAC;EAEf,IAAI,CAACA,IAAI,EAAE,OAAO,IAAI;EAEtB,IAAMyD,OAAO,GAAGvC,WAAW,CAAClB,IAAI,CAAC;EACjC,IAAM0D,OAAO,GAAGnC,WAAW,CAACvB,IAAI,CAAC;EACjC,IAAM2D,OAAO,GAAGnC,WAAW,CAACxB,IAAI,CAAC;EACjC,IAAMoB,QAAQ,GAAGrB,WAAW,CAACC,IAAI,CAAC;EAClC,IAAM4D,QAAQ,GAAGzD,WAAW,CAACH,IAAI,CAAC;EAClC,IAAM6D,MAAM,GAAG9C,SAAS,CAACf,IAAI,CAAC;EAC9B,IAAMsB,GAAG,GAAGd,UAAU,CAACR,IAAI,CAAC,IAAIoD,SAAS;;EAEzC;EACA,IAAIK,OAAO,EAAE;IACX,oBACE3D,KAAA;MACEiD,SAAS,KAAAe,MAAA,CAAKxB,MAAM,CAACyB,QAAQ,OAAAD,MAAA,CAAIpB,KAAK,KAAK,OAAO,GAAG,aAAa,GAAG,EAAE,OAAAoB,MAAA,CAAIf,SAAS,IAAI,EAAE,CAAG;MAC7FC,KAAK,EAAEA,KAAM;MAAAgB,QAAA,gBAGblE,KAAA;QAAKiD,SAAS,EAAET,MAAM,CAAC2B,cAAe;QAAAD,QAAA,gBACpCpE,IAAA,CAACd,KAAK;UACJoF,GAAG,EAAE5C,GAAI;UACT6C,GAAG,EAAE/C,QAAS;UACdgD,QAAQ,EAAC,wHAAwH;UACjIC,OAAO,EAAE;YACPH,GAAG,EAAE5C;UACP;QAAE,CACH,CAAC,EAGDtB,IAAI,CAACsE,MAAM,KAAK,WAAW,iBAC1B1E,IAAA;UAAKmD,SAAS,EAAET,MAAM,CAACiC,YAAa;UAAAP,QAAA,eAClCpE,IAAA,CAACZ,QAAQ;YACPuB,IAAI,EAAC,QAAQ;YACbiE,OAAO,EAAExE,IAAI,CAACyE,QAAS;YACvBrE,IAAI,EAAE,EAAG;YACTsE,WAAW,EAAC;UAAS,CACtB;QAAC,CACC,CACN;MAAA,CACE,CAAC,eAGN5E,KAAA;QAAKiD,SAAS,EAAET,MAAM,CAACqC,QAAS;QAAAX,QAAA,gBAC9BpE,IAAA,CAACb,OAAO;UAAC6F,KAAK,EAAExD,QAAS;UAAA4C,QAAA,eACvBpE,IAAA;YAAKmD,SAAS,EAAET,MAAM,CAAClB,QAAS;YAAA4C,QAAA,EAC7B5C,QAAQ,CAACyD,MAAM,GAAG,EAAE,MAAAf,MAAA,CACd1C,QAAQ,CAAC0D,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,WAC5B1D;UAAQ,CACT;QAAC,CACC,CAAC,eACVxB,IAAA;UAAKmD,SAAS,EAAET,MAAM,CAACsB,QAAS;UAAAI,QAAA,EAAE7B,cAAc,CAACyB,QAAQ;QAAC,CAAM,CAAC;MAAA,CAC9D,CAAC,EAGLhB,SAAS,iBACRhD,IAAA;QACEmD,SAAS,EAAET,MAAM,CAACyC,aAAc;QAChCC,OAAO,EAAE,SAAAA,QAAA;UAAA,OAAMlC,QAAQ,CAACe,MAAM,CAAC;QAAA,CAAC;QAChCoB,QAAQ,EAAEjF,IAAI,CAACsE,MAAM,KAAK,WAAY;QACtC,cAAW,0BAAM;QAAAN,QAAA,eAEjBpE,IAAA,CAACL,aAAa,IAAE;MAAC,CACX,CACT;IAAA,CACE,CAAC;EAEV;;EAEA;EACA,IAAImE,OAAO,EAAE;IACX,oBACE5D,KAAA;MACEiD,SAAS,KAAAe,MAAA,CAAKxB,MAAM,CAACyB,QAAQ,OAAAD,MAAA,CAAIpB,KAAK,KAAK,OAAO,GAAG,aAAa,GAAG,EAAE,OAAAoB,MAAA,CAAIf,SAAS,IAAI,EAAE,CAAG;MAC7FC,KAAK,EAAEA,KAAM;MAAAgB,QAAA,gBAEbpE,IAAA;QAAKmD,SAAS,EAAET,MAAM,CAAC4C,QAAS;QAAClC,KAAK,EAAE;UAAEf,KAAK,EAAE;QAAU,CAAE;QAAA+B,QAAA,eAC3DpE,IAAA,CAACJ,aAAa,IAAE;MAAC,CACd,CAAC,eAENM,KAAA;QAAKiD,SAAS,EAAET,MAAM,CAACqC,QAAS;QAAAX,QAAA,gBAC9BpE,IAAA,CAACb,OAAO;UAAC6F,KAAK,EAAExD,QAAS;UAAA4C,QAAA,eACvBpE,IAAA;YAAKmD,SAAS,EAAET,MAAM,CAAClB,QAAS;YAAA4C,QAAA,EAAE5C;UAAQ,CAAM;QAAC,CAC1C,CAAC,eAEVxB,IAAA;UACEsE,GAAG,EAAE5C,GAAI;UACT6D,QAAQ;UACRpC,SAAS,EAAET,MAAM,CAAC8C,YAAa;UAC/BpC,KAAK,EAAE;YAAEqC,KAAK,EAAE,MAAM;YAAEC,MAAM,EAAE;UAAG;QAAE,CACtC,CAAC;MAAA,CACC,CAAC,EAEL1C,SAAS,iBACRhD,IAAA;QACEmD,SAAS,EAAET,MAAM,CAACyC,aAAc;QAChCC,OAAO,EAAE,SAAAA,QAAA;UAAA,OAAMlC,QAAQ,CAACe,MAAM,CAAC;QAAA,CAAC;QAChCoB,QAAQ,EAAEjF,IAAI,CAACsE,MAAM,KAAK,WAAY;QACtC,cAAW,0BAAM;QAAAN,QAAA,eAEjBpE,IAAA,CAACL,aAAa,IAAE;MAAC,CACX,CACT;IAAA,CACE,CAAC;EAEV;;EAEA;EACA,IAAIoE,OAAO,EAAE;IACX,oBACE7D,KAAA;MACEiD,SAAS,KAAAe,MAAA,CAAKxB,MAAM,CAACyB,QAAQ,OAAAD,MAAA,CAAIpB,KAAK,KAAK,OAAO,GAAG,aAAa,GAAG,EAAE,OAAAoB,MAAA,CAAIf,SAAS,IAAI,EAAE,CAAG;MAC7FC,KAAK,EAAEA,KAAM;MAAAgB,QAAA,gBAEbpE,IAAA;QAAKmD,SAAS,EAAET,MAAM,CAAC4C,QAAS;QAAClC,KAAK,EAAE;UAAEf,KAAK,EAAE;QAAU,CAAE;QAAA+B,QAAA,eAC3DpE,IAAA,CAACH,mBAAmB,IAAE;MAAC,CACpB,CAAC,eAENK,KAAA;QAAKiD,SAAS,EAAET,MAAM,CAACqC,QAAS;QAAAX,QAAA,gBAC9BpE,IAAA,CAACb,OAAO;UAAC6F,KAAK,EAAExD,QAAS;UAAA4C,QAAA,eACvBpE,IAAA;YAAKmD,SAAS,EAAET,MAAM,CAAClB,QAAS;YAAA4C,QAAA,EAAE5C;UAAQ,CAAM;QAAC,CAC1C,CAAC,eAEVxB,IAAA;UACEsE,GAAG,EAAE5C,GAAI;UACT6D,QAAQ;UACRpC,SAAS,EAAET,MAAM,CAAC8C,YAAa;UAC/BpC,KAAK,EAAE;YAAEqC,KAAK,EAAE,MAAM;YAAEC,MAAM,EAAE;UAAG;QAAE,CACtC,CAAC;MAAA,CACC,CAAC,EAEL1C,SAAS,iBACRhD,IAAA;QACEmD,SAAS,EAAET,MAAM,CAACyC,aAAc;QAChCC,OAAO,EAAE,SAAAA,QAAA;UAAA,OAAMlC,QAAQ,CAACe,MAAM,CAAC;QAAA,CAAC;QAChCoB,QAAQ,EAAEjF,IAAI,CAACsE,MAAM,KAAK,WAAY;QACtC,cAAW,0BAAM;QAAAN,QAAA,eAEjBpE,IAAA,CAACL,aAAa,IAAE;MAAC,CACX,CACT;IAAA,CACE,CAAC;EAEV;;EAEA;EACA,IAAAgG,YAAA,GAAwBxD,WAAW,CAAC/B,IAAI,CAAC;IAAjCgC,IAAI,GAAAuD,YAAA,CAAJvD,IAAI;IAAEC,KAAK,GAAAsD,YAAA,CAALtD,KAAK;EACnB,IAAMuD,aAAa,GAAGlE,GAAG,IAAIA,GAAG,CAACH,UAAU,CAAC,MAAM,CAAC;EAEnD,oBACErB,KAAA;IACEiD,SAAS,KAAAe,MAAA,CAAKxB,MAAM,CAACyB,QAAQ,OAAAD,MAAA,CAAIpB,KAAK,KAAK,OAAO,GAAG,aAAa,GAAG,EAAE,OAAAoB,MAAA,CAAIf,SAAS,IAAI,EAAE,CAAG;IAC7FC,KAAK,EAAEA,KAAM;IAAAgB,QAAA,gBAEbpE,IAAA;MAAKmD,SAAS,EAAET,MAAM,CAAC4C,QAAS;MAAClC,KAAK,EAAE;QAAEf,KAAK,EAALA;MAAM,CAAE;MAAA+B,QAAA,EAC/ChC;IAAI,CACF,CAAC,eAENlC,KAAA;MAAKiD,SAAS,EAAET,MAAM,CAACqC,QAAS;MAAAX,QAAA,GAC7BwB,aAAa,gBACZ5F,IAAA;QACE6F,IAAI,EAAEnE,GAAI;QACVoE,MAAM,EAAC,QAAQ;QACfC,GAAG,EAAC,qBAAqB;QACzB5C,SAAS,EAAET,MAAM,CAACsD,QAAS;QAAA5B,QAAA,eAE3BpE,IAAA,CAACb,OAAO;UAAC6F,KAAK,EAAExD,QAAS;UAAA4C,QAAA,eACvBpE,IAAA;YAAKmD,SAAS,EAAET,MAAM,CAAClB,QAAS;YAAA4C,QAAA,EAC7B5C,QAAQ,CAACyD,MAAM,GAAG,EAAE,MAAAf,MAAA,CACd1C,QAAQ,CAAC0D,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,WAC5B1D;UAAQ,CACT;QAAC,CACC;MAAC,CACT,CAAC,gBAEJxB,IAAA,CAACb,OAAO;QAAC6F,KAAK,EAAExD,QAAS;QAAA4C,QAAA,eACvBpE,IAAA;UAAKmD,SAAS,EAAET,MAAM,CAAClB,QAAS;UAAA4C,QAAA,EAC7B5C,QAAQ,CAACyD,MAAM,GAAG,EAAE,MAAAf,MAAA,CACd1C,QAAQ,CAAC0D,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,WAC5B1D;QAAQ,CACT;MAAC,CACC,CACV,EAEApB,IAAI,CAACsE,MAAM,KAAK,WAAW,gBAC1B1E,IAAA,CAACZ,QAAQ;QACPwF,OAAO,EAAExE,IAAI,CAACyE,QAAS;QACvBrE,IAAI,EAAC,OAAO;QACZyF,QAAQ,EAAE,KAAM;QAChBnB,WAAW,EAAC,SAAS;QACrB3B,SAAS,EAAET,MAAM,CAACmC;MAAS,CAC5B,CAAC,GAEFb,QAAQ,GAAG,CAAC,iBACVhE,IAAA;QAAKmD,SAAS,EAAET,MAAM,CAACsB,QAAS;QAAAI,QAAA,EAAE7B,cAAc,CAACyB,QAAQ;MAAC,CAAM,CAEnE,EAEA5D,IAAI,CAACsE,MAAM,KAAK,OAAO,IAAItE,IAAI,CAAC8F,YAAY,iBAC3ClG,IAAA;QACEoD,KAAK,EAAE;UACL+C,QAAQ,EAAE,MAAM;UAChB9D,KAAK,EAAE,SAAS;UAChB+D,SAAS,EAAE;QACb,CAAE;QAAAhC,QAAA,EAEDhE,IAAI,CAAC8F;MAAY,CACf,CACN;IAAA,CACE,CAAC,EAELlD,SAAS,iBACRhD,IAAA;MACEmD,SAAS,EAAET,MAAM,CAACyC,aAAc;MAChCC,OAAO,EAAE,SAAAA,QAAA;QAAA,OAAMlC,QAAQ,CAACe,MAAM,CAAC;MAAA,CAAC;MAChCoB,QAAQ,EAAEjF,IAAI,CAACsE,MAAM,KAAK,WAAY;MACtC,cAAW,0BAAM;MAAAN,QAAA,eAEjBpE,IAAA,CAACL,aAAa,IAAE;IAAC,CACX,CACT;EAAA,CACE,CAAC;AAEV,CAAC;AAED,eAAegD,WAAW"}
@@ -6,7 +6,7 @@ export var useStyles = withBasicStyles(function () {
6
6
  return {
7
7
  container: css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\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 "]))),
8
8
  fileList: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n "]))),
9
- fileCard: css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n position: relative;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 12px;\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 "]))),
9
+ fileCard: css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n position: relative;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 12px;\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 \u65F6\u56FE\u6807\u5728\u53F3\u4FA7 */\n &.align-right {\n flex-direction: row-reverse;\n }\n "]))),
10
10
  imageThumbnail: css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\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 "]))),
11
11
  imageOverlay: css(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\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 "]))),
12
12
  fileIcon: css(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["\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 "]))),
@@ -1 +1 @@
1
- {"version":3,"names":["css","withBasicStyles","useStyles","container","_templateObject","_taggedTemplateLiteral","fileList","_templateObject2","fileCard","_templateObject3","imageThumbnail","_templateObject4","imageOverlay","_templateObject5","fileIcon","_templateObject6","fileInfo","_templateObject7","fileName","_templateObject8","fileSize","_templateObject9","progress","_templateObject10","fileRemoveBtn","_templateObject11","fileLink","_templateObject12","mediaWrapper","_templateObject13"],"sources":["../../../../src/components/FileGallery/styles.tsx"],"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 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\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}));\n\nexport default useStyles;\n"],"mappings":";;AAAA,SAASA,GAAG,QAAQ,cAAc;AAClC,SAASC,eAAe;AAExB,OAAO,IAAMC,SAAS,GAAGD,eAAe,CAAC;EAAA,OAAO;IAC9CE,SAAS,EAAEH,GAAG,CAAAI,eAAA,KAAAA,eAAA,GAAAC,sBAAA,+JASb;IAEDC,QAAQ,EAAEN,GAAG,CAAAO,gBAAA,KAAAA,gBAAA,GAAAF,sBAAA,qEAIZ;IAEDG,QAAQ,EAAER,GAAG,CAAAS,gBAAA,KAAAA,gBAAA,GAAAJ,sBAAA,qYAkBZ;IAEDK,cAAc,EAAEV,GAAG,CAAAW,gBAAA,KAAAA,gBAAA,GAAAN,sBAAA,4iBAwBlB;IAEDO,YAAY,EAAEZ,GAAG,CAAAa,gBAAA,KAAAA,gBAAA,GAAAR,sBAAA,mOAWhB;IAEDS,QAAQ,EAAEd,GAAG,CAAAe,gBAAA,KAAAA,gBAAA,GAAAV,sBAAA,wKAQZ;IAEDW,QAAQ,EAAEhB,GAAG,CAAAiB,gBAAA,KAAAA,gBAAA,GAAAZ,sBAAA,oEAIZ;IAEDa,QAAQ,EAAElB,GAAG,CAAAmB,gBAAA,KAAAA,gBAAA,GAAAd,sBAAA,sLAQZ;IAEDe,QAAQ,EAAEpB,GAAG,CAAAqB,gBAAA,KAAAA,gBAAA,GAAAhB,sBAAA,uDAGZ;IAEDiB,QAAQ,EAAEtB,GAAG,CAAAuB,iBAAA,KAAAA,iBAAA,GAAAlB,sBAAA,qKAUZ;IAEDmB,aAAa,EAAExB,GAAG,CAAAyB,iBAAA,KAAAA,iBAAA,GAAApB,sBAAA,mjBA4BjB;IAEDqB,QAAQ,EAAE1B,GAAG,CAAA2B,iBAAA,KAAAA,iBAAA,GAAAtB,sBAAA,2MAWZ;IAEDuB,YAAY,EAAE5B,GAAG,CAAA6B,iBAAA,KAAAA,iBAAA,GAAAxB,sBAAA;EAGnB,CAAC;AAAA,CAAC,CAAC;AAEH,eAAeH,SAAS"}
1
+ {"version":3,"names":["css","withBasicStyles","useStyles","container","_templateObject","_taggedTemplateLiteral","fileList","_templateObject2","fileCard","_templateObject3","imageThumbnail","_templateObject4","imageOverlay","_templateObject5","fileIcon","_templateObject6","fileInfo","_templateObject7","fileName","_templateObject8","fileSize","_templateObject9","progress","_templateObject10","fileRemoveBtn","_templateObject11","fileLink","_templateObject12","mediaWrapper","_templateObject13"],"sources":["../../../../src/components/FileGallery/styles.tsx"],"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 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}));\n\nexport default useStyles;\n"],"mappings":";;AAAA,SAASA,GAAG,QAAQ,cAAc;AAClC,SAASC,eAAe;AAExB,OAAO,IAAMC,SAAS,GAAGD,eAAe,CAAC;EAAA,OAAO;IAC9CE,SAAS,EAAEH,GAAG,CAAAI,eAAA,KAAAA,eAAA,GAAAC,sBAAA,+JASb;IAEDC,QAAQ,EAAEN,GAAG,CAAAO,gBAAA,KAAAA,gBAAA,GAAAF,sBAAA,qEAIZ;IAEDG,QAAQ,EAAER,GAAG,CAAAS,gBAAA,KAAAA,gBAAA,GAAAJ,sBAAA,mgBAuBZ;IAEDK,cAAc,EAAEV,GAAG,CAAAW,gBAAA,KAAAA,gBAAA,GAAAN,sBAAA,4iBAwBlB;IAEDO,YAAY,EAAEZ,GAAG,CAAAa,gBAAA,KAAAA,gBAAA,GAAAR,sBAAA,mOAWhB;IAEDS,QAAQ,EAAEd,GAAG,CAAAe,gBAAA,KAAAA,gBAAA,GAAAV,sBAAA,wKAQZ;IAEDW,QAAQ,EAAEhB,GAAG,CAAAiB,gBAAA,KAAAA,gBAAA,GAAAZ,sBAAA,oEAIZ;IAEDa,QAAQ,EAAElB,GAAG,CAAAmB,gBAAA,KAAAA,gBAAA,GAAAd,sBAAA,sLAQZ;IAEDe,QAAQ,EAAEpB,GAAG,CAAAqB,gBAAA,KAAAA,gBAAA,GAAAhB,sBAAA,uDAGZ;IAEDiB,QAAQ,EAAEtB,GAAG,CAAAuB,iBAAA,KAAAA,iBAAA,GAAAlB,sBAAA,qKAUZ;IAEDmB,aAAa,EAAExB,GAAG,CAAAyB,iBAAA,KAAAA,iBAAA,GAAApB,sBAAA,mjBA4BjB;IAEDqB,QAAQ,EAAE1B,GAAG,CAAA2B,iBAAA,KAAAA,iBAAA,GAAAtB,sBAAA,2MAWZ;IAEDuB,YAAY,EAAE5B,GAAG,CAAA6B,iBAAA,KAAAA,iBAAA,GAAAxB,sBAAA;EAGnB,CAAC;AAAA,CAAC,CAAC;AAEH,eAAeH,SAAS"}