@ai-group/chat-sdk 3.7.1-alpha11 → 3.7.1-alpha13

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 (28) hide show
  1. package/dist/cjs/components/XAdkSender/InlineTagInput.d.ts +4 -0
  2. package/dist/cjs/components/XAdkSender/InlineTagInput.js +28 -1
  3. package/dist/cjs/components/XAdkSender/InlineTagInput.js.map +2 -2
  4. package/dist/cjs/components/XAdkSender/{QuickList.d.ts → InputSuggestionList.d.ts} +4 -3
  5. package/dist/cjs/components/XAdkSender/{QuickList.js → InputSuggestionList.js} +55 -30
  6. package/dist/cjs/components/XAdkSender/InputSuggestionList.js.map +7 -0
  7. package/dist/cjs/components/XAdkSender/index.js +21 -7
  8. package/dist/cjs/components/XAdkSender/index.js.map +3 -3
  9. package/dist/cjs/components/XAdkSender/styles.js +13 -1
  10. package/dist/cjs/components/XAdkSender/styles.js.map +2 -2
  11. package/dist/cjs/types/XAdkSender.d.ts +4 -0
  12. package/dist/cjs/types/XAdkSender.js.map +1 -1
  13. package/dist/esm/components/XAdkSender/InlineTagInput.d.ts +4 -0
  14. package/dist/esm/components/XAdkSender/InlineTagInput.js +26 -7
  15. package/dist/esm/components/XAdkSender/InlineTagInput.js.map +1 -1
  16. package/dist/esm/components/XAdkSender/{QuickList.d.ts → InputSuggestionList.d.ts} +4 -3
  17. package/dist/esm/components/XAdkSender/{QuickList.js → InputSuggestionList.js} +53 -28
  18. package/dist/esm/components/XAdkSender/InputSuggestionList.js.map +1 -0
  19. package/dist/esm/components/XAdkSender/index.js +25 -12
  20. package/dist/esm/components/XAdkSender/index.js.map +1 -1
  21. package/dist/esm/components/XAdkSender/styles.js +2 -2
  22. package/dist/esm/components/XAdkSender/styles.js.map +1 -1
  23. package/dist/esm/types/XAdkSender.d.ts +4 -0
  24. package/dist/esm/types/XAdkSender.js.map +1 -1
  25. package/dist/umd/chat-sdk.min.js +1 -1
  26. package/package.json +1 -1
  27. package/dist/cjs/components/XAdkSender/QuickList.js.map +0 -7
  28. package/dist/esm/components/XAdkSender/QuickList.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/XAdkSender/index.tsx"],
4
- "sourcesContent": ["import React, {\n useState,\n useRef,\n useCallback,\n forwardRef,\n useImperativeHandle,\n useMemo,\n useEffect,\n} from \"react\";\nimport { Popconfirm, message, Tooltip, Input, Modal } from \"antd\";\nimport {\n ClearOutlined,\n LoadingOutlined,\n ArrowUpOutlined,\n} from \"@ant-design/icons\";\nimport {\n XAdkSenderProps,\n XAdkSenderHandle,\n ServerFile,\n LocalFile,\n ActionsComponents,\n FileValidator,\n UploadFileResult,\n MentionTag,\n XAdkSenderSubmitData,\n XAdkSenderSubmitFormat,\n XAdkSenderSubmitPart,\n} from \"@/types\";\nimport { useStyles } from \"./styles\";\nimport FileGallery from \"../FileGallery\";\nimport QuickList from \"./QuickList\";\nimport InputTags from \"./InputTags\";\nimport InlineTagInput, { InlineTagInputRef } from \"./InlineTagInput\";\nimport { getExt } from \"@/utils/file\";\n\nconst XAdkSender = forwardRef<XAdkSenderHandle, XAdkSenderProps>(\n (\n {\n clearBtnShow = true,\n draggable = false,\n onFileSelect,\n loading = false,\n disabled = false,\n value: controlledValue,\n defaultValue = \"\",\n uploadRequest = () => {},\n onClear,\n onChange,\n onSubmit,\n onStop,\n onFilesChange,\n onUploadSuccess,\n onUploadError,\n maxFileSize = 10,\n placeholder = \"\",\n validators: customValidators = [],\n allowedFileTypes = [],\n maxFiles = Infinity,\n sendButtonRender,\n suffix,\n header,\n prefix,\n footer,\n footerLeft,\n quickKeys = [],\n inlineTags = false,\n renderMention,\n renderTag,\n mentions: controlledMentions,\n tags: controlledTags,\n defaultMentions,\n defaultTags = [],\n defaultInputParts,\n onMentionsChange,\n onTagsChange,\n onQuickKeyTrigger,\n submitFormat = \"text\",\n formatMention,\n formatTag,\n transformSubmitData,\n },\n ref,\n ) => {\n const styles = useStyles();\n const isControlled = controlledValue !== undefined;\n const [internalValue, setInternalValue] = useState<string>(defaultValue);\n const value = isControlled ? controlledValue : internalValue;\n const setValue = (newValue: string) => {\n if (!isControlled) {\n setInternalValue(newValue);\n }\n onChange?.(newValue);\n };\n\n // mentions 支持受控/非受控两种模式;inlineTags 打开时会和输入内容混排。\n const resolvedControlledMentions = controlledMentions ?? controlledTags;\n const initialMentions = defaultMentions ?? defaultTags;\n const isMentionsControlled = resolvedControlledMentions !== undefined;\n const [internalMentions, setInternalMentions] =\n useState<MentionTag[]>(initialMentions);\n const mentions = isMentionsControlled\n ? resolvedControlledMentions!\n : internalMentions;\n const setMentions = (newMentions: MentionTag[]) => {\n if (!isMentionsControlled) {\n setInternalMentions(newMentions);\n }\n onMentionsChange?.(newMentions);\n onTagsChange?.(newMentions);\n };\n\n const [files, setFiles] = useState<LocalFile[]>([]);\n const [isDragOver, setIsDragOver] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n const textareaRef = useRef<any>(null);\n const inlineInputRef = useRef<InlineTagInputRef>(null);\n\n // 快捷键弹层状态:记录触发字符、关键词,以及触发字符在纯文本中的位置。\n // SDK 不内置搜索框;业务方可在 onQuickKeyTrigger 中根据 keyword 自行更新 quickKeys.options。\n const [activeQuickKey, setActiveQuickKey] = useState<string | null>(null);\n const [quickKeyKeyword, setQuickKeyKeyword] = useState(\"\");\n const [quickKeyTriggerIdx, setQuickKeyTriggerIdx] = useState(-1);\n const [quickKeyActiveIndex, setQuickKeyActiveIndex] = useState(0);\n\n // 生成唯一ID\n const generateId = () => {\n return Date.now().toString(36) + Math.random().toString(36).substr(2);\n };\n\n const normalizeUploadResponse = (response: any): UploadFileResult => {\n const data = response?.data ?? response;\n return (Array.isArray(data) ? data[0] : data) ?? {};\n };\n\n const escapeXml = (text: string) =>\n text\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\");\n\n const escapeMarkdownLabel = (text: string) =>\n text.replace(/\\\\/g, \"\\\\\\\\\").replace(/\\]/g, \"\\\\]\");\n\n const getMentionSubmitValue = (mention: MentionTag) =>\n String(\n mention.value ??\n mention.uri ??\n mention.data?.uri ??\n mention.data?.value ??\n mention.data?.name ??\n mention.targetId ??\n mention.displayName ??\n mention.label ??\n \"\",\n );\n\n const defaultFormatMention = (\n mention: MentionTag,\n format: Exclude<XAdkSenderSubmitFormat, \"structured\">,\n index: number,\n ) => {\n const value = getMentionSubmitValue(mention);\n if (format === \"xml\") {\n return `<mention type=\"${escapeXml(mention.type)}\" id=\"${escapeXml(mention.id)}\" label=\"${escapeXml(mention.label)}\" value=\"${escapeXml(value)}\" />`;\n }\n\n if (format === \"markdown\") {\n const href =\n mention.uri ||\n (value.includes(\"://\")\n ? value\n : `xadk-mention://${encodeURIComponent(mention.type)}/${encodeURIComponent(mention.id)}`);\n return `[@${escapeMarkdownLabel(mention.displayName || mention.label)}](${href})`;\n }\n\n return `@${mention.displayName || value || `mention-${index + 1}`}`;\n };\n\n const serializeMention = (\n mention: MentionTag,\n format: Exclude<XAdkSenderSubmitFormat, \"structured\">,\n index: number,\n ) =>\n formatMention?.(mention, { format, index }) ??\n formatTag?.(mention, { format, index }) ??\n defaultFormatMention(mention, format, index);\n\n const getSubmitParts = useCallback((): XAdkSenderSubmitPart[] => {\n if (inlineTags) {\n const parts = inlineInputRef.current?.getParts() || [];\n if (parts.length > 0) return parts;\n }\n\n const textParts: XAdkSenderSubmitPart[] = value ? [{ type: \"text\", text: value }] : [];\n const mentionParts = mentions.map((mention) => ({\n type: \"mention\" as const,\n mention,\n }));\n return [...mentionParts, ...textParts];\n }, [inlineTags, mentions, value]);\n\n const serializeParts = (\n parts: XAdkSenderSubmitPart[],\n format: XAdkSenderSubmitFormat,\n ) => {\n if (format === \"structured\") {\n return parts.reduce(\n (content, part) => content + (part.type === \"text\" ? part.text : \"\"),\n \"\",\n );\n }\n\n let tagIndex = 0;\n return parts\n .map((part) => {\n if (part.type === \"text\") return part.text;\n const result = serializeMention(part.mention, format, tagIndex);\n tagIndex += 1;\n return result;\n })\n .join(\"\");\n };\n\n const createSubmitData = (formattedFiles: ServerFile[]): XAdkSenderSubmitData => {\n const parts = getSubmitParts();\n const rawText = parts.reduce(\n (content, part) => content + (part.type === \"text\" ? part.text : \"\"),\n \"\",\n );\n const standardData: Omit<XAdkSenderSubmitData, \"payload\"> = {\n text: serializeParts(parts, submitFormat),\n rawText,\n format: submitFormat,\n parts,\n files: formattedFiles,\n mentions,\n tags: mentions,\n };\n\n return {\n ...standardData,\n payload: transformSubmitData?.(standardData),\n };\n };\n\n // 检查文件类型\n const checkFileType = (file: File): boolean => {\n if (allowedFileTypes?.length > 0) {\n const ext = getExt(file);\n\n return allowedFileTypes.some((type) => {\n if (type.includes(\"/\")) {\n if (type.endsWith(\"/*\")) {\n return file.type.startsWith(type.split(\"/\")[0]);\n }\n return file.type === type;\n }\n\n if (type.startsWith(\".\")) {\n return ext === type.slice(1);\n }\n\n return false;\n });\n }\n return true;\n };\n\n // 重复文件检测\n const isDuplicateFile = (file: File, files: LocalFile[]) => {\n return files.some((f) => f.name === file.name && f.size === file.size);\n };\n\n // 内置校验器集合\n const builtInValidators: FileValidator[] = [\n (_file, { files }) => {\n if (files.length >= maxFiles) {\n return `最多只能上传 ${maxFiles} 个文件`;\n }\n return null;\n },\n (file) => {\n const maxSize = maxFileSize * 1024 * 1024;\n if (file.size > maxSize) {\n return `文件大小不能超过 ${maxFileSize}MB`;\n }\n return null;\n },\n (file) => {\n if (!checkFileType(file)) {\n return \"不支持的文件类型\";\n }\n return null;\n },\n (file, { files }) => {\n if (isDuplicateFile(file, files)) {\n return \"文件已存在\";\n }\n return null;\n },\n ];\n\n const allValidators = [...builtInValidators, ...customValidators];\n\n // 验证文件\n const validateFile = (file: File): { valid: boolean; message?: string } => {\n for (const validator of allValidators) {\n const error = validator(file, { files });\n if (error) {\n return { valid: false, message: error };\n }\n }\n return { valid: true };\n };\n\n // 处理文件选择\n const handleFileSelect = useCallback(\n (selectedFiles: File[]) => {\n const fileArray = Array.from(selectedFiles);\n\n if (files.length + fileArray.length > maxFiles) {\n message.error(`最多只能上传 ${maxFiles} 个文件`);\n return;\n }\n\n const validFiles: LocalFile[] = [];\n\n fileArray.forEach((file) => {\n const validation = validateFile(file);\n\n if (validation.valid) {\n validFiles.push({\n id: generateId(),\n uid: generateId(),\n name: file.name,\n size: file.size,\n type: file.type,\n file,\n progress: 0,\n status: \"pending\",\n response: null,\n });\n } else {\n message.error(validation.message);\n }\n });\n\n if (validFiles.length > 0) {\n setFiles((prev) => {\n const next = [...prev, ...validFiles];\n onFilesChange?.(next);\n return next;\n });\n uploadFiles(validFiles);\n }\n },\n [files, maxFiles, maxFileSize, allowedFileTypes],\n );\n\n // 暴露给业务工具栏调用的命令式能力;外部 Popover 选择标签时可插入到当前光标位置。\n useImperativeHandle(\n ref,\n () => ({\n addFiles: (rawFiles: File[]) => {\n handleFileSelect(rawFiles);\n },\n insertMention: (mention: MentionTag) => {\n if (inlineTags) {\n inlineInputRef.current?.insertMention(mention);\n return;\n }\n setMentions([...mentions, mention]);\n },\n insertTag: (mention: MentionTag) => {\n if (inlineTags) {\n inlineInputRef.current?.insertMention(mention);\n return;\n }\n setMentions([...mentions, mention]);\n },\n focus: () => {\n inlineTags ? inlineInputRef.current?.focus() : textareaRef.current?.focus();\n },\n }),\n [handleFileSelect, inlineTags, setMentions, mentions],\n );\n\n // 上传文件\n const uploadFiles = async (fileList: LocalFile[]) => {\n for (const localFile of fileList) {\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id ? { ...f, status: \"uploading\" } : f,\n ),\n );\n\n try {\n await uploadRequest({\n file: localFile.file,\n onProgress: (e) => {\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id ? { ...f, progress: e.percent } : f,\n ),\n );\n },\n onSuccess: (response) => {\n const responseData = normalizeUploadResponse(response);\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id\n ? {\n ...f,\n status: \"success\",\n progress: 100,\n response,\n fileId: responseData.fileId || responseData.id,\n tempUrl:\n responseData.tempUrl ||\n responseData.fileUrl ||\n responseData.url,\n }\n : f,\n ),\n );\n\n onUploadSuccess?.({\n ...localFile,\n status: \"success\",\n response,\n fileId: responseData.fileId || responseData.id,\n tempUrl:\n responseData.tempUrl ||\n responseData.fileUrl ||\n responseData.url,\n });\n },\n onError: (error) => {\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id\n ? {\n ...f,\n status: \"error\",\n errorMessage: error.message,\n }\n : f,\n ),\n );\n onUploadError?.(localFile, error);\n },\n });\n } catch (error) {\n console.error(\"上传处理错误:\", error);\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id\n ? {\n ...f,\n status: \"error\",\n errorMessage:\n error instanceof Error ? error.message : \"上传处理失败\",\n }\n : f,\n ),\n );\n message.error(`${localFile.name} 上传失败`);\n }\n }\n };\n\n // 删除文件\n const handleRemoveFile = (id: string) => {\n setFiles((prev) => {\n const next = prev.filter((file) => file.id !== id);\n onFilesChange?.(next);\n return next;\n });\n };\n\n // 处理拖拽事件\n const handleDragOver = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n if (draggable) {\n setIsDragOver(true);\n }\n },\n [draggable],\n );\n\n const handleDragLeave = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n if (draggable) {\n setIsDragOver(false);\n }\n },\n [draggable],\n );\n\n const handleDrop = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragOver(false);\n\n if (\n draggable &&\n e.dataTransfer.files &&\n e.dataTransfer.files.length > 0\n ) {\n // 内核不再自行处理文件,交给外层(DefaultLayout/业务)通过 onFileSelect 决定\n onFileSelect?.(Array.from(e.dataTransfer.files));\n }\n },\n [draggable, onFileSelect],\n );\n\n // 删除标签\n const handleRemoveMention = useCallback(\n (id: string) => {\n setMentions(mentions.filter((item) => item.id !== id));\n },\n [mentions, setMentions],\n );\n\n // 查找当前活跃的快捷键配置\n const activeQuickKeyConfig = useMemo(() => {\n if (!activeQuickKey) return null;\n return quickKeys.find((qk) => qk.key === activeQuickKey) || null;\n }, [activeQuickKey, quickKeys]);\n\n const activeQuickKeyOptionsLength = activeQuickKeyConfig?.options.length || 0;\n\n useEffect(() => {\n setQuickKeyActiveIndex(0);\n }, [activeQuickKey]);\n\n useEffect(() => {\n if (activeQuickKeyOptionsLength <= 0) {\n setQuickKeyActiveIndex(0);\n return;\n }\n\n // 业务方可能在 onQuickKeyTrigger 中动态更新 options;\n // 这里只做越界归一化,不重置有效索引,避免键盘高亮移动后又跳回第一项。\n setQuickKeyActiveIndex(\n (prev) => ((prev % activeQuickKeyOptionsLength) + activeQuickKeyOptionsLength) %\n activeQuickKeyOptionsLength,\n );\n }, [activeQuickKeyOptionsLength]);\n\n const getNextQuickKeyIndex = useCallback(\n (current: number, step: number) => {\n if (activeQuickKeyOptionsLength <= 0) return 0;\n return (\n (current + step + activeQuickKeyOptionsLength) %\n activeQuickKeyOptionsLength\n );\n },\n [activeQuickKeyOptionsLength],\n );\n\n // 从当前光标前的连续文本片段中查找最近的快捷键,例如 abc@doc 会触发 @。\n const detectQuickKey = useCallback(\n (text: string, cursorPos: number) => {\n const quickKeyChars = quickKeys.map((qk) => qk.key);\n if (quickKeyChars.length === 0) return;\n\n const textBeforeCursor = text.slice(0, cursorPos);\n let found = false;\n for (let i = textBeforeCursor.length - 1; i >= 0; i--) {\n const char = textBeforeCursor[i];\n if (/\\s/.test(char)) break;\n if (quickKeyChars.includes(char)) {\n const keyword = textBeforeCursor.slice(i + 1);\n setActiveQuickKey(char);\n setQuickKeyKeyword(keyword);\n setQuickKeyTriggerIdx(i);\n setQuickKeyActiveIndex(0);\n onQuickKeyTrigger?.(char, keyword);\n found = true;\n break;\n }\n }\n\n if (!found && activeQuickKey) {\n const triggerChar = text[quickKeyTriggerIdx];\n const keyword = text.slice(quickKeyTriggerIdx + 1, cursorPos);\n if (\n quickKeyTriggerIdx < 0 ||\n !triggerChar ||\n !quickKeyChars.includes(triggerChar) ||\n /\\s/.test(keyword)\n ) {\n setActiveQuickKey(null);\n setQuickKeyKeyword(\"\");\n setQuickKeyTriggerIdx(-1);\n setQuickKeyActiveIndex(0);\n } else {\n setQuickKeyKeyword(keyword);\n }\n }\n },\n [activeQuickKey, onQuickKeyTrigger, quickKeyTriggerIdx, quickKeys],\n );\n\n // 选择快捷项后转成结构化 Mention;inline 模式会替换掉触发字符和关键词。\n const handleQuickKeySelect = useCallback(\n (option: any) => {\n const mentionType =\n activeQuickKeyConfig?.mentionType ||\n activeQuickKeyConfig?.tagType ||\n activeQuickKey ||\n \"unknown\";\n const newMention: MentionTag = {\n id: generateId(),\n label: option.label,\n type: mentionType,\n value: option.value ?? option.uri ?? option.name ?? option.label,\n uri: option.uri,\n targetId: option.targetId ?? option.skillNo ?? option.pluginNo,\n displayName: option.displayName ?? option.label,\n trigger: activeQuickKey || undefined,\n icon: option.icon,\n data: option,\n };\n activeQuickKeyConfig?.onSelect?.(option);\n\n if (inlineTags) {\n inlineInputRef.current?.insertMention(newMention, {\n start: quickKeyTriggerIdx,\n end: quickKeyTriggerIdx + 1 + quickKeyKeyword.length,\n });\n } else {\n setMentions([...mentions, newMention]);\n\n // 从输入框中删除快捷键字符和关键词\n if (quickKeyTriggerIdx >= 0) {\n const newValue =\n value.slice(0, quickKeyTriggerIdx) +\n value.slice(quickKeyTriggerIdx + 1 + quickKeyKeyword.length);\n setValue(newValue);\n }\n }\n\n setActiveQuickKey(null);\n setQuickKeyKeyword(\"\");\n setQuickKeyTriggerIdx(-1);\n setQuickKeyActiveIndex(0);\n inlineTags\n ? inlineInputRef.current?.focus()\n : textareaRef.current?.focus();\n },\n [\n activeQuickKey,\n activeQuickKeyConfig,\n inlineTags,\n mentions,\n setMentions,\n value,\n quickKeyTriggerIdx,\n quickKeyKeyword,\n setValue,\n ],\n );\n\n // 处理输入框变化(含快捷键检测)\n const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const newValue = e.target.value;\n setValue(newValue);\n\n // 检测快捷键触发\n detectQuickKey(newValue, e.target.selectionStart || 0);\n };\n\n const handleInlineInputChange = (newValue: string) => {\n setValue(newValue);\n // contenteditable 的 selection 不一定和 React state 同步,需实时读取内部光标 offset。\n detectQuickKey(\n newValue,\n inlineInputRef.current?.getCursorOffset() || newValue.length,\n );\n };\n\n const handleQuickKeyByText = (text: string, cursorPos: number) => {\n const quickKeyChars = quickKeys.map((qk) => qk.key);\n if (quickKeyChars.length === 0) return;\n\n const textBeforeCursor = text.slice(0, cursorPos);\n\n // 检测刚输入的字符是否是快捷键\n const lastChar = textBeforeCursor[cursorPos - 1];\n if (lastChar && quickKeyChars.includes(lastChar)) {\n // 上下键导航后会触发 keyup,此时光标前仍是同一个快捷键字符;\n // 如果重复重置 activeIndex,视觉上会“移动一下又回到第一项”。\n if (activeQuickKey === lastChar && quickKeyTriggerIdx === cursorPos - 1) {\n return;\n }\n setActiveQuickKey(lastChar);\n setQuickKeyKeyword(\"\");\n setQuickKeyTriggerIdx(cursorPos - 1);\n setQuickKeyActiveIndex(0);\n onQuickKeyTrigger?.(lastChar, \"\");\n }\n };\n\n // onChange 负责更新搜索词;onKeyUp 兜底捕获刚输入的快捷键字符。\n const isQuickListControlKey = (key: string) =>\n key === \"ArrowDown\" || key === \"ArrowUp\" || key === \"Enter\" || key === \"Escape\";\n\n const handleKeyUp = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (activeQuickKey && isQuickListControlKey(e.key)) return;\n const target = e.target as HTMLTextAreaElement;\n handleQuickKeyByText(target.value || \"\", target.selectionStart || 0);\n };\n\n const handleInlineKeyUp = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (activeQuickKey && isQuickListControlKey(e.key)) return;\n // inline 输入区不是 textarea,不能读 event.target.value,只能从 ref 取纯文本。\n const text = inlineInputRef.current?.getText() || \"\";\n const cursorPos =\n inlineInputRef.current?.getCursorOffset() || text.length;\n handleQuickKeyByText(text, cursorPos);\n };\n\n // 处理提交\n const handleSubmit = () => {\n // 生成期间允许继续编辑下一条消息,但停止按钮仍代表当前唯一可执行动作。\n if (loading) return;\n if (!value.trim() && files.length === 0 && mentions.length === 0) {\n message.warning(\"请输入消息或选择文件\");\n return;\n }\n\n const successFiles = files.filter((file) => file.status === \"success\");\n const uploadingFiles = files.filter(\n (file) => file.status === \"uploading\",\n );\n\n if (uploadingFiles.length > 0) {\n Modal.confirm({\n title: \"文件上传中\",\n content: `还有 ${uploadingFiles.length} 个文件正在上传,是否继续发送?`,\n okText: \"发送已完成的\",\n cancelText: \"等待全部完成\",\n onOk: () => {\n const formattedFiles = formatFilesForServer(successFiles);\n if (onSubmit) {\n onSubmit(createSubmitData(formattedFiles));\n }\n\n setValue(\"\");\n setMentions([]);\n setFiles((prev) => prev.filter((f) => f.status !== \"success\"));\n },\n onCancel: () => {\n message.info(\"请等待文件上传完成后再发送\");\n },\n });\n } else {\n const formattedFiles = formatFilesForServer(successFiles);\n\n if (onSubmit) {\n onSubmit(createSubmitData(formattedFiles));\n }\n\n setValue(\"\");\n setMentions([]);\n setFiles((prev) => prev.filter((f) => f.status !== \"success\"));\n }\n };\n\n // 格式化文件列表为服务端格式\n const formatFilesForServer = (fileList: LocalFile[]): ServerFile[] => {\n return fileList\n .filter((file) => file.status === \"success\" && file.response)\n .map((file) => {\n const responseData = normalizeUploadResponse(file.response);\n\n return {\n fileName: responseData.fileName || file.name,\n fileId: responseData.fileId || responseData.id || \"\",\n tempUrl:\n responseData.tempUrl ||\n responseData.fileUrl ||\n responseData.url ||\n \"\",\n type: responseData.fileType || responseData.type || getExt(file),\n size: responseData.fileSize || responseData.size || file.size,\n mimeType: responseData.mimeType || file.type,\n raw: {\n ...responseData,\n },\n };\n });\n };\n\n // 处理回车键\n const handleKeyDown = (e: React.KeyboardEvent<HTMLElement>) => {\n const quickKeyOptions = activeQuickKeyConfig?.options || [];\n\n if (activeQuickKey && quickKeyOptions.length > 0) {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setQuickKeyActiveIndex((prev) => getNextQuickKeyIndex(prev, 1));\n return;\n }\n\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setQuickKeyActiveIndex((prev) => getNextQuickKeyIndex(prev, -1));\n return;\n }\n\n if (e.key === \"Enter\") {\n e.preventDefault();\n handleQuickKeySelect(\n quickKeyOptions[\n Math.min(quickKeyActiveIndex, quickKeyOptions.length - 1)\n ],\n );\n return;\n }\n\n if (e.key === \"Escape\") {\n e.preventDefault();\n setActiveQuickKey(null);\n setQuickKeyKeyword(\"\");\n setQuickKeyTriggerIdx(-1);\n setQuickKeyActiveIndex(0);\n return;\n }\n }\n\n if (e.key === \"Enter\" && !e.shiftKey && !activeQuickKey) {\n e.preventDefault();\n handleSubmit();\n }\n };\n\n // 渲染文件列表\n const renderFileList = () => {\n if (files.length === 0) return null;\n\n return (\n <div className={styles.contextFiles}>\n {files.map((file) => (\n <FileGallery\n key={file.id}\n file={file}\n size=\"small\"\n removable\n onRemove={handleRemoveFile}\n />\n ))}\n </div>\n );\n };\n\n const containerClass = `${styles.container} ${isDragOver ? \"drag-over\" : \"\"}`;\n const uploading = files.some((f) => f.status === \"uploading\");\n const controlsDisabled = disabled || uploading || loading;\n const inputDisabled = disabled || uploading;\n const hasContent = value.trim().length > 0;\n const hasFiles = files.some((f) => f.status === \"success\");\n const hasMentions = mentions.length > 0;\n const canSend = hasContent || hasFiles || hasMentions;\n\n // 定义按钮组件\n const SendButton = (props: any) => {\n if (sendButtonRender) {\n return (\n <>\n {sendButtonRender({\n loading,\n disabled: uploading || disabled,\n canSend,\n onSend: handleSubmit,\n onStop,\n })}\n </>\n );\n }\n return (\n <Tooltip title={loading ? \"停止生成\" : \"发送消息\"}>\n <button\n className={`${styles.iconButton} ${styles.sendButton} ${loading ? \"stop\" : \"\"}`}\n onClick={loading ? onStop : handleSubmit}\n disabled={uploading || disabled}\n aria-label={loading ? \"停止生成\" : \"发送消息\"}\n {...props}\n >\n {loading ? <LoadingOutlined spin /> : <ArrowUpOutlined />}\n </button>\n </Tooltip>\n );\n };\n\n const ClearButton = (props: any) => (\n <Popconfirm\n title=\"确定要清空聊天记录吗?\"\n onConfirm={onClear}\n placement=\"top\"\n okText=\"确定\"\n cancelText=\"取消\"\n disabled={controlsDisabled}\n >\n <button\n className={`${styles.iconButton} ${styles.clearButton}`}\n disabled={controlsDisabled}\n aria-label=\"清空聊天记录\"\n {...props}\n >\n <ClearOutlined />\n </button>\n </Popconfirm>\n );\n\n const actionsComponents: ActionsComponents = {\n SendButton,\n ClearButton,\n };\n\n // 渲染插槽内容\n const renderSlot = (\n slot:\n | React.ReactNode\n | false\n | ((\n oriNode: React.ReactNode,\n info: { components: ActionsComponents },\n ) => React.ReactNode | false)\n | undefined,\n oriNode: React.ReactNode,\n ): React.ReactNode | null => {\n if (slot === false) return null;\n if (slot === undefined) return oriNode;\n if (typeof slot === \"function\") {\n const result = slot(oriNode, { components: actionsComponents });\n return result === false ? null : result;\n }\n return slot;\n };\n\n const headerNode = renderSlot(header, false);\n const fileListNode = files.length > 0 ? renderFileList() : null;\n\n // 默认后缀仅保留发送/停止按钮;上传与清空统一放到底部 actionBar,方便业务扩展左侧按钮组。\n const defaultSuffix = (\n <div className={styles.buttonGroup}>\n {sendButtonRender ? (\n sendButtonRender({\n loading,\n disabled: uploading || disabled,\n canSend,\n onSend: handleSubmit,\n onStop,\n })\n ) : (\n <Tooltip title={loading ? \"停止生成\" : \"发送消息\"}>\n <button\n className={`${styles.iconButton} ${styles.sendButton} ${loading ? \"stop\" : \"\"}`}\n onClick={loading ? onStop : handleSubmit}\n disabled={uploading || disabled}\n aria-label={loading ? \"停止生成\" : \"发送消息\"}\n >\n {loading ? <LoadingOutlined spin /> : <ArrowUpOutlined />}\n </button>\n </Tooltip>\n )}\n </div>\n );\n\n const defaultActionBar = (\n <div className={styles.actionBar}>\n <div className={styles.actionBarLeft}>\n {renderSlot(footerLeft, false)}\n </div>\n <div className={styles.actionBarRight}>\n {clearBtnShow && <ClearButton />}\n {renderSlot(suffix, defaultSuffix)}\n </div>\n </div>\n );\n\n return (\n <div\n ref={containerRef}\n className={containerClass}\n onDragOver={draggable ? handleDragOver : undefined}\n onDragLeave={draggable ? handleDragLeave : undefined}\n onDrop={draggable ? handleDrop : undefined}\n >\n <div className={styles.mainArea}>\n <div className={styles.senderWrap}>\n {(headerNode || fileListNode) && (\n <div className={styles.contextBar}>\n {/* 头部插槽与附件共享上下文行,便于知识库、文件等输入上下文统一展示。 */}\n {headerNode && (\n <div className={styles.contextHeader}>{headerNode}</div>\n )}\n {fileListNode}\n </div>\n )}\n\n {/* textarea 模式下保留历史标签展示;inlineTags 模式标签直接混排在输入区内 */}\n {!inlineTags && (\n <InputTags mentions={mentions} onRemove={handleRemoveMention} />\n )}\n\n <div className={styles.inputAndButtons}>\n {/* 前缀插槽 */}\n {renderSlot(prefix, false)}\n\n {inlineTags ? (\n <InlineTagInput\n ref={inlineInputRef}\n value={value}\n mentions={mentions}\n defaultInputParts={defaultInputParts}\n placeholder={placeholder}\n disabled={inputDisabled}\n onChange={handleInlineInputChange}\n onMentionsChange={setMentions}\n onKeyDown={handleKeyDown as any}\n onKeyUp={handleInlineKeyUp}\n renderMention={renderMention ?? renderTag}\n />\n ) : (\n <div className={styles.textAreaWrapper}>\n <Input.TextArea\n ref={textareaRef}\n className={styles.textArea}\n value={value}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onKeyUp={handleKeyUp}\n placeholder={placeholder}\n autoSize={{ minRows: 1, maxRows: 4 }}\n style={{\n border: \"none\",\n boxShadow: \"none\",\n outline: \"none\",\n padding: 0,\n }}\n />\n </div>\n )}\n </div>\n\n {/* 快捷键弹出列表 */}\n {activeQuickKey && activeQuickKeyConfig && (\n <div className={styles.quickListWrapper}>\n <QuickList\n config={activeQuickKeyConfig}\n activeIndex={quickKeyActiveIndex}\n onSelect={handleQuickKeySelect}\n onClose={() => {\n setActiveQuickKey(null);\n setQuickKeyKeyword(\"\");\n setQuickKeyTriggerIdx(-1);\n setQuickKeyActiveIndex(0);\n }}\n visible={true}\n />\n </div>\n )}\n\n {/* 底部操作行:左侧上传/业务按钮,右侧清空/发送按钮 */}\n {footer === false\n ? defaultActionBar\n : renderSlot(footer, defaultActionBar)}\n </div>\n </div>\n\n {/* 提示文案 */}\n {!footer && (\n <div className={styles.tip}>\n 内容由AI生成,无法确保真实准确,仅供参考\n </div>\n )}\n </div>\n );\n },\n);\n\nXAdkSender.displayName = \"XAdkSender\";\nexport default XAdkSender;\n"],
5
- "mappings": "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",
6
- "names": ["value", "files", "FileGallery", "InputTags", "InlineTagInput", "QuickList"]
4
+ "sourcesContent": ["import React, {\n useState,\n useRef,\n useCallback,\n forwardRef,\n useImperativeHandle,\n useMemo,\n useEffect,\n} from \"react\";\nimport { Popconfirm, message, Tooltip, Input, Modal } from \"antd\";\nimport {\n ClearOutlined,\n LoadingOutlined,\n ArrowUpOutlined,\n} from \"@ant-design/icons\";\nimport {\n XAdkSenderProps,\n XAdkSenderHandle,\n ServerFile,\n LocalFile,\n ActionsComponents,\n FileValidator,\n UploadFileResult,\n MentionTag,\n XAdkSenderSubmitData,\n XAdkSenderSubmitFormat,\n XAdkSenderSubmitPart,\n} from \"@/types\";\nimport { useStyles } from \"./styles\";\nimport FileGallery from \"../FileGallery\";\nimport InputSuggestionList from \"./InputSuggestionList\";\nimport InputTags from \"./InputTags\";\nimport InlineTagInput, { InlineTagInputRef } from \"./InlineTagInput\";\nimport { getExt } from \"@/utils/file\";\n\nconst XAdkSender = forwardRef<XAdkSenderHandle, XAdkSenderProps>(\n (\n {\n clearBtnShow = true,\n draggable = false,\n onFileSelect,\n loading = false,\n disabled = false,\n value: controlledValue,\n defaultValue = \"\",\n uploadRequest = () => {},\n onClear,\n onChange,\n onSubmit,\n onStop,\n onFilesChange,\n onUploadSuccess,\n onUploadError,\n maxFileSize = 10,\n placeholder = \"\",\n validators: customValidators = [],\n allowedFileTypes = [],\n maxFiles = Infinity,\n sendButtonRender,\n suffix,\n header,\n prefix,\n footer,\n footerLeft,\n quickKeys = [],\n inlineTags = false,\n renderMention,\n renderTag,\n mentions: controlledMentions,\n tags: controlledTags,\n defaultMentions,\n defaultTags = [],\n defaultInputParts,\n onMentionsChange,\n onTagsChange,\n onQuickKeyTrigger,\n submitFormat = \"text\",\n formatMention,\n formatTag,\n transformSubmitData,\n },\n ref,\n ) => {\n const styles = useStyles();\n const isControlled = controlledValue !== undefined;\n const [internalValue, setInternalValue] = useState<string>(defaultValue);\n const value = isControlled ? controlledValue : internalValue;\n const setValue = (newValue: string) => {\n if (!isControlled) {\n setInternalValue(newValue);\n }\n onChange?.(newValue);\n };\n\n // mentions 支持受控/非受控两种模式;inlineTags 打开时会和输入内容混排。\n const resolvedControlledMentions = controlledMentions ?? controlledTags;\n const initialMentions = defaultMentions ?? defaultTags;\n const isMentionsControlled = resolvedControlledMentions !== undefined;\n const [internalMentions, setInternalMentions] =\n useState<MentionTag[]>(initialMentions);\n const mentions = isMentionsControlled\n ? resolvedControlledMentions!\n : internalMentions;\n const setMentions = (newMentions: MentionTag[]) => {\n if (!isMentionsControlled) {\n setInternalMentions(newMentions);\n }\n onMentionsChange?.(newMentions);\n onTagsChange?.(newMentions);\n };\n\n const [files, setFiles] = useState<LocalFile[]>([]);\n const [isDragOver, setIsDragOver] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n const textareaRef = useRef<any>(null);\n const inlineInputRef = useRef<InlineTagInputRef>(null);\n\n // 快捷键弹层状态:记录触发字符、关键词,以及触发字符在纯文本中的位置。\n // SDK 不内置搜索框;业务方可在 onQuickKeyTrigger 中根据 keyword 自行更新 quickKeys.options。\n const [activeQuickKey, setActiveQuickKey] = useState<string | null>(null);\n const [quickKeyKeyword, setQuickKeyKeyword] = useState(\"\");\n const [quickKeyTriggerIdx, setQuickKeyTriggerIdx] = useState(-1);\n const [quickKeyActiveIndex, setQuickKeyActiveIndex] = useState(0);\n\n // 生成唯一ID\n const generateId = () => {\n return Date.now().toString(36) + Math.random().toString(36).substr(2);\n };\n\n const normalizeUploadResponse = (response: any): UploadFileResult => {\n const data = response?.data ?? response;\n return (Array.isArray(data) ? data[0] : data) ?? {};\n };\n\n const escapeXml = (text: string) =>\n text\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\");\n\n const escapeMarkdownLabel = (text: string) =>\n text.replace(/\\\\/g, \"\\\\\\\\\").replace(/\\]/g, \"\\\\]\");\n\n const getMentionSubmitValue = (mention: MentionTag) =>\n String(\n mention.value ??\n mention.uri ??\n mention.data?.uri ??\n mention.data?.value ??\n mention.data?.name ??\n mention.targetId ??\n mention.displayName ??\n mention.label ??\n \"\",\n );\n\n const defaultFormatMention = (\n mention: MentionTag,\n format: Exclude<XAdkSenderSubmitFormat, \"structured\">,\n index: number,\n ) => {\n const value = getMentionSubmitValue(mention);\n if (format === \"xml\") {\n return `<mention type=\"${escapeXml(mention.type)}\" id=\"${escapeXml(mention.id)}\" label=\"${escapeXml(mention.label)}\" value=\"${escapeXml(value)}\" />`;\n }\n\n if (format === \"markdown\") {\n const href =\n mention.uri ||\n (value.includes(\"://\")\n ? value\n : `xadk-mention://${encodeURIComponent(mention.type)}/${encodeURIComponent(mention.id)}`);\n return `[@${escapeMarkdownLabel(mention.displayName || mention.label)}](${href})`;\n }\n\n return `@${mention.displayName || value || `mention-${index + 1}`}`;\n };\n\n const serializeMention = (\n mention: MentionTag,\n format: Exclude<XAdkSenderSubmitFormat, \"structured\">,\n index: number,\n ) =>\n formatMention?.(mention, { format, index }) ??\n formatTag?.(mention, { format, index }) ??\n defaultFormatMention(mention, format, index);\n\n const getSubmitParts = useCallback((): XAdkSenderSubmitPart[] => {\n if (inlineTags) {\n const parts = inlineInputRef.current?.getParts() || [];\n if (parts.length > 0) return parts;\n }\n\n const textParts: XAdkSenderSubmitPart[] = value ? [{ type: \"text\", text: value }] : [];\n const mentionParts = mentions.map((mention) => ({\n type: \"mention\" as const,\n mention,\n }));\n return [...mentionParts, ...textParts];\n }, [inlineTags, mentions, value]);\n\n const serializeParts = (\n parts: XAdkSenderSubmitPart[],\n format: XAdkSenderSubmitFormat,\n ) => {\n if (format === \"structured\") {\n return parts.reduce(\n (content, part) => content + (part.type === \"text\" ? part.text : \"\"),\n \"\",\n );\n }\n\n let tagIndex = 0;\n return parts\n .map((part) => {\n if (part.type === \"text\") return part.text;\n const result = serializeMention(part.mention, format, tagIndex);\n tagIndex += 1;\n return result;\n })\n .join(\"\");\n };\n\n const createSubmitData = (formattedFiles: ServerFile[]): XAdkSenderSubmitData => {\n const parts = getSubmitParts();\n const rawText = parts.reduce(\n (content, part) => content + (part.type === \"text\" ? part.text : \"\"),\n \"\",\n );\n const standardData: Omit<XAdkSenderSubmitData, \"payload\"> = {\n text: serializeParts(parts, submitFormat),\n rawText,\n format: submitFormat,\n parts,\n files: formattedFiles,\n mentions,\n tags: mentions,\n };\n\n return {\n ...standardData,\n payload: transformSubmitData?.(standardData),\n };\n };\n\n // 检查文件类型\n const checkFileType = (file: File): boolean => {\n if (allowedFileTypes?.length > 0) {\n const ext = getExt(file);\n\n return allowedFileTypes.some((type) => {\n if (type.includes(\"/\")) {\n if (type.endsWith(\"/*\")) {\n return file.type.startsWith(type.split(\"/\")[0]);\n }\n return file.type === type;\n }\n\n if (type.startsWith(\".\")) {\n return ext === type.slice(1);\n }\n\n return false;\n });\n }\n return true;\n };\n\n // 重复文件检测\n const isDuplicateFile = (file: File, files: LocalFile[]) => {\n return files.some((f) => f.name === file.name && f.size === file.size);\n };\n\n // 内置校验器集合\n const builtInValidators: FileValidator[] = [\n (_file, { files }) => {\n if (files.length >= maxFiles) {\n return `最多只能上传 ${maxFiles} 个文件`;\n }\n return null;\n },\n (file) => {\n const maxSize = maxFileSize * 1024 * 1024;\n if (file.size > maxSize) {\n return `文件大小不能超过 ${maxFileSize}MB`;\n }\n return null;\n },\n (file) => {\n if (!checkFileType(file)) {\n return \"不支持的文件类型\";\n }\n return null;\n },\n (file, { files }) => {\n if (isDuplicateFile(file, files)) {\n return \"文件已存在\";\n }\n return null;\n },\n ];\n\n const allValidators = [...builtInValidators, ...customValidators];\n\n // 验证文件\n const validateFile = (file: File): { valid: boolean; message?: string } => {\n for (const validator of allValidators) {\n const error = validator(file, { files });\n if (error) {\n return { valid: false, message: error };\n }\n }\n return { valid: true };\n };\n\n // 处理文件选择\n const handleFileSelect = useCallback(\n (selectedFiles: File[]) => {\n const fileArray = Array.from(selectedFiles);\n\n if (files.length + fileArray.length > maxFiles) {\n message.error(`最多只能上传 ${maxFiles} 个文件`);\n return;\n }\n\n const validFiles: LocalFile[] = [];\n\n fileArray.forEach((file) => {\n const validation = validateFile(file);\n\n if (validation.valid) {\n validFiles.push({\n id: generateId(),\n uid: generateId(),\n name: file.name,\n size: file.size,\n type: file.type,\n file,\n progress: 0,\n status: \"pending\",\n response: null,\n });\n } else {\n message.error(validation.message);\n }\n });\n\n if (validFiles.length > 0) {\n setFiles((prev) => {\n const next = [...prev, ...validFiles];\n onFilesChange?.(next);\n return next;\n });\n uploadFiles(validFiles);\n }\n },\n [files, maxFiles, maxFileSize, allowedFileTypes],\n );\n\n // 暴露给业务工具栏调用的命令式能力;外部 Popover 选择标签时可插入到当前光标位置。\n useImperativeHandle(\n ref,\n () => ({\n addFiles: (rawFiles: File[]) => {\n handleFileSelect(rawFiles);\n },\n insertMention: (mention: MentionTag) => {\n if (inlineTags) {\n inlineInputRef.current?.insertMention(mention);\n return;\n }\n setMentions([...mentions, mention]);\n },\n insertTag: (mention: MentionTag) => {\n if (inlineTags) {\n inlineInputRef.current?.insertMention(mention);\n return;\n }\n setMentions([...mentions, mention]);\n },\n focus: () => {\n inlineTags ? inlineInputRef.current?.focus() : textareaRef.current?.focus();\n },\n }),\n [handleFileSelect, inlineTags, setMentions, mentions],\n );\n\n // 上传文件\n const uploadFiles = async (fileList: LocalFile[]) => {\n for (const localFile of fileList) {\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id ? { ...f, status: \"uploading\" } : f,\n ),\n );\n\n try {\n await uploadRequest({\n file: localFile.file,\n onProgress: (e) => {\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id ? { ...f, progress: e.percent } : f,\n ),\n );\n },\n onSuccess: (response) => {\n const responseData = normalizeUploadResponse(response);\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id\n ? {\n ...f,\n status: \"success\",\n progress: 100,\n response,\n fileId: responseData.fileId || responseData.id,\n tempUrl:\n responseData.tempUrl ||\n responseData.fileUrl ||\n responseData.url,\n }\n : f,\n ),\n );\n\n onUploadSuccess?.({\n ...localFile,\n status: \"success\",\n response,\n fileId: responseData.fileId || responseData.id,\n tempUrl:\n responseData.tempUrl ||\n responseData.fileUrl ||\n responseData.url,\n });\n },\n onError: (error) => {\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id\n ? {\n ...f,\n status: \"error\",\n errorMessage: error.message,\n }\n : f,\n ),\n );\n onUploadError?.(localFile, error);\n },\n });\n } catch (error) {\n console.error(\"上传处理错误:\", error);\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id\n ? {\n ...f,\n status: \"error\",\n errorMessage:\n error instanceof Error ? error.message : \"上传处理失败\",\n }\n : f,\n ),\n );\n message.error(`${localFile.name} 上传失败`);\n }\n }\n };\n\n // 删除文件\n const handleRemoveFile = (id: string) => {\n setFiles((prev) => {\n const next = prev.filter((file) => file.id !== id);\n onFilesChange?.(next);\n return next;\n });\n };\n\n // 处理拖拽事件\n const handleDragOver = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n if (draggable) {\n setIsDragOver(true);\n }\n },\n [draggable],\n );\n\n const handleDragLeave = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n if (draggable) {\n setIsDragOver(false);\n }\n },\n [draggable],\n );\n\n const handleDrop = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragOver(false);\n\n if (\n draggable &&\n e.dataTransfer.files &&\n e.dataTransfer.files.length > 0\n ) {\n // 内核不再自行处理文件,交给外层(DefaultLayout/业务)通过 onFileSelect 决定\n onFileSelect?.(Array.from(e.dataTransfer.files));\n }\n },\n [draggable, onFileSelect],\n );\n\n // 删除标签\n const handleRemoveMention = useCallback(\n (id: string) => {\n setMentions(mentions.filter((item) => item.id !== id));\n },\n [mentions, setMentions],\n );\n\n // 查找当前活跃的快捷键配置\n const activeQuickKeyConfig = useMemo(() => {\n if (!activeQuickKey) return null;\n return quickKeys.find((qk) => qk.key === activeQuickKey) || null;\n }, [activeQuickKey, quickKeys]);\n\n const activeQuickKeyOptionsLength = activeQuickKeyConfig?.options.length || 0;\n\n useEffect(() => {\n setQuickKeyActiveIndex(0);\n }, [activeQuickKey]);\n\n useEffect(() => {\n if (activeQuickKeyOptionsLength <= 0) {\n setQuickKeyActiveIndex(0);\n return;\n }\n\n // 业务方可能在 onQuickKeyTrigger 中动态更新 options;\n // 这里只做越界归一化,不重置有效索引,避免键盘高亮移动后又跳回第一项。\n setQuickKeyActiveIndex(\n (prev) => ((prev % activeQuickKeyOptionsLength) + activeQuickKeyOptionsLength) %\n activeQuickKeyOptionsLength,\n );\n }, [activeQuickKeyOptionsLength]);\n\n const getNextQuickKeyIndex = useCallback(\n (current: number, step: number) => {\n if (activeQuickKeyOptionsLength <= 0) return 0;\n return (\n (current + step + activeQuickKeyOptionsLength) %\n activeQuickKeyOptionsLength\n );\n },\n [activeQuickKeyOptionsLength],\n );\n\n // 从当前光标前的连续文本片段中查找最近的快捷键,例如 abc@doc 会触发 @。\n const detectQuickKey = useCallback(\n (text: string, cursorPos: number) => {\n const quickKeyChars = quickKeys.map((qk) => qk.key);\n if (quickKeyChars.length === 0) return;\n\n const textBeforeCursor = text.slice(0, cursorPos);\n let found = false;\n for (let i = textBeforeCursor.length - 1; i >= 0; i--) {\n const char = textBeforeCursor[i];\n if (/\\s/.test(char)) break;\n if (quickKeyChars.includes(char)) {\n const keyword = textBeforeCursor.slice(i + 1);\n setActiveQuickKey(char);\n setQuickKeyKeyword(keyword);\n setQuickKeyTriggerIdx(i);\n setQuickKeyActiveIndex(0);\n onQuickKeyTrigger?.(char, keyword);\n found = true;\n break;\n }\n }\n\n if (!found && activeQuickKey) {\n const triggerChar = text[quickKeyTriggerIdx];\n const keyword = text.slice(quickKeyTriggerIdx + 1, cursorPos);\n if (\n quickKeyTriggerIdx < 0 ||\n !triggerChar ||\n !quickKeyChars.includes(triggerChar) ||\n /\\s/.test(keyword)\n ) {\n setActiveQuickKey(null);\n setQuickKeyKeyword(\"\");\n setQuickKeyTriggerIdx(-1);\n setQuickKeyActiveIndex(0);\n } else {\n setQuickKeyKeyword(keyword);\n }\n }\n },\n [activeQuickKey, onQuickKeyTrigger, quickKeyTriggerIdx, quickKeys],\n );\n\n // 选择快捷项后转成结构化 Mention;inline 模式会替换掉触发字符和关键词。\n const handleQuickKeySelect = useCallback(\n (option: any) => {\n const mentionType =\n activeQuickKeyConfig?.mentionType ||\n activeQuickKeyConfig?.tagType ||\n activeQuickKey ||\n \"unknown\";\n const newMention: MentionTag = {\n id: generateId(),\n label: option.label,\n type: mentionType,\n value: option.value ?? option.uri ?? option.name ?? option.label,\n uri: option.uri,\n targetId: option.targetId ?? option.skillNo ?? option.pluginNo,\n displayName: option.displayName ?? option.label,\n trigger: activeQuickKey || undefined,\n icon: option.icon,\n data: option,\n };\n option.onSelect?.(option);\n activeQuickKeyConfig?.onSelect?.(option);\n\n if (option.action === \"command\") {\n if (inlineTags) {\n inlineInputRef.current?.deleteTextRange({\n start: quickKeyTriggerIdx,\n end: quickKeyTriggerIdx + 1 + quickKeyKeyword.length,\n });\n } else if (quickKeyTriggerIdx >= 0) {\n setValue(\n value.slice(0, quickKeyTriggerIdx) +\n value.slice(quickKeyTriggerIdx + 1 + quickKeyKeyword.length),\n );\n }\n } else if (inlineTags) {\n inlineInputRef.current?.insertMention(newMention, {\n start: quickKeyTriggerIdx,\n end: quickKeyTriggerIdx + 1 + quickKeyKeyword.length,\n });\n } else {\n setMentions([...mentions, newMention]);\n\n // 从输入框中删除快捷键字符和关键词\n if (quickKeyTriggerIdx >= 0) {\n const newValue =\n value.slice(0, quickKeyTriggerIdx) +\n value.slice(quickKeyTriggerIdx + 1 + quickKeyKeyword.length);\n setValue(newValue);\n }\n }\n\n setActiveQuickKey(null);\n setQuickKeyKeyword(\"\");\n setQuickKeyTriggerIdx(-1);\n setQuickKeyActiveIndex(0);\n inlineTags\n ? inlineInputRef.current?.focus()\n : textareaRef.current?.focus();\n },\n [\n activeQuickKey,\n activeQuickKeyConfig,\n inlineTags,\n mentions,\n setMentions,\n value,\n quickKeyTriggerIdx,\n quickKeyKeyword,\n setValue,\n ],\n );\n\n // 处理输入框变化(含快捷键检测)\n const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const newValue = e.target.value;\n setValue(newValue);\n\n // 检测快捷键触发\n detectQuickKey(newValue, e.target.selectionStart || 0);\n };\n\n const handleInlineInputChange = (newValue: string) => {\n setValue(newValue);\n // contenteditable 的 selection 不一定和 React state 同步,需实时读取内部光标 offset。\n detectQuickKey(\n newValue,\n inlineInputRef.current?.getCursorOffset() || newValue.length,\n );\n };\n\n const handleQuickKeyByText = (text: string, cursorPos: number) => {\n const quickKeyChars = quickKeys.map((qk) => qk.key);\n if (quickKeyChars.length === 0) return;\n\n const textBeforeCursor = text.slice(0, cursorPos);\n\n // 检测刚输入的字符是否是快捷键\n const lastChar = textBeforeCursor[cursorPos - 1];\n if (lastChar && quickKeyChars.includes(lastChar)) {\n // 上下键导航后会触发 keyup,此时光标前仍是同一个快捷键字符;\n // 如果重复重置 activeIndex,视觉上会“移动一下又回到第一项”。\n if (activeQuickKey === lastChar && quickKeyTriggerIdx === cursorPos - 1) {\n return;\n }\n setActiveQuickKey(lastChar);\n setQuickKeyKeyword(\"\");\n setQuickKeyTriggerIdx(cursorPos - 1);\n setQuickKeyActiveIndex(0);\n onQuickKeyTrigger?.(lastChar, \"\");\n }\n };\n\n // onChange 负责更新搜索词;onKeyUp 兜底捕获刚输入的快捷键字符。\n const isQuickListControlKey = (key: string) =>\n key === \"ArrowDown\" || key === \"ArrowUp\" || key === \"Enter\" || key === \"Escape\";\n\n const handleKeyUp = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (activeQuickKey && isQuickListControlKey(e.key)) return;\n const target = e.target as HTMLTextAreaElement;\n handleQuickKeyByText(target.value || \"\", target.selectionStart || 0);\n };\n\n const handleInlineKeyUp = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (activeQuickKey && isQuickListControlKey(e.key)) return;\n // inline 输入区不是 textarea,不能读 event.target.value,只能从 ref 取纯文本。\n const text = inlineInputRef.current?.getText() || \"\";\n const cursorPos =\n inlineInputRef.current?.getCursorOffset() || text.length;\n handleQuickKeyByText(text, cursorPos);\n };\n\n // 处理提交\n const handleSubmit = () => {\n // 生成期间允许继续编辑下一条消息,但停止按钮仍代表当前唯一可执行动作。\n if (loading) return;\n if (!value.trim() && files.length === 0 && mentions.length === 0) {\n message.warning(\"请输入消息或选择文件\");\n return;\n }\n\n const successFiles = files.filter((file) => file.status === \"success\");\n const uploadingFiles = files.filter(\n (file) => file.status === \"uploading\",\n );\n\n if (uploadingFiles.length > 0) {\n Modal.confirm({\n title: \"文件上传中\",\n content: `还有 ${uploadingFiles.length} 个文件正在上传,是否继续发送?`,\n okText: \"发送已完成的\",\n cancelText: \"等待全部完成\",\n onOk: () => {\n const formattedFiles = formatFilesForServer(successFiles);\n if (onSubmit) {\n onSubmit(createSubmitData(formattedFiles));\n }\n\n setValue(\"\");\n setMentions([]);\n setFiles((prev) => prev.filter((f) => f.status !== \"success\"));\n },\n onCancel: () => {\n message.info(\"请等待文件上传完成后再发送\");\n },\n });\n } else {\n const formattedFiles = formatFilesForServer(successFiles);\n\n if (onSubmit) {\n onSubmit(createSubmitData(formattedFiles));\n }\n\n setValue(\"\");\n setMentions([]);\n setFiles((prev) => prev.filter((f) => f.status !== \"success\"));\n }\n };\n\n // 格式化文件列表为服务端格式\n const formatFilesForServer = (fileList: LocalFile[]): ServerFile[] => {\n return fileList\n .filter((file) => file.status === \"success\" && file.response)\n .map((file) => {\n const responseData = normalizeUploadResponse(file.response);\n\n return {\n fileName: responseData.fileName || file.name,\n fileId: responseData.fileId || responseData.id || \"\",\n tempUrl:\n responseData.tempUrl ||\n responseData.fileUrl ||\n responseData.url ||\n \"\",\n type: responseData.fileType || responseData.type || getExt(file),\n size: responseData.fileSize || responseData.size || file.size,\n mimeType: responseData.mimeType || file.type,\n raw: {\n ...responseData,\n },\n };\n });\n };\n\n // 处理回车键\n const handleKeyDown = (e: React.KeyboardEvent<HTMLElement>) => {\n // 输入法候选阶段的 Enter 用于确认候选词,不能触发快捷项选择或消息发送。\n if (e.nativeEvent.isComposing || e.keyCode === 229) return;\n\n const quickKeyOptions = activeQuickKeyConfig?.options || [];\n\n if (activeQuickKey && quickKeyOptions.length > 0) {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setQuickKeyActiveIndex((prev) => getNextQuickKeyIndex(prev, 1));\n return;\n }\n\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setQuickKeyActiveIndex((prev) => getNextQuickKeyIndex(prev, -1));\n return;\n }\n\n if (e.key === \"Enter\") {\n e.preventDefault();\n handleQuickKeySelect(\n quickKeyOptions[\n Math.min(quickKeyActiveIndex, quickKeyOptions.length - 1)\n ],\n );\n return;\n }\n\n if (e.key === \"Escape\") {\n e.preventDefault();\n setActiveQuickKey(null);\n setQuickKeyKeyword(\"\");\n setQuickKeyTriggerIdx(-1);\n setQuickKeyActiveIndex(0);\n return;\n }\n }\n\n if (e.key === \"Enter\" && !e.shiftKey && !activeQuickKey) {\n e.preventDefault();\n handleSubmit();\n }\n };\n\n // 渲染文件列表\n const renderFileList = () => {\n if (files.length === 0) return null;\n\n return (\n <div className={styles.contextFiles}>\n {files.map((file) => (\n <FileGallery\n key={file.id}\n file={file}\n size=\"small\"\n removable\n onRemove={handleRemoveFile}\n />\n ))}\n </div>\n );\n };\n\n const containerClass = `${styles.container} ${isDragOver ? \"drag-over\" : \"\"}`;\n const uploading = files.some((f) => f.status === \"uploading\");\n const controlsDisabled = disabled || uploading || loading;\n const inputDisabled = disabled || uploading;\n const hasContent = value.trim().length > 0;\n const hasFiles = files.some((f) => f.status === \"success\");\n const hasMentions = mentions.length > 0;\n const canSend = hasContent || hasFiles || hasMentions;\n\n // 定义按钮组件\n const SendButton = (props: any) => {\n if (sendButtonRender) {\n return (\n <>\n {sendButtonRender({\n loading,\n disabled: uploading || disabled,\n canSend,\n onSend: handleSubmit,\n onStop,\n })}\n </>\n );\n }\n return (\n <Tooltip title={loading ? \"停止生成\" : \"发送消息\"}>\n <button\n className={`${styles.iconButton} ${styles.sendButton} ${loading ? \"stop\" : \"\"}`}\n onClick={loading ? onStop : handleSubmit}\n disabled={uploading || disabled}\n aria-label={loading ? \"停止生成\" : \"发送消息\"}\n {...props}\n >\n {loading ? <LoadingOutlined spin /> : <ArrowUpOutlined />}\n </button>\n </Tooltip>\n );\n };\n\n const ClearButton = (props: any) => (\n <Popconfirm\n title=\"确定要清空聊天记录吗?\"\n onConfirm={onClear}\n placement=\"top\"\n okText=\"确定\"\n cancelText=\"取消\"\n disabled={controlsDisabled}\n >\n <button\n className={`${styles.iconButton} ${styles.clearButton}`}\n disabled={controlsDisabled}\n aria-label=\"清空聊天记录\"\n {...props}\n >\n <ClearOutlined />\n </button>\n </Popconfirm>\n );\n\n const actionsComponents: ActionsComponents = {\n SendButton,\n ClearButton,\n };\n\n // 渲染插槽内容\n const renderSlot = (\n slot:\n | React.ReactNode\n | false\n | ((\n oriNode: React.ReactNode,\n info: { components: ActionsComponents },\n ) => React.ReactNode | false)\n | undefined,\n oriNode: React.ReactNode,\n ): React.ReactNode | null => {\n if (slot === false) return null;\n if (slot === undefined) return oriNode;\n if (typeof slot === \"function\") {\n const result = slot(oriNode, { components: actionsComponents });\n return result === false ? null : result;\n }\n return slot;\n };\n\n const headerNode = renderSlot(header, false);\n const fileListNode = files.length > 0 ? renderFileList() : null;\n\n // 默认后缀仅保留发送/停止按钮;上传与清空统一放到底部 actionBar,方便业务扩展左侧按钮组。\n const defaultSuffix = (\n <div className={styles.buttonGroup}>\n {sendButtonRender ? (\n sendButtonRender({\n loading,\n disabled: uploading || disabled,\n canSend,\n onSend: handleSubmit,\n onStop,\n })\n ) : (\n <Tooltip title={loading ? \"停止生成\" : \"发送消息\"}>\n <button\n className={`${styles.iconButton} ${styles.sendButton} ${loading ? \"stop\" : \"\"}`}\n onClick={loading ? onStop : handleSubmit}\n disabled={uploading || disabled}\n aria-label={loading ? \"停止生成\" : \"发送消息\"}\n >\n {loading ? <LoadingOutlined spin /> : <ArrowUpOutlined />}\n </button>\n </Tooltip>\n )}\n </div>\n );\n\n const defaultActionBar = (\n <div className={styles.actionBar}>\n <div className={styles.actionBarLeft}>\n {renderSlot(footerLeft, false)}\n </div>\n <div className={styles.actionBarRight}>\n {clearBtnShow && <ClearButton />}\n {renderSlot(suffix, defaultSuffix)}\n </div>\n </div>\n );\n\n return (\n <div\n ref={containerRef}\n className={containerClass}\n onDragOver={draggable ? handleDragOver : undefined}\n onDragLeave={draggable ? handleDragLeave : undefined}\n onDrop={draggable ? handleDrop : undefined}\n >\n <div className={styles.mainArea}>\n <div className={styles.senderWrap}>\n {(headerNode || fileListNode) && (\n <div className={styles.contextBar}>\n {/* 头部插槽与附件共享上下文行,便于知识库、文件等输入上下文统一展示。 */}\n {headerNode && (\n <div className={styles.contextHeader}>{headerNode}</div>\n )}\n {fileListNode}\n </div>\n )}\n\n {/* textarea 模式下保留历史标签展示;inlineTags 模式标签直接混排在输入区内 */}\n {!inlineTags && (\n <InputTags mentions={mentions} onRemove={handleRemoveMention} />\n )}\n\n <div className={styles.inputAndButtons}>\n {/* 前缀插槽 */}\n {renderSlot(prefix, false)}\n\n {inlineTags ? (\n <InlineTagInput\n ref={inlineInputRef}\n value={value}\n mentions={mentions}\n defaultInputParts={defaultInputParts}\n placeholder={placeholder}\n disabled={inputDisabled}\n onChange={handleInlineInputChange}\n onMentionsChange={setMentions}\n onKeyDown={handleKeyDown as any}\n onKeyUp={handleInlineKeyUp}\n renderMention={renderMention ?? renderTag}\n />\n ) : (\n <div className={styles.textAreaWrapper}>\n <Input.TextArea\n ref={textareaRef}\n className={styles.textArea}\n value={value}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onKeyUp={handleKeyUp}\n placeholder={placeholder}\n autoSize={{ minRows: 1, maxRows: 4 }}\n style={{\n border: \"none\",\n boxShadow: \"none\",\n outline: \"none\",\n padding: 0,\n }}\n />\n </div>\n )}\n </div>\n\n {/* 快捷键弹出列表 */}\n {activeQuickKey && activeQuickKeyConfig && (\n <div className={styles.quickListWrapper}>\n <InputSuggestionList\n config={activeQuickKeyConfig}\n activeIndex={quickKeyActiveIndex}\n onSelect={handleQuickKeySelect}\n onClose={() => {\n setActiveQuickKey(null);\n setQuickKeyKeyword(\"\");\n setQuickKeyTriggerIdx(-1);\n setQuickKeyActiveIndex(0);\n }}\n visible={true}\n />\n </div>\n )}\n\n {/* 底部操作行:左侧上传/业务按钮,右侧清空/发送按钮 */}\n {footer === false\n ? defaultActionBar\n : renderSlot(footer, defaultActionBar)}\n </div>\n </div>\n\n {/* 提示文案 */}\n {!footer && (\n <div className={styles.tip}>\n 内容由AI生成,无法确保真实准确,仅供参考\n </div>\n )}\n </div>\n );\n },\n);\n\nXAdkSender.displayName = \"XAdkSender\";\nexport default XAdkSender;\n"],
5
+ "mappings": "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",
6
+ "names": ["value", "files", "FileGallery", "InputTags", "InlineTagInput", "InputSuggestionList"]
7
7
  }
@@ -333,7 +333,7 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
333
333
  // 快捷键弹出列表
334
334
  quickList: import_css.css`
335
335
  max-height: 320px;
336
- width: 280px;
336
+ width: 380px;
337
337
  display: flex;
338
338
  flex-direction: column;
339
339
  overflow: hidden;
@@ -394,21 +394,33 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
394
394
  }
395
395
 
396
396
  .quick-list-item-content {
397
+ display: flex;
398
+ align-items: center;
397
399
  flex: 1;
398
400
  min-width: 0;
401
+ gap: 12px;
399
402
  }
400
403
 
401
404
  .quick-list-item-label {
405
+ flex: 0 0 112px;
406
+ overflow: hidden;
402
407
  font-size: 13px;
403
408
  font-weight: 500;
404
409
  color: #262626;
405
410
  line-height: 1.4;
411
+ text-overflow: ellipsis;
412
+ white-space: nowrap;
406
413
  }
407
414
 
408
415
  .quick-list-item-desc {
416
+ flex: 1;
417
+ min-width: 0;
418
+ overflow: hidden;
409
419
  font-size: 12px;
410
420
  color: #8c8c8c;
411
421
  line-height: 1.4;
422
+ text-overflow: ellipsis;
423
+ white-space: nowrap;
412
424
  }
413
425
  `,
414
426
  // 输入框内标签
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/XAdkSender/styles.tsx"],
4
- "sourcesContent": ["import { css } from \"@emotion/css\";\nimport { withBasicStyles } from \"@/styles/common\";\n\nexport const useStyles = withBasicStyles(() => ({\n // 容器样式 - 最外层边框\n container: css`\n position: relative;\n padding: 0 15px 10px;\n overflow: visible;\n border: 2px solid transparent;\n transition: all 0.3s ease;\n\n &.drag-over {\n border: 2px dashed #000;\n background: rgba(0, 0, 0, 0.02);\n }\n `,\n\n // 主内容区域\n mainArea: css`\n border-radius: 20px;\n overflow: visible;\n background: #fff;\n `,\n\n // 发送区域\n senderWrap: css`\n display: flex;\n flex-direction: column;\n gap: 6px;\n background: var(--yb-input-bg-color);\n border: 0.5px solid var(--widget-line, rgba(0, 0, 0, 0.08));\n border-radius: 20px;\n box-sizing: border-box;\n caret-color: var(--yb-input-caret-color);\n flex: auto;\n font-size: 14px;\n line-height: 22px;\n padding: 10px 12px 8px;\n position: relative;\n z-index: 1;\n transition-duration: 0.2s;\n transition-property:\n color, background-color, border-color, text-decoration-color, fill,\n stroke, box-shadow;\n transition-timing-function: linear;\n box-shadow: 0 6px 30px 0 rgba(0, 0, 0, 0.08);\n `,\n\n contextBar: css`\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px;\n `,\n\n contextHeader: css`\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px;\n flex: 0 0 auto;\n min-width: 0;\n `,\n\n contextFiles: css`\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px;\n flex: 1 1 auto;\n min-width: 0;\n `,\n\n // 输入框和按钮容器\n inputAndButtons: css`\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n `,\n\n // 文本输入框容器\n textAreaWrapper: css`\n flex: 1;\n display: flex;\n align-items: center;\n background: #fff;\n padding: 0 4px;\n min-height: 44px;\n\n /* 移除所有蓝色效果 */\n &:focus-within {\n border-color: #d9d9d9;\n box-shadow: none;\n }\n\n .ant-input:disabled {\n background: transparent !important;\n }\n\n &::placeholder {\n color: #bfbfbf;\n }\n `,\n\n // 文本输入框\n textArea: css`\n flex: 1;\n border: none;\n background: transparent;\n font-size: 14px;\n line-height: 1.5;\n padding: 12px 0;\n outline: none;\n color: #262626;\n `,\n\n inlineInputWrapper: css`\n position: relative;\n flex: 1;\n min-height: 44px;\n display: flex;\n align-items: center;\n padding: 0 4px;\n background: #fff;\n `,\n\n inlineInput: css`\n width: 100%;\n min-height: 24px;\n max-height: 112px;\n overflow-y: auto;\n outline: none;\n border: none;\n color: #262626;\n font-size: 14px;\n line-height: 24px;\n white-space: pre-wrap;\n word-break: break-word;\n `,\n\n inlinePlaceholder: css`\n position: absolute;\n left: 4px;\n top: 50%;\n transform: translateY(-50%);\n color: #bfbfbf;\n font-size: 14px;\n line-height: 24px;\n pointer-events: none;\n user-select: none;\n `,\n\n inlineTag: css`\n display: inline-flex;\n align-items: center;\n gap: 4px;\n max-width: 180px;\n height: 22px;\n padding: 0 7px;\n margin: 0 3px;\n vertical-align: baseline;\n border-radius: 6px;\n border: 1px solid #d6e4ff;\n background: #f0f7ff;\n color: #0958d9;\n font-size: 12px;\n line-height: 20px;\n user-select: none;\n\n .xadk-inline-tag-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .xadk-inline-tag-close {\n cursor: pointer;\n color: #597ef7;\n font-size: 12px;\n line-height: 1;\n }\n\n &[data-xadk-inline-mention-type=\"knowledge\"],\n &[data-xadk-inline-mention-type=\"knowledge_directory\"],\n &[data-xadk-inline-mention-type=\"knowledge_file\"],\n &[data-xadk-inline-mention-type=\"kb\"] {\n border-color: #f1f1f1;\n background: #f1f1f1;\n color: #1a1a1a;\n\n .xadk-inline-tag-close {\n color: #8c8c8c;\n }\n }\n `,\n\n // 按钮组\n buttonGroup: css`\n display: flex;\n gap: 8px;\n align-items: center;\n height: 36px;\n `,\n\n // 按钮统一样式\n iconButton: css`\n width: 36px;\n height: 36px;\n min-width: 36px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n\n &:hover {\n transform: translateY(-1px);\n }\n\n &:active {\n transform: translateY(0);\n }\n `,\n\n // 清空按钮\n clearButton: css`\n border: 1px solid #f0f0f0;\n background: #fff;\n color: #8c8c8c;\n\n &:hover {\n border-color: #d9d9d9;\n color: #262626;\n background: #fafafa;\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n `,\n\n // 上传按钮\n uploadButton: css`\n border: 1px solid #f0f0f0;\n background: #fff;\n\n &:hover {\n //\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n border-color: #f0f0f0;\n background: #fafafa;\n }\n `,\n\n // 发送按钮\n sendButton: css`\n background: #000;\n border: none;\n color: #fff;\n\n &:hover:not(:disabled) {\n background: #333; /* 悬停状态 */\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n background: #cccccc;\n color: #fff;\n }\n\n &.stop {\n //\n\n &:hover:not(:disabled) {\n //\n }\n\n &:disabled {\n background: #cccccc; /* 禁用状态也保持淡灰色 */\n }\n }\n `,\n\n // 底部提示\n tip: css`\n margin: 12px 0;\n text-align: center;\n font-size: 12px;\n color: #8c8c8c;\n `,\n\n actionBar: css`\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n min-height: 36px;\n `,\n\n actionBarLeft: css`\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n `,\n\n actionBarRight: css`\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n flex-shrink: 0;\n `,\n\n // 快捷键弹出列表外层容器\n quickListWrapper: css`\n position: absolute;\n left: 0;\n bottom: 100%;\n margin-bottom: 4px;\n z-index: 100;\n `,\n\n // 快捷键弹出列表\n quickList: css`\n max-height: 320px;\n width: 280px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n background: #fff;\n border-radius: 12px;\n box-shadow: 0 8px 40px 0 rgba(0, 0, 0, 0.12);\n `,\n\n quickListHeader: css`\n padding: 12px 16px 0;\n font-size: 13px;\n font-weight: 500;\n color: #8c8c8c;\n `,\n\n quickListBody: css`\n flex: 1;\n overflow-y: auto;\n padding: 4px 0;\n `,\n\n quickListEmpty: css`\n padding: 24px 16px;\n text-align: center;\n color: #8c8c8c;\n font-size: 13px;\n `,\n\n quickListGroup: css`\n padding: 8px 16px 4px;\n font-size: 11px;\n font-weight: 500;\n color: #8c8c8c;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n `,\n\n quickListItem: css`\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 16px;\n cursor: pointer;\n transition: background 0.15s ease;\n\n &:hover {\n background: #f5f5f5;\n }\n\n &.active {\n background: #f0f7ff;\n }\n\n .quick-list-item-icon {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n background: #f5f5f5;\n flex-shrink: 0;\n }\n\n .quick-list-item-content {\n flex: 1;\n min-width: 0;\n }\n\n .quick-list-item-label {\n font-size: 13px;\n font-weight: 500;\n color: #262626;\n line-height: 1.4;\n }\n\n .quick-list-item-desc {\n font-size: 12px;\n color: #8c8c8c;\n line-height: 1.4;\n }\n `,\n\n // 输入框内标签\n inputTags: css`\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 4px 0 8px;\n `,\n\n inputTag: css`\n margin: 0;\n font-size: 12px;\n border-radius: 6px;\n `,\n}));\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { css } from \"@emotion/css\";\nimport { withBasicStyles } from \"@/styles/common\";\n\nexport const useStyles = withBasicStyles(() => ({\n // 容器样式 - 最外层边框\n container: css`\n position: relative;\n padding: 0 15px 10px;\n overflow: visible;\n border: 2px solid transparent;\n transition: all 0.3s ease;\n\n &.drag-over {\n border: 2px dashed #000;\n background: rgba(0, 0, 0, 0.02);\n }\n `,\n\n // 主内容区域\n mainArea: css`\n border-radius: 20px;\n overflow: visible;\n background: #fff;\n `,\n\n // 发送区域\n senderWrap: css`\n display: flex;\n flex-direction: column;\n gap: 6px;\n background: var(--yb-input-bg-color);\n border: 0.5px solid var(--widget-line, rgba(0, 0, 0, 0.08));\n border-radius: 20px;\n box-sizing: border-box;\n caret-color: var(--yb-input-caret-color);\n flex: auto;\n font-size: 14px;\n line-height: 22px;\n padding: 10px 12px 8px;\n position: relative;\n z-index: 1;\n transition-duration: 0.2s;\n transition-property:\n color, background-color, border-color, text-decoration-color, fill,\n stroke, box-shadow;\n transition-timing-function: linear;\n box-shadow: 0 6px 30px 0 rgba(0, 0, 0, 0.08);\n `,\n\n contextBar: css`\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px;\n `,\n\n contextHeader: css`\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px;\n flex: 0 0 auto;\n min-width: 0;\n `,\n\n contextFiles: css`\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px;\n flex: 1 1 auto;\n min-width: 0;\n `,\n\n // 输入框和按钮容器\n inputAndButtons: css`\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n `,\n\n // 文本输入框容器\n textAreaWrapper: css`\n flex: 1;\n display: flex;\n align-items: center;\n background: #fff;\n padding: 0 4px;\n min-height: 44px;\n\n /* 移除所有蓝色效果 */\n &:focus-within {\n border-color: #d9d9d9;\n box-shadow: none;\n }\n\n .ant-input:disabled {\n background: transparent !important;\n }\n\n &::placeholder {\n color: #bfbfbf;\n }\n `,\n\n // 文本输入框\n textArea: css`\n flex: 1;\n border: none;\n background: transparent;\n font-size: 14px;\n line-height: 1.5;\n padding: 12px 0;\n outline: none;\n color: #262626;\n `,\n\n inlineInputWrapper: css`\n position: relative;\n flex: 1;\n min-height: 44px;\n display: flex;\n align-items: center;\n padding: 0 4px;\n background: #fff;\n `,\n\n inlineInput: css`\n width: 100%;\n min-height: 24px;\n max-height: 112px;\n overflow-y: auto;\n outline: none;\n border: none;\n color: #262626;\n font-size: 14px;\n line-height: 24px;\n white-space: pre-wrap;\n word-break: break-word;\n `,\n\n inlinePlaceholder: css`\n position: absolute;\n left: 4px;\n top: 50%;\n transform: translateY(-50%);\n color: #bfbfbf;\n font-size: 14px;\n line-height: 24px;\n pointer-events: none;\n user-select: none;\n `,\n\n inlineTag: css`\n display: inline-flex;\n align-items: center;\n gap: 4px;\n max-width: 180px;\n height: 22px;\n padding: 0 7px;\n margin: 0 3px;\n vertical-align: baseline;\n border-radius: 6px;\n border: 1px solid #d6e4ff;\n background: #f0f7ff;\n color: #0958d9;\n font-size: 12px;\n line-height: 20px;\n user-select: none;\n\n .xadk-inline-tag-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .xadk-inline-tag-close {\n cursor: pointer;\n color: #597ef7;\n font-size: 12px;\n line-height: 1;\n }\n\n &[data-xadk-inline-mention-type=\"knowledge\"],\n &[data-xadk-inline-mention-type=\"knowledge_directory\"],\n &[data-xadk-inline-mention-type=\"knowledge_file\"],\n &[data-xadk-inline-mention-type=\"kb\"] {\n border-color: #f1f1f1;\n background: #f1f1f1;\n color: #1a1a1a;\n\n .xadk-inline-tag-close {\n color: #8c8c8c;\n }\n }\n `,\n\n // 按钮组\n buttonGroup: css`\n display: flex;\n gap: 8px;\n align-items: center;\n height: 36px;\n `,\n\n // 按钮统一样式\n iconButton: css`\n width: 36px;\n height: 36px;\n min-width: 36px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n\n &:hover {\n transform: translateY(-1px);\n }\n\n &:active {\n transform: translateY(0);\n }\n `,\n\n // 清空按钮\n clearButton: css`\n border: 1px solid #f0f0f0;\n background: #fff;\n color: #8c8c8c;\n\n &:hover {\n border-color: #d9d9d9;\n color: #262626;\n background: #fafafa;\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n `,\n\n // 上传按钮\n uploadButton: css`\n border: 1px solid #f0f0f0;\n background: #fff;\n\n &:hover {\n //\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n border-color: #f0f0f0;\n background: #fafafa;\n }\n `,\n\n // 发送按钮\n sendButton: css`\n background: #000;\n border: none;\n color: #fff;\n\n &:hover:not(:disabled) {\n background: #333; /* 悬停状态 */\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n background: #cccccc;\n color: #fff;\n }\n\n &.stop {\n //\n\n &:hover:not(:disabled) {\n //\n }\n\n &:disabled {\n background: #cccccc; /* 禁用状态也保持淡灰色 */\n }\n }\n `,\n\n // 底部提示\n tip: css`\n margin: 12px 0;\n text-align: center;\n font-size: 12px;\n color: #8c8c8c;\n `,\n\n actionBar: css`\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n min-height: 36px;\n `,\n\n actionBarLeft: css`\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n `,\n\n actionBarRight: css`\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n flex-shrink: 0;\n `,\n\n // 快捷键弹出列表外层容器\n quickListWrapper: css`\n position: absolute;\n left: 0;\n bottom: 100%;\n margin-bottom: 4px;\n z-index: 100;\n `,\n\n // 快捷键弹出列表\n quickList: css`\n max-height: 320px;\n width: 380px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n background: #fff;\n border-radius: 12px;\n box-shadow: 0 8px 40px 0 rgba(0, 0, 0, 0.12);\n `,\n\n quickListHeader: css`\n padding: 12px 16px 0;\n font-size: 13px;\n font-weight: 500;\n color: #8c8c8c;\n `,\n\n quickListBody: css`\n flex: 1;\n overflow-y: auto;\n padding: 4px 0;\n `,\n\n quickListEmpty: css`\n padding: 24px 16px;\n text-align: center;\n color: #8c8c8c;\n font-size: 13px;\n `,\n\n quickListGroup: css`\n padding: 8px 16px 4px;\n font-size: 11px;\n font-weight: 500;\n color: #8c8c8c;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n `,\n\n quickListItem: css`\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 16px;\n cursor: pointer;\n transition: background 0.15s ease;\n\n &:hover {\n background: #f5f5f5;\n }\n\n &.active {\n background: #f0f7ff;\n }\n\n .quick-list-item-icon {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n background: #f5f5f5;\n flex-shrink: 0;\n }\n\n .quick-list-item-content {\n display: flex;\n align-items: center;\n flex: 1;\n min-width: 0;\n gap: 12px;\n }\n\n .quick-list-item-label {\n flex: 0 0 112px;\n overflow: hidden;\n font-size: 13px;\n font-weight: 500;\n color: #262626;\n line-height: 1.4;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .quick-list-item-desc {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n font-size: 12px;\n color: #8c8c8c;\n line-height: 1.4;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n `,\n\n // 输入框内标签\n inputTags: css`\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 4px 0 8px;\n `,\n\n inputTag: css`\n margin: 0;\n font-size: 12px;\n border-radius: 6px;\n `,\n}));\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -5,6 +5,10 @@ export interface QuickListOption {
5
5
  label: string;
6
6
  description?: string;
7
7
  icon?: React.ReactNode;
8
+ /** 选中后的行为。insert 会写入 Mention;command 仅执行回调。默认 insert。 */
9
+ action?: "insert" | "command";
10
+ /** 选中当前选项时执行,可用于 command 类型的业务动作。 */
11
+ onSelect?: (option: QuickListOption) => void;
8
12
  /** 分组名(用于聚合列表,子分组通过下划线分割) */
9
13
  group?: string;
10
14
  [key: string]: any;
@@ -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\n// ===================== 快捷键/Mention 相关类型 =====================\n\n/** 快捷键触发的列表项 */\nexport interface QuickListOption {\n id: string;\n label: string;\n description?: string;\n icon?: React.ReactNode;\n /** 分组名(用于聚合列表,子分组通过下划线分割) */\n group?: string;\n [key: string]: any;\n}\n\n/** 快捷键配置 */\nexport interface QuickKeyConfig {\n /** 触发字符,如 '@', '#', '$' */\n key: string;\n /** 选中后写入 MentionTag.type 的语义类型,不传时回退为 key */\n mentionType?: string;\n /** @deprecated 请使用 mentionType。 */\n tagType?: string;\n /** 列表标题 */\n title?: string;\n /** 列表数据 */\n options: QuickListOption[];\n /** 自定义列表项渲染 */\n renderItem?: (option: QuickListOption) => React.ReactNode;\n /** 选中回调 */\n onSelect?: (option: QuickListOption) => void;\n}\n\n/** 输入框内的资源引用。SDK 只理解通用 Mention,业务语义可放入 data 或可选语义字段。 */\nexport interface MentionTag {\n id: string;\n label: string;\n /** Mention 类型,如 'knowledge', 'skill', 'plugin', 'agent' */\n type: string;\n /** 资源 URI,如 skill://skillNo、kb://kb/knNo/dir/docs/2024 */\n uri?: string;\n /** 业务资源 ID,如 skillNo、knowledgeNo */\n targetId?: string;\n /** 展示名;不传时回退 label */\n displayName?: string;\n /** 提交为纯文本/Markdown/XML 时使用的业务值,不传时回退 uri/targetId/label */\n value?: string;\n /** 触发字符,如 '@', '#', '$',用于业务方区分来源 */\n trigger?: string;\n color?: string;\n icon?: React.ReactNode;\n /** 业务扩展上下文,例如知识库目录 scope */\n scope?: any;\n /** 原始数据 */\n data?: any;\n}\n\n/** @deprecated 请使用 MentionTag。 */\nexport type InputTag = MentionTag;\n\nexport interface InlineTagRenderInfo {\n onRemove: () => void;\n}\n\nexport type XAdkSenderSubmitFormat = \"text\" | \"structured\" | \"markdown\" | \"xml\";\n\nexport type XAdkSenderSubmitPart =\n | { type: \"text\"; text: string }\n | { type: \"mention\"; mention: MentionTag };\n\n/** @deprecated 旧 tag part,仅用于兼容 defaultInputParts 历史传入。 */\nexport type XAdkSenderLegacyTagPart = { type: \"tag\"; tag: MentionTag };\n\n/** 输入框文本/Mention 有序片段,表示用户正在编辑的输入内容 */\nexport type XAdkSenderInputPart =\n | XAdkSenderSubmitPart\n | XAdkSenderLegacyTagPart;\n\nexport interface XAdkSenderFormatMentionContext {\n format: Exclude<XAdkSenderSubmitFormat, \"structured\">;\n index: number;\n}\n\n/** @deprecated 请使用 XAdkSenderFormatMentionContext。 */\nexport type XAdkSenderFormatTagContext = XAdkSenderFormatMentionContext;\n\nexport interface XAdkSenderSubmitData<TPayload = unknown> {\n /** 根据 submitFormat 生成的最终内容,默认是纯文本 */\n text: string;\n /** 去掉标签后的用户原始输入文本 */\n rawText: string;\n /** 当前提交格式 */\n format: XAdkSenderSubmitFormat;\n /** 文本与 Mention 的有序片段,inlineTags 模式下可还原资源引用在输入框中的位置 */\n parts: XAdkSenderSubmitPart[];\n files: ServerFile[];\n /** 当前 Mention 列表 */\n mentions?: MentionTag[];\n /** @deprecated 请使用 mentions。 */\n tags?: MentionTag[];\n /** 业务方通过 transformSubmitData 派生出的自定义提交结构 */\n payload?: TPayload;\n}\n\n// ===================== 上传相关类型 =====================\n\nexport interface UploadFileResult {\n fileName?: string;\n fileId?: string | number;\n tempUrl?: string;\n url?: string;\n fileUrl?: string;\n fileType?: string;\n fileSize?: number;\n mimeType?: string;\n [key: string]: any;\n}\n\nexport interface UploadSuccessResponse {\n data?: UploadFileResult | UploadFileResult[];\n [key: string]: any;\n}\n\ninterface uploadRequestProps {\n (options: {\n file: File;\n onProgress?: (e: { percent: number }) => void;\n onSuccess?: (\n response: UploadFileResult | UploadFileResult[] | UploadSuccessResponse,\n ) => void;\n onError?: (error: Error) => void;\n }): Promise<void> | void;\n}\n\nexport type UploadRequestFn = uploadRequestProps;\n\nexport interface ServerFile {\n fileName: string;\n fileId: string | number;\n tempUrl: string;\n type: string;\n size?: number;\n mimeType: string;\n raw?: UploadFileResult;\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?: string | 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 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 /**\n * 是否启用 Sender 自身的拖拽上传。\n * 拖拽产生的文件通过 onFileSelect 回调交给业务/外层处理;\n * 默认 false,由外层(如 DefaultLayout)管理拖拽时无需开启。\n */\n draggable?: boolean;\n /**\n * 拖拽文件回调:当 draggable 为 true 且用户向输入区拖拽文件时触发。\n * 业务/外层在此回调中决定如何处理文件(通常调用 senderRef.addFiles 注入)。\n */\n onFileSelect?: (files: File[]) => void;\n loading?: boolean;\n disabled?: boolean; // 只读状态\n placeholder?: string;\n /** 受控:输入框的值 */\n value?: string;\n /** 非受控:输入框默认值 */\n defaultValue?: string;\n onClear?: () => void;\n onChange?: (value: string) => void;\n onSubmit?: (data: XAdkSenderSubmitData) => void;\n onStop?: () => void;\n\n /** 自定义发送按钮渲染 */\n sendButtonRender?: (info: {\n loading: boolean;\n disabled: boolean;\n /** 当前是否可以发送(文本非空或有已上传的文件) */\n canSend: boolean;\n onSend: () => void;\n onStop?: () => void;\n }) => React.ReactNode;\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 /** 底部左侧拓展区域,不传时 footer 保持原有居中布局 */\n footerLeft?: React.ReactNode | false | SlotRenderFunction;\n\n // 快捷键/Mention 功能\n /** 快捷键配置列表 */\n quickKeys?: QuickKeyConfig[];\n /** 是否把 Mention 以内联 token 形式展示在输入区内;默认 false 保持历史 textarea 行为 */\n inlineTags?: boolean;\n /** 自定义内联 Mention 渲染 */\n renderMention?: (\n mention: MentionTag,\n info: InlineTagRenderInfo,\n ) => React.ReactNode;\n /** @deprecated 请使用 renderMention。 */\n renderTag?: (\n mention: MentionTag,\n info: InlineTagRenderInfo,\n ) => React.ReactNode;\n /** 受控:Mention 列表 */\n mentions?: MentionTag[];\n /** @deprecated 请使用 mentions。 */\n tags?: MentionTag[];\n /** 非受控:默认 Mention 列表 */\n defaultMentions?: MentionTag[];\n /** @deprecated 请使用 defaultMentions。 */\n defaultTags?: MentionTag[];\n /** 非受控:默认输入内容片段,用于初始化内联 Mention 输入区 */\n defaultInputParts?: XAdkSenderInputPart[];\n /** Mention 变化回调 */\n onMentionsChange?: (mentions: MentionTag[]) => void;\n /** @deprecated 请使用 onMentionsChange。 */\n onTagsChange?: (mentions: MentionTag[]) => void;\n /** 快捷键触发回调(业务方可在此处理搜索等逻辑) */\n onQuickKeyTrigger?: (key: string, keyword: string) => void;\n /**\n * 提交内容格式:\n * - text: 默认,输出文字 + Mention 文本(如 @生图技能)\n * - structured: 保留 parts/mentions/files 结构化数据,text 为 rawText\n * - markdown/xml: 输出对应标记文本\n */\n submitFormat?: XAdkSenderSubmitFormat;\n /** 自定义 Mention 在 text/markdown/xml 格式中的序列化结果 */\n formatMention?: (\n mention: MentionTag,\n context: XAdkSenderFormatMentionContext,\n ) => string;\n /** @deprecated 请使用 formatMention。 */\n formatTag?: (\n mention: MentionTag,\n context: XAdkSenderFormatMentionContext,\n ) => string;\n /**\n * 基于 SDK 标准提交结构派生业务 payload。\n * SDK 不理解 knowledge/skill/agent 等业务字段,只负责把 payload 原样放入 onSubmit 数据中。\n */\n transformSubmitData?: (\n data: Omit<XAdkSenderSubmitData, \"payload\">,\n ) => unknown;\n}\n\nexport type XAdkSenderProps = SenderUIProps & UploaderCoreProps;\n\nexport interface XAdkSenderHandle {\n addFiles: (files: File[]) => void;\n /** 向当前光标位置插入一个内联 Mention;未启用 inlineTags 时会退化为追加 Mention。 */\n insertMention: (mention: MentionTag) => void;\n /** @deprecated 请使用 insertMention。 */\n insertTag: (mention: MentionTag) => void;\n /** 聚焦输入区 */\n focus: () => void;\n}\n"],
4
+ "sourcesContent": ["// types/XAdkSender.ts\nimport React from \"react\";\n\n// ===================== 快捷键/Mention 相关类型 =====================\n\n/** 快捷键触发的列表项 */\nexport interface QuickListOption {\n id: string;\n label: string;\n description?: string;\n icon?: React.ReactNode;\n /** 选中后的行为。insert 会写入 Mention;command 仅执行回调。默认 insert。 */\n action?: \"insert\" | \"command\";\n /** 选中当前选项时执行,可用于 command 类型的业务动作。 */\n onSelect?: (option: QuickListOption) => void;\n /** 分组名(用于聚合列表,子分组通过下划线分割) */\n group?: string;\n [key: string]: any;\n}\n\n/** 快捷键配置 */\nexport interface QuickKeyConfig {\n /** 触发字符,如 '@', '#', '$' */\n key: string;\n /** 选中后写入 MentionTag.type 的语义类型,不传时回退为 key */\n mentionType?: string;\n /** @deprecated 请使用 mentionType。 */\n tagType?: string;\n /** 列表标题 */\n title?: string;\n /** 列表数据 */\n options: QuickListOption[];\n /** 自定义列表项渲染 */\n renderItem?: (option: QuickListOption) => React.ReactNode;\n /** 选中回调 */\n onSelect?: (option: QuickListOption) => void;\n}\n\n/** 输入框内的资源引用。SDK 只理解通用 Mention,业务语义可放入 data 或可选语义字段。 */\nexport interface MentionTag {\n id: string;\n label: string;\n /** Mention 类型,如 'knowledge', 'skill', 'plugin', 'agent' */\n type: string;\n /** 资源 URI,如 skill://skillNo、kb://kb/knNo/dir/docs/2024 */\n uri?: string;\n /** 业务资源 ID,如 skillNo、knowledgeNo */\n targetId?: string;\n /** 展示名;不传时回退 label */\n displayName?: string;\n /** 提交为纯文本/Markdown/XML 时使用的业务值,不传时回退 uri/targetId/label */\n value?: string;\n /** 触发字符,如 '@', '#', '$',用于业务方区分来源 */\n trigger?: string;\n color?: string;\n icon?: React.ReactNode;\n /** 业务扩展上下文,例如知识库目录 scope */\n scope?: any;\n /** 原始数据 */\n data?: any;\n}\n\n/** @deprecated 请使用 MentionTag。 */\nexport type InputTag = MentionTag;\n\nexport interface InlineTagRenderInfo {\n onRemove: () => void;\n}\n\nexport type XAdkSenderSubmitFormat = \"text\" | \"structured\" | \"markdown\" | \"xml\";\n\nexport type XAdkSenderSubmitPart =\n | { type: \"text\"; text: string }\n | { type: \"mention\"; mention: MentionTag };\n\n/** @deprecated 旧 tag part,仅用于兼容 defaultInputParts 历史传入。 */\nexport type XAdkSenderLegacyTagPart = { type: \"tag\"; tag: MentionTag };\n\n/** 输入框文本/Mention 有序片段,表示用户正在编辑的输入内容 */\nexport type XAdkSenderInputPart =\n | XAdkSenderSubmitPart\n | XAdkSenderLegacyTagPart;\n\nexport interface XAdkSenderFormatMentionContext {\n format: Exclude<XAdkSenderSubmitFormat, \"structured\">;\n index: number;\n}\n\n/** @deprecated 请使用 XAdkSenderFormatMentionContext。 */\nexport type XAdkSenderFormatTagContext = XAdkSenderFormatMentionContext;\n\nexport interface XAdkSenderSubmitData<TPayload = unknown> {\n /** 根据 submitFormat 生成的最终内容,默认是纯文本 */\n text: string;\n /** 去掉标签后的用户原始输入文本 */\n rawText: string;\n /** 当前提交格式 */\n format: XAdkSenderSubmitFormat;\n /** 文本与 Mention 的有序片段,inlineTags 模式下可还原资源引用在输入框中的位置 */\n parts: XAdkSenderSubmitPart[];\n files: ServerFile[];\n /** 当前 Mention 列表 */\n mentions?: MentionTag[];\n /** @deprecated 请使用 mentions。 */\n tags?: MentionTag[];\n /** 业务方通过 transformSubmitData 派生出的自定义提交结构 */\n payload?: TPayload;\n}\n\n// ===================== 上传相关类型 =====================\n\nexport interface UploadFileResult {\n fileName?: string;\n fileId?: string | number;\n tempUrl?: string;\n url?: string;\n fileUrl?: string;\n fileType?: string;\n fileSize?: number;\n mimeType?: string;\n [key: string]: any;\n}\n\nexport interface UploadSuccessResponse {\n data?: UploadFileResult | UploadFileResult[];\n [key: string]: any;\n}\n\ninterface uploadRequestProps {\n (options: {\n file: File;\n onProgress?: (e: { percent: number }) => void;\n onSuccess?: (\n response: UploadFileResult | UploadFileResult[] | UploadSuccessResponse,\n ) => void;\n onError?: (error: Error) => void;\n }): Promise<void> | void;\n}\n\nexport type UploadRequestFn = uploadRequestProps;\n\nexport interface ServerFile {\n fileName: string;\n fileId: string | number;\n tempUrl: string;\n type: string;\n size?: number;\n mimeType: string;\n raw?: UploadFileResult;\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?: string | 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 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 /**\n * 是否启用 Sender 自身的拖拽上传。\n * 拖拽产生的文件通过 onFileSelect 回调交给业务/外层处理;\n * 默认 false,由外层(如 DefaultLayout)管理拖拽时无需开启。\n */\n draggable?: boolean;\n /**\n * 拖拽文件回调:当 draggable 为 true 且用户向输入区拖拽文件时触发。\n * 业务/外层在此回调中决定如何处理文件(通常调用 senderRef.addFiles 注入)。\n */\n onFileSelect?: (files: File[]) => void;\n loading?: boolean;\n disabled?: boolean; // 只读状态\n placeholder?: string;\n /** 受控:输入框的值 */\n value?: string;\n /** 非受控:输入框默认值 */\n defaultValue?: string;\n onClear?: () => void;\n onChange?: (value: string) => void;\n onSubmit?: (data: XAdkSenderSubmitData) => void;\n onStop?: () => void;\n\n /** 自定义发送按钮渲染 */\n sendButtonRender?: (info: {\n loading: boolean;\n disabled: boolean;\n /** 当前是否可以发送(文本非空或有已上传的文件) */\n canSend: boolean;\n onSend: () => void;\n onStop?: () => void;\n }) => React.ReactNode;\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 /** 底部左侧拓展区域,不传时 footer 保持原有居中布局 */\n footerLeft?: React.ReactNode | false | SlotRenderFunction;\n\n // 快捷键/Mention 功能\n /** 快捷键配置列表 */\n quickKeys?: QuickKeyConfig[];\n /** 是否把 Mention 以内联 token 形式展示在输入区内;默认 false 保持历史 textarea 行为 */\n inlineTags?: boolean;\n /** 自定义内联 Mention 渲染 */\n renderMention?: (\n mention: MentionTag,\n info: InlineTagRenderInfo,\n ) => React.ReactNode;\n /** @deprecated 请使用 renderMention。 */\n renderTag?: (\n mention: MentionTag,\n info: InlineTagRenderInfo,\n ) => React.ReactNode;\n /** 受控:Mention 列表 */\n mentions?: MentionTag[];\n /** @deprecated 请使用 mentions。 */\n tags?: MentionTag[];\n /** 非受控:默认 Mention 列表 */\n defaultMentions?: MentionTag[];\n /** @deprecated 请使用 defaultMentions。 */\n defaultTags?: MentionTag[];\n /** 非受控:默认输入内容片段,用于初始化内联 Mention 输入区 */\n defaultInputParts?: XAdkSenderInputPart[];\n /** Mention 变化回调 */\n onMentionsChange?: (mentions: MentionTag[]) => void;\n /** @deprecated 请使用 onMentionsChange。 */\n onTagsChange?: (mentions: MentionTag[]) => void;\n /** 快捷键触发回调(业务方可在此处理搜索等逻辑) */\n onQuickKeyTrigger?: (key: string, keyword: string) => void;\n /**\n * 提交内容格式:\n * - text: 默认,输出文字 + Mention 文本(如 @生图技能)\n * - structured: 保留 parts/mentions/files 结构化数据,text 为 rawText\n * - markdown/xml: 输出对应标记文本\n */\n submitFormat?: XAdkSenderSubmitFormat;\n /** 自定义 Mention 在 text/markdown/xml 格式中的序列化结果 */\n formatMention?: (\n mention: MentionTag,\n context: XAdkSenderFormatMentionContext,\n ) => string;\n /** @deprecated 请使用 formatMention。 */\n formatTag?: (\n mention: MentionTag,\n context: XAdkSenderFormatMentionContext,\n ) => string;\n /**\n * 基于 SDK 标准提交结构派生业务 payload。\n * SDK 不理解 knowledge/skill/agent 等业务字段,只负责把 payload 原样放入 onSubmit 数据中。\n */\n transformSubmitData?: (\n data: Omit<XAdkSenderSubmitData, \"payload\">,\n ) => unknown;\n}\n\nexport type XAdkSenderProps = SenderUIProps & UploaderCoreProps;\n\nexport interface XAdkSenderHandle {\n addFiles: (files: File[]) => void;\n /** 向当前光标位置插入一个内联 Mention;未启用 inlineTags 时会退化为追加 Mention。 */\n insertMention: (mention: MentionTag) => void;\n /** @deprecated 请使用 insertMention。 */\n insertTag: (mention: MentionTag) => void;\n /** 聚焦输入区 */\n focus: () => void;\n}\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -5,6 +5,10 @@ export interface InlineTagInputRef {
5
5
  getText: () => string;
6
6
  getParts: () => XAdkSenderSubmitPart[];
7
7
  getCursorOffset: () => number;
8
+ deleteTextRange: (range: {
9
+ start: number;
10
+ end: number;
11
+ }) => void;
8
12
  insertMention: (mention: MentionTag, replace?: {
9
13
  start: number;
10
14
  end: number;
@@ -541,10 +541,23 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
541
541
  getText: getPlainText,
542
542
  getParts: getParts,
543
543
  getCursorOffset: getOffsetInEditor,
544
+ deleteTextRange: function deleteTextRange(_ref2) {
545
+ var start = _ref2.start,
546
+ end = _ref2.end;
547
+ var range = replaceTextRange(start, end);
548
+ cleanupCaretTextNodes();
549
+ if (range) {
550
+ var selection = window.getSelection();
551
+ selection === null || selection === void 0 || selection.removeAllRanges();
552
+ selection === null || selection === void 0 || selection.addRange(range);
553
+ savedRangeRef.current = range.cloneRange();
554
+ }
555
+ emitChange();
556
+ },
544
557
  insertMention: insertMention,
545
558
  insertTag: insertMention
546
559
  };
547
- }, [getOffsetInEditor, getParts, getPlainText, insertMention]);
560
+ }, [cleanupCaretTextNodes, emitChange, getOffsetInEditor, getParts, getPlainText, insertMention, replaceTextRange]);
548
561
  useIsomorphicLayoutEffect(function () {
549
562
  var editor = editorRef.current;
550
563
  if (!editor) return;
@@ -555,7 +568,13 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
555
568
  // emitChange 的受控回写要到下一次 render 才生效;跳过本轮紧随其后的空值清理,
556
569
  // 避免刚渲染的默认 Mention 被旧的空 value/mentions 立即移除。
557
570
  skipEmptyCleanupOnceRef.current = true;
571
+ latestMentionsRef.current = defaultInputParts.flatMap(function (part) {
572
+ if (part.type === "mention") return [part.mention];
573
+ if (part.type === "tag") return [part.tag];
574
+ return [];
575
+ });
558
576
  renderPartsToEditor(defaultInputParts);
577
+ setHasContent(true);
559
578
  emitChange();
560
579
  return;
561
580
  }
@@ -663,9 +682,9 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
663
682
  if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
664
683
  var selection = window.getSelection();
665
684
  if (selection !== null && selection !== void 0 && selection.rangeCount) {
666
- var range = selection.getRangeAt(0);
667
- if (range.collapsed) {
668
- var targetMention = event.key === "ArrowLeft" ? getMentionBeforeRange(range) : getMentionAfterRange(range);
685
+ var _range = selection.getRangeAt(0);
686
+ if (_range.collapsed) {
687
+ var targetMention = event.key === "ArrowLeft" ? getMentionBeforeRange(_range) : getMentionAfterRange(_range);
669
688
  if (targetMention) {
670
689
  event.preventDefault();
671
690
  moveCursorAroundMention(targetMention, event.key === "ArrowLeft" ? "before" : "after");
@@ -677,9 +696,9 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
677
696
  if (event.key === "Backspace" || event.key === "Delete") {
678
697
  var _selection = window.getSelection();
679
698
  if (_selection !== null && _selection !== void 0 && _selection.rangeCount) {
680
- var _range = _selection.getRangeAt(0);
681
- if (_range.collapsed) {
682
- var _targetMention = event.key === "Backspace" ? getMentionBeforeRange(_range) : getMentionAfterRange(_range);
699
+ var _range2 = _selection.getRangeAt(0);
700
+ if (_range2.collapsed) {
701
+ var _targetMention = event.key === "Backspace" ? getMentionBeforeRange(_range2) : getMentionAfterRange(_range2);
683
702
  if (_targetMention) {
684
703
  event.preventDefault();
685
704
  removeMentionById(_targetMention.dataset.xadkInlineMentionId || "");