@ryanhe919/lumen-ui 0.2.2 → 0.3.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 (112) hide show
  1. package/dist/{LMBadge-OEGi87jW.js → LMBadge-BBDOGTps.js} +3 -3
  2. package/dist/{LMBadge-OEGi87jW.js.map → LMBadge-BBDOGTps.js.map} +1 -1
  3. package/dist/{LMBadge-1rGc3lqC.cjs → LMBadge-D95iccla.cjs} +3 -3
  4. package/dist/{LMBadge-1rGc3lqC.cjs.map → LMBadge-D95iccla.cjs.map} +1 -1
  5. package/dist/{LMCard-Sulq0Yjh.js → LMCard-D7ABNC95.js} +2 -2
  6. package/dist/{LMCard-Sulq0Yjh.js.map → LMCard-D7ABNC95.js.map} +1 -1
  7. package/dist/{LMCard-C48UclOk.cjs → LMCard-D_K051f2.cjs} +2 -2
  8. package/dist/{LMCard-C48UclOk.cjs.map → LMCard-D_K051f2.cjs.map} +1 -1
  9. package/dist/{LMDatePicker-BlKctoyr.cjs → LMDatePicker-BlUwN4On.cjs} +12 -12
  10. package/dist/LMDatePicker-BlUwN4On.cjs.map +1 -0
  11. package/dist/{LMDatePicker-CXiYSome.js → LMDatePicker-DSv28BFH.js} +12 -12
  12. package/dist/LMDatePicker-DSv28BFH.js.map +1 -0
  13. package/dist/{LMDrawer-BcVtcYCN.cjs → LMDrawer--lFV_a3m.cjs} +3 -3
  14. package/dist/{LMDrawer-BcVtcYCN.cjs.map → LMDrawer--lFV_a3m.cjs.map} +1 -1
  15. package/dist/{LMDrawer-DcPqwiuo.js → LMDrawer-DJ5ugeZR.js} +3 -3
  16. package/dist/{LMDrawer-DcPqwiuo.js.map → LMDrawer-DJ5ugeZR.js.map} +1 -1
  17. package/dist/{LMStatCard-4mDqhlHt.js → LMStatCard-D5HV9r6d.js} +4 -4
  18. package/dist/{LMStatCard-4mDqhlHt.js.map → LMStatCard-D5HV9r6d.js.map} +1 -1
  19. package/dist/{LMStatCard-Du5Mti-p.cjs → LMStatCard-MXs9Z0qH.cjs} +4 -4
  20. package/dist/{LMStatCard-Du5Mti-p.cjs.map → LMStatCard-MXs9Z0qH.cjs.map} +1 -1
  21. package/dist/{LMSwitch-CVFdgSPh.js → LMSwitch-CP1_nrfU.js} +2 -2
  22. package/dist/LMSwitch-CP1_nrfU.js.map +1 -0
  23. package/dist/{LMSwitch-CKnrY30F.cjs → LMSwitch-DYoSH6wE.cjs} +2 -2
  24. package/dist/LMSwitch-DYoSH6wE.cjs.map +1 -0
  25. package/dist/{LMTabs-DZFAU58t.js → LMTabs-D5n9lB8X.js} +3 -3
  26. package/dist/{LMTabs-DZFAU58t.js.map → LMTabs-D5n9lB8X.js.map} +1 -1
  27. package/dist/{LMTabs-DCVaqbrn.cjs → LMTabs-NPmOzPat.cjs} +3 -3
  28. package/dist/{LMTabs-DCVaqbrn.cjs.map → LMTabs-NPmOzPat.cjs.map} +1 -1
  29. package/dist/{LMUpload-B_GA4O8W.js → LMUpload-BwXoxIfE.js} +5 -5
  30. package/dist/LMUpload-BwXoxIfE.js.map +1 -0
  31. package/dist/{LMUpload-BpISVQGz.cjs → LMUpload-CJopkWc6.cjs} +5 -5
  32. package/dist/LMUpload-CJopkWc6.cjs.map +1 -0
  33. package/dist/components/Chat/LMChatBubble/LMChatBubble.d.ts +28 -0
  34. package/dist/components/Chat/LMChatBubble/LMChatBubble.d.ts.map +1 -0
  35. package/dist/components/Chat/LMChatBubble/LMChatBubble.stories.d.ts +25 -0
  36. package/dist/components/Chat/LMChatBubble/LMChatBubble.stories.d.ts.map +1 -0
  37. package/dist/components/Chat/LMChatBubble/index.d.ts +3 -0
  38. package/dist/components/Chat/LMChatBubble/index.d.ts.map +1 -0
  39. package/dist/components/Chat/LMChatContainer/LMChatContainer.d.ts +85 -0
  40. package/dist/components/Chat/LMChatContainer/LMChatContainer.d.ts.map +1 -0
  41. package/dist/components/Chat/LMChatContainer/LMChatContainer.stories.d.ts +23 -0
  42. package/dist/components/Chat/LMChatContainer/LMChatContainer.stories.d.ts.map +1 -0
  43. package/dist/components/Chat/LMChatContainer/index.d.ts +3 -0
  44. package/dist/components/Chat/LMChatContainer/index.d.ts.map +1 -0
  45. package/dist/components/Chat/LMChatInput/LMChatInput.d.ts +55 -0
  46. package/dist/components/Chat/LMChatInput/LMChatInput.d.ts.map +1 -0
  47. package/dist/components/Chat/LMChatInput/LMChatInput.stories.d.ts +27 -0
  48. package/dist/components/Chat/LMChatInput/LMChatInput.stories.d.ts.map +1 -0
  49. package/dist/components/Chat/LMChatInput/index.d.ts +3 -0
  50. package/dist/components/Chat/LMChatInput/index.d.ts.map +1 -0
  51. package/dist/components/Chat/LMChatList/LMChatList.d.ts +60 -0
  52. package/dist/components/Chat/LMChatList/LMChatList.d.ts.map +1 -0
  53. package/dist/components/Chat/LMChatList/LMChatList.stories.d.ts +21 -0
  54. package/dist/components/Chat/LMChatList/LMChatList.stories.d.ts.map +1 -0
  55. package/dist/components/Chat/LMChatList/index.d.ts +3 -0
  56. package/dist/components/Chat/LMChatList/index.d.ts.map +1 -0
  57. package/dist/components/Chat/LMChatMessage/LMChatMessage.d.ts +56 -0
  58. package/dist/components/Chat/LMChatMessage/LMChatMessage.d.ts.map +1 -0
  59. package/dist/components/Chat/LMChatMessage/LMChatMessage.stories.d.ts +27 -0
  60. package/dist/components/Chat/LMChatMessage/LMChatMessage.stories.d.ts.map +1 -0
  61. package/dist/components/Chat/LMChatMessage/index.d.ts +3 -0
  62. package/dist/components/Chat/LMChatMessage/index.d.ts.map +1 -0
  63. package/dist/components/Chat/LMCodeBlock/LMCodeBlock.d.ts +32 -0
  64. package/dist/components/Chat/LMCodeBlock/LMCodeBlock.d.ts.map +1 -0
  65. package/dist/components/Chat/LMCodeBlock/LMCodeBlock.stories.d.ts +27 -0
  66. package/dist/components/Chat/LMCodeBlock/LMCodeBlock.stories.d.ts.map +1 -0
  67. package/dist/components/Chat/LMCodeBlock/index.d.ts +3 -0
  68. package/dist/components/Chat/LMCodeBlock/index.d.ts.map +1 -0
  69. package/dist/components/Chat/LMMarkdownRenderer/LMMarkdownRenderer.d.ts +24 -0
  70. package/dist/components/Chat/LMMarkdownRenderer/LMMarkdownRenderer.d.ts.map +1 -0
  71. package/dist/components/Chat/LMMarkdownRenderer/LMMarkdownRenderer.stories.d.ts +23 -0
  72. package/dist/components/Chat/LMMarkdownRenderer/LMMarkdownRenderer.stories.d.ts.map +1 -0
  73. package/dist/components/Chat/LMMarkdownRenderer/index.d.ts +3 -0
  74. package/dist/components/Chat/LMMarkdownRenderer/index.d.ts.map +1 -0
  75. package/dist/components/Chat/LMTypingIndicator/LMTypingIndicator.d.ts +21 -0
  76. package/dist/components/Chat/LMTypingIndicator/LMTypingIndicator.d.ts.map +1 -0
  77. package/dist/components/Chat/LMTypingIndicator/LMTypingIndicator.stories.d.ts +25 -0
  78. package/dist/components/Chat/LMTypingIndicator/LMTypingIndicator.stories.d.ts.map +1 -0
  79. package/dist/components/Chat/LMTypingIndicator/index.d.ts +3 -0
  80. package/dist/components/Chat/LMTypingIndicator/index.d.ts.map +1 -0
  81. package/dist/components/Chat/index.d.ts +9 -0
  82. package/dist/components/Chat/index.d.ts.map +1 -0
  83. package/dist/components/badge/index.cjs +1 -1
  84. package/dist/components/badge/index.js +1 -1
  85. package/dist/components/card/index.cjs +1 -1
  86. package/dist/components/card/index.js +1 -1
  87. package/dist/components/date-picker/index.cjs +1 -1
  88. package/dist/components/date-picker/index.js +1 -1
  89. package/dist/components/drawer/index.cjs +1 -1
  90. package/dist/components/drawer/index.js +1 -1
  91. package/dist/components/stat-card/index.cjs +1 -1
  92. package/dist/components/stat-card/index.js +1 -1
  93. package/dist/components/switch/index.cjs +1 -1
  94. package/dist/components/switch/index.js +1 -1
  95. package/dist/components/tabs/index.cjs +1 -1
  96. package/dist/components/tabs/index.js +1 -1
  97. package/dist/components/upload/index.cjs +1 -1
  98. package/dist/components/upload/index.js +1 -1
  99. package/dist/index.cjs +2017 -8
  100. package/dist/index.cjs.map +1 -1
  101. package/dist/index.d.ts +1 -0
  102. package/dist/index.d.ts.map +1 -1
  103. package/dist/index.js +2023 -13
  104. package/dist/index.js.map +1 -1
  105. package/dist/style.css +254 -2
  106. package/package.json +1 -1
  107. package/dist/LMDatePicker-BlKctoyr.cjs.map +0 -1
  108. package/dist/LMDatePicker-CXiYSome.js.map +0 -1
  109. package/dist/LMSwitch-CKnrY30F.cjs.map +0 -1
  110. package/dist/LMSwitch-CVFdgSPh.js.map +0 -1
  111. package/dist/LMUpload-B_GA4O8W.js.map +0 -1
  112. package/dist/LMUpload-BpISVQGz.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/utils/cn.ts"],"sourcesContent":["/**\n * Utility for merging class names\n * Simple implementation without external dependencies\n */\n\ntype ClassValue = string | undefined | null | false | ClassValue[]\n\nexport function cn(...inputs: ClassValue[]): string {\n return inputs\n .flat()\n .filter((x): x is string => typeof x === 'string' && x.length > 0)\n .join(' ')\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOO,SAAS,MAAM,QAA8B;AAClD,SAAO,OACJ,KAAA,EACA,OAAO,CAAC,MAAmB,OAAO,MAAM,YAAY,EAAE,SAAS,CAAC,EAChE,KAAK,GAAG;AACb;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/components/Chat/LMChatInput/LMChatInput.tsx","../src/components/Chat/LMChatBubble/LMChatBubble.tsx","../src/components/Chat/LMChatMessage/LMChatMessage.tsx","../src/components/Chat/LMCodeBlock/LMCodeBlock.tsx","../src/components/Chat/LMMarkdownRenderer/LMMarkdownRenderer.tsx","../src/components/Chat/LMTypingIndicator/LMTypingIndicator.tsx","../src/components/Chat/LMChatList/LMChatList.tsx","../src/components/Chat/LMChatContainer/LMChatContainer.tsx","../src/utils/cn.ts"],"sourcesContent":["import React, { memo, useRef, useCallback, useState, useEffect } from 'react'\nimport type { ComponentSize } from '../../../utils/componentSizes'\nimport { clampComponentSize, COMPONENT_SIZE_ORDER, SIZE_TEXT_CLASSES } from '../../../utils/componentSizes'\n\n/** 聊天输入框主题样式 */\nconst chatInputThemeStyles = `\n :root, [data-theme=\"light\"] {\n --lm-chat-input-bg: rgba(255, 255, 255, 0.85);\n --lm-chat-input-bg-focus: rgba(255, 255, 255, 0.98);\n --lm-chat-input-border: rgba(0, 0, 0, 0.06);\n --lm-chat-input-border-focus: rgba(0, 0, 0, 0.12);\n --lm-chat-input-shadow: 0 2px 12px rgba(0, 0, 0, 0.03), 0 1px 2px rgba(0, 0, 0, 0.02);\n --lm-chat-input-shadow-focus: 0 4px 24px rgba(0, 0, 0, 0.08), 0 1px 3px rgba(0, 0, 0, 0.04);\n }\n [data-theme=\"dark\"] {\n --lm-chat-input-bg: rgba(30, 41, 59, 0.85);\n --lm-chat-input-bg-focus: rgba(30, 41, 59, 0.98);\n --lm-chat-input-border: rgba(255, 255, 255, 0.08);\n --lm-chat-input-border-focus: rgba(255, 255, 255, 0.15);\n --lm-chat-input-shadow: 0 2px 12px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.1);\n --lm-chat-input-shadow-focus: 0 4px 24px rgba(0, 0, 0, 0.3), 0 1px 3px rgba(0, 0, 0, 0.15);\n }\n`\n\nexport interface LMChatInputProps {\n /** 输入值 */\n value?: string\n /** 值变化回调 */\n onChange?: (value: string) => void\n /** 发送消息回调 */\n onSend?: (value: string) => void\n /** 占位符文本 */\n placeholder?: string\n /** 尺寸 */\n size?: ComponentSize\n /** 是否禁用 */\n disabled?: boolean\n /** 是否正在发送(加载状态) */\n sending?: boolean\n /** 最大字符数 */\n maxLength?: number\n /** 显示字符计数 */\n showCount?: boolean\n /** 最大高度 */\n maxRows?: number\n /** 自定义类名 */\n className?: string\n /** 是否自动聚焦 */\n autoFocus?: boolean\n /** 发送按钮文本 */\n sendButtonText?: string\n /** 是否显示发送按钮 */\n showSendButton?: boolean\n /** 右侧自定义内容(发送按钮之前) */\n rightSlot?: React.ReactNode\n /** 底部工具栏 */\n toolbar?: React.ReactNode\n /** 是否按 Enter 发送(Shift+Enter 换行) */\n enterToSend?: boolean\n /** 停止生成回调(显示停止按钮) */\n onStop?: () => void\n /** 是否正在生成 */\n isGenerating?: boolean\n}\n\n/** 工具栏按钮组件 */\nexport interface ToolbarButtonProps {\n icon: React.ReactNode\n label?: string\n onClick?: () => void\n disabled?: boolean\n active?: boolean\n}\n\nexport const ToolbarButton: React.FC<ToolbarButtonProps> = ({\n icon,\n label,\n onClick,\n disabled = false,\n active = false,\n}) => (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n className={`\n flex items-center gap-1 px-2 py-1 rounded-md cursor-pointer\n transition-all duration-150\n disabled:opacity-40 disabled:cursor-not-allowed\n hover:bg-(--lm-bg-hover) active:scale-95\n `.trim().replace(/\\s+/g, ' ')}\n style={{\n backgroundColor: active ? 'var(--lm-primary-50)' : 'transparent',\n color: active ? 'var(--lm-primary-600)' : 'var(--lm-text-tertiary)',\n }}\n title={label}\n >\n <span className=\"w-4 h-4 flex items-center justify-center\">{icon}</span>\n {label && <span className=\"text-xs font-medium\">{label}</span>}\n </button>\n)\n\n/** 发送图标 - 更现代的箭头设计 */\nconst SendIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M5 12h14\" />\n <path d=\"M12 5l7 7-7 7\" />\n </svg>\n)\n\n/** 停止图标 - 更圆润的设计 */\nconst StopIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n >\n <rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"3\" />\n </svg>\n)\n\n/** 加载图标 - 更流畅的动画 */\nconst LoadingIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg\n className={className}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeOpacity=\"0.2\"\n />\n <path\n d=\"M12 2C6.5 2 2 6.5 2 12\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n >\n <animateTransform\n attributeName=\"transform\"\n type=\"rotate\"\n from=\"0 12 12\"\n to=\"360 12 12\"\n dur=\"0.8s\"\n repeatCount=\"indefinite\"\n />\n </path>\n </svg>\n)\n\n/** 尺寸配置 */\nconst SIZE_CONFIG: Record<ComponentSize, {\n minHeight: string\n padding: string\n buttonSize: string\n iconSize: string\n gap: string\n sendButtonSize: string\n sendIconSize: string\n}> = {\n xs: { minHeight: '28px', padding: 'px-3 py-2', buttonSize: 'w-6 h-6', iconSize: 'w-3 h-3', gap: 'gap-2', sendButtonSize: 'w-6 h-6', sendIconSize: 'w-3 h-3' },\n sm: { minHeight: '32px', padding: 'px-3.5 py-2.5', buttonSize: 'w-7 h-7', iconSize: 'w-3.5 h-3.5', gap: 'gap-2.5', sendButtonSize: 'w-7 h-7', sendIconSize: 'w-3.5 h-3.5' },\n md: { minHeight: '36px', padding: 'px-4 py-3', buttonSize: 'w-8 h-8', iconSize: 'w-4 h-4', gap: 'gap-3', sendButtonSize: 'w-8 h-8', sendIconSize: 'w-4 h-4' },\n lg: { minHeight: '44px', padding: 'px-5 py-3.5', buttonSize: 'w-9 h-9', iconSize: 'w-4.5 h-4.5', gap: 'gap-3', sendButtonSize: 'w-9 h-9', sendIconSize: 'w-4.5 h-4.5' },\n xl: { minHeight: '52px', padding: 'px-5 py-4', buttonSize: 'w-10 h-10', iconSize: 'w-5 h-5', gap: 'gap-4', sendButtonSize: 'w-10 h-10', sendIconSize: 'w-5 h-5' },\n '2xl': { minHeight: '60px', padding: 'px-6 py-4.5', buttonSize: 'w-11 h-11', iconSize: 'w-5.5 h-5.5', gap: 'gap-4', sendButtonSize: 'w-11 h-11', sendIconSize: 'w-5.5 h-5.5' },\n}\n\nconst LMChatInput: React.FC<LMChatInputProps> = ({\n value = '',\n onChange,\n onSend,\n placeholder = '输入消息...',\n size = 'md',\n disabled = false,\n sending = false,\n maxLength,\n showCount = false,\n maxRows = 6,\n className = '',\n autoFocus = false,\n sendButtonText,\n showSendButton = true,\n rightSlot,\n toolbar,\n enterToSend = true,\n onStop,\n isGenerating = false,\n}) => {\n const textareaRef = useRef<HTMLTextAreaElement>(null)\n const [isFocused, setIsFocused] = useState(false)\n const [internalValue, setInternalValue] = useState(value)\n\n const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER)\n const config = SIZE_CONFIG[resolvedSize]\n\n // 同步外部 value\n useEffect(() => {\n setInternalValue(value)\n }, [value])\n\n // 自动调整高度\n const adjustHeight = useCallback(() => {\n const textarea = textareaRef.current\n if (!textarea) return\n\n textarea.style.height = 'auto'\n const lineHeight = parseInt(getComputedStyle(textarea).lineHeight) || 24\n const maxHeight = lineHeight * maxRows\n const newHeight = Math.min(textarea.scrollHeight, maxHeight)\n textarea.style.height = `${newHeight}px`\n }, [maxRows])\n\n useEffect(() => {\n adjustHeight()\n }, [internalValue, adjustHeight])\n\n const handleChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const newValue = e.target.value\n if (maxLength && newValue.length > maxLength) return\n\n setInternalValue(newValue)\n onChange?.(newValue)\n }, [maxLength, onChange])\n\n const handleSend = useCallback(() => {\n const trimmedValue = internalValue.trim()\n if (!trimmedValue || disabled || sending) return\n\n onSend?.(trimmedValue)\n setInternalValue('')\n onChange?.('')\n\n // 重置高度\n if (textareaRef.current) {\n textareaRef.current.style.height = 'auto'\n }\n }, [internalValue, disabled, sending, onSend, onChange])\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (enterToSend && e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault()\n handleSend()\n }\n }, [enterToSend, handleSend])\n\n const handleStop = useCallback(() => {\n onStop?.()\n }, [onStop])\n\n const isDisabled = disabled || sending\n const canSend = internalValue.trim().length > 0 && !isDisabled\n const showStopButton = isGenerating && onStop\n\n // 容器样式 - 更现代的 glassmorphism 效果\n const getContainerStyles = (): React.CSSProperties => ({\n backgroundColor: isFocused\n ? 'var(--lm-chat-input-bg-focus)'\n : 'var(--lm-chat-input-bg)',\n backdropFilter: 'blur(20px) saturate(180%)',\n WebkitBackdropFilter: 'blur(20px) saturate(180%)',\n borderColor: isFocused\n ? 'var(--lm-chat-input-border-focus)'\n : 'var(--lm-chat-input-border)',\n boxShadow: isFocused\n ? 'var(--lm-chat-input-shadow-focus)'\n : 'var(--lm-chat-input-shadow)',\n transition: 'all var(--lm-transition-normal) var(--lm-ease-out)',\n } as React.CSSProperties)\n\n // 发送按钮样式 - 更精致的渐变效果\n const getSendButtonStyles = (): React.CSSProperties => {\n const baseStyles: React.CSSProperties = {\n transition: 'all var(--lm-transition-fast) var(--lm-ease-spring)',\n borderRadius: 'var(--lm-radius-md)',\n }\n\n if (showStopButton) {\n return {\n ...baseStyles,\n background: 'linear-gradient(135deg, var(--lm-error-500) 0%, var(--lm-error-600) 100%)',\n color: 'white',\n boxShadow: '0 2px 8px rgba(239, 68, 68, 0.3)',\n }\n }\n\n if (canSend) {\n return {\n ...baseStyles,\n background: 'linear-gradient(135deg, var(--lm-primary-500) 0%, var(--lm-primary-600) 100%)',\n color: 'white',\n boxShadow: '0 2px 8px rgba(0, 122, 255, 0.3)',\n }\n }\n\n return {\n ...baseStyles,\n backgroundColor: 'var(--lm-gray-100)',\n color: 'var(--lm-gray-400)',\n }\n }\n\n return (\n <>\n <style>{chatInputThemeStyles}</style>\n <div\n className={`\n relative flex flex-col border rounded-2xl\n ${config.padding}\n ${className}\n `.trim().replace(/\\s+/g, ' ')}\n style={getContainerStyles()}\n >\n {/* 输入区域 */}\n <div className={`flex items-start ${config.gap}`}>\n {/* 输入框 */}\n <div className=\"flex-1 min-w-0\">\n <textarea\n ref={textareaRef}\n value={internalValue}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n placeholder={placeholder}\n disabled={isDisabled}\n autoFocus={autoFocus}\n rows={1}\n className={`\n w-full resize-none bg-transparent leading-relaxed\n outline-none focus:outline-none focus:ring-0 border-none\n ${SIZE_TEXT_CLASSES[resolvedSize]}\n placeholder:text-(--lm-text-tertiary)\n disabled:text-(--lm-text-disabled) disabled:cursor-not-allowed\n `.trim().replace(/\\s+/g, ' ')}\n style={{\n color: 'var(--lm-text-primary)',\n minHeight: config.minHeight,\n maxHeight: `calc(${config.minHeight} * ${maxRows})`,\n outline: 'none',\n boxShadow: 'none',\n }}\n />\n </div>\n\n {/* 右侧插槽 */}\n {rightSlot && (\n <div className=\"flex items-center shrink-0 pt-0.5\">\n {rightSlot}\n </div>\n )}\n </div>\n\n {/* 底部工具栏 */}\n <div className=\"flex items-center justify-between mt-2 -mb-1\">\n {/* 左侧工具栏 */}\n <div className=\"flex items-center gap-0.5\">\n {toolbar}\n </div>\n\n {/* 右侧:字符计数 + 发送按钮 */}\n <div className=\"flex items-center gap-2\">\n {/* 字符计数 */}\n {showCount && (\n <span\n className=\"text-xs font-medium\"\n style={{\n color: maxLength && internalValue.length > maxLength * 0.9\n ? 'var(--lm-warning-500)'\n : 'var(--lm-text-tertiary)'\n }}\n >\n {internalValue.length}{maxLength ? `/${maxLength}` : ''}\n </span>\n )}\n\n {/* 发送/停止按钮 */}\n {showSendButton && (\n <button\n type=\"button\"\n onClick={showStopButton ? handleStop : handleSend}\n disabled={!showStopButton && !canSend}\n className={`\n ${config.sendButtonSize}\n flex items-center justify-center shrink-0\n cursor-pointer select-none\n focus:outline-none\n disabled:cursor-not-allowed disabled:opacity-50\n hover:scale-105 active:scale-95\n `.trim().replace(/\\s+/g, ' ')}\n style={getSendButtonStyles()}\n aria-label={showStopButton ? '停止生成' : '发送消息'}\n >\n {sending ? (\n <LoadingIcon className={config.sendIconSize} />\n ) : showStopButton ? (\n <StopIcon className={config.sendIconSize} />\n ) : sendButtonText ? (\n <span className={`${SIZE_TEXT_CLASSES[resolvedSize]} font-medium`}>{sendButtonText}</span>\n ) : (\n <SendIcon className={config.sendIconSize} />\n )}\n </button>\n )}\n </div>\n </div>\n </div>\n </>\n )\n}\n\nexport default memo(LMChatInput)\n","import React, { memo } from 'react'\nimport type { ComponentSize } from '../../../utils/componentSizes'\nimport { clampComponentSize, COMPONENT_SIZE_ORDER, SIZE_TEXT_CLASSES, SIZE_PADDING_CLASSES } from '../../../utils/componentSizes'\n\n/** 聊天气泡主题样式 */\nconst chatBubbleThemeStyles = `\n :root, [data-theme=\"light\"] {\n --lm-bubble-assistant-bg: rgba(255, 255, 255, 0.85);\n --lm-bubble-assistant-border: rgba(0, 0, 0, 0.06);\n --lm-bubble-assistant-shadow: 0 4px 16px rgba(0, 0, 0, 0.06), 0 1px 3px rgba(0, 0, 0, 0.04);\n --lm-bubble-outline-bg: rgba(255, 255, 255, 0.9);\n --lm-bubble-outline-border: rgba(0, 0, 0, 0.1);\n --lm-bubble-soft-bg: rgba(249, 250, 251, 0.9);\n --lm-bubble-soft-border: rgba(0, 0, 0, 0.04);\n --lm-bubble-system-bg: rgba(249, 250, 251, 0.7);\n --lm-bubble-system-border: rgba(0, 0, 0, 0.1);\n --lm-bubble-error-bg: rgba(254, 226, 226, 0.9);\n --lm-bubble-error-border: rgba(239, 68, 68, 0.2);\n }\n [data-theme=\"dark\"] {\n --lm-bubble-assistant-bg: rgba(51, 65, 85, 0.85);\n --lm-bubble-assistant-border: rgba(255, 255, 255, 0.08);\n --lm-bubble-assistant-shadow: 0 4px 16px rgba(0, 0, 0, 0.2), 0 1px 3px rgba(0, 0, 0, 0.1);\n --lm-bubble-outline-bg: rgba(51, 65, 85, 0.6);\n --lm-bubble-outline-border: rgba(255, 255, 255, 0.12);\n --lm-bubble-soft-bg: rgba(30, 41, 59, 0.9);\n --lm-bubble-soft-border: rgba(255, 255, 255, 0.06);\n --lm-bubble-system-bg: rgba(30, 41, 59, 0.7);\n --lm-bubble-system-border: rgba(255, 255, 255, 0.1);\n --lm-bubble-error-bg: rgba(127, 29, 29, 0.5);\n --lm-bubble-error-border: rgba(239, 68, 68, 0.3);\n }\n`\n\nexport type ChatRole = 'user' | 'assistant' | 'system'\n\nexport type ChatBubbleVariant = 'default' | 'filled' | 'outline' | 'soft'\n\nexport interface LMChatBubbleProps {\n /** 消息角色 */\n role?: ChatRole\n /** 气泡变体 */\n variant?: ChatBubbleVariant\n /** 尺寸 */\n size?: ComponentSize\n /** 气泡内容 */\n children: React.ReactNode\n /** 是否正在打字(流式输出中) */\n isStreaming?: boolean\n /** 自定义类名 */\n className?: string\n /** 错误状态 */\n error?: boolean\n /** 尾部装饰(如时间戳、状态图标) */\n footer?: React.ReactNode\n /** 自定义样式 */\n style?: React.CSSProperties\n}\n\n/** 气泡配置 - 更精致的圆角设计 */\nconst BUBBLE_CONFIG: Record<ChatRole, {\n align: 'left' | 'right'\n borderRadius: string\n}> = {\n user: {\n align: 'right',\n borderRadius: '20px 4px 20px 20px',\n },\n assistant: {\n align: 'left',\n borderRadius: '4px 20px 20px 20px',\n },\n system: {\n align: 'left',\n borderRadius: '16px',\n },\n}\n\nconst LMChatBubble: React.FC<LMChatBubbleProps> = ({\n role = 'user',\n variant = 'default',\n size = 'md',\n children,\n isStreaming = false,\n className = '',\n error = false,\n footer,\n style,\n}) => {\n const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER)\n const config = BUBBLE_CONFIG[role]\n\n // 获取气泡样式 - 更现代的 glassmorphism 效果\n const getBubbleStyles = (): React.CSSProperties => {\n const baseStyles: React.CSSProperties = {\n borderRadius: config.borderRadius,\n transition: 'all var(--lm-transition-normal) var(--lm-ease-out)',\n maxWidth: '85%',\n wordBreak: 'break-word',\n position: 'relative',\n }\n\n // 错误状态\n if (error) {\n return {\n ...baseStyles,\n backgroundColor: 'var(--lm-bubble-error-bg)',\n color: 'var(--lm-error-700)',\n border: '1px solid var(--lm-bubble-error-border)',\n backdropFilter: 'blur(8px)',\n boxShadow: '0 2px 8px rgba(239, 68, 68, 0.1)',\n }\n }\n\n // 用户消息样式 - 渐变蓝色\n if (role === 'user') {\n switch (variant) {\n case 'filled':\n case 'default':\n return {\n ...baseStyles,\n background: 'linear-gradient(135deg, var(--lm-primary-500) 0%, var(--lm-primary-600) 100%)',\n color: 'white',\n boxShadow: '0 2px 12px rgba(0, 122, 255, 0.25), 0 1px 3px rgba(0, 122, 255, 0.1)',\n }\n case 'outline':\n return {\n ...baseStyles,\n backgroundColor: 'var(--lm-bubble-outline-bg)',\n backdropFilter: 'blur(12px)',\n color: 'var(--lm-primary-600)',\n border: '1.5px solid var(--lm-primary-300)',\n boxShadow: '0 2px 8px rgba(0, 122, 255, 0.08)',\n }\n case 'soft':\n return {\n ...baseStyles,\n backgroundColor: 'var(--lm-bubble-soft-bg)',\n backdropFilter: 'blur(8px)',\n color: 'var(--lm-primary-700)',\n border: '1px solid rgba(0, 122, 255, 0.12)',\n }\n default:\n return {\n ...baseStyles,\n background: 'linear-gradient(135deg, var(--lm-primary-500) 0%, var(--lm-primary-600) 100%)',\n color: 'white',\n boxShadow: '0 2px 12px rgba(0, 122, 255, 0.25)',\n }\n }\n }\n\n // 助手消息样式 - glassmorphism 效果\n if (role === 'assistant') {\n switch (variant) {\n case 'filled':\n case 'default':\n return {\n ...baseStyles,\n backgroundColor: 'var(--lm-bubble-assistant-bg)',\n backdropFilter: 'blur(20px) saturate(180%)',\n WebkitBackdropFilter: 'blur(20px) saturate(180%)',\n color: 'var(--lm-text-primary)',\n boxShadow: 'var(--lm-bubble-assistant-shadow)',\n border: '1px solid var(--lm-bubble-assistant-border)',\n }\n case 'outline':\n return {\n ...baseStyles,\n backgroundColor: 'var(--lm-bubble-outline-bg)',\n backdropFilter: 'blur(12px)',\n color: 'var(--lm-text-primary)',\n border: '1.5px solid var(--lm-bubble-outline-border)',\n }\n case 'soft':\n return {\n ...baseStyles,\n backgroundColor: 'var(--lm-bubble-soft-bg)',\n backdropFilter: 'blur(8px)',\n color: 'var(--lm-text-primary)',\n border: '1px solid var(--lm-bubble-soft-border)',\n }\n default:\n return {\n ...baseStyles,\n backgroundColor: 'var(--lm-bubble-assistant-bg)',\n backdropFilter: 'blur(20px) saturate(180%)',\n color: 'var(--lm-text-primary)',\n boxShadow: 'var(--lm-bubble-assistant-shadow)',\n border: '1px solid var(--lm-bubble-assistant-border)',\n }\n }\n }\n\n // 系统消息样式 - 微妙的玻璃效果\n return {\n ...baseStyles,\n backgroundColor: 'var(--lm-bubble-system-bg)',\n backdropFilter: 'blur(8px)',\n color: 'var(--lm-text-secondary)',\n border: '1px dashed var(--lm-bubble-system-border)',\n }\n }\n\n return (\n <>\n <style>{chatBubbleThemeStyles}</style>\n <div\n className={`\n w-full\n ${SIZE_PADDING_CLASSES[resolvedSize]}\n ${SIZE_TEXT_CLASSES[resolvedSize]}\n ${className}\n `.trim().replace(/\\s+/g, ' ')}\n style={{\n ...getBubbleStyles(),\n ...style,\n }}\n >\n {/* 内容 */}\n <div className=\"relative leading-relaxed\">\n {children}\n\n {/* 流式输出光标 - 更精致的动画 */}\n {isStreaming && (\n <span\n className=\"inline-block w-0.5 h-[1.1em] ml-1 align-middle rounded-full\"\n style={{\n backgroundColor: role === 'user' ? 'rgba(255, 255, 255, 0.8)' : 'var(--lm-primary-500)',\n animation: 'lm-cursor-blink 1s ease-in-out infinite',\n }}\n />\n )}\n </div>\n\n {/* 尾部装饰 */}\n {footer && (\n <div\n className=\"mt-2 text-xs font-medium\"\n style={{\n color: role === 'user'\n ? 'rgba(255, 255, 255, 0.7)'\n : 'var(--lm-text-tertiary)'\n }}\n >\n {footer}\n </div>\n )}\n\n {/* 光标闪烁动画样式 */}\n <style>{`\n @keyframes lm-cursor-blink {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.3; }\n }\n @media (prefers-reduced-motion: reduce) {\n .lm-cursor-blink { animation: none; opacity: 1; }\n }\n `}</style>\n </div>\n </>\n )\n}\n\nexport default memo(LMChatBubble)\n","import React, { memo, useState, useCallback } from 'react'\nimport type { ComponentSize } from '../../../utils/componentSizes'\nimport { clampComponentSize, COMPONENT_SIZE_ORDER, SIZE_TEXT_CLASSES } from '../../../utils/componentSizes'\nimport { LMChatBubble, type ChatRole, type ChatBubbleVariant } from '../LMChatBubble'\n\nexport type MessageStatus = 'sending' | 'sent' | 'error' | 'streaming'\n\nexport interface ChatMessageAction {\n /** 操作唯一标识 */\n key: string\n /** 图标 */\n icon: React.ReactNode\n /** 提示文字 */\n tooltip?: string\n /** 点击回调 */\n onClick?: () => void\n /** 是否禁用 */\n disabled?: boolean\n}\n\nexport interface LMChatMessageProps {\n /** 消息唯一 ID */\n id?: string\n /** 消息角色 */\n role?: ChatRole\n /** 消息内容(纯文本或自定义 React 节点) */\n content: React.ReactNode\n /** 头像(URL 或 React 节点) */\n avatar?: string | React.ReactNode\n /** 发送者名称 */\n name?: string\n /** 时间戳 */\n timestamp?: string | Date\n /** 消息状态 */\n status?: MessageStatus\n /** 尺寸 */\n size?: ComponentSize\n /** 气泡变体 */\n variant?: ChatBubbleVariant\n /** 操作按钮 */\n actions?: ChatMessageAction[]\n /** 是否显示操作按钮(hover 时显示) */\n showActions?: boolean\n /** 错误信息 */\n errorMessage?: string\n /** 重试回调 */\n onRetry?: () => void\n /** 自定义类名 */\n className?: string\n /** 是否隐藏头像 */\n hideAvatar?: boolean\n /** 自定义气泡渲染 */\n renderBubble?: (content: React.ReactNode) => React.ReactNode\n /** 气泡最大宽度(默认 85%) */\n bubbleMaxWidth?: string | number\n}\n\n/** 复制图标 */\nconst CopyIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2}>\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" />\n <path d=\"M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1\" />\n </svg>\n)\n\n/** 重新生成图标 */\nconst RefreshIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2}>\n <path d=\"M21 2v6h-6\" />\n <path d=\"M3 12a9 9 0 0115-6.7L21 8\" />\n <path d=\"M3 22v-6h6\" />\n <path d=\"M21 12a9 9 0 01-15 6.7L3 16\" />\n </svg>\n)\n\n/** 对勾图标 */\nconst CheckIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2}>\n <polyline points=\"20,6 9,17 4,12\" />\n </svg>\n)\n\n/** 错误图标 */\nconst ErrorIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2}>\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\" />\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\" />\n </svg>\n)\n\n/** 加载图标 */\nconst LoadingDots: React.FC<{ className?: string }> = ({ className }) => (\n <span className={`inline-flex items-center gap-1 ${className}`}>\n {[0, 1, 2].map((i) => (\n <span\n key={i}\n className=\"w-1.5 h-1.5 rounded-full animate-bounce\"\n style={{\n backgroundColor: 'currentColor',\n animationDelay: `${i * 0.15}s`,\n }}\n />\n ))}\n </span>\n)\n\n/** 头像尺寸配置 */\nconst AVATAR_SIZE: Record<ComponentSize, string> = {\n xs: 'w-6 h-6',\n sm: 'w-7 h-7',\n md: 'w-8 h-8',\n lg: 'w-10 h-10',\n xl: 'w-12 h-12',\n '2xl': 'w-14 h-14',\n}\n\n/** 操作按钮尺寸配置 */\nconst ACTION_BUTTON_SIZE: Record<ComponentSize, string> = {\n xs: 'w-5 h-5',\n sm: 'w-6 h-6',\n md: 'w-7 h-7',\n lg: 'w-8 h-8',\n xl: 'w-9 h-9',\n '2xl': 'w-10 h-10',\n}\n\nconst LMChatMessage: React.FC<LMChatMessageProps> = ({\n id,\n role = 'user',\n content,\n avatar,\n name,\n timestamp,\n status,\n size = 'md',\n variant = 'default',\n actions,\n showActions = true,\n errorMessage,\n onRetry,\n className = '',\n hideAvatar = false,\n renderBubble,\n bubbleMaxWidth = '95%',\n}) => {\n const [isHovered, setIsHovered] = useState(false)\n const [copiedAction, setCopiedAction] = useState<string | null>(null)\n\n const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER)\n const isUser = role === 'user'\n const isStreaming = status === 'streaming'\n const isError = status === 'error'\n\n // 格式化时间\n const formatTimestamp = useCallback((ts: string | Date): string => {\n if (typeof ts === 'string') return ts\n const date = new Date(ts)\n return date.toLocaleTimeString('zh-CN', {\n hour: '2-digit',\n minute: '2-digit',\n })\n }, [])\n\n // 复制内容\n const handleCopy = useCallback(async (actionKey: string) => {\n try {\n const text = typeof content === 'string' ? content : ''\n await navigator.clipboard.writeText(text)\n setCopiedAction(actionKey)\n setTimeout(() => setCopiedAction(null), 2000)\n } catch (err) {\n console.error('Failed to copy:', err)\n }\n }, [content])\n\n // 默认操作按钮\n const defaultActions: ChatMessageAction[] = role === 'assistant' ? [\n {\n key: 'copy',\n icon: copiedAction === 'copy' ? <CheckIcon className=\"w-4 h-4\" /> : <CopyIcon className=\"w-4 h-4\" />,\n tooltip: copiedAction === 'copy' ? '已复制' : '复制',\n onClick: () => handleCopy('copy'),\n },\n ...(onRetry ? [{\n key: 'retry',\n icon: <RefreshIcon className=\"w-4 h-4\" />,\n tooltip: '重新生成',\n onClick: onRetry,\n }] : []),\n ] : []\n\n const finalActions = actions || defaultActions\n\n // 渲染头像\n const renderAvatar = () => {\n if (hideAvatar) return null\n\n const avatarClasses = `\n ${AVATAR_SIZE[resolvedSize]}\n rounded-full overflow-hidden shrink-0\n flex items-center justify-center\n `.trim().replace(/\\s+/g, ' ')\n\n if (typeof avatar === 'string') {\n return (\n <img\n src={avatar}\n alt={name || role}\n className={avatarClasses}\n style={{ objectFit: 'cover' }}\n />\n )\n }\n\n if (avatar) {\n return <div className={avatarClasses}>{avatar}</div>\n }\n\n // 默认头像\n const defaultAvatarStyle: React.CSSProperties = {\n backgroundColor: isUser ? 'var(--lm-primary-100)' : 'var(--lm-gray-100)',\n color: isUser ? 'var(--lm-primary-600)' : 'var(--lm-gray-600)',\n }\n\n return (\n <div className={avatarClasses} style={defaultAvatarStyle}>\n <span className={SIZE_TEXT_CLASSES[resolvedSize]}>\n {isUser ? 'U' : 'AI'}\n </span>\n </div>\n )\n }\n\n // 渲染操作按钮\n const renderActions = () => {\n if (!showActions || finalActions.length === 0) return null\n\n return (\n <div\n className={`\n flex items-center gap-1 mt-1\n transition-opacity duration-150\n ${isHovered ? 'opacity-100' : 'opacity-0'}\n `.trim().replace(/\\s+/g, ' ')}\n >\n {finalActions.map((action) => (\n <button\n key={action.key}\n onClick={action.onClick}\n disabled={action.disabled}\n className={`\n ${ACTION_BUTTON_SIZE[resolvedSize]}\n flex items-center justify-center\n rounded-lg cursor-pointer\n hover:bg-(--lm-bg-hover)\n active:scale-95\n disabled:opacity-50 disabled:cursor-not-allowed\n transition-all duration-150\n `.trim().replace(/\\s+/g, ' ')}\n style={{ color: 'var(--lm-text-tertiary)' }}\n title={action.tooltip}\n aria-label={action.tooltip}\n >\n {action.icon}\n </button>\n ))}\n </div>\n )\n }\n\n // 渲染状态指示器\n const renderStatus = () => {\n if (!status || status === 'sent') return null\n\n if (status === 'sending') {\n return (\n <div className=\"flex items-center gap-1 mt-1\" style={{ color: 'var(--lm-text-tertiary)' }}>\n <LoadingDots className=\"text-xs\" />\n <span className=\"text-xs\">发送中</span>\n </div>\n )\n }\n\n if (status === 'error') {\n return (\n <div className=\"flex items-center gap-2 mt-2\">\n <div\n className=\"flex items-center gap-1 text-xs\"\n style={{ color: 'var(--lm-error-500)' }}\n >\n <ErrorIcon className=\"w-3.5 h-3.5\" />\n <span>{errorMessage || '发送失败'}</span>\n </div>\n {onRetry && (\n <button\n onClick={onRetry}\n className=\"text-xs px-2 py-0.5 rounded-md cursor-pointer hover:opacity-80 active:scale-95\"\n style={{\n backgroundColor: 'var(--lm-error-50)',\n color: 'var(--lm-error-600)',\n }}\n >\n 重试\n </button>\n )}\n </div>\n )\n }\n\n return null\n }\n\n // 气泡内容\n const bubbleContent = (\n <LMChatBubble\n role={role}\n variant={variant}\n size={resolvedSize}\n isStreaming={isStreaming}\n error={isError}\n >\n {content}\n </LMChatBubble>\n )\n\n return (\n <div\n id={id}\n className={`\n flex gap-3\n ${isUser ? 'flex-row-reverse' : 'flex-row'}\n ${className}\n `.trim().replace(/\\s+/g, ' ')}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n {/* 头像 */}\n {renderAvatar()}\n\n {/* 消息主体 */}\n <div\n className={`\n flex flex-col min-w-0\n ${isUser ? 'items-end' : 'items-start'}\n `.trim().replace(/\\s+/g, ' ')}\n style={{\n maxWidth: typeof bubbleMaxWidth === 'number' ? `${bubbleMaxWidth}px` : bubbleMaxWidth,\n width: typeof bubbleMaxWidth === 'number' ? `${bubbleMaxWidth}px` : bubbleMaxWidth,\n }}\n >\n {/* 名称和时间 */}\n {(name || timestamp) && (\n <div\n className={`\n flex items-center gap-2 mb-1\n ${isUser ? 'flex-row-reverse' : 'flex-row'}\n `.trim().replace(/\\s+/g, ' ')}\n >\n {name && (\n <span\n className=\"text-xs font-medium\"\n style={{ color: 'var(--lm-text-secondary)' }}\n >\n {name}\n </span>\n )}\n {timestamp && (\n <span\n className=\"text-xs\"\n style={{ color: 'var(--lm-text-tertiary)' }}\n >\n {formatTimestamp(timestamp)}\n </span>\n )}\n </div>\n )}\n\n {/* 气泡 */}\n {renderBubble ? renderBubble(bubbleContent) : bubbleContent}\n\n {/* 状态指示器 */}\n {renderStatus()}\n\n {/* 操作按钮 */}\n {!isError && renderActions()}\n </div>\n </div>\n )\n}\n\nexport default memo(LMChatMessage)\n","import React, { memo, useState, useCallback, useMemo } from 'react'\nimport type { ComponentSize } from '../../../utils/componentSizes'\nimport { clampComponentSize, COMPONENT_SIZE_ORDER } from '../../../utils/componentSizes'\n\nexport interface LMCodeBlockProps {\n /** 代码内容 */\n code: string\n /** 编程语言 */\n language?: string\n /** 文件名(可选) */\n filename?: string\n /** 尺寸 */\n size?: ComponentSize\n /** 是否显示行号 */\n showLineNumbers?: boolean\n /** 起始行号 */\n startLineNumber?: number\n /** 高亮行(数组) */\n highlightLines?: number[]\n /** 是否显示复制按钮 */\n showCopyButton?: boolean\n /** 自定义类名 */\n className?: string\n /** 最大高度 */\n maxHeight?: string | number\n /** 是否允许换行 */\n wrapLines?: boolean\n /** 是否启用语法高亮 */\n enableHighlight?: boolean\n}\n\n/** 复制图标 */\nconst CopyIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.5} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" />\n <path d=\"M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1\" />\n </svg>\n)\n\n/** 对勾图标 */\nconst CheckIcon: React.FC<{ className?: string }> = ({ className }) => (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"20,6 9,17 4,12\" />\n </svg>\n)\n\n/** 语法高亮 CSS 变量名 */\nconst HIGHLIGHT_VARS = {\n keyword: '--lm-code-keyword',\n string: '--lm-code-string',\n number: '--lm-code-number',\n comment: '--lm-code-comment',\n function: '--lm-code-function',\n operator: '--lm-code-operator',\n className: '--lm-code-class',\n tag: '--lm-code-tag',\n property: '--lm-code-property',\n default: '--lm-code-default',\n}\n\n/** 简单的语法高亮器 */\nconst highlightCode = (code: string, language: string): React.ReactNode[] => {\n const lang = language.toLowerCase()\n\n // 通用关键字\n const keywords = {\n js: /\\b(const|let|var|function|return|if|else|for|while|do|switch|case|break|continue|try|catch|finally|throw|new|typeof|instanceof|in|of|class|extends|super|import|export|default|from|as|async|await|yield|static|get|set|null|undefined|true|false|this|void|delete|debugger)\\b/g,\n ts: /\\b(const|let|var|function|return|if|else|for|while|do|switch|case|break|continue|try|catch|finally|throw|new|typeof|instanceof|in|of|class|extends|super|import|export|default|from|as|async|await|yield|static|get|set|null|undefined|true|false|this|void|delete|debugger|type|interface|enum|namespace|module|declare|abstract|implements|private|protected|public|readonly|keyof|infer|never|unknown|any)\\b/g,\n py: /\\b(def|return|if|elif|else|for|while|break|continue|try|except|finally|raise|import|from|as|class|with|yield|lambda|pass|None|True|False|and|or|not|in|is|global|nonlocal|assert|del|async|await|self)\\b/g,\n go: /\\b(func|return|if|else|for|range|switch|case|break|continue|go|select|defer|panic|recover|type|struct|interface|map|chan|package|import|const|var|nil|true|false|make|new|append|len|cap)\\b/g,\n rust: /\\b(fn|return|if|else|for|while|loop|match|break|continue|let|mut|const|static|struct|enum|impl|trait|type|pub|mod|use|crate|self|super|where|async|await|move|ref|unsafe|extern|dyn|true|false|None|Some|Ok|Err)\\b/g,\n }\n\n const patterns: { pattern: RegExp; varName: string }[] = [\n // 注释\n { pattern: /(\\/\\/.*$|\\/\\*[\\s\\S]*?\\*\\/|#.*$)/gm, varName: HIGHLIGHT_VARS.comment },\n // 字符串\n { pattern: /(['\"`])(?:(?!\\1)[^\\\\]|\\\\.)*\\1/g, varName: HIGHLIGHT_VARS.string },\n // 模板字符串中的表达式\n { pattern: /\\$\\{[^}]+\\}/g, varName: HIGHLIGHT_VARS.operator },\n // 数字\n { pattern: /\\b(\\d+\\.?\\d*|0x[a-fA-F0-9]+|0b[01]+|0o[0-7]+)\\b/g, varName: HIGHLIGHT_VARS.number },\n // 函数调用\n { pattern: /\\b([a-zA-Z_]\\w*)\\s*(?=\\()/g, varName: HIGHLIGHT_VARS.function },\n // JSX/HTML 标签\n { pattern: /<\\/?([a-zA-Z][a-zA-Z0-9]*)/g, varName: HIGHLIGHT_VARS.tag },\n // 类名 (大写开头)\n { pattern: /\\b([A-Z][a-zA-Z0-9]*)\\b/g, varName: HIGHLIGHT_VARS.className },\n // 操作符\n { pattern: /[+\\-*/%=<>!&|^~?:]+|\\.{3}/g, varName: HIGHLIGHT_VARS.operator },\n ]\n\n // 获取语言对应的关键字模式\n const keywordPattern = keywords[lang as keyof typeof keywords] || keywords.js\n\n // 收集所有匹配\n const allMatches: { start: number; end: number; text: string; varName: string }[] = []\n\n // 关键字匹配\n let match\n while ((match = keywordPattern.exec(code)) !== null) {\n allMatches.push({\n start: match.index,\n end: match.index + match[0].length,\n text: match[0],\n varName: HIGHLIGHT_VARS.keyword,\n })\n }\n\n // 其他模式匹配\n for (const { pattern, varName } of patterns) {\n pattern.lastIndex = 0\n while ((match = pattern.exec(code)) !== null) {\n allMatches.push({\n start: match.index,\n end: match.index + match[0].length,\n text: match[0],\n varName,\n })\n }\n }\n\n // 按位置排序\n allMatches.sort((a, b) => a.start - b.start || b.end - a.end)\n\n // 构建 token 列表\n const tokens: { text: string; varName?: string }[] = []\n let lastIndex = 0\n\n for (const m of allMatches) {\n if (m.start >= lastIndex) {\n if (m.start > lastIndex) {\n tokens.push({ text: code.slice(lastIndex, m.start) })\n }\n tokens.push({ text: m.text, varName: m.varName })\n lastIndex = m.end\n }\n }\n\n if (lastIndex < code.length) {\n tokens.push({ text: code.slice(lastIndex) })\n }\n\n return tokens.map((token, i) => (\n token.varName ? (\n <span key={i} style={{ color: `var(${token.varName})` }}>{token.text}</span>\n ) : (\n <span key={i}>{token.text}</span>\n )\n ))\n}\n\n/** 语言显示名称映射 */\nconst LANGUAGE_DISPLAY: Record<string, string> = {\n javascript: 'JS', typescript: 'TS', python: 'Python', java: 'Java',\n cpp: 'C++', c: 'C', csharp: 'C#', go: 'Go', rust: 'Rust', swift: 'Swift',\n kotlin: 'Kotlin', ruby: 'Ruby', php: 'PHP', html: 'HTML', css: 'CSS',\n json: 'JSON', yaml: 'YAML', sql: 'SQL', bash: 'Bash', shell: 'Shell',\n jsx: 'JSX', tsx: 'TSX', vue: 'Vue', svelte: 'Svelte', markdown: 'MD',\n}\n\n/** 代码字体尺寸配置 */\nconst CODE_SIZE: Record<ComponentSize, { fontSize: string; lineHeight: string; padding: string }> = {\n xs: { fontSize: '11px', lineHeight: '1.5', padding: '12px' },\n sm: { fontSize: '12px', lineHeight: '1.5', padding: '14px' },\n md: { fontSize: '13px', lineHeight: '1.6', padding: '16px' },\n lg: { fontSize: '14px', lineHeight: '1.6', padding: '18px' },\n xl: { fontSize: '14px', lineHeight: '1.7', padding: '20px' },\n '2xl': { fontSize: '15px', lineHeight: '1.7', padding: '24px' },\n}\n\n/** 代码高亮主题样式 */\nconst codeThemeStyles = `\n :root, [data-theme=\"light\"] {\n --lm-code-bg: #f8fafc;\n --lm-code-border: #e2e8f0;\n --lm-code-text: #334155;\n --lm-code-line-number: #94a3b8;\n --lm-code-keyword: #8250df;\n --lm-code-string: #0a7d46;\n --lm-code-number: #cf5c00;\n --lm-code-comment: #6b7280;\n --lm-code-function: #0969da;\n --lm-code-operator: #cf222e;\n --lm-code-class: #953800;\n --lm-code-tag: #1a7f37;\n --lm-code-property: #0550ae;\n }\n [data-theme=\"dark\"] {\n --lm-code-bg: #1e293b;\n --lm-code-border: #334155;\n --lm-code-text: #e2e8f0;\n --lm-code-line-number: #64748b;\n --lm-code-keyword: #c792ea;\n --lm-code-string: #c3e88d;\n --lm-code-number: #f78c6c;\n --lm-code-comment: #64748b;\n --lm-code-function: #82aaff;\n --lm-code-operator: #89ddff;\n --lm-code-class: #ffcb6b;\n --lm-code-tag: #f07178;\n --lm-code-property: #89ddff;\n }\n`\n\nconst LMCodeBlock: React.FC<LMCodeBlockProps> = ({\n code,\n language = 'plaintext',\n filename,\n size = 'md',\n showLineNumbers = true,\n startLineNumber = 1,\n highlightLines = [],\n showCopyButton = true,\n className = '',\n maxHeight,\n wrapLines = false,\n enableHighlight = true,\n}) => {\n const [copied, setCopied] = useState(false)\n\n const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER)\n const sizeConfig = CODE_SIZE[resolvedSize]\n const lines = code.split('\\n')\n const displayLang = LANGUAGE_DISPLAY[language.toLowerCase()] || language\n\n // 复制代码\n const handleCopy = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(code)\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n } catch (err) {\n console.error('Failed to copy:', err)\n }\n }, [code])\n\n // 行号宽度\n const lineNumWidth = String(lines.length + startLineNumber - 1).length\n\n // 高亮后的代码行\n const highlightedLines = useMemo(() => {\n if (!enableHighlight) return lines\n return lines.map(line => highlightCode(line, language))\n }, [lines, language, enableHighlight])\n\n return (\n <>\n <style>{codeThemeStyles}</style>\n <div\n className={`overflow-hidden ${className}`.trim()}\n style={{\n backgroundColor: 'var(--lm-code-bg)',\n borderRadius: 'var(--lm-radius-lg)',\n border: '1px solid var(--lm-code-border)',\n ...(maxHeight ? { maxHeight: typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight } : {}),\n }}\n >\n {/* 头部 */}\n <div\n className=\"flex items-center justify-between px-3 py-2\"\n style={{\n borderBottom: '1px solid var(--lm-code-border)',\n }}\n >\n <div className=\"flex items-center gap-2\">\n {/* 语言标签 */}\n <span\n className=\"text-xs font-medium px-1.5 py-0.5 rounded\"\n style={{\n backgroundColor: 'var(--lm-code-border)',\n color: 'var(--lm-code-line-number)',\n }}\n >\n {displayLang}\n </span>\n\n {/* 文件名 */}\n {filename && (\n <span\n className=\"text-xs truncate max-w-45\"\n style={{ color: 'var(--lm-code-line-number)' }}\n >\n {filename}\n </span>\n )}\n </div>\n\n {/* 复制按钮 */}\n {showCopyButton && (\n <button\n onClick={handleCopy}\n className=\"flex items-center gap-1 px-2 py-1 rounded cursor-pointer transition-colors duration-150 active:scale-95\"\n style={{\n color: copied ? 'var(--lm-success-500)' : 'var(--lm-code-line-number)',\n }}\n aria-label={copied ? '已复制' : '复制'}\n >\n {copied ? <CheckIcon className=\"w-3.5 h-3.5\" /> : <CopyIcon className=\"w-3.5 h-3.5\" />}\n <span className=\"text-xs\">{copied ? '已复制' : '复制'}</span>\n </button>\n )}\n </div>\n\n {/* 代码区域 */}\n <pre\n className=\"m-0 overflow-auto\"\n style={{\n padding: sizeConfig.padding,\n fontSize: sizeConfig.fontSize,\n lineHeight: sizeConfig.lineHeight,\n fontFamily: '\"SF Mono\", ui-monospace, Menlo, Monaco, \"Cascadia Code\", monospace',\n color: 'var(--lm-code-text)',\n }}\n >\n <code>\n {lines.map((line, index) => {\n const lineNum = startLineNumber + index\n const isHighlighted = highlightLines.includes(lineNum)\n\n return (\n <div\n key={index}\n className=\"flex\"\n style={{\n backgroundColor: isHighlighted ? 'var(--lm-primary-50)' : 'transparent',\n marginLeft: isHighlighted ? '-4px' : '0',\n paddingLeft: isHighlighted ? '4px' : '0',\n borderLeft: isHighlighted ? '2px solid var(--lm-primary-500)' : 'none',\n }}\n >\n {/* 行号 */}\n {showLineNumbers && (\n <span\n className=\"select-none text-right shrink-0 pr-4\"\n style={{\n width: `${lineNumWidth + 2}ch`,\n color: isHighlighted ? 'var(--lm-primary-500)' : 'var(--lm-code-line-number)',\n }}\n >\n {lineNum}\n </span>\n )}\n\n {/* 代码内容 */}\n <span className={`flex-1 min-w-0 ${wrapLines ? 'whitespace-pre-wrap break-all' : 'whitespace-pre'}`}>\n {enableHighlight ? highlightedLines[index] : (line || ' ')}\n </span>\n </div>\n )\n })}\n </code>\n </pre>\n </div>\n </>\n )\n}\n\nexport default memo(LMCodeBlock)\n","import React, { memo, useMemo } from 'react'\nimport type { ComponentSize } from '../../../utils/componentSizes'\nimport { clampComponentSize, COMPONENT_SIZE_ORDER } from '../../../utils/componentSizes'\nimport { LMCodeBlock } from '../LMCodeBlock'\n\nexport interface LMMarkdownRendererProps {\n /** Markdown 内容 */\n content: string\n /** 尺寸 */\n size?: ComponentSize\n /** 自定义类名 */\n className?: string\n /** 是否允许 HTML */\n allowHtml?: boolean\n /** 代码块渲染器(可自定义) */\n renderCodeBlock?: (code: string, language?: string, filename?: string) => React.ReactNode\n /** 链接点击处理 */\n onLinkClick?: (url: string, event: React.MouseEvent) => void\n /** 是否在新窗口打开链接 */\n openLinksInNewTab?: boolean\n /** 自定义渲染器(完全自定义解析) */\n customRenderer?: (content: string) => React.ReactNode\n}\n\n/** 文本尺寸配置 */\nconst TEXT_SIZE_CONFIG: Record<ComponentSize, {\n base: string\n h1: string\n h2: string\n h3: string\n code: string\n}> = {\n xs: { base: 'text-xs', h1: 'text-lg', h2: 'text-base', h3: 'text-sm', code: 'text-[10px]' },\n sm: { base: 'text-sm', h1: 'text-xl', h2: 'text-lg', h3: 'text-base', code: 'text-xs' },\n md: { base: 'text-base', h1: 'text-2xl', h2: 'text-xl', h3: 'text-lg', code: 'text-sm' },\n lg: { base: 'text-lg', h1: 'text-3xl', h2: 'text-2xl', h3: 'text-xl', code: 'text-base' },\n xl: { base: 'text-xl', h1: 'text-4xl', h2: 'text-3xl', h3: 'text-2xl', code: 'text-lg' },\n '2xl': { base: 'text-2xl', h1: 'text-5xl', h2: 'text-4xl', h3: 'text-3xl', code: 'text-xl' },\n}\n\n/** 简单的 Markdown 解析 token 类型 */\ntype TokenType =\n | 'heading'\n | 'paragraph'\n | 'codeBlock'\n | 'blockquote'\n | 'list'\n | 'listItem'\n | 'hr'\n | 'table'\n\ninterface Token {\n type: TokenType\n content: string\n level?: number\n language?: string\n filename?: string\n ordered?: boolean\n items?: string[]\n rows?: string[][]\n}\n\n/** 解析 Markdown 为 tokens */\nconst parseMarkdown = (content: string): Token[] => {\n const tokens: Token[] = []\n const lines = content.split('\\n')\n let i = 0\n\n while (i < lines.length) {\n const line = lines[i]\n\n // 代码块\n if (line.startsWith('```')) {\n const match = line.match(/^```(\\w+)?(?:\\s+(.+))?/)\n const language = match?.[1] || 'plaintext'\n const filename = match?.[2]\n const codeLines: string[] = []\n i++\n\n while (i < lines.length && !lines[i].startsWith('```')) {\n codeLines.push(lines[i])\n i++\n }\n\n tokens.push({\n type: 'codeBlock',\n content: codeLines.join('\\n'),\n language,\n filename,\n })\n i++\n continue\n }\n\n // 标题\n const headingMatch = line.match(/^(#{1,6})\\s+(.+)$/)\n if (headingMatch) {\n tokens.push({\n type: 'heading',\n content: headingMatch[2],\n level: headingMatch[1].length,\n })\n i++\n continue\n }\n\n // 水平线\n if (/^(-{3,}|_{3,}|\\*{3,})$/.test(line.trim())) {\n tokens.push({ type: 'hr', content: '' })\n i++\n continue\n }\n\n // 引用块\n if (line.startsWith('>')) {\n const quoteLines: string[] = []\n while (i < lines.length && (lines[i].startsWith('>') || lines[i].trim() === '')) {\n if (lines[i].startsWith('>')) {\n quoteLines.push(lines[i].replace(/^>\\s?/, ''))\n } else {\n quoteLines.push('')\n }\n i++\n }\n tokens.push({\n type: 'blockquote',\n content: quoteLines.join('\\n').trim(),\n })\n continue\n }\n\n // 无序列表\n if (/^[-*+]\\s/.test(line)) {\n const items: string[] = []\n while (i < lines.length && /^[-*+]\\s/.test(lines[i])) {\n items.push(lines[i].replace(/^[-*+]\\s/, ''))\n i++\n }\n tokens.push({\n type: 'list',\n content: '',\n ordered: false,\n items,\n })\n continue\n }\n\n // 有序列表\n if (/^\\d+\\.\\s/.test(line)) {\n const items: string[] = []\n while (i < lines.length && /^\\d+\\.\\s/.test(lines[i])) {\n items.push(lines[i].replace(/^\\d+\\.\\s/, ''))\n i++\n }\n tokens.push({\n type: 'list',\n content: '',\n ordered: true,\n items,\n })\n continue\n }\n\n // 表格\n if (line.includes('|') && i + 1 < lines.length && /^\\|?[\\s-:|]+\\|?$/.test(lines[i + 1])) {\n const rows: string[][] = []\n while (i < lines.length && lines[i].includes('|')) {\n const cells = lines[i]\n .split('|')\n .map((cell) => cell.trim())\n .filter((cell) => cell !== '')\n if (cells.length > 0 && !/^[\\s-:]+$/.test(cells.join(''))) {\n rows.push(cells)\n }\n i++\n }\n if (rows.length > 0) {\n tokens.push({\n type: 'table',\n content: '',\n rows,\n })\n }\n continue\n }\n\n // 空行跳过\n if (line.trim() === '') {\n i++\n continue\n }\n\n // 段落\n const paragraphLines: string[] = [line]\n i++\n while (\n i < lines.length &&\n lines[i].trim() !== '' &&\n !lines[i].startsWith('#') &&\n !lines[i].startsWith('```') &&\n !lines[i].startsWith('>') &&\n !/^[-*+]\\s/.test(lines[i]) &&\n !/^\\d+\\.\\s/.test(lines[i]) &&\n !/^(-{3,}|_{3,}|\\*{3,})$/.test(lines[i].trim())\n ) {\n paragraphLines.push(lines[i])\n i++\n }\n tokens.push({\n type: 'paragraph',\n content: paragraphLines.join('\\n'),\n })\n }\n\n return tokens\n}\n\n/** 解析行内样式 */\nconst parseInlineStyles = (\n text: string,\n onLinkClick?: (url: string, event: React.MouseEvent) => void,\n openLinksInNewTab?: boolean\n): React.ReactNode => {\n // 定义行内样式的正则表达式和对应的组件\n const patterns: Array<{\n regex: RegExp\n render: (match: RegExpMatchArray, key: number) => React.ReactNode\n }> = [\n // 粗体\n {\n regex: /\\*\\*(.+?)\\*\\*|__(.+?)__/g,\n render: (match, key) => (\n <strong key={key} className=\"font-semibold\">\n {match[1] || match[2]}\n </strong>\n ),\n },\n // 斜体\n {\n regex: /\\*(.+?)\\*|_(.+?)_/g,\n render: (match, key) => (\n <em key={key} className=\"italic\">\n {match[1] || match[2]}\n </em>\n ),\n },\n // 删除线\n {\n regex: /~~(.+?)~~/g,\n render: (match, key) => (\n <del key={key} className=\"line-through\">\n {match[1]}\n </del>\n ),\n },\n // 行内代码\n {\n regex: /`([^`]+)`/g,\n render: (match, key) => (\n <code\n key={key}\n className=\"px-1.5 py-0.5 rounded-md font-mono text-[0.9em]\"\n style={{\n backgroundColor: 'var(--lm-bg-paper)',\n color: 'var(--lm-primary-600)',\n }}\n >\n {match[1]}\n </code>\n ),\n },\n // 链接\n {\n regex: /\\[([^\\]]+)\\]\\(([^)]+)\\)/g,\n render: (match, key) => (\n <a\n key={key}\n href={match[2]}\n onClick={(e) => onLinkClick?.(match[2], e)}\n target={openLinksInNewTab ? '_blank' : undefined}\n rel={openLinksInNewTab ? 'noopener noreferrer' : undefined}\n className=\"underline decoration-1 underline-offset-2 hover:opacity-80\"\n style={{ color: 'var(--lm-primary-500)' }}\n >\n {match[1]}\n </a>\n ),\n },\n ]\n\n // 简化处理:按顺序应用每个模式\n let result: React.ReactNode[] = [text]\n let keyCounter = 0\n\n patterns.forEach(({ regex, render }) => {\n const newResult: React.ReactNode[] = []\n result.forEach((node) => {\n if (typeof node !== 'string') {\n newResult.push(node)\n return\n }\n\n let lastIndex = 0\n let match: RegExpExecArray | null\n const clonedRegex = new RegExp(regex.source, regex.flags)\n\n while ((match = clonedRegex.exec(node)) !== null) {\n if (match.index > lastIndex) {\n newResult.push(node.slice(lastIndex, match.index))\n }\n newResult.push(render(match, keyCounter++))\n lastIndex = match.index + match[0].length\n }\n\n if (lastIndex < node.length) {\n newResult.push(node.slice(lastIndex))\n }\n })\n result = newResult\n })\n\n return result\n}\n\nconst LMMarkdownRenderer: React.FC<LMMarkdownRendererProps> = ({\n content,\n size = 'md',\n className = '',\n allowHtml: _allowHtml = false,\n renderCodeBlock,\n onLinkClick,\n openLinksInNewTab = true,\n customRenderer,\n}) => {\n const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER)\n const sizeConfig = TEXT_SIZE_CONFIG[resolvedSize]\n\n // 解析 Markdown(必须在所有条件返回之前调用 Hook)\n const tokens = useMemo(() => parseMarkdown(content), [content])\n\n // 使用自定义渲染器\n if (customRenderer) {\n return <div className={className}>{customRenderer(content)}</div>\n }\n\n // 渲染单个 token\n const renderToken = (token: Token, index: number): React.ReactNode => {\n switch (token.type) {\n case 'heading': {\n const HeadingTag = `h${token.level}` as keyof JSX.IntrinsicElements\n const headingSizeClass =\n token.level === 1 ? sizeConfig.h1 :\n token.level === 2 ? sizeConfig.h2 :\n sizeConfig.h3\n\n return (\n <HeadingTag\n key={index}\n className={`\n ${headingSizeClass}\n font-semibold leading-tight tracking-tight\n mt-6 mb-3 first:mt-0\n `.trim().replace(/\\s+/g, ' ')}\n style={{ color: 'var(--lm-text-primary)' }}\n >\n {parseInlineStyles(token.content, onLinkClick, openLinksInNewTab)}\n </HeadingTag>\n )\n }\n\n case 'paragraph':\n return (\n <p\n key={index}\n className={`\n ${sizeConfig.base}\n leading-relaxed my-3 first:mt-0 last:mb-0\n `.trim().replace(/\\s+/g, ' ')}\n style={{ color: 'var(--lm-text-primary)' }}\n >\n {parseInlineStyles(token.content, onLinkClick, openLinksInNewTab)}\n </p>\n )\n\n case 'codeBlock':\n if (renderCodeBlock) {\n return (\n <div key={index} className=\"my-4\">\n {renderCodeBlock(token.content, token.language, token.filename)}\n </div>\n )\n }\n return (\n <div key={index} className=\"my-4\">\n <LMCodeBlock\n code={token.content}\n language={token.language}\n filename={token.filename}\n size={resolvedSize}\n />\n </div>\n )\n\n case 'blockquote':\n return (\n <blockquote\n key={index}\n className=\"my-4 pl-4 border-l-4 italic\"\n style={{\n borderColor: 'var(--lm-primary-300)',\n color: 'var(--lm-text-secondary)',\n }}\n >\n {parseInlineStyles(token.content, onLinkClick, openLinksInNewTab)}\n </blockquote>\n )\n\n case 'list': {\n const ListTag = token.ordered ? 'ol' : 'ul'\n return (\n <ListTag\n key={index}\n className={`\n ${sizeConfig.base}\n my-3 pl-6\n ${token.ordered ? 'list-decimal' : 'list-disc'}\n `.trim().replace(/\\s+/g, ' ')}\n style={{ color: 'var(--lm-text-primary)' }}\n >\n {token.items?.map((item, i) => (\n <li key={i} className=\"my-1\">\n {parseInlineStyles(item, onLinkClick, openLinksInNewTab)}\n </li>\n ))}\n </ListTag>\n )\n }\n\n case 'hr':\n return (\n <hr\n key={index}\n className=\"my-6 border-0 h-px\"\n style={{ backgroundColor: 'var(--lm-border-default)' }}\n />\n )\n\n case 'table':\n return (\n <div key={index} className=\"my-4 overflow-x-auto\">\n <table\n className=\"w-full border-collapse\"\n style={{ borderColor: 'var(--lm-border-default)' }}\n >\n <thead>\n <tr>\n {token.rows?.[0]?.map((cell, i) => (\n <th\n key={i}\n className=\"px-3 py-2 text-left font-semibold border\"\n style={{\n backgroundColor: 'var(--lm-bg-paper)',\n borderColor: 'var(--lm-border-default)',\n color: 'var(--lm-text-primary)',\n }}\n >\n {parseInlineStyles(cell, onLinkClick, openLinksInNewTab)}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {token.rows?.slice(1).map((row, rowIndex) => (\n <tr key={rowIndex}>\n {row.map((cell, cellIndex) => (\n <td\n key={cellIndex}\n className=\"px-3 py-2 border\"\n style={{\n borderColor: 'var(--lm-border-default)',\n color: 'var(--lm-text-primary)',\n }}\n >\n {parseInlineStyles(cell, onLinkClick, openLinksInNewTab)}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )\n\n default:\n return null\n }\n }\n\n return (\n <div className={`${sizeConfig.base} ${className}`.trim()}>\n {tokens.map((token, index) => renderToken(token, index))}\n </div>\n )\n}\n\nexport default memo(LMMarkdownRenderer)\n","import React, { memo } from 'react'\nimport type { ComponentSize } from '../../../utils/componentSizes'\nimport { clampComponentSize, COMPONENT_SIZE_ORDER } from '../../../utils/componentSizes'\n\n/** 打字指示器主题样式 */\nconst typingIndicatorThemeStyles = `\n :root, [data-theme=\"light\"] {\n --lm-typing-bg: rgba(255, 255, 255, 0.85);\n --lm-typing-border: rgba(0, 0, 0, 0.06);\n --lm-typing-shadow: 0 4px 16px rgba(0, 0, 0, 0.06), 0 1px 3px rgba(0, 0, 0, 0.04);\n --lm-typing-avatar-bg: linear-gradient(135deg, var(--lm-gray-100) 0%, var(--lm-gray-200) 100%);\n }\n [data-theme=\"dark\"] {\n --lm-typing-bg: rgba(51, 65, 85, 0.85);\n --lm-typing-border: rgba(255, 255, 255, 0.08);\n --lm-typing-shadow: 0 4px 16px rgba(0, 0, 0, 0.2), 0 1px 3px rgba(0, 0, 0, 0.1);\n --lm-typing-avatar-bg: linear-gradient(135deg, var(--lm-gray-700) 0%, var(--lm-gray-600) 100%);\n }\n`\n\nexport type TypingIndicatorVariant = 'dots' | 'pulse' | 'wave' | 'bounce'\n\nexport interface LMTypingIndicatorProps {\n /** 变体样式 */\n variant?: TypingIndicatorVariant\n /** 尺寸 */\n size?: ComponentSize\n /** 显示文字(如 \"正在输入...\") */\n text?: string\n /** 头像 */\n avatar?: React.ReactNode\n /** 自定义类名 */\n className?: string\n /** 颜色 */\n color?: string\n}\n\n/** 尺寸配置 */\nconst SIZE_CONFIG: Record<ComponentSize, {\n dotSize: string\n gap: string\n padding: string\n fontSize: string\n avatarGap: string\n}> = {\n xs: { dotSize: 'w-1.5 h-1.5', gap: 'gap-1', padding: 'px-3 py-2', fontSize: 'text-xs', avatarGap: 'gap-2' },\n sm: { dotSize: 'w-1.5 h-1.5', gap: 'gap-1', padding: 'px-3.5 py-2.5', fontSize: 'text-sm', avatarGap: 'gap-2.5' },\n md: { dotSize: 'w-2 h-2', gap: 'gap-1.5', padding: 'px-4 py-3', fontSize: 'text-sm', avatarGap: 'gap-3' },\n lg: { dotSize: 'w-2.5 h-2.5', gap: 'gap-1.5', padding: 'px-5 py-3.5', fontSize: 'text-base', avatarGap: 'gap-3' },\n xl: { dotSize: 'w-3 h-3', gap: 'gap-2', padding: 'px-5 py-4', fontSize: 'text-base', avatarGap: 'gap-4' },\n '2xl': { dotSize: 'w-3.5 h-3.5', gap: 'gap-2', padding: 'px-6 py-4.5', fontSize: 'text-lg', avatarGap: 'gap-4' },\n}\n\n/** 头像尺寸 */\nconst AVATAR_SIZE: Record<ComponentSize, string> = {\n xs: 'w-6 h-6',\n sm: 'w-7 h-7',\n md: 'w-8 h-8',\n lg: 'w-10 h-10',\n xl: 'w-12 h-12',\n '2xl': 'w-14 h-14',\n}\n\nconst LMTypingIndicator: React.FC<LMTypingIndicatorProps> = ({\n variant = 'dots',\n size = 'md',\n text,\n avatar,\n className = '',\n color,\n}) => {\n const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER)\n const config = SIZE_CONFIG[resolvedSize]\n\n // 获取点的动画样式 - 更流畅的时间曲线\n const getDotAnimation = (index: number): React.CSSProperties => {\n const baseDelay = index * 0.16\n\n switch (variant) {\n case 'dots':\n return {\n animation: `lm-typing-dots 1.4s cubic-bezier(0.4, 0, 0.2, 1) ${baseDelay}s infinite`,\n }\n case 'pulse':\n return {\n animation: `lm-typing-pulse 1.5s cubic-bezier(0.4, 0, 0.6, 1) ${baseDelay}s infinite`,\n }\n case 'wave':\n return {\n animation: `lm-typing-wave 1.2s cubic-bezier(0.4, 0, 0.2, 1) ${baseDelay}s infinite`,\n }\n case 'bounce':\n return {\n animation: `lm-typing-bounce 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) ${baseDelay}s infinite alternate`,\n }\n default:\n return {}\n }\n }\n\n // 内联 CSS 动画 - 更精致的动画效果\n const animationStyles = `\n @keyframes lm-typing-dots {\n 0%, 80%, 100% {\n opacity: 0.35;\n transform: scale(0.85);\n }\n 40% {\n opacity: 1;\n transform: scale(1.1);\n }\n }\n @keyframes lm-typing-pulse {\n 0%, 100% {\n opacity: 0.3;\n transform: scale(0.9);\n }\n 50% {\n opacity: 1;\n transform: scale(1.05);\n }\n }\n @keyframes lm-typing-wave {\n 0%, 100% {\n transform: translateY(0);\n }\n 50% {\n transform: translateY(-5px);\n }\n }\n @keyframes lm-typing-bounce {\n 0% {\n transform: translateY(0) scale(1);\n }\n 100% {\n transform: translateY(-6px) scale(1.1);\n }\n }\n @media (prefers-reduced-motion: reduce) {\n [data-typing-indicator] span {\n animation: none !important;\n opacity: 0.6;\n }\n }\n `\n\n return (\n <>\n <style>{typingIndicatorThemeStyles}</style>\n <style>{animationStyles}</style>\n <div\n className={`\n flex items-center ${config.avatarGap}\n ${className}\n `.trim().replace(/\\s+/g, ' ')}\n data-typing-indicator\n >\n {/* 头像 */}\n {avatar && (\n <div\n className={`\n ${AVATAR_SIZE[resolvedSize]}\n rounded-full overflow-hidden shrink-0\n flex items-center justify-center\n `.trim().replace(/\\s+/g, ' ')}\n style={{\n background: 'var(--lm-typing-avatar-bg)',\n boxShadow: '0 2px 8px rgba(0, 0, 0, 0.06)',\n }}\n >\n {avatar}\n </div>\n )}\n\n {/* 指示器主体 - glassmorphism 效果 */}\n <div\n className={`\n inline-flex items-center\n ${config.padding}\n `.trim().replace(/\\s+/g, ' ')}\n style={{\n backgroundColor: 'var(--lm-typing-bg)',\n backdropFilter: 'blur(20px) saturate(180%)',\n WebkitBackdropFilter: 'blur(20px) saturate(180%)',\n border: '1px solid var(--lm-typing-border)',\n boxShadow: 'var(--lm-typing-shadow)',\n borderRadius: '20px 20px 20px 4px',\n }}\n >\n {/* 动画点 */}\n <div className={`flex items-center ${config.gap}`}>\n {[0, 1, 2].map((i) => (\n <span\n key={i}\n className={`\n ${config.dotSize}\n rounded-full\n `.trim()}\n style={{\n backgroundColor: color || 'var(--lm-primary-500)',\n ...getDotAnimation(i),\n }}\n />\n ))}\n </div>\n\n {/* 文字 */}\n {text && (\n <span\n className={`ml-2.5 font-medium ${config.fontSize}`}\n style={{ color: 'var(--lm-text-secondary)' }}\n >\n {text}\n </span>\n )}\n </div>\n </div>\n </>\n )\n}\n\nexport default memo(LMTypingIndicator)\n","import React, { memo, useRef, useEffect, useCallback, forwardRef, useImperativeHandle } from 'react'\nimport type { ComponentSize } from '../../../utils/componentSizes'\nimport { clampComponentSize, COMPONENT_SIZE_ORDER } from '../../../utils/componentSizes'\nimport { LMChatMessage, type LMChatMessageProps } from '../LMChatMessage'\nimport { LMTypingIndicator, type TypingIndicatorVariant } from '../LMTypingIndicator'\n\n/** 滚动条主题样式 */\nconst scrollbarThemeStyles = `\n :root, [data-theme=\"light\"] {\n --lm-scrollbar-track: rgba(0, 0, 0, 0.02);\n --lm-scrollbar-thumb: rgba(0, 0, 0, 0.15);\n --lm-scrollbar-thumb-hover: rgba(0, 0, 0, 0.25);\n }\n [data-theme=\"dark\"] {\n --lm-scrollbar-track: rgba(255, 255, 255, 0.02);\n --lm-scrollbar-thumb: rgba(255, 255, 255, 0.15);\n --lm-scrollbar-thumb-hover: rgba(255, 255, 255, 0.25);\n }\n\n /* WebKit scrollbar styling */\n .lm-chat-list-scrollbar::-webkit-scrollbar {\n width: 6px;\n }\n .lm-chat-list-scrollbar::-webkit-scrollbar-track {\n background: var(--lm-scrollbar-track);\n border-radius: 3px;\n }\n .lm-chat-list-scrollbar::-webkit-scrollbar-thumb {\n background: var(--lm-scrollbar-thumb);\n border-radius: 3px;\n transition: background 0.2s ease;\n }\n .lm-chat-list-scrollbar::-webkit-scrollbar-thumb:hover {\n background: var(--lm-scrollbar-thumb-hover);\n }\n\n /* Firefox scrollbar styling */\n .lm-chat-list-scrollbar {\n scrollbar-width: thin;\n scrollbar-color: var(--lm-scrollbar-thumb) var(--lm-scrollbar-track);\n }\n`\n\nexport interface ChatMessage extends Omit<LMChatMessageProps, 'size' | 'variant'> {\n /** 消息唯一 ID(必须) */\n id: string\n}\n\nexport interface LMChatListProps {\n /** 消息列表 */\n messages: ChatMessage[]\n /** 尺寸 */\n size?: ComponentSize\n /** 消息气泡变体 */\n variant?: 'default' | 'filled' | 'outline' | 'soft'\n /** 是否显示打字指示器 */\n showTypingIndicator?: boolean\n /** 打字指示器变体 */\n typingIndicatorVariant?: TypingIndicatorVariant\n /** 打字指示器文字 */\n typingIndicatorText?: string\n /** 打字指示器头像 */\n typingIndicatorAvatar?: React.ReactNode\n /** 是否自动滚动到底部 */\n autoScrollToBottom?: boolean\n /** 滚动行为 */\n scrollBehavior?: 'auto' | 'smooth'\n /** 消息间距 */\n messageGap?: number\n /** 自定义类名 */\n className?: string\n /** 空状态内容 */\n emptyContent?: React.ReactNode\n /** 加载中状态 */\n loading?: boolean\n /** 加载更多回调(滚动到顶部时触发) */\n onLoadMore?: () => void\n /** 是否还有更多消息 */\n hasMore?: boolean\n /** 加载更多文字 */\n loadMoreText?: string\n /** 自定义渲染消息 */\n renderMessage?: (message: ChatMessage, index: number) => React.ReactNode\n /** 消息重试回调 */\n onMessageRetry?: (messageId: string) => void\n /** 气泡最大宽度(默认 85%) */\n bubbleMaxWidth?: string | number\n}\n\nexport interface LMChatListRef {\n /** 滚动到底部 */\n scrollToBottom: (behavior?: 'auto' | 'smooth') => void\n /** 滚动到指定消息 */\n scrollToMessage: (messageId: string, behavior?: 'auto' | 'smooth') => void\n /** 获取容器元素 */\n getContainer: () => HTMLDivElement | null\n}\n\n/** 加载骨架屏 */\nconst LoadingSkeleton: React.FC = () => (\n <div className=\"flex flex-col gap-4 p-4 animate-pulse\">\n {[1, 2, 3].map((i) => (\n <div key={i} className={`flex gap-3 ${i % 2 === 0 ? 'flex-row-reverse' : ''}`}>\n <div\n className=\"w-8 h-8 rounded-full shrink-0\"\n style={{ backgroundColor: 'var(--lm-bg-hover)' }}\n />\n <div\n className=\"h-16 rounded-2xl flex-1 max-w-[70%]\"\n style={{ backgroundColor: 'var(--lm-bg-hover)' }}\n />\n </div>\n ))}\n </div>\n)\n\n/** 空状态 */\nconst EmptyState: React.FC<{ children?: React.ReactNode }> = ({ children }) => (\n <div\n className=\"flex flex-col items-center justify-center h-full p-8 text-center\"\n style={{ color: 'var(--lm-text-tertiary)' }}\n >\n {children || (\n <>\n <svg\n className=\"w-16 h-16 mb-4 opacity-40\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.5}\n >\n <path d=\"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2v10z\" />\n </svg>\n <p className=\"text-sm\">暂无消息</p>\n <p className=\"text-xs mt-1 opacity-60\">开始一段新的对话吧</p>\n </>\n )}\n </div>\n)\n\n/** 加载更多组件 */\nconst LoadMoreTrigger: React.FC<{\n loading?: boolean\n hasMore?: boolean\n text?: string\n onLoadMore?: () => void\n}> = ({ loading, hasMore, text = '加载更多', onLoadMore }) => {\n if (!hasMore) return null\n\n return (\n <div className=\"flex justify-center py-3\">\n <button\n onClick={onLoadMore}\n disabled={loading}\n className=\"px-4 py-2 text-sm rounded-lg cursor-pointer hover:opacity-80 disabled:opacity-50\"\n style={{\n backgroundColor: 'var(--lm-bg-paper)',\n color: 'var(--lm-text-secondary)',\n }}\n >\n {loading ? (\n <span className=\"flex items-center gap-2\">\n <span className=\"w-4 h-4 border-2 rounded-full animate-spin border-current border-t-transparent\" />\n 加载中...\n </span>\n ) : (\n text\n )}\n </button>\n </div>\n )\n}\n\nconst LMChatList = forwardRef<LMChatListRef, LMChatListProps>(({\n messages,\n size = 'md',\n variant = 'default',\n showTypingIndicator = false,\n typingIndicatorVariant = 'dots',\n typingIndicatorText,\n typingIndicatorAvatar,\n autoScrollToBottom = true,\n scrollBehavior = 'smooth',\n messageGap = 16,\n className = '',\n emptyContent,\n loading = false,\n onLoadMore,\n hasMore = false,\n loadMoreText,\n renderMessage,\n onMessageRetry,\n bubbleMaxWidth,\n}, ref) => {\n const containerRef = useRef<HTMLDivElement>(null)\n const bottomRef = useRef<HTMLDivElement>(null)\n const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER)\n\n // 暴露方法给父组件\n useImperativeHandle(ref, () => ({\n scrollToBottom: (behavior: 'auto' | 'smooth' = scrollBehavior) => {\n bottomRef.current?.scrollIntoView({ behavior })\n },\n scrollToMessage: (messageId: string, behavior: 'auto' | 'smooth' = scrollBehavior) => {\n const element = containerRef.current?.querySelector(`[id=\"${messageId}\"]`)\n element?.scrollIntoView({ behavior, block: 'center' })\n },\n getContainer: () => containerRef.current,\n }), [scrollBehavior])\n\n // 自动滚动到底部\n useEffect(() => {\n if (autoScrollToBottom && messages.length > 0) {\n bottomRef.current?.scrollIntoView({ behavior: scrollBehavior })\n }\n }, [messages.length, autoScrollToBottom, scrollBehavior])\n\n // 显示打字指示器时也滚动到底部\n useEffect(() => {\n if (showTypingIndicator && autoScrollToBottom) {\n bottomRef.current?.scrollIntoView({ behavior: scrollBehavior })\n }\n }, [showTypingIndicator, autoScrollToBottom, scrollBehavior])\n\n // 检测滚动到顶部\n const handleScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {\n if (!onLoadMore || !hasMore) return\n\n const { scrollTop } = e.currentTarget\n if (scrollTop < 50) {\n onLoadMore()\n }\n }, [onLoadMore, hasMore])\n\n // 加载中\n if (loading && messages.length === 0) {\n return (\n <>\n <style>{scrollbarThemeStyles}</style>\n <div\n ref={containerRef}\n className={`flex-1 overflow-y-auto lm-chat-list-scrollbar ${className}`.trim()}\n >\n <LoadingSkeleton />\n </div>\n </>\n )\n }\n\n // 空状态\n if (messages.length === 0 && !showTypingIndicator) {\n return (\n <>\n <style>{scrollbarThemeStyles}</style>\n <div\n ref={containerRef}\n className={`flex-1 overflow-y-auto lm-chat-list-scrollbar ${className}`.trim()}\n >\n <EmptyState>{emptyContent}</EmptyState>\n </div>\n </>\n )\n }\n\n return (\n <>\n <style>{scrollbarThemeStyles}</style>\n <div\n ref={containerRef}\n className={`flex-1 overflow-y-auto lm-chat-list-scrollbar ${className}`.trim()}\n onScroll={handleScroll}\n >\n {/* 加载更多 */}\n <LoadMoreTrigger\n loading={loading}\n hasMore={hasMore}\n text={loadMoreText}\n onLoadMore={onLoadMore}\n />\n\n {/* 消息列表 */}\n <div\n className=\"flex flex-col p-4\"\n style={{ gap: `${messageGap}px` }}\n >\n {messages.map((message, index) => (\n renderMessage ? (\n <React.Fragment key={message.id}>\n {renderMessage(message, index)}\n </React.Fragment>\n ) : (\n <LMChatMessage\n key={message.id}\n {...message}\n size={resolvedSize}\n variant={variant}\n onRetry={onMessageRetry ? () => onMessageRetry(message.id) : undefined}\n bubbleMaxWidth={bubbleMaxWidth}\n />\n )\n ))}\n\n {/* 打字指示器 */}\n {showTypingIndicator && (\n <LMTypingIndicator\n variant={typingIndicatorVariant}\n size={resolvedSize}\n text={typingIndicatorText}\n avatar={typingIndicatorAvatar}\n />\n )}\n\n {/* 滚动锚点 */}\n <div ref={bottomRef} />\n </div>\n </div>\n </>\n )\n})\n\nLMChatList.displayName = 'LMChatList'\n\nexport default memo(LMChatList)\n","import React, { memo, useRef, useCallback, forwardRef, useImperativeHandle } from 'react'\nimport type { ComponentSize } from '../../../utils/componentSizes'\nimport { clampComponentSize, COMPONENT_SIZE_ORDER } from '../../../utils/componentSizes'\nimport { LMChatList, type LMChatListRef, type ChatMessage, type LMChatListProps } from '../LMChatList'\nimport { LMChatInput } from '../LMChatInput'\n\nexport interface LMChatContainerProps {\n /** 消息列表 */\n messages: ChatMessage[]\n /** 尺寸 */\n size?: ComponentSize\n /** 消息气泡变体 */\n variant?: 'default' | 'filled' | 'outline' | 'soft'\n /** 发送消息回调 */\n onSend?: (content: string) => void\n /** 停止生成回调 */\n onStop?: () => void\n /** 是否正在生成 */\n isGenerating?: boolean\n /** 是否禁用输入 */\n disabled?: boolean\n /** 输入框占位符 */\n placeholder?: string\n /** 输入框值(受控) */\n inputValue?: string\n /** 输入框值变化回调 */\n onInputChange?: (value: string) => void\n /** 最大输入字符数 */\n maxInputLength?: number\n /** 显示字符计数 */\n showInputCount?: boolean\n /** 是否显示打字指示器 */\n showTypingIndicator?: boolean\n /** 打字指示器文字 */\n typingIndicatorText?: string\n /** 打字指示器头像 */\n typingIndicatorAvatar?: React.ReactNode\n /** 自定义类名 */\n className?: string\n /** 头部内容 */\n header?: React.ReactNode\n /** 底部额外内容(输入框上方) */\n footer?: React.ReactNode\n /** 输入框右侧插槽 */\n inputRightSlot?: React.ReactNode\n /** 输入框底部工具栏 */\n inputToolbar?: React.ReactNode\n /** 空状态内容 */\n emptyContent?: React.ReactNode\n /** 加载中状态 */\n loading?: boolean\n /** 加载更多回调 */\n onLoadMore?: () => void\n /** 是否还有更多消息 */\n hasMore?: boolean\n /** 消息重试回调 */\n onMessageRetry?: (messageId: string) => void\n /** 自定义渲染消息 */\n renderMessage?: LMChatListProps['renderMessage']\n /** 输入框自动聚焦 */\n autoFocus?: boolean\n /** 按 Enter 发送 */\n enterToSend?: boolean\n /** 高度 */\n height?: string | number\n /** 最大高度 */\n maxHeight?: string | number\n /** 气泡最大宽度(默认 85%) */\n bubbleMaxWidth?: string | number\n}\n\nexport interface LMChatContainerRef {\n /** 滚动到底部 */\n scrollToBottom: (behavior?: 'auto' | 'smooth') => void\n /** 滚动到指定消息 */\n scrollToMessage: (messageId: string, behavior?: 'auto' | 'smooth') => void\n /** 聚焦输入框 */\n focusInput: () => void\n /** 获取输入框值 */\n getInputValue: () => string\n /** 设置输入框值 */\n setInputValue: (value: string) => void\n /** 清空输入框 */\n clearInput: () => void\n}\n\nconst LMChatContainer = forwardRef<LMChatContainerRef, LMChatContainerProps>(({\n messages,\n size = 'md',\n variant = 'default',\n onSend,\n onStop,\n isGenerating = false,\n disabled = false,\n placeholder = '输入消息...',\n inputValue,\n onInputChange,\n maxInputLength,\n showInputCount = false,\n showTypingIndicator = false,\n typingIndicatorText,\n typingIndicatorAvatar,\n className = '',\n header,\n footer,\n inputRightSlot,\n inputToolbar,\n emptyContent,\n loading = false,\n onLoadMore,\n hasMore = false,\n onMessageRetry,\n renderMessage,\n autoFocus = false,\n enterToSend = true,\n height,\n maxHeight,\n bubbleMaxWidth,\n}, ref) => {\n const chatListRef = useRef<LMChatListRef>(null)\n const inputRef = useRef<string>('')\n const resolvedSize = clampComponentSize(size, COMPONENT_SIZE_ORDER)\n\n // 处理发送\n const handleSend = useCallback((value: string) => {\n if (!value.trim() || disabled || isGenerating) return\n onSend?.(value)\n }, [disabled, isGenerating, onSend])\n\n // 处理输入变化\n const handleInputChange = useCallback((value: string) => {\n inputRef.current = value\n onInputChange?.(value)\n }, [onInputChange])\n\n // 暴露方法给父组件\n useImperativeHandle(ref, () => ({\n scrollToBottom: (behavior) => {\n chatListRef.current?.scrollToBottom(behavior)\n },\n scrollToMessage: (messageId, behavior) => {\n chatListRef.current?.scrollToMessage(messageId, behavior)\n },\n focusInput: () => {\n // 输入框会自动处理聚焦\n },\n getInputValue: () => inputRef.current,\n setInputValue: (value) => {\n inputRef.current = value\n onInputChange?.(value)\n },\n clearInput: () => {\n inputRef.current = ''\n onInputChange?.('')\n },\n }), [onInputChange])\n\n // 容器样式\n const getContainerStyles = (): React.CSSProperties => ({\n backgroundColor: 'var(--lm-bg-default)',\n borderColor: 'var(--lm-border-default)',\n ...(height ? { height: typeof height === 'number' ? `${height}px` : height } : {}),\n ...(maxHeight ? { maxHeight: typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight } : {}),\n })\n\n return (\n <div\n className={`\n flex flex-col border rounded-2xl overflow-hidden\n ${className}\n `.trim().replace(/\\s+/g, ' ')}\n style={getContainerStyles()}\n >\n {/* 头部 */}\n {header && (\n <div\n className=\"shrink-0 border-b px-4 py-3\"\n style={{\n backgroundColor: 'var(--lm-bg-elevated)',\n borderColor: 'var(--lm-border-default)',\n }}\n >\n {header}\n </div>\n )}\n\n {/* 消息列表 */}\n <LMChatList\n ref={chatListRef}\n messages={messages}\n size={resolvedSize}\n variant={variant}\n showTypingIndicator={showTypingIndicator}\n typingIndicatorText={typingIndicatorText}\n typingIndicatorAvatar={typingIndicatorAvatar}\n emptyContent={emptyContent}\n loading={loading}\n onLoadMore={onLoadMore}\n hasMore={hasMore}\n onMessageRetry={onMessageRetry}\n renderMessage={renderMessage}\n className=\"flex-1 min-h-0\"\n bubbleMaxWidth={bubbleMaxWidth}\n />\n\n {/* 底部额外内容 */}\n {footer && (\n <div\n className=\"shrink-0 px-4 py-2 border-t\"\n style={{ borderColor: 'var(--lm-border-light)' }}\n >\n {footer}\n </div>\n )}\n\n {/* 输入区域 */}\n <div\n className=\"shrink-0 p-4 border-t\"\n style={{\n backgroundColor: 'var(--lm-bg-elevated)',\n borderColor: 'var(--lm-border-default)',\n }}\n >\n <LMChatInput\n value={inputValue}\n onChange={handleInputChange}\n onSend={handleSend}\n onStop={onStop}\n isGenerating={isGenerating}\n placeholder={placeholder}\n size={resolvedSize}\n disabled={disabled}\n sending={isGenerating}\n maxLength={maxInputLength}\n showCount={showInputCount}\n autoFocus={autoFocus}\n enterToSend={enterToSend}\n rightSlot={inputRightSlot}\n toolbar={inputToolbar}\n />\n </div>\n </div>\n )\n})\n\nLMChatContainer.displayName = 'LMChatContainer'\n\nexport default memo(LMChatContainer)\n","/**\n * Utility for merging class names\n * Simple implementation without external dependencies\n */\n\ntype ClassValue = string | undefined | null | false | ClassValue[]\n\nexport function cn(...inputs: ClassValue[]): string {\n return inputs\n .flat()\n .filter((x): x is string => typeof x === 'string' && x.length > 0)\n .join(' ')\n}\n"],"names":["jsxs","jsx","SIZE_CONFIG","LMChatInput","useRef","useState","clampComponentSize","COMPONENT_SIZE_ORDER","useEffect","useCallback","Fragment","SIZE_TEXT_CLASSES","memo","LMChatBubble","SIZE_PADDING_CLASSES","CopyIcon","CheckIcon","AVATAR_SIZE","LMChatMessage","LMCodeBlock","useMemo","LMTypingIndicator","LMChatList","forwardRef","useImperativeHandle"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export * from './components/Form';
4
4
  export * from './components/DataDisplay';
5
5
  export * from './components/Navigation';
6
6
  export * from './components/Feedback';
7
+ export * from './components/Chat';
7
8
  export * from './utils';
8
9
  export * from './types';
9
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,mBAAmB,CAAA;AAG1B,cAAc,sBAAsB,CAAA;AACpC,cAAc,mBAAmB,CAAA;AACjC,cAAc,0BAA0B,CAAA;AACxC,cAAc,yBAAyB,CAAA;AACvC,cAAc,uBAAuB,CAAA;AAGrC,cAAc,SAAS,CAAA;AAGvB,cAAc,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,mBAAmB,CAAA;AAG1B,cAAc,sBAAsB,CAAA;AACpC,cAAc,mBAAmB,CAAA;AACjC,cAAc,0BAA0B,CAAA;AACxC,cAAc,yBAAyB,CAAA;AACvC,cAAc,uBAAuB,CAAA;AACrC,cAAc,mBAAmB,CAAA;AAGjC,cAAc,SAAS,CAAA;AAGvB,cAAc,SAAS,CAAA"}