ai-chat-ui-kit 0.1.0 → 0.1.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 (96) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +4 -7
  3. package/package.json +8 -4
  4. package/.eslintrc.cjs +0 -74
  5. package/.github/actions/screenshot/action.yml +0 -35
  6. package/.github/workflows/pages.yml +0 -46
  7. package/docs/README.md +0 -176
  8. package/docs/api/components.md +0 -344
  9. package/docs/api/core.md +0 -349
  10. package/docs/chat-style-1-minimal.html +0 -78
  11. package/docs/chat-style-2-neon.html +0 -74
  12. package/docs/chat-style-3-glass.html +0 -73
  13. package/docs/chat-style-4-terminal.html +0 -84
  14. package/docs/chat-style-5-gradient.html +0 -69
  15. package/docs/chat-style-6-corporate.html +0 -116
  16. package/docs/examples/basic-chat.md +0 -291
  17. package/docs/examples/custom-plugins.md +0 -431
  18. package/docs/examples/multi-model.md +0 -466
  19. package/docs/guide/api-adapters.md +0 -431
  20. package/docs/guide/getting-started.md +0 -244
  21. package/docs/guide/headless-mode.md +0 -508
  22. package/docs/guide/plugins.md +0 -416
  23. package/docs/guide/themes.md +0 -327
  24. package/docs/index.html +0 -256
  25. package/docs/theme-preview-1-minimal.html +0 -74
  26. package/docs/theme-preview-2-neon.html +0 -73
  27. package/docs/theme-preview-3-glass.html +0 -77
  28. package/docs/theme-preview-4-terminal.html +0 -86
  29. package/docs/theme-preview-5-gradient.html +0 -79
  30. package/docs/theme-preview-6-corporate.html +0 -71
  31. package/examples/index.html +0 -414
  32. package/examples/react-app/App.tsx +0 -131
  33. package/examples/react-app/index.html +0 -12
  34. package/examples/react-app/main.tsx +0 -15
  35. package/examples/react-app/package.json +0 -24
  36. package/examples/vue-app/index.html +0 -12
  37. package/examples/vue-app/package.json +0 -22
  38. package/examples/vue-app/src/App.vue +0 -145
  39. package/examples/vue-app/src/main.ts +0 -9
  40. package/packages/components/package.json +0 -25
  41. package/packages/components/src/chat/chat.css +0 -80
  42. package/packages/components/src/chat/chat.ts +0 -236
  43. package/packages/components/src/index.ts +0 -36
  44. package/packages/components/src/input/input.css +0 -52
  45. package/packages/components/src/input/input.ts +0 -116
  46. package/packages/components/src/markdown/markdown.css +0 -118
  47. package/packages/components/src/markdown/markdown.ts +0 -229
  48. package/packages/components/src/message/message.css +0 -56
  49. package/packages/components/src/message/message.ts +0 -72
  50. package/packages/components/src/styles/global.css +0 -43
  51. package/packages/components/src/tool-call/tool-call.css +0 -98
  52. package/packages/components/src/tool-call/tool-call.ts +0 -171
  53. package/packages/components/src/types.ts +0 -55
  54. package/packages/components/src/utils/helpers.ts +0 -128
  55. package/packages/components/tsconfig.json +0 -25
  56. package/packages/components/tsup.config.ts +0 -18
  57. package/packages/core/package.json +0 -47
  58. package/packages/core/pnpm-lock.yaml +0 -2032
  59. package/packages/core/pnpm-workspace.yaml +0 -2
  60. package/packages/core/src/api/adapters.ts +0 -717
  61. package/packages/core/src/api/base.ts +0 -210
  62. package/packages/core/src/api/index.ts +0 -54
  63. package/packages/core/src/index.ts +0 -93
  64. package/packages/core/src/parser/latex.ts +0 -274
  65. package/packages/core/src/parser/markdown.test.ts +0 -58
  66. package/packages/core/src/parser/markdown.ts +0 -206
  67. package/packages/core/src/parser/mermaid.ts +0 -276
  68. package/packages/core/src/plugins/PluginManager.ts +0 -232
  69. package/packages/core/src/plugins/builtin.ts +0 -406
  70. package/packages/core/src/store/ChatStore.ts +0 -163
  71. package/packages/core/src/store/ModelConfigStore.ts +0 -136
  72. package/packages/core/src/store/ToolCallStore.ts +0 -164
  73. package/packages/core/src/store/base.ts +0 -75
  74. package/packages/core/src/types/index.ts +0 -133
  75. package/packages/core/tsup.config.ts +0 -18
  76. package/packages/themes/package.json +0 -33
  77. package/packages/themes/src/corporate/index.ts +0 -52
  78. package/packages/themes/src/corporate/theme.css +0 -228
  79. package/packages/themes/src/glass/index.ts +0 -52
  80. package/packages/themes/src/glass/theme.css +0 -237
  81. package/packages/themes/src/gradient/index.ts +0 -53
  82. package/packages/themes/src/gradient/theme.css +0 -218
  83. package/packages/themes/src/index.ts +0 -13
  84. package/packages/themes/src/minimal/index.ts +0 -52
  85. package/packages/themes/src/minimal/theme.css +0 -198
  86. package/packages/themes/src/neon/index.ts +0 -52
  87. package/packages/themes/src/neon/theme.css +0 -233
  88. package/packages/themes/src/terminal/index.ts +0 -52
  89. package/packages/themes/src/terminal/theme.css +0 -235
  90. package/packages/themes/src/types.ts +0 -10
  91. package/packages/themes/src/vite-env.d.ts +0 -9
  92. package/packages/themes/tsup.config.ts +0 -21
  93. package/pnpm-workspace.yaml +0 -4
  94. package/tsconfig.json +0 -27
  95. package/vite.config.ts +0 -25
  96. package/vitest.config.ts +0 -28
@@ -1,164 +0,0 @@
1
- /**
2
- * @generated-by AI: edenxpzhang
3
- * @generated-date 2026-05-13
4
- */
5
-
6
- import { BaseStore } from './base.js';
7
- import { ToolCall } from '../types/index.js';
8
-
9
- // 工具调用状态
10
- interface ToolCallState {
11
- // 所有工具调用
12
- toolCalls: Map<string, ToolCall>;
13
- // 按消息 ID 索引
14
- messageToolCalls: Map<string, string[]>;
15
- // 正在执行的工具调用 ID
16
- executingIds: Set<string>;
17
- }
18
-
19
- // 初始状态
20
- const initialState: ToolCallState = {
21
- toolCalls: new Map(),
22
- messageToolCalls: new Map(),
23
- executingIds: new Set()
24
- };
25
-
26
- export class ToolCallStore extends BaseStore<ToolCallState> {
27
- constructor() {
28
- super(initialState);
29
- }
30
-
31
- // 添加工具调用
32
- addToolCall(messageId: string, toolCall: ToolCall): void {
33
- const toolCalls = new Map(this.state.toolCalls);
34
- toolCalls.set(toolCall.id, toolCall);
35
-
36
- const messageToolCalls = new Map(this.state.messageToolCalls);
37
- const ids = messageToolCalls.get(messageId) || [];
38
- messageToolCalls.set(messageId, [...ids, toolCall.id]);
39
-
40
- this.setState({ toolCalls, messageToolCalls });
41
- }
42
-
43
- // 批量添加工具调用
44
- addToolCalls(messageId: string, toolCalls: ToolCall[]): void {
45
- const newToolCalls = new Map(this.state.toolCalls);
46
- const newMessageToolCalls = new Map(this.state.messageToolCalls);
47
-
48
- const ids = newMessageToolCalls.get(messageId) || [];
49
- const newIds: string[] = [];
50
-
51
- toolCalls.forEach(tc => {
52
- newToolCalls.set(tc.id, tc);
53
- newIds.push(tc.id);
54
- });
55
-
56
- newMessageToolCalls.set(messageId, [...ids, ...newIds]);
57
-
58
- this.setState({
59
- toolCalls: newToolCalls,
60
- messageToolCalls: newMessageToolCalls
61
- });
62
- }
63
-
64
- // 更新工具调用状态
65
- updateToolCallStatus(id: string, status: ToolCall['status']): void {
66
- const toolCalls = new Map(this.state.toolCalls);
67
- const toolCall = toolCalls.get(id);
68
-
69
- if (toolCall) {
70
- toolCalls.set(id, { ...toolCall, status });
71
-
72
- const executingIds = new Set(this.state.executingIds);
73
- if (status === 'executing') {
74
- executingIds.add(id);
75
- } else {
76
- executingIds.delete(id);
77
- }
78
-
79
- this.setState({ toolCalls, executingIds });
80
- }
81
- }
82
-
83
- // 设置工具调用结果
84
- setToolCallResult(id: string, result: unknown): void {
85
- const toolCalls = new Map(this.state.toolCalls);
86
- const toolCall = toolCalls.get(id);
87
-
88
- if (toolCall) {
89
- toolCalls.set(id, { ...toolCall, result, status: 'completed' });
90
-
91
- const executingIds = new Set(this.state.executingIds);
92
- executingIds.delete(id);
93
-
94
- this.setState({ toolCalls, executingIds });
95
- }
96
- }
97
-
98
- // 设置工具调用错误
99
- setToolCallError(id: string, error: unknown): void {
100
- const toolCalls = new Map(this.state.toolCalls);
101
- const toolCall = toolCalls.get(id);
102
-
103
- if (toolCall) {
104
- toolCalls.set(id, {
105
- ...toolCall,
106
- result: error,
107
- status: 'failed'
108
- });
109
-
110
- const executingIds = new Set(this.state.executingIds);
111
- executingIds.delete(id);
112
-
113
- this.setState({ toolCalls, executingIds });
114
- }
115
- }
116
-
117
- // 获取消息的工具调用
118
- getToolCallsForMessage(messageId: string): ToolCall[] {
119
- const ids = this.state.messageToolCalls.get(messageId) || [];
120
- return ids
121
- .map(id => this.state.toolCalls.get(id))
122
- .filter(Boolean) as ToolCall[];
123
- }
124
-
125
- // 获取正在执行的工具调用
126
- getExecutingToolCalls(): ToolCall[] {
127
- return Array.from(this.state.executingIds)
128
- .map(id => this.state.toolCalls.get(id))
129
- .filter(Boolean) as ToolCall[];
130
- }
131
-
132
- // 是否有正在执行的工具调用
133
- hasExecuting(): boolean {
134
- return this.state.executingIds.size > 0;
135
- }
136
-
137
- // 清除消息的工具调用
138
- clearToolCallsForMessage(messageId: string): void {
139
- const messageToolCalls = new Map(this.state.messageToolCalls);
140
- const ids = messageToolCalls.get(messageId) || [];
141
-
142
- const toolCalls = new Map(this.state.toolCalls);
143
- const executingIds = new Set(this.state.executingIds);
144
-
145
- ids.forEach(id => {
146
- toolCalls.delete(id);
147
- executingIds.delete(id);
148
- });
149
-
150
- messageToolCalls.delete(messageId);
151
-
152
- this.setState({ toolCalls, messageToolCalls, executingIds });
153
- }
154
-
155
- // 清除所有工具调用
156
- clearAll(): void {
157
- this.setState(initialState);
158
- }
159
-
160
- // 重置
161
- reset(): void {
162
- this.setState(initialState);
163
- }
164
- }
@@ -1,75 +0,0 @@
1
- /**
2
- * @generated-by AI: edenxpzhang
3
- * @generated-date 2026-05-13
4
- */
5
-
6
- // 简单的事件发射器(用于状态管理)
7
- export class EventEmitter {
8
- private events: Map<string, Set<Function>> = new Map();
9
-
10
- // 订阅事件
11
- on(event: string, callback: Function): void {
12
- if (!this.events.has(event)) {
13
- this.events.set(event, new Set());
14
- }
15
- this.events.get(event)?.add(callback);
16
- }
17
-
18
- // 取消订阅
19
- off(event: string, callback: Function): void {
20
- const callbacks = this.events.get(event);
21
- if (callbacks) {
22
- callbacks.delete(callback);
23
- }
24
- }
25
-
26
- // 触发事件
27
- emit(event: string, ...args: unknown[]): void {
28
- const callbacks = this.events.get(event);
29
- if (callbacks) {
30
- callbacks.forEach((callback) => {
31
- try {
32
- callback(...args);
33
- } catch (error) {
34
- console.error(`Error in event listener for "${event}":`, error);
35
- }
36
- });
37
- }
38
- }
39
-
40
- // 清空所有事件
41
- clear(): void {
42
- this.events.clear();
43
- }
44
- }
45
-
46
- // Store 基类
47
- export abstract class BaseStore<T> {
48
- protected state: T;
49
- protected emitter: EventEmitter;
50
-
51
- constructor(initialState: T) {
52
- this.state = initialState;
53
- this.emitter = new EventEmitter();
54
- }
55
-
56
- // 获取状态
57
- getState(): T {
58
- return this.state;
59
- }
60
-
61
- // 更新状态
62
- protected setState(partial: Partial<T>): void {
63
- this.state = { ...this.state, ...partial };
64
- this.emitter.emit('change', this.state);
65
- }
66
-
67
- // 订阅状态变化
68
- subscribe(callback: (state: T) => void): () => void {
69
- this.emitter.on('change', callback);
70
- return () => this.emitter.off('change', callback);
71
- }
72
-
73
- // 重置状态
74
- abstract reset(): void;
75
- }
@@ -1,133 +0,0 @@
1
- /**
2
- * @generated-by AI: edenxpzhang
3
- * @generated-date 2026-05-13
4
- */
5
-
6
- // 消息角色枚举
7
- export enum MessageRole {
8
- User = 'user',
9
- Assistant = 'assistant',
10
- System = 'system',
11
- Tool = 'tool'
12
- }
13
-
14
- // 消息类型
15
- export interface Message {
16
- id: string;
17
- role: MessageRole;
18
- content: string;
19
- timestamp: number;
20
- // 工具调用相关
21
- toolCalls?: ToolCall[];
22
- // 元数据(用于插件扩展)
23
- metadata?: Record<string, unknown>;
24
- }
25
-
26
- // 工具调用
27
- export interface ToolCall {
28
- id: string;
29
- name: string;
30
- arguments: Record<string, unknown>;
31
- result?: unknown;
32
- status: 'pending' | 'executing' | 'completed' | 'failed';
33
- }
34
-
35
- // 模型配置
36
- export interface ModelConfig {
37
- // 模型提供商
38
- provider: 'openai' | 'ernie' | 'qwen' | 'spark' | 'hunyuan' | 'custom';
39
- // 模型名称
40
- model: string;
41
- // API 端点
42
- apiEndpoint?: string;
43
- // API Key
44
- apiKey?: string;
45
- // 自定义请求头
46
- headers?: Record<string, string>;
47
- // 请求参数
48
- params?: {
49
- temperature?: number;
50
- topP?: number;
51
- maxTokens?: number;
52
- [key: string]: unknown;
53
- };
54
- }
55
-
56
- // 聊天配置
57
- export interface ChatConfig {
58
- // 是否启用流式输出
59
- stream?: boolean;
60
- // 系统提示词
61
- systemPrompt?: string;
62
- // 历史消息数量限制
63
- maxHistory?: number;
64
- // 是否启用工具调用
65
- enableTools?: boolean;
66
- }
67
-
68
- // API 适配器接口
69
- export interface APIAdapter {
70
- // 发送消息
71
- sendMessage(params: {
72
- messages: Message[];
73
- modelConfig: ModelConfig;
74
- chatConfig: ChatConfig;
75
- onChunk?: (chunk: string) => void;
76
- onToolCall?: (toolCall: ToolCall) => void;
77
- onComplete?: (message: Message) => void;
78
- onError?: (error: Error) => void;
79
- }): Promise<void>;
80
-
81
- // 取消请求
82
- abort(): void;
83
- }
84
-
85
- // 消息插件接口
86
- export interface MessagePlugin {
87
- // 插件类型标识
88
- type: string;
89
- // 判断是否匹配该插件
90
- match: (content: string) => boolean;
91
- // 渲染函数
92
- render: (content: string, context: RenderContext) => HTMLElement | string;
93
- // 优先级(数字越大优先级越高)
94
- priority?: number;
95
- }
96
-
97
- // 渲染上下文
98
- export interface RenderContext {
99
- // 消息对象
100
- message: Message;
101
- // 是否流式输出中
102
- isStreaming: boolean;
103
- // 主题
104
- theme: string;
105
- // 自定义配置
106
- [key: string]: unknown;
107
- }
108
-
109
- // 主题配置
110
- export interface ThemeConfig {
111
- // 主题名称
112
- name: string;
113
- // CSS 变量
114
- variables: Record<string, string>;
115
- // 自定义样式
116
- styles?: string;
117
- }
118
-
119
- // 聊天状态
120
- export interface ChatState {
121
- // 消息列表
122
- messages: Message[];
123
- // 是否加载中
124
- isLoading: boolean;
125
- // 是否流式输出中
126
- isStreaming: boolean;
127
- // 错误
128
- error: Error | null;
129
- // 当前会话 ID
130
- sessionId: string;
131
- }
132
-
133
-
@@ -1,18 +0,0 @@
1
- /**
2
- * @generated-by AI: edenxpzhang
3
- * @generated-date 2026-05-13
4
- */
5
- import { defineConfig } from 'tsup';
6
-
7
- export default defineConfig({
8
- entry: ['src/**/*.ts'],
9
- outDir: 'dist',
10
- format: ['esm', 'cjs'],
11
- target: 'es2020',
12
- splitting: true,
13
- clean: true,
14
- dts: true,
15
- sourcemap: true,
16
- treeshake: true,
17
- external: ['vitest', 'vitest/**'],
18
- });
@@ -1,33 +0,0 @@
1
- {
2
- "name": "@ai-chat/themes",
3
- "version": "0.1.0",
4
- "description": "Theme packages for AI Chat UI Kit",
5
- "main": "dist/index.js",
6
- "module": "dist/index.mjs",
7
- "types": "dist/index.d.mts",
8
- "exports": {
9
- ".": {
10
- "import": "./dist/index.mjs",
11
- "require": "./dist/index.js",
12
- "types": "./dist/index.d.mts"
13
- },
14
- "./package.json": "./package.json"
15
- },
16
- "files": ["dist"],
17
- "scripts": {
18
- "dev": "tsup --watch",
19
- "build": "tsup"
20
- },
21
- "dependencies": {},
22
- "devDependencies": {
23
- "copyfiles": "^2.0.0"
24
- },
25
- "peerDependenciesMeta": {
26
- "@ai-chat/components": {
27
- "optional": true
28
- }
29
- },
30
- "keywords": ["ai", "chat", "theme", "ui"],
31
- "author": "edenxpzhang",
32
- "license": "MIT"
33
- }
@@ -1,52 +0,0 @@
1
- /**
2
- * @generated-by AI: edenxpzhang
3
- * @generated-date 2026-05-13
4
- */
5
-
6
- import type { ThemeConfig } from '../types.js';
7
- import themeStyles from './theme.css?raw';
8
-
9
- export const corporateTheme: ThemeConfig = {
10
- name: 'corporate',
11
- variables: {
12
- '--ai-primary': '#1890ff',
13
- '--ai-primary-hover': '#40a9ff',
14
- '--ai-primary-active': '#096dd9',
15
- '--ai-bg-primary': '#ffffff',
16
- '--ai-bg-secondary': '#fafafa',
17
- '--ai-bg-tertiary': '#f0f2f5',
18
- '--ai-bg-chat': '#fafafa',
19
- '--ai-text-primary': '#333333',
20
- '--ai-text-secondary': '#666666',
21
- '--ai-text-tertiary': '#999999',
22
- '--ai-text-inverse': '#ffffff',
23
- '--ai-message-user-bg': '#1890ff',
24
- '--ai-message-user-text': '#ffffff',
25
- '--ai-message-ai-bg': '#ffffff',
26
- '--ai-message-ai-text': '#333333',
27
- '--ai-message-border': '#e8e8e8',
28
- '--ai-input-bg': '#ffffff',
29
- '--ai-input-border': '#d9d9d9',
30
- '--ai-input-focus-border': '#1890ff',
31
- '--ai-input-text': '#333333',
32
- '--ai-input-placeholder': '#999999',
33
- '--ai-tool-call-bg': '#f6f8fa',
34
- '--ai-tool-call-border': '#d1d9e0',
35
- '--ai-tool-call-success': '#52c41a',
36
- '--ai-tool-call-error': '#ff4d4f',
37
- '--ai-tool-call-running': '#1890ff',
38
- '--ai-shadow-sm': '0 1px 2px rgba(0, 0, 0, 0.06)',
39
- '--ai-shadow-md': '0 2px 8px rgba(0, 0, 0, 0.1)',
40
- '--ai-shadow-lg': '0 2px 8px rgba(0, 0, 0, 0.1)',
41
- '--ai-radius-sm': '2px',
42
- '--ai-radius-md': '4px',
43
- '--ai-radius-lg': '8px',
44
- '--ai-radius-xl': '8px',
45
- '--ai-spacing-xs': '4px',
46
- '--ai-spacing-sm': '8px',
47
- '--ai-spacing-md': '12px',
48
- '--ai-spacing-lg': '24px',
49
- '--ai-spacing-xl': '24px',
50
- },
51
- styles: themeStyles,
52
- };
@@ -1,228 +0,0 @@
1
- /**
2
- * @generated-by AI: edenxpzhang
3
- * @generated-date 2026-05-13
4
- *
5
- * Corporate Professional —— 企业商务
6
- * 对齐 docs/chat-style-6-corporate.html
7
- */
8
-
9
- :root[data-theme='corporate'],
10
- .ai-theme-corporate {
11
- --ai-primary: #1890ff;
12
- --ai-primary-hover: #40a9ff;
13
- --ai-bg-primary: #ffffff;
14
- --ai-bg-secondary: #fafafa;
15
- --ai-text-primary: #333;
16
- --ai-border: #e8e8e8;
17
- --ai-message-user-bg: #1890ff;
18
- --ai-message-user-text: #fff;
19
- --ai-message-ai-bg: #fff;
20
- --ai-message-ai-text: #333;
21
- }
22
-
23
- /* body */
24
- .ai-theme-corporate-host,
25
- body[data-theme='corporate'] {
26
- background: #f0f2f5;
27
- }
28
-
29
- /* 容器 */
30
- .ai-theme-corporate .ai-chat,
31
- [data-theme='corporate'] .ai-chat {
32
- background: #fff;
33
- border-radius: 8px;
34
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
35
- border: 1px solid #e8e8e8;
36
- font-family: 'Microsoft YaHei', 'Segoe UI', sans-serif;
37
- overflow: hidden;
38
- }
39
-
40
- /* Header */
41
- .ai-theme-corporate .ai-chat__header,
42
- [data-theme='corporate'] .ai-chat__header {
43
- padding: 16px 24px;
44
- background: #fff;
45
- border-bottom: 3px solid #1890ff;
46
- display: flex;
47
- align-items: center;
48
- gap: 16px;
49
- }
50
- .ai-theme-corporate .ai-chat__avatar,
51
- [data-theme='corporate'] .ai-chat__avatar {
52
- width: 42px;
53
- height: 42px;
54
- background: #1890ff;
55
- border-radius: 8px;
56
- color: #fff;
57
- font-size: 18px;
58
- font-weight: bold;
59
- display: flex;
60
- align-items: center;
61
- justify-content: center;
62
- }
63
- .ai-theme-corporate .ai-chat__title,
64
- [data-theme='corporate'] .ai-chat__title {
65
- font-size: 16px;
66
- font-weight: 600;
67
- color: #333;
68
- }
69
- .ai-theme-corporate .ai-chat__subtitle,
70
- [data-theme='corporate'] .ai-chat__subtitle {
71
- font-size: 12px;
72
- color: #999;
73
- }
74
-
75
- /* Messages */
76
- .ai-theme-corporate .ai-chat__messages,
77
- [data-theme='corporate'] .ai-chat__messages {
78
- background: #fafafa;
79
- padding: 24px;
80
- gap: 20px;
81
- }
82
- .ai-theme-corporate .ai-chat__messages::-webkit-scrollbar,
83
- [data-theme='corporate'] .ai-chat__messages::-webkit-scrollbar { width: 6px; }
84
- .ai-theme-corporate .ai-chat__messages::-webkit-scrollbar-thumb,
85
- [data-theme='corporate'] .ai-chat__messages::-webkit-scrollbar-thumb {
86
- background: #d9d9d9;
87
- border-radius: 3px;
88
- }
89
-
90
- /* Message */
91
- .ai-theme-corporate .ai-message,
92
- [data-theme='corporate'] .ai-message {
93
- max-width: 85%;
94
- display: flex;
95
- gap: 12px;
96
- }
97
- .ai-theme-corporate .ai-message__avatar,
98
- [data-theme='corporate'] .ai-message__avatar {
99
- display: flex;
100
- width: 36px;
101
- height: 36px;
102
- border-radius: 50%;
103
- align-items: center;
104
- justify-content: center;
105
- font-size: 13px;
106
- font-weight: bold;
107
- color: #fff;
108
- flex-shrink: 0;
109
- }
110
- .ai-theme-corporate .ai-message--user .ai-message__avatar,
111
- [data-theme='corporate'] .ai-message--user .ai-message__avatar { background: #52c41a; }
112
- .ai-theme-corporate .ai-message--assistant .ai-message__avatar,
113
- [data-theme='corporate'] .ai-message--assistant .ai-message__avatar { background: #1890ff; }
114
- .ai-theme-corporate .ai-message__content,
115
- [data-theme='corporate'] .ai-message__content {
116
- padding: 12px 16px;
117
- border-radius: 8px;
118
- font-size: 14px;
119
- line-height: 1.6;
120
- }
121
- .ai-theme-corporate .ai-message--user .ai-message__content,
122
- [data-theme='corporate'] .ai-message--user .ai-message__content {
123
- background: #1890ff;
124
- color: #fff;
125
- border-top-right-radius: 2px;
126
- }
127
- .ai-theme-corporate .ai-message--assistant .ai-message__content,
128
- [data-theme='corporate'] .ai-message--assistant .ai-message__content {
129
- background: #fff;
130
- color: #333;
131
- border: 1px solid #e8e8e8;
132
- border-top-left-radius: 2px;
133
- }
134
- .ai-theme-corporate .ai-message__time,
135
- [data-theme='corporate'] .ai-message__time {
136
- font-size: 11px;
137
- color: #999;
138
- margin-top: 4px;
139
- }
140
- .ai-theme-corporate .ai-message--user .ai-message__time,
141
- [data-theme='corporate'] .ai-message--user .ai-message__time { text-align: right; }
142
-
143
- /* Input */
144
- .ai-theme-corporate .ai-input,
145
- [data-theme='corporate'] .ai-input {
146
- padding: 16px 24px;
147
- background: #fff;
148
- border-top: 1px solid #e8e8e8;
149
- }
150
- .ai-theme-corporate .ai-input__wrapper,
151
- [data-theme='corporate'] .ai-input__wrapper {
152
- display: flex;
153
- gap: 12px;
154
- align-items: flex-end;
155
- }
156
- .ai-theme-corporate .ai-input__textarea,
157
- [data-theme='corporate'] .ai-input__textarea {
158
- flex: 1;
159
- padding: 12px 16px;
160
- border: 1px solid #d9d9d9;
161
- border-radius: 6px;
162
- font-size: 14px;
163
- resize: none;
164
- outline: none;
165
- min-height: 44px;
166
- max-height: 120px;
167
- font-family: inherit;
168
- transition: all 0.2s;
169
- background: #fff;
170
- color: #333;
171
- }
172
- .ai-theme-corporate .ai-input__textarea:focus,
173
- [data-theme='corporate'] .ai-input__textarea:focus {
174
- border-color: #1890ff;
175
- box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
176
- }
177
- .ai-theme-corporate .ai-input__send,
178
- [data-theme='corporate'] .ai-input__send {
179
- padding: 12px 24px;
180
- background: #1890ff;
181
- color: #fff;
182
- border: none;
183
- border-radius: 6px;
184
- cursor: pointer;
185
- font-size: 14px;
186
- font-weight: 500;
187
- transition: all 0.2s;
188
- white-space: nowrap;
189
- }
190
- .ai-theme-corporate .ai-input__send:hover:not(:disabled),
191
- [data-theme='corporate'] .ai-input__send:hover:not(:disabled) {
192
- background: #40a9ff;
193
- }
194
- .ai-theme-corporate .ai-input__send:disabled,
195
- [data-theme='corporate'] .ai-input__send:disabled {
196
- background: #d9d9d9;
197
- cursor: not-allowed;
198
- }
199
-
200
- /* Typing */
201
- .ai-theme-corporate .ai-typing-indicator,
202
- [data-theme='corporate'] .ai-typing-indicator {
203
- display: flex;
204
- gap: 4px;
205
- padding: 14px 16px;
206
- background: #fff;
207
- border: 1px solid #e8e8e8;
208
- border-radius: 8px;
209
- border-top-left-radius: 2px;
210
- width: fit-content;
211
- }
212
- .ai-theme-corporate .ai-typing-indicator__dot,
213
- [data-theme='corporate'] .ai-typing-indicator__dot {
214
- width: 6px;
215
- height: 6px;
216
- background: #999;
217
- border-radius: 50%;
218
- animation: ai-typing-bounce 1.4s infinite;
219
- }
220
- .ai-theme-corporate .ai-typing-indicator__dot:nth-child(2),
221
- [data-theme='corporate'] .ai-typing-indicator__dot:nth-child(2) { animation-delay: 0.2s; }
222
- .ai-theme-corporate .ai-typing-indicator__dot:nth-child(3),
223
- [data-theme='corporate'] .ai-typing-indicator__dot:nth-child(3) { animation-delay: 0.4s; }
224
-
225
- @keyframes ai-typing-bounce {
226
- 0%, 60%, 100% { transform: translateY(0); }
227
- 30% { transform: translateY(-6px); }
228
- }