@composy/chat-core 0.0.1

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 (123) hide show
  1. package/README.md +123 -0
  2. package/dist/index.js +1868 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/index.min.js +1868 -0
  5. package/es/constants/dom.d.ts +41 -0
  6. package/es/constants/dom.d.ts.map +1 -0
  7. package/es/constants/dom.js +30 -0
  8. package/es/constants/dom.js.map +1 -0
  9. package/es/core/chat-manager.d.ts +34 -0
  10. package/es/core/chat-manager.d.ts.map +1 -0
  11. package/es/core/chat-manager.js +93 -0
  12. package/es/core/chat-manager.js.map +1 -0
  13. package/es/core/event-emitter.d.ts +48 -0
  14. package/es/core/event-emitter.d.ts.map +1 -0
  15. package/es/core/event-emitter.js +75 -0
  16. package/es/core/event-emitter.js.map +1 -0
  17. package/es/core/mention-engine.d.ts +41 -0
  18. package/es/core/mention-engine.d.ts.map +1 -0
  19. package/es/core/mention-engine.js +117 -0
  20. package/es/core/mention-engine.js.map +1 -0
  21. package/es/index.d.ts +28 -0
  22. package/es/index.d.ts.map +1 -0
  23. package/es/index.js +140 -0
  24. package/es/index.js.map +1 -0
  25. package/es/renderer/dom-renderer.d.ts +79 -0
  26. package/es/renderer/dom-renderer.d.ts.map +1 -0
  27. package/es/renderer/dom-renderer.js +677 -0
  28. package/es/renderer/dom-renderer.js.map +1 -0
  29. package/es/renderer/style-manager.d.ts +58 -0
  30. package/es/renderer/style-manager.d.ts.map +1 -0
  31. package/es/renderer/style-manager.js +641 -0
  32. package/es/renderer/style-manager.js.map +1 -0
  33. package/es/theme/theme-manager.d.ts +33 -0
  34. package/es/theme/theme-manager.d.ts.map +1 -0
  35. package/es/theme/theme-manager.js +70 -0
  36. package/es/theme/theme-manager.js.map +1 -0
  37. package/es/theme/tokens.d.ts +57 -0
  38. package/es/theme/tokens.d.ts.map +1 -0
  39. package/es/theme/tokens.js +108 -0
  40. package/es/theme/tokens.js.map +1 -0
  41. package/es/types/index.d.ts +204 -0
  42. package/es/types/index.d.ts.map +1 -0
  43. package/es/types/index.js +10 -0
  44. package/esm/constants/dom.d.ts +41 -0
  45. package/esm/constants/dom.d.ts.map +1 -0
  46. package/esm/constants/dom.js +30 -0
  47. package/esm/constants/dom.js.map +1 -0
  48. package/esm/core/chat-manager.d.ts +34 -0
  49. package/esm/core/chat-manager.d.ts.map +1 -0
  50. package/esm/core/chat-manager.js +93 -0
  51. package/esm/core/chat-manager.js.map +1 -0
  52. package/esm/core/event-emitter.d.ts +48 -0
  53. package/esm/core/event-emitter.d.ts.map +1 -0
  54. package/esm/core/event-emitter.js +75 -0
  55. package/esm/core/event-emitter.js.map +1 -0
  56. package/esm/core/mention-engine.d.ts +41 -0
  57. package/esm/core/mention-engine.d.ts.map +1 -0
  58. package/esm/core/mention-engine.js +117 -0
  59. package/esm/core/mention-engine.js.map +1 -0
  60. package/esm/index.d.ts +28 -0
  61. package/esm/index.d.ts.map +1 -0
  62. package/esm/index.js +140 -0
  63. package/esm/index.js.map +1 -0
  64. package/esm/renderer/dom-renderer.d.ts +79 -0
  65. package/esm/renderer/dom-renderer.d.ts.map +1 -0
  66. package/esm/renderer/dom-renderer.js +677 -0
  67. package/esm/renderer/dom-renderer.js.map +1 -0
  68. package/esm/renderer/style-manager.d.ts +58 -0
  69. package/esm/renderer/style-manager.d.ts.map +1 -0
  70. package/esm/renderer/style-manager.js +641 -0
  71. package/esm/renderer/style-manager.js.map +1 -0
  72. package/esm/theme/theme-manager.d.ts +33 -0
  73. package/esm/theme/theme-manager.d.ts.map +1 -0
  74. package/esm/theme/theme-manager.js +70 -0
  75. package/esm/theme/theme-manager.js.map +1 -0
  76. package/esm/theme/tokens.d.ts +57 -0
  77. package/esm/theme/tokens.d.ts.map +1 -0
  78. package/esm/theme/tokens.js +108 -0
  79. package/esm/theme/tokens.js.map +1 -0
  80. package/esm/types/index.d.ts +204 -0
  81. package/esm/types/index.d.ts.map +1 -0
  82. package/esm/types/index.js +10 -0
  83. package/lib/constants/dom.cjs +36 -0
  84. package/lib/constants/dom.cjs.map +1 -0
  85. package/lib/constants/dom.d.ts +41 -0
  86. package/lib/constants/dom.d.ts.map +1 -0
  87. package/lib/core/chat-manager.cjs +94 -0
  88. package/lib/core/chat-manager.cjs.map +1 -0
  89. package/lib/core/chat-manager.d.ts +34 -0
  90. package/lib/core/chat-manager.d.ts.map +1 -0
  91. package/lib/core/event-emitter.cjs +76 -0
  92. package/lib/core/event-emitter.cjs.map +1 -0
  93. package/lib/core/event-emitter.d.ts +48 -0
  94. package/lib/core/event-emitter.d.ts.map +1 -0
  95. package/lib/core/mention-engine.cjs +118 -0
  96. package/lib/core/mention-engine.cjs.map +1 -0
  97. package/lib/core/mention-engine.d.ts +41 -0
  98. package/lib/core/mention-engine.d.ts.map +1 -0
  99. package/lib/index.cjs +160 -0
  100. package/lib/index.cjs.map +1 -0
  101. package/lib/index.d.ts +28 -0
  102. package/lib/index.d.ts.map +1 -0
  103. package/lib/package.json +3 -0
  104. package/lib/renderer/dom-renderer.cjs +678 -0
  105. package/lib/renderer/dom-renderer.cjs.map +1 -0
  106. package/lib/renderer/dom-renderer.d.ts +79 -0
  107. package/lib/renderer/dom-renderer.d.ts.map +1 -0
  108. package/lib/renderer/style-manager.cjs +646 -0
  109. package/lib/renderer/style-manager.cjs.map +1 -0
  110. package/lib/renderer/style-manager.d.ts +58 -0
  111. package/lib/renderer/style-manager.d.ts.map +1 -0
  112. package/lib/theme/theme-manager.cjs +71 -0
  113. package/lib/theme/theme-manager.cjs.map +1 -0
  114. package/lib/theme/theme-manager.d.ts +33 -0
  115. package/lib/theme/theme-manager.d.ts.map +1 -0
  116. package/lib/theme/tokens.cjs +110 -0
  117. package/lib/theme/tokens.cjs.map +1 -0
  118. package/lib/theme/tokens.d.ts +57 -0
  119. package/lib/theme/tokens.d.ts.map +1 -0
  120. package/lib/types/index.cjs +11 -0
  121. package/lib/types/index.d.ts +204 -0
  122. package/lib/types/index.d.ts.map +1 -0
  123. package/package.json +107 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["row"],"sources":["../src/core/event-emitter.ts","../src/core/chat-manager.ts","../src/core/mention-engine.ts","../src/theme/tokens.ts","../src/theme/theme-manager.ts","../src/constants/dom.ts","../src/renderer/dom-renderer.ts","../src/renderer/style-manager.ts","../src/index.ts"],"sourcesContent":["/**\n * 轻量事件总线\n * 提供发布/订阅模式的事件管理功能,支持事件的注册、注销、触发等操作\n */\n\n// 定义事件处理函数的类型签名:接收任意数量的未知类型参数,无返回值\ntype Handler = (...args: unknown[]) => void;\n\n/**\n * EventEmitter - 事件发射器类\n * 实现了经典的发布/订阅(Pub/Sub)模式,用于模块间的解耦通信\n * 支持:一次性监听、批量移除、自动清理等功能\n */\nexport class EventEmitter {\n // 使用 Map 存储事件名到处理函数集合的映射关系\n // 键为事件名称(字符串),值为该事件对应的处理函数 Set 集合\n // 使用 Set 而非数组,可自动去重同一处理函数的重复注册\n private listeners = new Map<string, Set<Handler>>();\n\n /**\n * 注册事件监听器\n * @param event - 要监听的事件名称\n * @param handler - 事件触发时执行的回调函数\n * @returns 返回一个取消订阅的函数,调用即可移除该监听器\n */\n on(event: string, handler: Handler): () => void {\n // 如果该事件还没有任何监听器,则创建一个新的 Set 集合\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n // 将处理函数添加到该事件的监听器集合中\n // 使用非空断言(!)因为上方已确认该事件集合存在\n this.listeners.get(event)!.add(handler);\n // 返回一个取消订阅函数,方便调用者链式调用后自行移除\n return () => this.off(event, handler);\n }\n\n /**\n * 移除指定事件的某个监听器\n * @param event - 事件名称\n * @param handler - 要移除的处理函数引用(必须与注册时为同一函数引用)\n */\n off(event: string, handler: Handler): void {\n // 可选链调用:如果该事件存在监听器集合,则从中删除指定处理函数\n // 若事件不存在则安全跳过,不会抛出异常\n this.listeners.get(event)?.delete(handler);\n }\n\n /**\n * 触发(发射)指定事件,依次调用所有已注册的监听器\n * @param event - 要触发的事件名称\n * @param args - 传递给监听器函数的参数列表(剩余参数语法)\n */\n emit(event: string, ...args: unknown[]): void {\n // 获取该事件的监听器集合,若存在则遍历调用每个处理函数\n this.listeners.get(event)?.forEach((handler) => {\n try {\n // 使用展开运算符将参数数组传递给处理函数\n handler(...args);\n } catch (err) {\n // 捕获单个处理函数的异常,避免影响其他监听器的执行\n // 同时输出错误日志便于调试,标注所属模块为 [Chat]\n console.error(`[Chat] Event handler error for \"${event}\":`, err);\n }\n });\n }\n\n /**\n * 注册一次性事件监听器(触发一次后自动移除)\n * @param event - 要监听的事件名称\n * @param handler - 事件触发时执行的回调函数\n * @returns 返回取消订阅的函数,可在触发前手动取消\n */\n once(event: string, handler: Handler): () => void {\n // 创建包装函数:先移除自身,再调用原始处理函数\n // 这样保证该监听器只执行一次\n const wrapper = (...args: unknown[]) => {\n // 先从事件中移除包装函数自身,防止重复触发\n this.off(event, wrapper);\n // 再执行用户注册的原始处理函数\n handler(...args);\n };\n // 将包装函数注册为普通监听器,复用 on() 的逻辑\n return this.on(event, wrapper);\n }\n\n /**\n * 批量移除事件监听器\n * @param event - 可选的事件名称\n * - 若传入事件名,则只移除该事件的所有监听器\n * - 若不传参数,则清空所有事件的所有监听器\n */\n removeAll(event?: string): void {\n if (event) {\n // 移除指定事件的全部监听器(直接删除整个事件条目)\n this.listeners.delete(event);\n } else {\n // 不传参数时,清空整个监听器映射表,移除所有事件\n this.listeners.clear();\n }\n }\n}\n","/**\n * 聊天管理器 - 消息增删改查、状态管理\n */\n\nimport type { ChatMessage } from '../types';\nimport { EventEmitter } from './event-emitter';\n\n/**\n * ChatManager - Chat Manager class\n */\nexport class ChatManager {\n private messages: ChatMessage[] = [];\n private emitter: EventEmitter;\n\n constructor(emitter: EventEmitter, initialMessages?: ChatMessage[]) {\n this.emitter = emitter;\n if (initialMessages?.length) {\n this.messages = [...initialMessages];\n }\n }\n\n /** 获取所有消息 */\n getMessages(): ChatMessage[] {\n return [...this.messages];\n }\n\n /** 根据 ID 获取消息 */\n getMessage(id: string): ChatMessage | undefined {\n return this.messages.find((m) => m.id === id);\n }\n\n /** 添加消息(末尾追加) */\n addMessage(message: ChatMessage): void {\n this.messages.push(message);\n this.emitter.emit('message-added', message);\n this.emitter.emit('messages-changed', this.getMessages());\n }\n\n /** 在顶部批量插入消息(用于加载更多) */\n prependMessages(messages: ChatMessage[]): void {\n this.messages.unshift(...messages);\n this.emitter.emit('messages-prepended', messages);\n this.emitter.emit('messages-changed', this.getMessages());\n }\n\n /** 更新消息 */\n updateMessage(id: string, updates: Partial<ChatMessage>): void {\n const index = this.messages.findIndex((m) => m.id === id);\n if (index === -1) return;\n\n this.messages[index] = { ...this.messages[index], ...updates };\n this.emitter.emit('message-updated', this.messages[index]);\n this.emitter.emit('messages-changed', this.getMessages());\n }\n\n /** 删除消息 */\n removeMessage(id: string): void {\n const index = this.messages.findIndex((m) => m.id === id);\n if (index === -1) return;\n\n const removed = this.messages.splice(index, 1)[0];\n this.emitter.emit('message-removed', removed);\n this.emitter.emit('messages-changed', this.getMessages());\n }\n\n /** 替换全部消息 */\n setMessages(messages: ChatMessage[]): void {\n this.messages = [...messages];\n this.emitter.emit('messages-changed', this.getMessages());\n }\n\n /** 清空所有消息 */\n clearMessages(): void {\n this.messages = [];\n this.emitter.emit('messages-changed', []);\n }\n\n /** 追加流式消息内容 */\n appendMessageContent(id: string, chunk: string): void {\n const index = this.messages.findIndex((m) => m.id === id);\n if (index === -1) return;\n\n const msg = this.messages[index];\n this.messages[index] = {\n ...msg,\n content: (msg.content ?? '') + chunk,\n };\n this.emitter.emit('message-content-appended', id, this.messages[index].content);\n this.emitter.emit('messages-changed', this.getMessages());\n }\n\n /** 完成流式消息 */\n finishStreaming(id: string): void {\n const index = this.messages.findIndex((m) => m.id === id);\n if (index === -1) return;\n\n this.messages[index] = { ...this.messages[index], streaming: false };\n this.emitter.emit('message-updated', this.messages[index]);\n this.emitter.emit('messages-changed', this.getMessages());\n }\n}\n","/**\n * @file mention-engine.ts\n * @description mention-engine 模块\n */\n\nimport type { MentionItem } from '../types';\nimport { EventEmitter } from './event-emitter';\n\n/**\n * MentionState interface\n */\nexport interface MentionState {\n active: boolean;\n query: string;\n filtered: MentionItem[];\n activeIndex: number;\n triggerPosition: number;\n}\n\n/**\n * MentionEngine 类\n */\nexport class MentionEngine {\n private members: MentionItem[] = [];\n private emitter: EventEmitter;\n private state: MentionState = {\n active: false,\n query: '',\n filtered: [],\n activeIndex: 0,\n triggerPosition: -1,\n };\n private selectedMentions: MentionItem[] = [];\n\n constructor(emitter: EventEmitter, members?: MentionItem[]) {\n this.emitter = emitter;\n if (members) this.members = [...members];\n }\n\n getState(): MentionState {\n return {\n ...this.state,\n filtered: [...this.state.filtered],\n };\n }\n\n getSelectedMentions(): MentionItem[] {\n return [...this.selectedMentions];\n }\n\n setMembers(members: MentionItem[]): void {\n this.members = [...members];\n if (this.state.active) {\n this.filter(this.state.query);\n }\n }\n\n handleInput(text: string, cursorPos: number): void {\n const beforeCursor = text.slice(0, cursorPos);\n const atIndex = beforeCursor.lastIndexOf('@');\n\n if (atIndex === -1) {\n this.deactivate();\n return;\n }\n\n if (atIndex > 0 && !/\\s/.test(beforeCursor[atIndex - 1])) {\n this.deactivate();\n return;\n }\n\n const query = beforeCursor.slice(atIndex + 1);\n if (/[^\\S\\r\\n]/.test(query)) {\n this.deactivate();\n return;\n }\n\n this.state.active = true;\n this.state.triggerPosition = atIndex;\n this.filter(query);\n }\n\n moveUp(): void {\n if (!this.state.active || this.state.filtered.length === 0) return;\n this.state.activeIndex =\n (this.state.activeIndex - 1 + this.state.filtered.length) %\n this.state.filtered.length;\n this.emitter.emit('mention-active-change', this.state.activeIndex);\n }\n\n moveDown(): void {\n if (!this.state.active || this.state.filtered.length === 0) return;\n this.state.activeIndex =\n (this.state.activeIndex + 1) % this.state.filtered.length;\n this.emitter.emit('mention-active-change', this.state.activeIndex);\n }\n\n selectCurrent(): MentionItem | null {\n if (!this.state.active || this.state.filtered.length === 0) return null;\n return this.select(this.state.activeIndex);\n }\n\n select(index: number): MentionItem | null {\n if (index < 0 || index >= this.state.filtered.length) return null;\n const member = this.state.filtered[index];\n if (!this.selectedMentions.find((m) => m.id === member.id)) {\n this.selectedMentions.push(member);\n }\n this.emitter.emit('mention-select', member);\n this.deactivate();\n return member;\n }\n\n deactivate(): void {\n if (!this.state.active) return;\n this.state = {\n active: false,\n query: '',\n filtered: [],\n activeIndex: 0,\n triggerPosition: -1,\n };\n this.emitter.emit('mention-deactivate');\n }\n\n parseMentions(text: string): MentionItem[] {\n const mentions: MentionItem[] = [];\n const sortedMembers = [...this.members].sort((a, b) => b.name.length - a.name.length);\n\n for (const member of sortedMembers) {\n const pattern = new RegExp(`(^|\\\\s)@${this.escapeRegex(member.name)}(?=\\\\s|$|[,。!?,.!?])`, 'u');\n if (pattern.test(text) && !mentions.find((m) => m.id === member.id)) {\n mentions.push(member);\n }\n }\n\n return mentions;\n }\n\n resetSelected(): void {\n this.selectedMentions = [];\n }\n\n getInsertText(member: MentionItem): string {\n return `@${member.name} `;\n }\n\n private filter(query: string): void {\n const normalizedQuery = query.trim().toLowerCase();\n this.state.query = query;\n this.state.filtered = this.members.filter((member) =>\n member.name.toLowerCase().includes(normalizedQuery) ||\n member.id.toLowerCase().includes(normalizedQuery),\n );\n this.state.activeIndex = 0;\n this.emitter.emit('mention-filter', this.getState());\n }\n\n private escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n }\n}\n","/**\n * @file tokens.ts\n * @description tokens 模块\n */\n\n/**\n * ThemeTokens interface\n */\nexport interface ThemeTokens {\n bgPrimary: string;\n bgSecondary: string;\n bgBubbleOutgoing: string;\n bgBubbleIncoming: string;\n bgInput: string;\n bgMention: string;\n bgMentionHover: string;\n bgMentionActive: string;\n bgLoadMore: string;\n bgSystemMessage: string;\n bgDropOverlay: string;\n bgDangerSoft: string;\n\n textPrimary: string;\n textSecondary: string;\n textBubbleOutgoing: string;\n textBubbleIncoming: string;\n textMention: string;\n textMentionTag: string;\n textTimestamp: string;\n textSystem: string;\n textPlaceholder: string;\n\n borderPrimary: string;\n borderInput: string;\n borderInputFocus: string;\n borderMention: string;\n\n colorSending: string;\n colorSent: string;\n colorDelivered: string;\n colorRead: string;\n colorFailed: string;\n colorLink: string;\n\n shadowPanel: string;\n shadowMention: string;\n\n avatarBg: string;\n avatarText: string;\n\n btnPrimaryBg: string;\n btnPrimaryText: string;\n btnPrimaryHover: string;\n\n scrollbarThumb: string;\n scrollbarTrack: string;\n\n bgToolbar: string;\n borderToolbar: string;\n toolbarIconColor: string;\n toolbarIconHover: string;\n toolbarVoiceActive: string;\n}\n\nexport const lightTokens: ThemeTokens = {\n bgPrimary: 'var(--color-gray-50)',\n bgSecondary: 'var(--color-gray-100)',\n bgBubbleOutgoing: 'var(--color-primary-default)',\n bgBubbleIncoming: 'var(--color-gray-100)',\n bgInput: 'var(--color-gray-50)',\n bgMention: 'var(--color-gray-50)',\n bgMentionHover: 'var(--color-primary-50)',\n bgMentionActive: 'var(--color-primary-100)',\n bgLoadMore: 'var(--color-gray-100)',\n bgSystemMessage: 'var(--color-gray-100)',\n bgDropOverlay: 'color-mix(in srgb, var(--color-primary-default) 10%, var(--color-gray-50))',\n bgDangerSoft: 'color-mix(in srgb, var(--color-danger-default) 12%, var(--color-gray-50))',\n\n textPrimary: 'var(--color-gray-900)',\n textSecondary: 'var(--color-gray-600)',\n textBubbleOutgoing: 'var(--color-gray-50)',\n textBubbleIncoming: 'var(--color-gray-900)',\n textMention: 'var(--color-gray-900)',\n textMentionTag: 'var(--color-primary-default)',\n textTimestamp: 'var(--color-gray-500)',\n textSystem: 'var(--color-gray-600)',\n textPlaceholder: 'var(--color-gray-400)',\n\n borderPrimary: 'var(--color-gray-200)',\n borderInput: 'var(--color-gray-300)',\n borderInputFocus: 'var(--color-primary-default)',\n borderMention: 'var(--color-gray-200)',\n\n colorSending: 'var(--color-gray-400)',\n colorSent: 'var(--color-gray-500)',\n colorDelivered: 'var(--color-primary-default)',\n colorRead: 'var(--color-success-default)',\n colorFailed: 'var(--color-danger-default)',\n colorLink: 'var(--color-primary-default)',\n\n shadowPanel: 'var(--size-shadow-2)',\n shadowMention: 'var(--size-shadow-4)',\n\n avatarBg: 'var(--color-primary-default)',\n avatarText: 'var(--color-gray-50)',\n\n btnPrimaryBg: 'var(--color-primary-default)',\n btnPrimaryText: 'var(--color-gray-50)',\n btnPrimaryHover: 'var(--color-primary-hover)',\n\n scrollbarThumb: 'var(--color-gray-300)',\n scrollbarTrack: 'var(--color-gray-100)',\n\n bgToolbar: 'var(--color-gray-100)',\n borderToolbar: 'var(--color-gray-200)',\n toolbarIconColor: 'var(--color-gray-600)',\n toolbarIconHover: 'var(--color-primary-default)',\n toolbarVoiceActive: 'var(--color-danger-default)',\n};\n\nexport const darkTokens: ThemeTokens = {\n bgPrimary: 'var(--color-gray-900)',\n bgSecondary: 'var(--color-gray-800)',\n bgBubbleOutgoing: 'var(--color-primary-default)',\n bgBubbleIncoming: 'var(--color-gray-800)',\n bgInput: 'var(--color-gray-900)',\n bgMention: 'var(--color-gray-900)',\n bgMentionHover: 'var(--color-gray-800)',\n bgMentionActive: 'var(--color-primary-900)',\n bgLoadMore: 'var(--color-gray-800)',\n bgSystemMessage: 'var(--color-gray-800)',\n bgDropOverlay: 'color-mix(in srgb, var(--color-primary-default) 16%, var(--color-gray-900))',\n bgDangerSoft: 'color-mix(in srgb, var(--color-danger-default) 18%, var(--color-gray-900))',\n\n textPrimary: 'var(--color-gray-50)',\n textSecondary: 'var(--color-gray-300)',\n textBubbleOutgoing: 'var(--color-gray-50)',\n textBubbleIncoming: 'var(--color-gray-50)',\n textMention: 'var(--color-gray-50)',\n textMentionTag: 'var(--color-primary-300)',\n textTimestamp: 'var(--color-gray-400)',\n textSystem: 'var(--color-gray-300)',\n textPlaceholder: 'var(--color-gray-500)',\n\n borderPrimary: 'var(--color-gray-700)',\n borderInput: 'var(--color-gray-700)',\n borderInputFocus: 'var(--color-primary-default)',\n borderMention: 'var(--color-gray-700)',\n\n colorSending: 'var(--color-gray-500)',\n colorSent: 'var(--color-gray-400)',\n colorDelivered: 'var(--color-primary-300)',\n colorRead: 'var(--color-success-default)',\n colorFailed: 'var(--color-danger-default)',\n colorLink: 'var(--color-primary-300)',\n\n shadowPanel: 'var(--size-shadow-3)',\n shadowMention: 'var(--size-shadow-6)',\n\n avatarBg: 'var(--color-primary-default)',\n avatarText: 'var(--color-gray-50)',\n\n btnPrimaryBg: 'var(--color-primary-default)',\n btnPrimaryText: 'var(--color-gray-50)',\n btnPrimaryHover: 'var(--color-primary-hover)',\n\n scrollbarThumb: 'var(--color-gray-700)',\n scrollbarTrack: 'var(--color-gray-800)',\n\n bgToolbar: 'var(--color-gray-800)',\n borderToolbar: 'var(--color-gray-700)',\n toolbarIconColor: 'var(--color-gray-300)',\n toolbarIconHover: 'var(--color-primary-300)',\n toolbarVoiceActive: 'var(--color-danger-default)',\n};\n","/**\n * 主题管理器\n */\n\nimport type { ThemeMode } from '../types';\nimport type { ThemeTokens } from './tokens';\nimport { lightTokens, darkTokens } from './tokens';\nimport { EventEmitter } from '../core/event-emitter';\n\n/**\n * ThemeManager - Theme Manager class\n */\nexport class ThemeManager {\n private mode: ThemeMode = 'light';\n private emitter: EventEmitter;\n private mediaQuery: MediaQueryList | null = null;\n private mediaHandler: ((e: MediaQueryListEvent) => void) | null = null;\n\n constructor(emitter: EventEmitter, mode?: ThemeMode) {\n this.emitter = emitter;\n if (mode) this.setTheme(mode);\n }\n\n /** 获取当前模式 */\n getMode(): ThemeMode {\n return this.mode;\n }\n\n /** 获取当前实际主题(auto 时解析为 light/dark) */\n getResolvedTheme(): 'light' | 'dark' {\n if (this.mode === 'auto') {\n return this.getSystemTheme();\n }\n return this.mode;\n }\n\n /** 获取当前主题令牌 */\n getTokens(): ThemeTokens {\n return this.getResolvedTheme() === 'dark' ? darkTokens : lightTokens;\n }\n\n /** 设置主题 */\n setTheme(mode: ThemeMode): void {\n this.cleanupMediaListener();\n this.mode = mode;\n\n if (mode === 'auto') {\n this.setupMediaListener();\n }\n\n this.emitter.emit('theme-change', this.getResolvedTheme(), this.getTokens());\n }\n\n /** 获取系统主题偏好 */\n private getSystemTheme(): 'light' | 'dark' {\n if (typeof window === 'undefined') return 'light';\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n\n /** 监听系统主题变化 */\n private setupMediaListener(): void {\n if (typeof window === 'undefined') return;\n this.mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n this.mediaHandler = () => {\n this.emitter.emit('theme-change', this.getResolvedTheme(), this.getTokens());\n };\n this.mediaQuery.addEventListener('change', this.mediaHandler);\n }\n\n /** 清理监听器 */\n private cleanupMediaListener(): void {\n if (this.mediaQuery && this.mediaHandler) {\n this.mediaQuery.removeEventListener('change', this.mediaHandler);\n this.mediaQuery = null;\n this.mediaHandler = null;\n }\n }\n\n /** 销毁 */\n destroy(): void {\n this.cleanupMediaListener();\n }\n}\n","/**\n * @file dom.ts\n * @description dom 模块\n */\n\nexport const DEFAULT_CLASS_PREFIX = 'ldesign-chat';\nexport const COMPONENT_CSS_VAR_PREFIX = '--ldesign-chat';\nexport const STYLE_ELEMENT_ID = 'ldesign-chat-styles';\n\n/**\n * normalizeClassPrefix 函数\n * @param prefix? - 参数\n * @returns 返回值\n */\n/**\n * normalizeClassPrefix - normalize Class Prefix function\n * @param prefix? - 参数说明\n * @returns 返回值说明\n */\nexport function normalizeClassPrefix(prefix?: string): string {\n const trimmed = prefix?.trim();\n if (!trimmed) return DEFAULT_CLASS_PREFIX;\n if (trimmed.startsWith('ldesign-')) return trimmed;\n return `ldesign-${trimmed.replace(/^-+/, '')}`;\n}\n\n/**\n * getStyleElementId 函数\n * @param prefix = DEFAULT_CLASS_PREFIX - 参数\n * @returns 返回值\n */\n/**\n * getStyleElementId - get Style Element Id function\n * @param prefix = DEFAULT_CLASS_PREFIX - 参数说明\n * @returns 返回值说明\n */\nexport function getStyleElementId(prefix = DEFAULT_CLASS_PREFIX): string {\n const normalized = normalizeClassPrefix(prefix);\n return normalized === DEFAULT_CLASS_PREFIX\n ? STYLE_ELEMENT_ID\n : `${normalized}-styles`;\n}\n\n/**\n * cx 函数\n * @param ...classes - 参数\n * @returns 返回值\n */\n/**\n * cx - cx function\n * @param ...classes - 参数说明\n * @returns 返回值说明\n */\nexport function cx(...classes: (string | false | null | undefined)[]): string {\n return classes.filter(Boolean).join(' ');\n}\n","import type { ChatConfig, ChatMessage, MentionItem, MessageStatus } from '../types';\nimport { EventEmitter } from '../core/event-emitter';\nimport { MentionEngine } from '../core/mention-engine';\nimport { DEFAULT_CLASS_PREFIX, cx, normalizeClassPrefix } from '../constants/dom';\n\nconst SEND_ICON_SVG = '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line><polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon></svg>';\nconst ICON_IMAGE = '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" ry=\"2\"/><circle cx=\"9\" cy=\"9\" r=\"2\"/><path d=\"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21\"/></svg>';\nconst ICON_PAPERCLIP = '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48\"/></svg>';\nconst ICON_MIC = '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z\"/><path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"/><line x1=\"12\" x2=\"12\" y1=\"19\" y2=\"22\"/></svg>';\nconst ICON_MIC_OFF = '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"2\" x2=\"22\" y1=\"2\" y2=\"22\"/><path d=\"M18.89 13.23A7.12 7.12 0 0 0 19 12v-2\"/><path d=\"M5 10v2a7 7 0 0 0 12 5.29\"/><path d=\"M15 9.34V5a3 3 0 0 0-5.68-1.33\"/><path d=\"M9 9v3a3 3 0 0 0 5.12 2.12\"/><line x1=\"12\" x2=\"12\" y1=\"19\" y2=\"22\"/></svg>';\nconst FILE_ICON = '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\"/><path d=\"M14 2v4a2 2 0 0 0 2 2h4\"/></svg>';\n\nconst STATUS_MAP: Record<MessageStatus, string> = {\n sending: '...',\n sent: '✓',\n delivered: '✓✓',\n read: '✓✓',\n failed: '!',\n};\n\nexport class DOMRenderer {\n private container: HTMLElement;\n private config: ChatConfig;\n private emitter: EventEmitter;\n private mentionEngine: MentionEngine;\n private prefix: string;\n\n private root!: HTMLElement;\n private messageListEl!: HTMLElement;\n private inputArea: HTMLElement | null = null;\n private textareaEl: HTMLTextAreaElement | null = null;\n private sendBtn: HTMLButtonElement | null = null;\n private mentionPanel: HTMLElement | null = null;\n private loadMoreEl: HTMLElement | null = null;\n private toolbarEl: HTMLElement | null = null;\n private dropOverlay: HTMLElement | null = null;\n private voiceBtn: HTMLElement | null = null;\n private loadingMore = false;\n private isRecording = false;\n private recognition: any = null;\n private lastVoiceTranscript = '';\n\n constructor(\n container: HTMLElement,\n config: ChatConfig,\n emitter: EventEmitter,\n mentionEngine: MentionEngine,\n ) {\n this.container = container;\n this.config = config;\n this.emitter = emitter;\n this.mentionEngine = mentionEngine;\n this.prefix = normalizeClassPrefix(config.classPrefix ?? DEFAULT_CLASS_PREFIX);\n }\n\n init(): void {\n this.container.innerHTML = '';\n this.root = this.el('div', `${this.prefix}-container`);\n this.messageListEl = this.el('div', `${this.prefix}-message-list`);\n this.root.appendChild(this.messageListEl);\n\n if (this.config.showInput !== false) {\n this.renderInputArea();\n }\n\n this.container.appendChild(this.root);\n this.setupEventListeners();\n }\n\n updateMessageContent(id: string, content: string): void {\n const rowEl = this.messageListEl.querySelector(`[data-msg-id=\"${this.escapeAttr(id)}\"]`) as HTMLElement | null;\n const bubble = rowEl?.querySelector(`.${this.prefix}-bubble`) as HTMLElement | null;\n if (!bubble) return;\n bubble.innerHTML = this.renderTextContent(content);\n }\n\n renderMessages(messages: ChatMessage[]): void {\n this.messageListEl.innerHTML = '';\n\n if (this.config.enableLoadMore) {\n this.renderLoadMoreButton();\n }\n\n if (messages.length === 0) {\n this.renderEmpty();\n return;\n }\n\n let lastTimestamp = 0;\n const interval = this.config.timeGroupInterval ?? 300000;\n for (const message of messages) {\n if (this.config.showTimestamp !== false && message.timestamp - lastTimestamp > interval) {\n this.renderTimeDivider(message.timestamp);\n lastTimestamp = message.timestamp;\n }\n this.renderMessageRow(message);\n }\n }\n\n appendMessage(message: ChatMessage): void {\n this.removeEmpty();\n const messageEls = this.getMessageElements();\n const lastTime = messageEls.length > 0\n ? Number.parseInt(messageEls[messageEls.length - 1].dataset.timestamp ?? '0', 10)\n : 0;\n const interval = this.config.timeGroupInterval ?? 300000;\n\n if (this.config.showTimestamp !== false && message.timestamp - lastTime > interval) {\n this.renderTimeDivider(message.timestamp);\n }\n\n this.renderMessageRow(message);\n }\n\n prependMessages(messages: ChatMessage[]): void {\n if (!messages.length) return;\n this.removeEmpty();\n\n const scrollHeight = this.messageListEl.scrollHeight;\n const scrollTop = this.messageListEl.scrollTop;\n const fragment = document.createDocumentFragment();\n let lastTimestamp = 0;\n const interval = this.config.timeGroupInterval ?? 300000;\n\n for (const message of messages) {\n if (this.config.showTimestamp !== false && message.timestamp - lastTimestamp > interval) {\n fragment.appendChild(this.createTimeDivider(message.timestamp));\n lastTimestamp = message.timestamp;\n }\n fragment.appendChild(this.createMessageRow(message));\n }\n\n const firstMessage = this.messageListEl.querySelector(`.${this.prefix}-message-row, .${this.prefix}-time-divider`);\n if (firstMessage) {\n firstMessage.before(fragment);\n } else if (this.loadMoreEl) {\n this.loadMoreEl.after(fragment);\n } else {\n this.messageListEl.appendChild(fragment);\n }\n\n this.messageListEl.scrollTop = scrollTop + (this.messageListEl.scrollHeight - scrollHeight);\n }\n\n updateMessage(id: string, message: ChatMessage): void {\n const rowEl = this.messageListEl.querySelector(`[data-msg-id=\"${this.escapeAttr(id)}\"]`);\n if (!rowEl) return;\n rowEl.replaceWith(this.createMessageRow(message));\n }\n\n removeMessage(id: string): void {\n this.messageListEl.querySelector(`[data-msg-id=\"${this.escapeAttr(id)}\"]`)?.remove();\n if (this.getMessageElements().length === 0) {\n this.renderEmpty();\n }\n }\n\n scrollToBottom(smooth = true): void {\n if (typeof this.messageListEl.scrollTo === 'function') {\n this.messageListEl.scrollTo({\n top: this.messageListEl.scrollHeight,\n behavior: smooth ? 'smooth' : 'auto',\n });\n return;\n }\n this.messageListEl.scrollTop = this.messageListEl.scrollHeight;\n }\n\n isAtBottom(threshold = 4): boolean {\n const distance = this.messageListEl.scrollHeight - this.messageListEl.scrollTop - this.messageListEl.clientHeight;\n return distance <= threshold;\n }\n\n setLoadingMore(loading: boolean): void {\n this.loadingMore = loading;\n if (!this.loadMoreEl) return;\n this.loadMoreEl.textContent = loading ? '加载中...' : (this.config.loadMoreText ?? '加载更多');\n this.loadMoreEl.classList.toggle(`${this.prefix}-load-more--loading`, loading);\n }\n\n focusInput(): void {\n this.textareaEl?.focus();\n }\n\n setInputContent(content: string): void {\n if (!this.textareaEl) return;\n this.textareaEl.value = this.limitInput(content);\n this.autoResize();\n this.updateSendButtonState();\n this.config.onInputChange?.(this.textareaEl.value);\n }\n\n getInputContent(): string {\n return this.textareaEl?.value ?? '';\n }\n\n clearInput(): void {\n this.setInputContent('');\n }\n\n renderMentionPanel(members: MentionItem[], activeIndex: number): void {\n if (!this.mentionPanel) return;\n\n if (members.length === 0) {\n this.mentionPanel.style.display = 'none';\n return;\n }\n\n this.mentionPanel.style.display = 'block';\n this.mentionPanel.innerHTML = '';\n\n members.forEach((member, index) => {\n const item = this.el(\n 'div',\n cx(`${this.prefix}-mention-item`, index === activeIndex && `${this.prefix}-mention-item--active`),\n );\n item.setAttribute('role', 'option');\n item.setAttribute('aria-selected', String(index === activeIndex));\n\n const avatar = this.el('div', `${this.prefix}-mention-item-avatar`);\n if (member.avatar) {\n const img = document.createElement('img');\n img.src = member.avatar;\n img.alt = '';\n avatar.appendChild(img);\n } else {\n avatar.textContent = member.name[0]?.toUpperCase() ?? '';\n }\n item.appendChild(avatar);\n\n const name = this.el('span', `${this.prefix}-mention-item-name`);\n name.textContent = member.name;\n item.appendChild(name);\n\n item.addEventListener('click', () => {\n this.mentionEngine.select(index);\n });\n\n this.mentionPanel?.appendChild(item);\n });\n }\n\n hideMentionPanel(): void {\n if (this.mentionPanel) {\n this.mentionPanel.style.display = 'none';\n }\n }\n\n destroy(): void {\n this.stopVoice();\n this.container.innerHTML = '';\n }\n\n private renderInputArea(): void {\n this.inputArea = this.el('div', `${this.prefix}-input-area`);\n const wrapper = this.el('div', `${this.prefix}-input-wrapper`);\n\n this.mentionPanel = this.el('div', `${this.prefix}-mention-panel`);\n this.mentionPanel.style.display = 'none';\n this.mentionPanel.setAttribute('role', 'listbox');\n wrapper.appendChild(this.mentionPanel);\n\n if (this.config.enableToolbar !== false) {\n this.renderToolbar(wrapper);\n }\n\n this.textareaEl = document.createElement('textarea');\n this.textareaEl.className = `${this.prefix}-textarea`;\n this.textareaEl.placeholder = this.config.inputPlaceholder ?? '输入消息...';\n this.textareaEl.rows = 1;\n if (this.config.maxInputLength && this.config.maxInputLength > 0) {\n this.textareaEl.maxLength = this.config.maxInputLength;\n }\n wrapper.appendChild(this.textareaEl);\n\n this.dropOverlay = this.el('div', `${this.prefix}-drop-overlay`);\n this.dropOverlay.innerHTML = '<span>拖放文件到这里</span>';\n this.dropOverlay.style.display = 'none';\n wrapper.appendChild(this.dropOverlay);\n\n this.inputArea.appendChild(wrapper);\n\n this.sendBtn = document.createElement('button');\n this.sendBtn.className = `${this.prefix}-send-btn`;\n this.sendBtn.innerHTML = SEND_ICON_SVG;\n this.sendBtn.title = '发送';\n this.sendBtn.type = 'button';\n this.sendBtn.disabled = true;\n this.inputArea.appendChild(this.sendBtn);\n\n this.root.appendChild(this.inputArea);\n }\n\n private renderToolbar(wrapper: HTMLElement): void {\n const toolbar = this.config.toolbarConfig ?? {};\n this.toolbarEl = this.el('div', `${this.prefix}-toolbar`);\n\n if (toolbar.image !== false) {\n const imageBtn = this.createToolbarBtn(ICON_IMAGE, '插入图片');\n imageBtn.addEventListener('click', () => this.openFilePicker('image/*'));\n this.toolbarEl.appendChild(imageBtn);\n }\n\n if (toolbar.file !== false) {\n const fileBtn = this.createToolbarBtn(ICON_PAPERCLIP, '插入文件');\n fileBtn.addEventListener('click', () => this.openFilePicker('*/*'));\n this.toolbarEl.appendChild(fileBtn);\n }\n\n if (toolbar.voice !== false) {\n this.voiceBtn = this.createToolbarBtn(ICON_MIC, '语音输入');\n this.voiceBtn.addEventListener('click', () => this.toggleVoice());\n this.toolbarEl.appendChild(this.voiceBtn);\n }\n\n wrapper.insertBefore(this.toolbarEl, wrapper.firstChild);\n }\n\n private createToolbarBtn(iconSvg: string, title: string): HTMLButtonElement {\n const btn = document.createElement('button');\n btn.className = `${this.prefix}-toolbar-btn`;\n btn.innerHTML = iconSvg;\n btn.title = title;\n btn.type = 'button';\n return btn;\n }\n\n private openFilePicker(accept: string): void {\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = accept;\n input.multiple = true;\n input.style.display = 'none';\n input.addEventListener('change', () => {\n const files = Array.from(input.files ?? []);\n input.remove();\n if (!files.length) return;\n const isImage = accept.startsWith('image');\n this.emitter.emit(isImage ? 'toolbar-image' : 'toolbar-file', files);\n if (isImage) {\n this.config.onImageUpload?.(files);\n } else {\n this.config.onFileUpload?.(files);\n }\n });\n document.body.appendChild(input);\n input.click();\n }\n\n private toggleVoice(): void {\n if (this.isRecording) {\n this.stopVoice();\n } else {\n this.startVoice();\n }\n }\n\n private startVoice(): void {\n if (typeof window === 'undefined') return;\n const SpeechRecognition = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition;\n if (!SpeechRecognition) {\n this.emitter.emit('toolbar-voice-unsupported');\n this.config.onVoiceUnsupported?.();\n return;\n }\n\n try {\n this.lastVoiceTranscript = '';\n this.recognition = new SpeechRecognition();\n this.recognition.continuous = false;\n this.recognition.interimResults = true;\n this.recognition.lang = this.config.voiceLang ?? 'zh-CN';\n\n this.recognition.onresult = (event: any) => {\n let transcript = '';\n for (let i = 0; i < event.results.length; i++) {\n transcript += event.results[i][0].transcript;\n }\n this.lastVoiceTranscript = transcript;\n const lastResult = event.results[event.results.length - 1];\n if (lastResult?.isFinal && this.textareaEl) {\n this.insertTextAtCursor(transcript);\n }\n };\n\n this.recognition.onend = () => {\n this.finishVoice();\n this.emitter.emit('toolbar-voice-end', this.lastVoiceTranscript);\n this.config.onVoiceEnd?.(this.lastVoiceTranscript);\n };\n\n this.recognition.onerror = (error: unknown) => {\n this.finishVoice();\n this.emitter.emit('toolbar-voice-error', error);\n this.config.onVoiceError?.(error);\n };\n\n this.isRecording = true;\n this.voiceBtn?.classList.add(`${this.prefix}-toolbar-btn--active`);\n if (this.voiceBtn) this.voiceBtn.innerHTML = ICON_MIC_OFF;\n this.recognition.start();\n this.emitter.emit('toolbar-voice-start');\n this.config.onVoiceStart?.();\n } catch (error) {\n this.finishVoice();\n this.emitter.emit('toolbar-voice-error', error);\n this.config.onVoiceError?.(error);\n }\n }\n\n private stopVoice(): void {\n if (!this.recognition) return;\n const recognition = this.recognition;\n this.recognition = null;\n try {\n recognition.stop();\n } catch {\n this.finishVoice();\n }\n }\n\n private finishVoice(): void {\n this.isRecording = false;\n this.recognition = null;\n this.voiceBtn?.classList.remove(`${this.prefix}-toolbar-btn--active`);\n if (this.voiceBtn) this.voiceBtn.innerHTML = ICON_MIC;\n }\n\n private setupEventListeners(): void {\n if (this.textareaEl) {\n this.textareaEl.addEventListener('input', () => {\n const limited = this.limitInput(this.textareaEl?.value ?? '');\n if (this.textareaEl && limited !== this.textareaEl.value) {\n this.textareaEl.value = limited;\n }\n this.autoResize();\n this.updateSendButtonState();\n this.config.onInputChange?.(this.textareaEl?.value ?? '');\n if (this.config.enableMention && this.textareaEl) {\n this.mentionEngine.handleInput(this.textareaEl.value, this.textareaEl.selectionStart);\n }\n });\n\n this.textareaEl.addEventListener('keydown', (event) => {\n const mentionState = this.mentionEngine.getState();\n\n if (mentionState.active) {\n if (event.key === 'ArrowUp') {\n event.preventDefault();\n this.mentionEngine.moveUp();\n } else if (event.key === 'ArrowDown') {\n event.preventDefault();\n this.mentionEngine.moveDown();\n } else if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n const member = this.mentionEngine.selectCurrent();\n if (member) this.insertMention(member);\n } else if (event.key === 'Escape') {\n event.preventDefault();\n this.mentionEngine.deactivate();\n }\n return;\n }\n\n if (this.config.enterToSend !== false && event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n this.handleSend();\n }\n });\n\n this.textareaEl.addEventListener('paste', (event) => {\n const items = event.clipboardData?.items;\n if (!items) return;\n const files: File[] = [];\n for (let i = 0; i < items.length; i++) {\n if (items[i].kind === 'file') {\n const file = items[i].getAsFile();\n if (file) files.push(file);\n }\n }\n if (files.length > 0) {\n event.preventDefault();\n this.emitter.emit('toolbar-paste', files);\n this.config.onPaste?.(files);\n }\n });\n }\n\n if (this.inputArea) {\n const wrapper = this.inputArea.querySelector(`.${this.prefix}-input-wrapper`) as HTMLElement | null;\n if (wrapper) this.setupDropEvents(wrapper);\n }\n\n this.sendBtn?.addEventListener('click', () => {\n this.handleSend();\n });\n\n this.emitter.on('mention-filter', (state: { filtered: MentionItem[]; activeIndex: number }) => {\n this.renderMentionPanel(state.filtered, state.activeIndex);\n });\n this.emitter.on('mention-active-change', (index: number) => {\n const items = this.mentionPanel?.querySelectorAll(`.${this.prefix}-mention-item`);\n items?.forEach((el, i) => {\n el.classList.toggle(`${this.prefix}-mention-item--active`, i === index);\n el.setAttribute('aria-selected', String(i === index));\n });\n });\n this.emitter.on('mention-deactivate', () => {\n this.hideMentionPanel();\n });\n }\n\n private setupDropEvents(wrapper: HTMLElement): void {\n let dragCounter = 0;\n wrapper.addEventListener('dragenter', (event) => {\n event.preventDefault();\n dragCounter++;\n if (this.dropOverlay) this.dropOverlay.style.display = 'flex';\n });\n wrapper.addEventListener('dragleave', (event) => {\n event.preventDefault();\n dragCounter--;\n if (dragCounter <= 0) {\n dragCounter = 0;\n if (this.dropOverlay) this.dropOverlay.style.display = 'none';\n }\n });\n wrapper.addEventListener('dragover', (event) => {\n event.preventDefault();\n });\n wrapper.addEventListener('drop', (event) => {\n event.preventDefault();\n dragCounter = 0;\n if (this.dropOverlay) this.dropOverlay.style.display = 'none';\n const files = Array.from(event.dataTransfer?.files ?? []);\n if (files.length > 0) {\n this.emitter.emit('toolbar-drop', files);\n this.config.onDrop?.(files);\n }\n });\n }\n\n private handleSend(): void {\n const rawContent = this.textareaEl?.value ?? '';\n const content = rawContent.trim();\n if (!content) return;\n\n const mentions = this.mentionEngine.parseMentions(content);\n this.emitter.emit('send', content, mentions);\n this.config.onSend?.(content, mentions);\n\n if (this.config.clearInputOnSend !== false) {\n this.clearInput();\n }\n this.mentionEngine.resetSelected();\n }\n\n private insertMention(member: MentionItem): void {\n if (!this.textareaEl) return;\n const state = this.mentionEngine.getState();\n const text = this.textareaEl.value;\n const pos = this.textareaEl.selectionStart;\n const insertText = this.mentionEngine.getInsertText(member);\n\n const before = text.slice(0, state.triggerPosition);\n const after = text.slice(pos);\n this.textareaEl.value = this.limitInput(before + insertText + after);\n const newPos = Math.min(before.length + insertText.length, this.textareaEl.value.length);\n this.textareaEl.setSelectionRange(newPos, newPos);\n this.textareaEl.focus();\n this.autoResize();\n this.updateSendButtonState();\n this.config.onInputChange?.(this.textareaEl.value);\n }\n\n private insertTextAtCursor(text: string): void {\n if (!this.textareaEl) return;\n const current = this.textareaEl.value;\n const start = this.textareaEl.selectionStart;\n const end = this.textareaEl.selectionEnd;\n this.textareaEl.value = this.limitInput(current.slice(0, start) + text + current.slice(end));\n const nextCursor = Math.min(start + text.length, this.textareaEl.value.length);\n this.textareaEl.setSelectionRange(nextCursor, nextCursor);\n this.autoResize();\n this.updateSendButtonState();\n this.config.onInputChange?.(this.textareaEl.value);\n }\n\n private autoResize(): void {\n if (!this.textareaEl) return;\n this.textareaEl.style.height = 'auto';\n const maxHeight = this.getCssSizeValue('--ldesign-chat-textarea-max-height', 120);\n this.textareaEl.style.height = `${Math.min(this.textareaEl.scrollHeight, maxHeight)}px`;\n }\n\n private updateSendButtonState(): void {\n if (!this.sendBtn) return;\n this.sendBtn.disabled = !this.getInputContent().trim();\n }\n\n private renderLoadMoreButton(): void {\n this.loadMoreEl = this.el('div', `${this.prefix}-load-more`);\n this.loadMoreEl.textContent = this.config.loadMoreText ?? '加载更多';\n this.loadMoreEl.addEventListener('click', () => {\n if (this.loadingMore) return;\n this.setLoadingMore(true);\n this.emitter.emit('load-more');\n Promise.resolve(this.config.onLoadMore?.()).finally(() => {\n this.setLoadingMore(false);\n });\n });\n this.messageListEl.appendChild(this.loadMoreEl);\n }\n\n private renderTimeDivider(timestamp: number): void {\n this.messageListEl.appendChild(this.createTimeDivider(timestamp));\n }\n\n private createTimeDivider(timestamp: number): HTMLElement {\n const divider = this.el('div', `${this.prefix}-time-divider`);\n const span = document.createElement('span');\n span.textContent = this.formatTime(timestamp);\n divider.appendChild(span);\n return divider;\n }\n\n private renderMessageRow(message: ChatMessage): void {\n this.messageListEl.appendChild(this.createMessageRow(message));\n }\n\n private createMessageRow(message: ChatMessage): HTMLElement {\n const p = this.prefix;\n\n if (message.type === 'system') {\n const row = this.el('div', cx(`${p}-message-row`, `${p}-message-row--system`));\n row.dataset.msgId = message.id;\n row.dataset.timestamp = String(message.timestamp);\n const system = this.el('div', `${p}-system-message`);\n system.textContent = message.content ?? '';\n row.appendChild(system);\n return row;\n }\n\n const isOutgoing = message.direction === 'outgoing';\n const row = this.el('div', cx(`${p}-message-row`, isOutgoing && `${p}-message-row--outgoing`));\n row.dataset.msgId = message.id;\n row.dataset.timestamp = String(message.timestamp);\n\n if (this.config.showAvatar !== false) {\n row.appendChild(this.createAvatar(message.sender.nickname, message.sender.avatar));\n }\n\n const body = this.el('div', `${p}-message-body`);\n if (this.config.showNickname !== false && !isOutgoing) {\n const nickname = this.el('div', `${p}-nickname`);\n nickname.textContent = message.sender.nickname;\n body.appendChild(nickname);\n }\n\n body.appendChild(this.createBubble(message, isOutgoing));\n body.appendChild(this.createMessageFooter(message, isOutgoing));\n row.appendChild(body);\n\n row.addEventListener('click', () => {\n this.emitter.emit('message-click', message);\n this.config.onMessageClick?.(message);\n });\n\n return row;\n }\n\n private createAvatar(name: string, avatarUrl?: string): HTMLElement {\n const avatar = this.el('div', `${this.prefix}-avatar`);\n if (avatarUrl) {\n const img = document.createElement('img');\n img.src = avatarUrl;\n img.alt = name;\n avatar.appendChild(img);\n } else {\n avatar.textContent = name[0]?.toUpperCase() ?? '';\n }\n return avatar;\n }\n\n private createMessageFooter(message: ChatMessage, isOutgoing: boolean): HTMLElement {\n const footer = this.el('div', `${this.prefix}-message-footer`);\n if (this.config.showTimestamp !== false) {\n const time = this.el('span', `${this.prefix}-timestamp`);\n time.textContent = this.formatShortTime(message.timestamp);\n footer.appendChild(time);\n }\n if (this.config.showStatus !== false && isOutgoing && message.status) {\n const status = this.el('span', cx(`${this.prefix}-status`, `${this.prefix}-status--${message.status}`));\n status.textContent = STATUS_MAP[message.status] ?? '';\n if (message.status === 'failed') {\n status.addEventListener('click', (event) => {\n event.stopPropagation();\n this.emitter.emit('message-retry', message);\n });\n }\n footer.appendChild(status);\n }\n return footer;\n }\n\n private createBubble(message: ChatMessage, isOutgoing: boolean): HTMLElement {\n const p = this.prefix;\n const dirClass = isOutgoing ? `${p}-bubble--outgoing` : `${p}-bubble--incoming`;\n\n if (message.revoked) {\n const bubble = this.el('div', cx(`${p}-bubble`, dirClass, `${p}-bubble--revoked`));\n bubble.textContent = '消息已撤回';\n return bubble;\n }\n\n switch (message.type) {\n case 'image': {\n const bubble = this.el('div', cx(`${p}-bubble`, dirClass, `${p}-bubble--image`));\n if (message.image) {\n const img = document.createElement('img');\n img.src = message.image.thumbUrl ?? message.image.url;\n img.alt = message.content ?? '';\n if (message.image.width) img.width = Math.min(message.image.width, 240);\n bubble.appendChild(img);\n }\n return bubble;\n }\n\n case 'file': {\n const bubble = this.el('div', cx(`${p}-bubble`, dirClass, `${p}-bubble--file`));\n const icon = this.el('div', `${p}-file-icon`);\n icon.innerHTML = FILE_ICON;\n bubble.appendChild(icon);\n\n const info = this.el('div', `${p}-file-info`);\n const name = this.el('div', `${p}-file-name`);\n name.textContent = message.file?.name ?? 'file';\n info.appendChild(name);\n\n if (message.file?.size) {\n const size = this.el('div', `${p}-file-size`);\n size.textContent = this.formatFileSize(message.file.size);\n info.appendChild(size);\n }\n bubble.appendChild(info);\n return bubble;\n }\n\n case 'custom': {\n const bubble = this.el('div', cx(`${p}-bubble`, dirClass));\n if (message.customHtml) {\n bubble.innerHTML = message.customHtml;\n } else {\n bubble.textContent = message.content ?? '';\n }\n return bubble;\n }\n\n default: {\n const bubble = this.el('div', cx(`${p}-bubble`, dirClass, message.streaming && `${p}-bubble--streaming`));\n bubble.innerHTML = this.renderTextContent(message.content ?? '', message.mentions);\n return bubble;\n }\n }\n }\n\n private renderTextContent(content: string, mentions?: MentionItem[]): string {\n let html = this.escapeHtml(content);\n\n if (mentions?.length) {\n for (const mention of mentions) {\n const tag = `<span class=\"${this.prefix}-mention-tag\" data-mention-id=\"${this.escapeAttr(mention.id)}\">@${this.escapeHtml(mention.name)}</span>`;\n html = html.replace(new RegExp(`@${this.escapeRegex(mention.name)}`, 'g'), tag);\n }\n }\n\n return html.replace(\n /(https?:\\/\\/[^\\s<]+)/g,\n `<a class=\"${this.prefix}-link\" href=\"$1\" target=\"_blank\" rel=\"noopener noreferrer\">$1</a>`,\n );\n }\n\n private renderEmpty(): void {\n if (this.messageListEl.querySelector(`.${this.prefix}-empty`)) return;\n const empty = this.el('div', `${this.prefix}-empty`);\n empty.textContent = '暂无消息';\n this.messageListEl.appendChild(empty);\n }\n\n private removeEmpty(): void {\n this.messageListEl.querySelector(`.${this.prefix}-empty`)?.remove();\n }\n\n private el(tag: string, className: string): HTMLElement {\n const el = document.createElement(tag);\n el.className = className;\n return el;\n }\n\n private getMessageElements(): HTMLElement[] {\n return Array.from(this.messageListEl.querySelectorAll<HTMLElement>(`.${this.prefix}-message-row`));\n }\n\n private formatTime(timestamp: number): string {\n if (this.config.formatTime) return this.config.formatTime(timestamp);\n const date = new Date(timestamp);\n const now = new Date();\n const isToday = date.toDateString() === now.toDateString();\n if (isToday) {\n return date.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' });\n }\n return date.toLocaleDateString('zh-CN', {\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n });\n }\n\n private formatShortTime(timestamp: number): string {\n return new Date(timestamp).toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' });\n }\n\n private formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n }\n\n private limitInput(content: string): string {\n const max = this.config.maxInputLength;\n if (!max || max <= 0) return content;\n return content.slice(0, max);\n }\n\n private getCssSizeValue(name: string, fallback: number): number {\n if (typeof window === 'undefined' || !this.root) return fallback;\n const value = window.getComputedStyle(this.root).getPropertyValue(name).trim();\n const parsed = Number.parseFloat(value);\n return Number.isFinite(parsed) ? parsed : fallback;\n }\n\n private escapeHtml(str: string): string {\n const div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n }\n\n private escapeAttr(str: string): string {\n return str\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\n }\n\n private escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n }\n}\n","/**\n * @file style-manager.ts\n * @description style-manager 模块\n */\n\nimport type { ThemeTokens } from '../theme/tokens';\nimport {\n COMPONENT_CSS_VAR_PREFIX,\n DEFAULT_CLASS_PREFIX,\n cx,\n getStyleElementId,\n normalizeClassPrefix,\n} from '../constants/dom';\n\nconst styleRefs = new Map<string, number>();\n\n/**\n * injectStyles 函数\n * @param tokens - 参数\n * @param prefix - 参数\n * @returns 返回值\n */\n/**\n * injectStyles - inject Styles function\n * @param tokens - 参数说明\n * @param prefix - 参数说明\n * @returns 返回值说明\n */\nexport function injectStyles(tokens: ThemeTokens, prefix: string = DEFAULT_CLASS_PREFIX): void {\n const normalizedPrefix = normalizeClassPrefix(prefix);\n const styleId = getStyleElementId(normalizedPrefix);\n styleRefs.set(styleId, (styleRefs.get(styleId) ?? 0) + 1);\n upsertStyle(styleId, generateCSS(tokens, normalizedPrefix));\n}\n\n/**\n * updateStyles 函数\n * @param tokens - 参数\n * @param prefix - 参数\n * @returns 返回值\n */\n/**\n * updateStyles - update Styles function\n * @param tokens - 参数说明\n * @param prefix - 参数说明\n * @returns 返回值说明\n */\nexport function updateStyles(tokens: ThemeTokens, prefix: string = DEFAULT_CLASS_PREFIX): void {\n const normalizedPrefix = normalizeClassPrefix(prefix);\n const styleId = getStyleElementId(normalizedPrefix);\n upsertStyle(styleId, generateCSS(tokens, normalizedPrefix));\n}\n\n/**\n * removeStyles 函数\n * @param prefix - 参数\n * @returns 返回值\n */\n/**\n * removeStyles - remove Styles function\n * @param prefix - 参数说明\n * @returns 返回值说明\n */\nexport function removeStyles(prefix: string = DEFAULT_CLASS_PREFIX): void {\n const styleId = getStyleElementId(prefix);\n const refs = styleRefs.get(styleId) ?? 0;\n if (refs > 1) {\n styleRefs.set(styleId, refs - 1);\n return;\n }\n\n styleRefs.delete(styleId);\n document.getElementById(styleId)?.remove();\n}\n\n/**\n * cls 函数\n * @param prefix - 参数\n * @param ...parts - 参数\n * @returns 返回值\n */\n/**\n * cls - cls function\n * @param prefix - 参数说明\n * @param ...parts - 参数说明\n * @returns 返回值说明\n */\nexport function cls(prefix: string, ...parts: string[]): string {\n const normalizedPrefix = normalizeClassPrefix(prefix);\n return parts.map((part) => `${normalizedPrefix}-${part}`).join(' ');\n}\n\nexport const clsx = cx;\n\nfunction upsertStyle(styleId: string, cssText: string): void {\n let style = document.getElementById(styleId) as HTMLStyleElement | null;\n if (!style) {\n style = document.createElement('style');\n style.id = styleId;\n style.dataset.ldesignChat = 'true';\n document.head.appendChild(style);\n }\n style.textContent = cssText;\n}\n\nfunction tokenVars(t: ThemeTokens): string {\n const vars: Record<string, string> = {\n bgPrimary: t.bgPrimary,\n bgSecondary: t.bgSecondary,\n bgBubbleOutgoing: t.bgBubbleOutgoing,\n bgBubbleIncoming: t.bgBubbleIncoming,\n bgInput: t.bgInput,\n bgMention: t.bgMention,\n bgMentionHover: t.bgMentionHover,\n bgMentionActive: t.bgMentionActive,\n bgLoadMore: t.bgLoadMore,\n bgSystemMessage: t.bgSystemMessage,\n bgDropOverlay: t.bgDropOverlay,\n bgDangerSoft: t.bgDangerSoft,\n textPrimary: t.textPrimary,\n textSecondary: t.textSecondary,\n textBubbleOutgoing: t.textBubbleOutgoing,\n textBubbleIncoming: t.textBubbleIncoming,\n textMention: t.textMention,\n textMentionTag: t.textMentionTag,\n textTimestamp: t.textTimestamp,\n textSystem: t.textSystem,\n textPlaceholder: t.textPlaceholder,\n borderPrimary: t.borderPrimary,\n borderInput: t.borderInput,\n borderInputFocus: t.borderInputFocus,\n borderMention: t.borderMention,\n colorSending: t.colorSending,\n colorSent: t.colorSent,\n colorDelivered: t.colorDelivered,\n colorRead: t.colorRead,\n colorFailed: t.colorFailed,\n colorLink: t.colorLink,\n shadowPanel: t.shadowPanel,\n shadowMention: t.shadowMention,\n avatarBg: t.avatarBg,\n avatarText: t.avatarText,\n btnPrimaryBg: t.btnPrimaryBg,\n btnPrimaryText: t.btnPrimaryText,\n btnPrimaryHover: t.btnPrimaryHover,\n scrollbarThumb: t.scrollbarThumb,\n scrollbarTrack: t.scrollbarTrack,\n bgToolbar: t.bgToolbar,\n borderToolbar: t.borderToolbar,\n toolbarIconColor: t.toolbarIconColor,\n toolbarIconHover: t.toolbarIconHover,\n toolbarVoiceActive: t.toolbarVoiceActive,\n };\n\n return Object.entries(vars)\n .map(([key, value]) => ` ${COMPONENT_CSS_VAR_PREFIX}-${toKebab(key)}: ${value};`)\n .join('\\n');\n}\n\nfunction sizeVars(): string {\n return `\n ${COMPONENT_CSS_VAR_PREFIX}-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;\n ${COMPONENT_CSS_VAR_PREFIX}-font-size: var(--size-font-base);\n ${COMPONENT_CSS_VAR_PREFIX}-font-size-sm: var(--size-font-sm);\n ${COMPONENT_CSS_VAR_PREFIX}-font-size-xs: var(--size-font-xs);\n ${COMPONENT_CSS_VAR_PREFIX}-font-size-lg: var(--size-font-lg);\n ${COMPONENT_CSS_VAR_PREFIX}-font-weight-regular: var(--size-font-weight-regular);\n ${COMPONENT_CSS_VAR_PREFIX}-font-weight-medium: var(--size-font-weight-medium);\n ${COMPONENT_CSS_VAR_PREFIX}-font-weight-semibold: var(--size-font-weight-semibold);\n ${COMPONENT_CSS_VAR_PREFIX}-line-height: var(--size-line-normal);\n ${COMPONENT_CSS_VAR_PREFIX}-line-height-bubble: var(--size-line-relaxed);\n ${COMPONENT_CSS_VAR_PREFIX}-space-1: var(--size-1);\n ${COMPONENT_CSS_VAR_PREFIX}-space-2: var(--size-2);\n ${COMPONENT_CSS_VAR_PREFIX}-space-3: var(--size-3);\n ${COMPONENT_CSS_VAR_PREFIX}-space-4: var(--size-4);\n ${COMPONENT_CSS_VAR_PREFIX}-space-5: var(--size-5);\n ${COMPONENT_CSS_VAR_PREFIX}-space-6: var(--size-6);\n ${COMPONENT_CSS_VAR_PREFIX}-space-8: var(--size-8);\n ${COMPONENT_CSS_VAR_PREFIX}-avatar-size: var(--size-11);\n ${COMPONENT_CSS_VAR_PREFIX}-mention-avatar-size: var(--size-9);\n ${COMPONENT_CSS_VAR_PREFIX}-toolbar-button-size: var(--size-9);\n ${COMPONENT_CSS_VAR_PREFIX}-input-button-size: var(--size-11);\n ${COMPONENT_CSS_VAR_PREFIX}-file-icon-size: var(--size-12);\n ${COMPONENT_CSS_VAR_PREFIX}-image-max-size: calc(var(--size-13) * 5);\n ${COMPONENT_CSS_VAR_PREFIX}-panel-max-height: calc(var(--size-24) + var(--size-4));\n ${COMPONENT_CSS_VAR_PREFIX}-textarea-min-height: var(--size-11);\n ${COMPONENT_CSS_VAR_PREFIX}-textarea-max-height: calc(var(--size-12) * 3);\n ${COMPONENT_CSS_VAR_PREFIX}-message-max-width: 65%;\n ${COMPONENT_CSS_VAR_PREFIX}-system-message-max-width: 80%;\n ${COMPONENT_CSS_VAR_PREFIX}-file-bubble-min-width: calc(var(--size-24) + var(--size-4));\n ${COMPONENT_CSS_VAR_PREFIX}-border-width: var(--size-border-width-thin);\n ${COMPONENT_CSS_VAR_PREFIX}-border-width-drop: var(--size-border-width-medium);\n ${COMPONENT_CSS_VAR_PREFIX}-radius-xs: var(--size-radius-sm);\n ${COMPONENT_CSS_VAR_PREFIX}-radius-sm: var(--size-radius-md);\n ${COMPONENT_CSS_VAR_PREFIX}-radius-md: var(--size-radius-lg);\n ${COMPONENT_CSS_VAR_PREFIX}-radius-lg: var(--size-radius-xl);\n ${COMPONENT_CSS_VAR_PREFIX}-radius-pill: var(--size-radius-full);\n ${COMPONENT_CSS_VAR_PREFIX}-radius-circle: var(--size-radius-circle);\n ${COMPONENT_CSS_VAR_PREFIX}-transition-fast: var(--size-duration-fast) var(--size-ease-out);\n ${COMPONENT_CSS_VAR_PREFIX}-transition-normal: var(--size-duration-normal) var(--size-ease-out);\n ${COMPONENT_CSS_VAR_PREFIX}-z-overlay: var(--size-z-dropdown);\n ${COMPONENT_CSS_VAR_PREFIX}-z-mention: var(--size-z-popover);\n`;\n}\n\nfunction generateCSS(tokens: ThemeTokens, p: string): string {\n return `\n/* @composy/chat-core styles */\n.${p}-container,\n.${p}-container * {\n box-sizing: border-box;\n}\n\n.${p}-container {\n${tokenVars(tokens)}\n${sizeVars()}\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n position: relative;\n background: ${v('bg-primary')};\n color: ${v('text-primary')};\n font-family: ${v('font-family')};\n font-size: ${v('font-size')};\n line-height: ${v('line-height')};\n border: ${v('border-width')} solid ${v('border-primary')};\n border-radius: ${v('radius-md')};\n box-shadow: ${v('shadow-panel')};\n}\n\n.${p}-message-list {\n flex: 1;\n min-width: 0;\n overflow-y: auto;\n overflow-x: hidden;\n padding: ${v('space-6')};\n scroll-behavior: smooth;\n}\n\n.${p}-message-list::-webkit-scrollbar {\n width: var(--size-3);\n}\n\n.${p}-message-list::-webkit-scrollbar-thumb {\n background: ${v('scrollbar-thumb')};\n border-radius: ${v('radius-pill')};\n}\n\n.${p}-message-list::-webkit-scrollbar-track {\n background: ${v('scrollbar-track')};\n}\n\n.${p}-load-more {\n margin-bottom: ${v('space-5')};\n padding: ${v('space-5')};\n text-align: center;\n color: ${v('color-link')};\n font-size: ${v('font-size-sm')};\n background: ${v('bg-load-more')};\n border-radius: ${v('radius-sm')};\n cursor: pointer;\n user-select: none;\n transition: opacity ${v('transition-fast')}, background ${v('transition-fast')};\n}\n\n.${p}-load-more:hover {\n background: ${v('bg-mention-hover')};\n}\n\n.${p}-load-more--loading {\n cursor: default;\n opacity: .6;\n}\n\n.${p}-time-divider {\n padding: ${v('space-4')} 0;\n color: ${v('text-timestamp')};\n font-size: ${v('font-size-sm')};\n text-align: center;\n user-select: none;\n}\n\n.${p}-time-divider span {\n padding: ${v('space-1')} ${v('space-5')};\n background: ${v('bg-secondary')};\n border-radius: ${v('radius-pill')};\n}\n\n.${p}-message-row {\n display: flex;\n align-items: flex-start;\n gap: ${v('space-4')};\n margin-bottom: ${v('space-5')};\n}\n\n.${p}-message-row--outgoing {\n flex-direction: row-reverse;\n}\n\n.${p}-message-row--system {\n justify-content: center;\n}\n\n.${p}-avatar {\n display: flex;\n align-items: center;\n justify-content: center;\n width: ${v('avatar-size')};\n height: ${v('avatar-size')};\n overflow: hidden;\n flex-shrink: 0;\n color: ${v('avatar-text')};\n background: ${v('avatar-bg')};\n border-radius: ${v('radius-circle')};\n font-size: ${v('font-size')};\n font-weight: ${v('font-weight-semibold')};\n}\n\n.${p}-avatar img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.${p}-message-body {\n display: flex;\n flex-direction: column;\n max-width: ${v('message-max-width')};\n min-width: 0;\n}\n\n.${p}-message-row--outgoing .${p}-message-body {\n align-items: flex-end;\n}\n\n.${p}-nickname {\n margin-bottom: ${v('space-2')};\n padding: 0 ${v('space-2')};\n color: ${v('text-secondary')};\n font-size: ${v('font-size-sm')};\n}\n\n.${p}-bubble {\n position: relative;\n max-width: 100%;\n padding: ${v('space-5')} ${v('space-6')};\n border-radius: ${v('radius-lg')};\n word-break: break-word;\n overflow-wrap: unknownwhere;\n white-space: pre-wrap;\n line-height: ${v('line-height-bubble')};\n}\n\n.${p}-bubble--incoming {\n color: ${v('text-bubble-incoming')};\n background: ${v('bg-bubble-incoming')};\n border-top-left-radius: ${v('radius-xs')};\n}\n\n.${p}-bubble--outgoing {\n color: ${v('text-bubble-outgoing')};\n background: ${v('bg-bubble-outgoing')};\n border-top-right-radius: ${v('radius-xs')};\n}\n\n.${p}-bubble--image {\n padding: ${v('space-2')};\n background: unset;\n}\n\n.${p}-bubble--image img {\n display: block;\n max-width: ${v('image-max-size')};\n max-height: ${v('image-max-size')};\n border-radius: ${v('radius-md')};\n cursor: pointer;\n}\n\n.${p}-bubble--file {\n display: flex;\n align-items: center;\n gap: ${v('space-5')};\n min-width: ${v('file-bubble-min-width')};\n}\n\n.${p}-file-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: ${v('file-icon-size')};\n height: ${v('file-icon-size')};\n flex-shrink: 0;\n background: ${v('bg-secondary')};\n border-radius: ${v('radius-sm')};\n font-size: ${v('font-size-lg')};\n}\n\n.${p}-file-info {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n}\n\n.${p}-file-name {\n overflow: hidden;\n font-size: ${v('font-size')};\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.${p}-file-size {\n margin-top: ${v('space-1')};\n color: ${v('text-secondary')};\n font-size: ${v('font-size-sm')};\n}\n\n.${p}-system-message {\n max-width: ${v('system-message-max-width')};\n padding: ${v('space-2')} ${v('space-6')};\n color: ${v('text-system')};\n background: ${v('bg-system-message')};\n border-radius: ${v('radius-pill')};\n font-size: ${v('font-size-sm')};\n text-align: center;\n}\n\n.${p}-message-footer {\n display: flex;\n align-items: center;\n gap: ${v('space-3')};\n margin-top: ${v('space-1')};\n padding: 0 ${v('space-2')};\n}\n\n.${p}-message-row--outgoing .${p}-message-footer {\n flex-direction: row-reverse;\n}\n\n.${p}-timestamp,\n.${p}-status {\n font-size: ${v('font-size-xs')};\n}\n\n.${p}-timestamp {\n color: ${v('text-timestamp')};\n}\n\n.${p}-status--sending { color: ${v('color-sending')}; }\n.${p}-status--sent { color: ${v('color-sent')}; }\n.${p}-status--delivered { color: ${v('color-delivered')}; }\n.${p}-status--read { color: ${v('color-read')}; }\n.${p}-status--failed {\n color: ${v('color-failed')};\n cursor: pointer;\n}\n\n.${p}-mention-tag,\n.${p}-link {\n color: ${v('text-mention-tag')};\n font-weight: ${v('font-weight-medium')};\n}\n\n.${p}-mention-tag {\n cursor: pointer;\n}\n\n.${p}-mention-tag:hover,\n.${p}-link:hover {\n text-decoration: underline;\n}\n\n.${p}-input-area {\n display: flex;\n align-items: flex-end;\n gap: ${v('space-4')};\n position: relative;\n padding: ${v('space-5')} ${v('space-6')};\n border-top: ${v('border-width')} solid ${v('border-primary')};\n background: ${v('bg-input')};\n}\n\n.${p}-input-wrapper {\n flex: 1;\n min-width: 0;\n position: relative;\n}\n\n.${p}-textarea {\n width: 100%;\n min-height: ${v('textarea-min-height')};\n max-height: ${v('textarea-max-height')};\n padding: ${v('space-4')} ${v('space-5')};\n overflow-y: auto;\n resize: none;\n outline: none;\n color: ${v('text-primary')};\n background: ${v('bg-primary')};\n border: ${v('border-width')} solid ${v('border-input')};\n border-radius: ${v('radius-md')};\n font-family: inherit;\n font-size: ${v('font-size')};\n line-height: ${v('line-height')};\n transition: border-color ${v('transition-fast')}, box-shadow ${v('transition-fast')};\n}\n\n.${p}-textarea:focus {\n border-color: ${v('border-input-focus')};\n box-shadow: 0 0 0 ${v('border-width-drop')} ${v('bg-drop-overlay')};\n}\n\n.${p}-textarea::placeholder {\n color: ${v('text-placeholder')};\n}\n\n.${p}-send-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: ${v('input-button-size')};\n height: ${v('input-button-size')};\n flex-shrink: 0;\n color: ${v('btn-primary-text')};\n background: ${v('btn-primary-bg')};\n border: 0;\n border-radius: ${v('radius-md')};\n cursor: pointer;\n transition: background ${v('transition-fast')}, opacity ${v('transition-fast')};\n}\n\n.${p}-send-btn:hover {\n background: ${v('btn-primary-hover')};\n}\n\n.${p}-send-btn:disabled {\n cursor: default;\n opacity: .5;\n}\n\n.${p}-send-btn svg {\n width: var(--size-7);\n height: var(--size-7);\n}\n\n.${p}-mention-panel {\n position: absolute;\n left: 0;\n right: 0;\n bottom: 100%;\n z-index: ${v('z-mention')};\n max-height: ${v('panel-max-height')};\n margin-bottom: ${v('space-2')};\n overflow-y: auto;\n background: ${v('bg-mention')};\n border: ${v('border-width')} solid ${v('border-mention')};\n border-radius: ${v('radius-md')};\n box-shadow: ${v('shadow-mention')};\n}\n\n.${p}-mention-item {\n display: flex;\n align-items: center;\n gap: ${v('space-4')};\n padding: ${v('space-4')} ${v('space-5')};\n color: ${v('text-mention')};\n cursor: pointer;\n transition: background ${v('transition-fast')};\n}\n\n.${p}-mention-item:hover {\n background: ${v('bg-mention-hover')};\n}\n\n.${p}-mention-item--active {\n background: ${v('bg-mention-active')};\n}\n\n.${p}-mention-item-avatar {\n display: flex;\n align-items: center;\n justify-content: center;\n width: ${v('mention-avatar-size')};\n height: ${v('mention-avatar-size')};\n flex-shrink: 0;\n overflow: hidden;\n color: ${v('avatar-text')};\n background: ${v('avatar-bg')};\n border-radius: ${v('radius-circle')};\n font-size: ${v('font-size-sm')};\n font-weight: ${v('font-weight-semibold')};\n}\n\n.${p}-mention-item-avatar img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.${p}-mention-item-name {\n font-size: ${v('font-size')};\n}\n\n.${p}-empty {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: ${v('text-secondary')};\n font-size: ${v('font-size')};\n}\n\n.${p}-toolbar {\n display: flex;\n align-items: center;\n gap: ${v('space-1')};\n padding: ${v('space-3')} ${v('space-4')};\n background: ${v('bg-toolbar')};\n border-bottom: ${v('border-width')} solid ${v('border-toolbar')};\n border-radius: ${v('radius-md')} ${v('radius-md')} 0 0;\n}\n\n.${p}-toolbar-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: ${v('toolbar-button-size')};\n height: ${v('toolbar-button-size')};\n flex-shrink: 0;\n padding: 0;\n color: ${v('toolbar-icon-color')};\n background: unset;\n border: 0;\n border-radius: ${v('radius-sm')};\n cursor: pointer;\n transition: background ${v('transition-fast')}, color ${v('transition-fast')};\n}\n\n.${p}-toolbar-btn svg {\n width: var(--size-6);\n height: var(--size-6);\n}\n\n.${p}-toolbar-btn:hover {\n color: ${v('toolbar-icon-hover')};\n background: ${v('bg-drop-overlay')};\n}\n\n.${p}-toolbar-btn--active {\n color: ${v('toolbar-voice-active')};\n background: ${v('bg-danger-soft')};\n}\n\n.${p}-toolbar-btn--active:hover {\n color: ${v('toolbar-voice-active')};\n background: ${v('bg-danger-soft')};\n}\n\n.${p}-drop-overlay {\n position: absolute;\n inset: 0;\n z-index: ${v('z-overlay')};\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n background: ${v('bg-drop-overlay')};\n border: ${v('border-width-drop')} dashed ${v('toolbar-icon-hover')};\n border-radius: ${v('radius-md')};\n}\n\n.${p}-drop-overlay span {\n color: ${v('toolbar-icon-hover')};\n font-size: ${v('font-size-sm')};\n font-weight: ${v('font-weight-medium')};\n}\n\n@keyframes ${p}-blink {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0; }\n}\n\n.${p}-bubble--streaming::after {\n content: '';\n display: inline-block;\n width: ${v('border-width-drop')};\n height: 1em;\n margin-left: ${v('space-1')};\n vertical-align: text-bottom;\n background: currentColor;\n animation: ${p}-blink 800ms infinite;\n}\n`;\n}\n\nfunction v(name: string): string {\n return `var(${COMPONENT_CSS_VAR_PREFIX}-${name})`;\n}\n\nfunction toKebab(key: string): string {\n return key.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);\n}\n","/**\n * @composy/chat-core - 即时通讯/IM 组件核心库\n *\n * 提供聊天气泡、消息列表、@提及、多消息类型(文本/图片/文件/系统消息/自定义)、\n * 消息状态管理(发送中/已发送/已送达/已读/失败)、亮暗主题切换等能力。\n * 框架无关的核心实现,配合 Vue/React 适配层使用。\n *\n * @packageDocumentation\n * @module @composy/chat-core\n */\n\nimport type { ChatConfig, ChatInstance, ChatMessage, ThemeMode, MentionItem, ToolbarConfig } from './types';\nimport type { ThemeTokens } from './theme/tokens';\nimport { EventEmitter } from './core/event-emitter';\nimport { ChatManager } from './core/chat-manager';\nimport { MentionEngine } from './core/mention-engine';\nimport { ThemeManager } from './theme/theme-manager';\nimport { DOMRenderer } from './renderer/dom-renderer';\nimport { injectStyles, updateStyles, removeStyles } from './renderer/style-manager';\nimport { DEFAULT_CLASS_PREFIX, normalizeClassPrefix } from './constants/dom';\n\nexport const version = '0.1.0';\n\n// Types\nexport * from './types';\n\n// Core\nexport { EventEmitter } from './core/event-emitter';\nexport { ChatManager } from './core/chat-manager';\nexport { MentionEngine } from './core/mention-engine';\nexport type { MentionState } from './core/mention-engine';\n\n// Theme\nexport { ThemeManager } from './theme/theme-manager';\nexport type { ThemeTokens } from './theme/tokens';\nexport { lightTokens, darkTokens } from './theme/tokens';\n\n// Renderer\nexport { DOMRenderer } from './renderer/dom-renderer';\nexport { injectStyles, updateStyles, removeStyles, cls, clsx } from './renderer/style-manager';\nexport {\n DEFAULT_CLASS_PREFIX,\n COMPONENT_CSS_VAR_PREFIX,\n STYLE_ELEMENT_ID,\n getStyleElementId,\n normalizeClassPrefix,\n cx,\n} from './constants/dom';\n\n/**\n * 创建聊天实例\n */\nexport function createChat(config: ChatConfig): ChatInstance {\n // 解析容器\n const container =\n typeof config.container === 'string'\n ? document.querySelector<HTMLElement>(config.container)\n : config.container;\n\n if (!container) {\n throw new Error(`[Chat] Container not found: ${config.container}`);\n }\n\n const prefix = normalizeClassPrefix(config.classPrefix ?? DEFAULT_CLASS_PREFIX);\n const normalizedConfig = {\n ...config,\n classPrefix: prefix,\n };\n const emitter = new EventEmitter();\n const chatManager = new ChatManager(emitter, normalizedConfig.messages);\n const mentionEngine = new MentionEngine(emitter, normalizedConfig.mentionMembers);\n const themeManager = new ThemeManager(emitter, normalizedConfig.theme ?? 'light');\n const renderer = new DOMRenderer(container, normalizedConfig, emitter, mentionEngine);\n\n // 注入样式\n injectStyles(themeManager.getTokens(), prefix);\n\n // 初始化渲染\n renderer.init();\n renderer.renderMessages(chatManager.getMessages());\n\n // 初始滚动到底部\n requestAnimationFrame(() => {\n renderer.scrollToBottom(false);\n });\n\n // 监听主题变化\n emitter.on('theme-change', (_resolved: string, tokens: ThemeTokens) => {\n updateStyles(tokens, prefix);\n });\n\n // 监听消息变化\n emitter.on('message-added', (message: ChatMessage) => {\n renderer.appendMessage(message);\n requestAnimationFrame(() => {\n renderer.scrollToBottom(true);\n });\n });\n\n emitter.on('messages-prepended', (messages: ChatMessage[]) => {\n renderer.prependMessages(messages);\n });\n\n emitter.on('message-updated', (message: ChatMessage) => {\n renderer.updateMessage(message.id, message);\n });\n\n emitter.on('message-removed', (message: ChatMessage) => {\n renderer.removeMessage(message.id);\n });\n\n // 流式消息内容追加\n emitter.on('message-content-appended', (id: string, content: string) => {\n renderer.updateMessageContent(id, content);\n requestAnimationFrame(() => {\n renderer.scrollToBottom(false);\n });\n });\n\n // 创建实例\n const instance: ChatInstance = {\n addMessage(message: ChatMessage) {\n chatManager.addMessage(message);\n },\n\n prependMessages(messages: ChatMessage[]) {\n chatManager.prependMessages(messages);\n },\n\n updateMessage(id: string, updates: Partial<ChatMessage>) {\n chatManager.updateMessage(id, updates);\n },\n\n removeMessage(id: string) {\n chatManager.removeMessage(id);\n },\n\n setMessages(messages: ChatMessage[]) {\n chatManager.setMessages(messages);\n renderer.renderMessages(chatManager.getMessages());\n requestAnimationFrame(() => {\n renderer.scrollToBottom(false);\n });\n },\n\n clearMessages() {\n chatManager.clearMessages();\n renderer.renderMessages([]);\n },\n\n scrollToBottom(smooth = true) {\n renderer.scrollToBottom(smooth);\n },\n\n setTheme(theme: ThemeMode) {\n themeManager.setTheme(theme);\n },\n\n setMentionMembers(members: MentionItem[]) {\n mentionEngine.setMembers(members);\n },\n\n setLoadingMore(loading: boolean) {\n renderer.setLoadingMore(loading);\n },\n\n focusInput() {\n renderer.focusInput();\n },\n\n setInputContent(content: string) {\n renderer.setInputContent(content);\n },\n\n getInputContent() {\n return renderer.getInputContent();\n },\n\n clearInput() {\n renderer.clearInput();\n },\n\n isAtBottom(threshold?: number) {\n return renderer.isAtBottom(threshold);\n },\n\n on(event: string, handler: (...args: unknown[]) => void) {\n return emitter.on(event, handler);\n },\n\n getMessages() {\n return chatManager.getMessages();\n },\n\n getMessage(id: string) {\n return chatManager.getMessage(id);\n },\n\n appendMessageContent(id: string, chunk: string) {\n chatManager.appendMessageContent(id, chunk);\n },\n\n finishStreaming(id: string) {\n chatManager.finishStreaming(id);\n },\n\n destroy() {\n themeManager.destroy();\n renderer.destroy();\n emitter.removeAll();\n removeStyles(prefix);\n },\n };\n\n return instance;\n}\n"],"mappings":"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"}