@blueking/chat-x 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.css +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp/generated/docs/activity-message.md +428 -0
- package/dist/mcp/generated/docs/ai-image.md +227 -0
- package/dist/mcp/generated/docs/ai-loading.md +129 -0
- package/dist/mcp/generated/docs/ai-selection.md +436 -0
- package/dist/mcp/generated/docs/animation-text.md +199 -0
- package/dist/mcp/generated/docs/assistant-message.md +424 -0
- package/dist/mcp/generated/docs/chat-container.md +365 -0
- package/dist/mcp/generated/docs/chat-input.md +625 -0
- package/dist/mcp/generated/docs/cite-content.md +138 -0
- package/dist/mcp/generated/docs/code-content.md +199 -0
- package/dist/mcp/generated/docs/common-error-content.md +70 -0
- package/dist/mcp/generated/docs/constants.md +216 -0
- package/dist/mcp/generated/docs/content-render.md +238 -0
- package/dist/mcp/generated/docs/delete-tool.md +188 -0
- package/dist/mcp/generated/docs/desc-panel.md +139 -0
- package/dist/mcp/generated/docs/execution-summary.md +126 -0
- package/dist/mcp/generated/docs/file-content.md +300 -0
- package/dist/mcp/generated/docs/file-upload-btn.md +174 -0
- package/dist/mcp/generated/docs/flow-message.md +305 -0
- package/dist/mcp/generated/docs/highlight-keyword.md +144 -0
- package/dist/mcp/generated/docs/image-content.md +178 -0
- package/dist/mcp/generated/docs/image-preview-group.md +181 -0
- package/dist/mcp/generated/docs/image-preview.md +224 -0
- package/dist/mcp/generated/docs/info-message.md +124 -0
- package/dist/mcp/generated/docs/key-value-content.md +124 -0
- package/dist/mcp/generated/docs/latex-content.md +196 -0
- package/dist/mcp/generated/docs/loading-message.md +171 -0
- package/dist/mcp/generated/docs/markdown-content.md +186 -0
- package/dist/mcp/generated/docs/markdown-latex.md +208 -0
- package/dist/mcp/generated/docs/markdown-mermaid.md +250 -0
- package/dist/mcp/generated/docs/mermaid-content.md +185 -0
- package/dist/mcp/generated/docs/message-container.md +534 -0
- package/dist/mcp/generated/docs/message-render.md +329 -0
- package/dist/mcp/generated/docs/message-tools.md +376 -0
- package/dist/mcp/generated/docs/messages.md +472 -0
- package/dist/mcp/generated/docs/overflow-tips.md +209 -0
- package/dist/mcp/generated/docs/reasoning-message.md +233 -0
- package/dist/mcp/generated/docs/reference-content.md +132 -0
- package/dist/mcp/generated/docs/scroll-btn.md +155 -0
- package/dist/mcp/generated/docs/selection-footer.md +75 -0
- package/dist/mcp/generated/docs/shortcut-btn.md +202 -0
- package/dist/mcp/generated/docs/shortcut-btns.md +264 -0
- package/dist/mcp/generated/docs/shortcut-render.md +418 -0
- package/dist/mcp/generated/docs/text-content.md +74 -0
- package/dist/mcp/generated/docs/theme.md +388 -0
- package/dist/mcp/generated/docs/tool-btn.md +254 -0
- package/dist/mcp/generated/docs/tool-message.md +217 -0
- package/dist/mcp/generated/docs/toolcall-render.md +299 -0
- package/dist/mcp/generated/docs/use-animation-text.md +198 -0
- package/dist/mcp/generated/docs/use-clipboard.md +206 -0
- package/dist/mcp/generated/docs/use-command-selection.md +128 -0
- package/dist/mcp/generated/docs/use-container-scroll.md +56 -0
- package/dist/mcp/generated/docs/use-custom-tab.md +122 -0
- package/dist/mcp/generated/docs/use-global-config.md +154 -0
- package/dist/mcp/generated/docs/use-menu-keydown.md +164 -0
- package/dist/mcp/generated/docs/use-message-group.md +175 -0
- package/dist/mcp/generated/docs/use-observer-visible-list.md +189 -0
- package/dist/mcp/generated/docs/use-parent-scrolling.md +46 -0
- package/dist/mcp/generated/docs/user-feedback.md +229 -0
- package/dist/mcp/generated/docs/user-message.md +347 -0
- package/dist/mcp/generated/index.json +1311 -0
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.js +42 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.js +43 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/get-component-doc.d.ts +19 -0
- package/dist/mcp/tools/get-component-doc.js +60 -0
- package/dist/mcp/tools/get-component-doc.js.map +1 -0
- package/dist/mcp/tools/list-components.d.ts +35 -0
- package/dist/mcp/tools/list-components.js +147 -0
- package/dist/mcp/tools/list-components.js.map +1 -0
- package/dist/mcp/tools/search-docs.d.ts +14 -0
- package/dist/mcp/tools/search-docs.js +82 -0
- package/dist/mcp/tools/search-docs.js.map +1 -0
- package/dist/mcp/utils/doc-loader.d.ts +35 -0
- package/dist/mcp/utils/doc-loader.js +64 -0
- package/dist/mcp/utils/doc-loader.js.map +1 -0
- package/package.json +5 -7
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
<!-- AI SUMMARY -->
|
|
2
|
+
## 快速了解
|
|
3
|
+
|
|
4
|
+
说明通过 SCSS 变量(尺寸、颜色、z-index)与 CSS 类覆盖(chat-input、用户/助手消息、shortcut-btns、markdown-body、tool-btn 等)自定义主题。 含渐变边框 mixin、ai-markdown-fade-in 与弹窗过渡。暗色示例通过根 class 切换。组件随包引入样式,业务侧按需覆写。
|
|
5
|
+
|
|
6
|
+
### 关联组件
|
|
7
|
+
- **chat-container** — 整体布局与侧栏
|
|
8
|
+
- **chat-input** — 输入区与渐变边框
|
|
9
|
+
- **message-container** — 消息区样式上下文
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
<!-- FULL DOC -->
|
|
13
|
+
|
|
14
|
+
# 主题配置
|
|
15
|
+
|
|
16
|
+
> **分类**:theme
|
|
17
|
+
|
|
18
|
+
`@blueking/chat-x` 使用 SCSS 变量和 CSS 类来控制样式,支持通过覆盖变量或样式来自定义主题。
|
|
19
|
+
|
|
20
|
+
## 样式引入
|
|
21
|
+
|
|
22
|
+
组件库的样式会在引入组件时自动加载,无需单独引入:
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
// 引入组件时会自动引入样式
|
|
26
|
+
import { ChatInput, MessageContainer } from '@blueking/chat-x';
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## SCSS 变量
|
|
30
|
+
|
|
31
|
+
组件库使用以下 SCSS 变量,可以在项目中覆盖:
|
|
32
|
+
|
|
33
|
+
### 尺寸变量
|
|
34
|
+
|
|
35
|
+
```scss
|
|
36
|
+
// 输入框尺寸
|
|
37
|
+
$chat-input-min-width: 350px;
|
|
38
|
+
$chat-input-max-width: 700px;
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 颜色变量
|
|
42
|
+
|
|
43
|
+
```scss
|
|
44
|
+
// 主题色
|
|
45
|
+
$primary-color: #3a84ff;
|
|
46
|
+
|
|
47
|
+
// 文字颜色
|
|
48
|
+
$text-color-primary: #313238;
|
|
49
|
+
$text-color-secondary: #4d4f56;
|
|
50
|
+
$text-color-placeholder: #979ba5;
|
|
51
|
+
|
|
52
|
+
// 背景色
|
|
53
|
+
$bg-color-white: #fff;
|
|
54
|
+
$bg-color-light: #f5f7fa;
|
|
55
|
+
$bg-color-hover: #f0f1f5;
|
|
56
|
+
|
|
57
|
+
// 边框色
|
|
58
|
+
$border-color: #dcdee5;
|
|
59
|
+
$border-color-hover: #c4c6cc;
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Z-Index 变量
|
|
63
|
+
|
|
64
|
+
组件库使用分层的 z-index 管理:
|
|
65
|
+
|
|
66
|
+
```scss
|
|
67
|
+
// 基础 z-index
|
|
68
|
+
$chat-z-index: 9999;
|
|
69
|
+
|
|
70
|
+
// 编辑器 z-index
|
|
71
|
+
$editor-z-index: $chat-z-index + 1;
|
|
72
|
+
|
|
73
|
+
// 编辑器菜单 z-index
|
|
74
|
+
$editor-menu-z-index: $editor-z-index + 1;
|
|
75
|
+
|
|
76
|
+
// 快捷指令菜单 z-index
|
|
77
|
+
$shortcut-menu-z-index: $editor-menu-z-index + 1;
|
|
78
|
+
|
|
79
|
+
// 划选弹窗 z-index
|
|
80
|
+
$selection-z-index: $shortcut-menu-z-index + 1;
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## CSS 类覆盖
|
|
84
|
+
|
|
85
|
+
### 输入框样式
|
|
86
|
+
|
|
87
|
+
```scss
|
|
88
|
+
// 覆盖输入框容器样式
|
|
89
|
+
.chat-input-container {
|
|
90
|
+
.chat-input {
|
|
91
|
+
min-height: 120px; // 自定义最小高度
|
|
92
|
+
max-height: 250px; // 自定义最大高度
|
|
93
|
+
background: #fafafa; // 自定义背景色
|
|
94
|
+
|
|
95
|
+
// 覆盖边框渐变
|
|
96
|
+
&::before {
|
|
97
|
+
background: linear-gradient(180deg, #ff6b6b, #ff8e53);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 消息样式
|
|
104
|
+
|
|
105
|
+
```scss
|
|
106
|
+
// 用户消息样式
|
|
107
|
+
.ai-user-message {
|
|
108
|
+
&-content {
|
|
109
|
+
background-color: #d4edda; // 自定义背景色
|
|
110
|
+
border-radius: 8px;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// AI 消息样式
|
|
115
|
+
.assistant-message {
|
|
116
|
+
&-content {
|
|
117
|
+
background-color: #f8f9fa;
|
|
118
|
+
border-left: 3px solid #3a84ff;
|
|
119
|
+
padding-left: 12px;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 快捷指令按钮样式
|
|
125
|
+
|
|
126
|
+
```scss
|
|
127
|
+
// 快捷指令按钮
|
|
128
|
+
.shortcut-btns {
|
|
129
|
+
&-item {
|
|
130
|
+
background: linear-gradient(135deg, #667eea, #764ba2);
|
|
131
|
+
color: #fff;
|
|
132
|
+
|
|
133
|
+
&:hover {
|
|
134
|
+
transform: translateY(-2px);
|
|
135
|
+
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// 移除默认渐变边框
|
|
139
|
+
&::before {
|
|
140
|
+
display: none;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### 消息工具栏样式
|
|
147
|
+
|
|
148
|
+
```scss
|
|
149
|
+
// 工具按钮
|
|
150
|
+
.tool-btn {
|
|
151
|
+
width: 24px;
|
|
152
|
+
height: 24px;
|
|
153
|
+
font-size: 16px;
|
|
154
|
+
|
|
155
|
+
&:hover {
|
|
156
|
+
background-color: #e1ecff;
|
|
157
|
+
color: #3a84ff;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Markdown 内容样式
|
|
163
|
+
|
|
164
|
+
```scss
|
|
165
|
+
// Markdown 内容
|
|
166
|
+
.markdown-content {
|
|
167
|
+
.markdown-body {
|
|
168
|
+
font-size: 14px;
|
|
169
|
+
line-height: 1.6;
|
|
170
|
+
|
|
171
|
+
// 代码块样式
|
|
172
|
+
pre code.hljs {
|
|
173
|
+
background-color: #1e1e1e;
|
|
174
|
+
border-radius: 8px;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// 表格样式
|
|
178
|
+
table {
|
|
179
|
+
border-collapse: collapse;
|
|
180
|
+
|
|
181
|
+
th,
|
|
182
|
+
td {
|
|
183
|
+
border: 1px solid #dcdee5;
|
|
184
|
+
padding: 8px 12px;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
th {
|
|
188
|
+
background-color: #f5f7fa;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## 主题切换示例
|
|
196
|
+
|
|
197
|
+
### 暗色主题
|
|
198
|
+
|
|
199
|
+
```scss
|
|
200
|
+
// 暗色主题变量
|
|
201
|
+
.dark-theme {
|
|
202
|
+
// 输入框
|
|
203
|
+
.chat-input-container .chat-input {
|
|
204
|
+
background: #2d2d2d;
|
|
205
|
+
|
|
206
|
+
&::before {
|
|
207
|
+
background: linear-gradient(180deg, #4a90d9, #357abd);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// 用户消息
|
|
212
|
+
.ai-user-message-content {
|
|
213
|
+
background-color: #3d5a80;
|
|
214
|
+
color: #fff;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// AI 消息
|
|
218
|
+
.assistant-message {
|
|
219
|
+
color: #e0e0e0;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Markdown 内容
|
|
223
|
+
.markdown-content .markdown-body {
|
|
224
|
+
color: #e0e0e0;
|
|
225
|
+
|
|
226
|
+
h1,
|
|
227
|
+
h2,
|
|
228
|
+
h3,
|
|
229
|
+
h4,
|
|
230
|
+
h5,
|
|
231
|
+
h6 {
|
|
232
|
+
color: #fff;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
a {
|
|
236
|
+
color: #6cb2eb;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
code {
|
|
240
|
+
background-color: #3d3d3d;
|
|
241
|
+
color: #e0e0e0;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// 快捷指令
|
|
246
|
+
.shortcut-btns-item {
|
|
247
|
+
background: #3d3d3d;
|
|
248
|
+
color: #e0e0e0;
|
|
249
|
+
|
|
250
|
+
&::before {
|
|
251
|
+
background: linear-gradient(105deg, #4a90d940, #9b59b640);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// 工具按钮
|
|
256
|
+
.tool-btn {
|
|
257
|
+
color: #9e9e9e;
|
|
258
|
+
|
|
259
|
+
&:hover {
|
|
260
|
+
background-color: #424242;
|
|
261
|
+
color: #fff;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### 使用暗色主题
|
|
268
|
+
|
|
269
|
+
```vue
|
|
270
|
+
<template>
|
|
271
|
+
<div :class="{ 'dark-theme': isDark }">
|
|
272
|
+
<ChatInput v-model="input" />
|
|
273
|
+
<MessageContainer :messages="messages" />
|
|
274
|
+
</div>
|
|
275
|
+
</template>
|
|
276
|
+
|
|
277
|
+
<script setup lang="ts">
|
|
278
|
+
import { ref } from 'vue';
|
|
279
|
+
import { ChatInput, MessageContainer } from '@blueking/chat-x';
|
|
280
|
+
|
|
281
|
+
const isDark = ref(false);
|
|
282
|
+
const input = ref('');
|
|
283
|
+
const messages = ref([]);
|
|
284
|
+
</script>
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## 渐变边框
|
|
288
|
+
|
|
289
|
+
组件库使用 CSS mask 实现渐变边框效果:
|
|
290
|
+
|
|
291
|
+
```scss
|
|
292
|
+
// 渐变边框 mixin
|
|
293
|
+
@mixin linear-gradient-border($angle: 105deg, $start-color: #235dfa40, $end-color: #bc81ef40) {
|
|
294
|
+
content: '';
|
|
295
|
+
position: absolute;
|
|
296
|
+
inset: 0;
|
|
297
|
+
padding: 1px;
|
|
298
|
+
background: linear-gradient($angle, $start-color, $end-color);
|
|
299
|
+
mask:
|
|
300
|
+
linear-gradient(#fff 0 0) content-box,
|
|
301
|
+
linear-gradient(#fff 0 0);
|
|
302
|
+
mask-composite: xor;
|
|
303
|
+
mask-composite: exclude;
|
|
304
|
+
border-radius: inherit;
|
|
305
|
+
pointer-events: none;
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
使用示例:
|
|
310
|
+
|
|
311
|
+
```scss
|
|
312
|
+
.custom-card {
|
|
313
|
+
position: relative;
|
|
314
|
+
border-radius: 8px;
|
|
315
|
+
|
|
316
|
+
&::before {
|
|
317
|
+
@include linear-gradient-border(180deg, #6cbaff, #3a84ff);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## 动画效果
|
|
323
|
+
|
|
324
|
+
### 淡入动画
|
|
325
|
+
|
|
326
|
+
```scss
|
|
327
|
+
// 全局淡入动画
|
|
328
|
+
@keyframes ai-markdown-fade-in {
|
|
329
|
+
from {
|
|
330
|
+
opacity: 0;
|
|
331
|
+
}
|
|
332
|
+
to {
|
|
333
|
+
opacity: 1;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
.ai-blueking-markdown-fade-in {
|
|
338
|
+
animation: ai-markdown-fade-in 0.2s ease-out forwards;
|
|
339
|
+
}
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### 弹窗过渡
|
|
343
|
+
|
|
344
|
+
```scss
|
|
345
|
+
// 选择弹窗过渡
|
|
346
|
+
.ai-fade-enter-active,
|
|
347
|
+
.ai-fade-leave-active {
|
|
348
|
+
transition:
|
|
349
|
+
opacity 0.2s ease,
|
|
350
|
+
transform 0.2s ease;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.ai-fade-enter-from,
|
|
354
|
+
.ai-fade-leave-to {
|
|
355
|
+
opacity: 0;
|
|
356
|
+
transform: translateY(4px);
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## 响应式设计
|
|
361
|
+
|
|
362
|
+
```scss
|
|
363
|
+
// 移动端适配
|
|
364
|
+
@media (max-width: 768px) {
|
|
365
|
+
.chat-input-container .chat-input {
|
|
366
|
+
min-width: 100%;
|
|
367
|
+
max-width: 100%;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
.shortcut-btns {
|
|
371
|
+
min-width: 100%;
|
|
372
|
+
max-width: 100%;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
## 注意事项
|
|
378
|
+
|
|
379
|
+
1. **样式优先级**:覆盖样式时可能需要使用更高优先级的选择器
|
|
380
|
+
2. **变量位置**:SCSS 变量需要在组件样式之前定义
|
|
381
|
+
3. **构建配置**:确保项目配置支持 SCSS 处理
|
|
382
|
+
4. **组件隔离**:使用 scoped 样式时,深度选择器 `::v-deep` 或 `:deep()` 可能需要
|
|
383
|
+
|
|
384
|
+
## 关联组件
|
|
385
|
+
|
|
386
|
+
- [ChatContainer](../components/molecular/chat-container.md) — 布局与主题根节点
|
|
387
|
+
- [ChatInput](../components/molecular/chat-input.md) — 输入区变量与类名
|
|
388
|
+
- [MessageContainer](../components/molecular/message-container.md) — 消息列表区域
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
<!-- AI SUMMARY -->
|
|
2
|
+
## 快速了解
|
|
3
|
+
|
|
4
|
+
ToolBtn 为消息工具栏提供单个操作入口:内置常用 id 与 SVG 图标映射、Tippy 提示、激活与禁用态。 通常由 MessageTools 遍历配置渲染;DeleteTool 也可将其作为删除触发的视觉入口。
|
|
5
|
+
|
|
6
|
+
### 关联组件
|
|
7
|
+
- **message-tools** — 父级组装多个工具按钮与交互
|
|
8
|
+
- **delete-tool** — 删除确认场景内嵌为触发控件
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
<!-- FULL DOC -->
|
|
12
|
+
|
|
13
|
+
# ToolBtn 工具按钮
|
|
14
|
+
|
|
15
|
+
> **层级**:原子组件 · **功能域**:工具与反馈
|
|
16
|
+
|
|
17
|
+
消息工具栏中的单个操作按钮,内置 SVG 图标映射、Tippy 悬浮提示、激活态与禁用态,通常由 `MessageTools` 管理,一般不需要手动使用。
|
|
18
|
+
|
|
19
|
+
## 组件结构
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
div.ai-tool-btn(v-tippy,flex,min-width: 20px,height: 20px,border-radius: 4px)
|
|
23
|
+
color: #a8aab2; background: transparent
|
|
24
|
+
active=true → .is-active(color: var(--ai-tool-btn-active-color))
|
|
25
|
+
disabled=true → .is-disabled(color: #979ba5; cursor: not-allowed)
|
|
26
|
+
:not(.is-disabled):hover → color: #4d4f56; background: #eaebf0
|
|
27
|
+
│
|
|
28
|
+
├── [id in ToolIconsMap] → <component :is="ToolIconsMap[id]" />(SVG 图标,font-size: 16px 控制大小)
|
|
29
|
+
└── [id not in ToolIconsMap] → <div>{{ name }}</div>(文本回退,XSS 安全)
|
|
30
|
+
|
|
31
|
+
Tippy:content=description, theme='ai-chat-box', disabled=true 时 onShow 返回 false 不显示
|
|
32
|
+
click 事件:disabled=true 时被 JS 拦截,不触发 emit
|
|
33
|
+
|
|
34
|
+
激活色(CSS 变量 --ai-tool-btn-active-color):
|
|
35
|
+
id === 'like' 或 'activeLike' → #3a84ff(蓝色)
|
|
36
|
+
其他 id(如 'unlike'、'delete') → #E71818(红色)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 预置图标(ToolIconsMap)
|
|
40
|
+
|
|
41
|
+
| id | 说明 | 备注 |
|
|
42
|
+
| -------------- | -------------- | ------------------------ |
|
|
43
|
+
| `copy` | 复制 | |
|
|
44
|
+
| `cite` | 引用 | |
|
|
45
|
+
| `rebuild` | 重新生成 | |
|
|
46
|
+
| `share` | 分享 | |
|
|
47
|
+
| `like` | 点赞(空心) | 配合 `activeLike` 使用 |
|
|
48
|
+
| `unlike` | 不满意(空心) | 配合 `activeUnLike` 使用 |
|
|
49
|
+
| `delete` | 删除 | |
|
|
50
|
+
| `edit` | 编辑 | |
|
|
51
|
+
| `activeLike` | 点赞(实心) | 激活态填充图标 |
|
|
52
|
+
| `activeUnLike` | 不满意(实心) | 激活态填充图标 |
|
|
53
|
+
|
|
54
|
+
> `id` 不在上表时,组件渲染 `<div>{{ name }}</div>` 作为文本回退。此时 `id` 的 TypeScript 类型会报错(`keyof typeof ToolIconsMap`),建议优先使用预置 ID。
|
|
55
|
+
|
|
56
|
+
## 基础用法
|
|
57
|
+
|
|
58
|
+
```vue
|
|
59
|
+
<template>
|
|
60
|
+
<div style="display: flex; gap: 6px;">
|
|
61
|
+
<ToolBtn
|
|
62
|
+
id="copy"
|
|
63
|
+
name="复制"
|
|
64
|
+
description="复制消息内容"
|
|
65
|
+
@click="handleClick"
|
|
66
|
+
/>
|
|
67
|
+
<ToolBtn
|
|
68
|
+
id="cite"
|
|
69
|
+
name="引用"
|
|
70
|
+
description="引用此消息"
|
|
71
|
+
@click="handleClick"
|
|
72
|
+
/>
|
|
73
|
+
<ToolBtn
|
|
74
|
+
id="rebuild"
|
|
75
|
+
name="重新生成"
|
|
76
|
+
description="重新生成回答"
|
|
77
|
+
@click="handleClick"
|
|
78
|
+
/>
|
|
79
|
+
<ToolBtn
|
|
80
|
+
id="share"
|
|
81
|
+
name="分享"
|
|
82
|
+
description="分享消息"
|
|
83
|
+
@click="handleClick"
|
|
84
|
+
/>
|
|
85
|
+
<ToolBtn
|
|
86
|
+
id="like"
|
|
87
|
+
name="点赞"
|
|
88
|
+
description="对此回答满意"
|
|
89
|
+
@click="handleClick"
|
|
90
|
+
/>
|
|
91
|
+
<ToolBtn
|
|
92
|
+
id="unlike"
|
|
93
|
+
name="不满意"
|
|
94
|
+
description="对此回答不满意"
|
|
95
|
+
@click="handleClick"
|
|
96
|
+
/>
|
|
97
|
+
<ToolBtn
|
|
98
|
+
id="edit"
|
|
99
|
+
name="编辑"
|
|
100
|
+
description="编辑消息"
|
|
101
|
+
@click="handleClick"
|
|
102
|
+
/>
|
|
103
|
+
<ToolBtn
|
|
104
|
+
id="delete"
|
|
105
|
+
name="删除"
|
|
106
|
+
description="删除消息"
|
|
107
|
+
@click="handleClick"
|
|
108
|
+
/>
|
|
109
|
+
</div>
|
|
110
|
+
</template>
|
|
111
|
+
|
|
112
|
+
<script setup lang="ts">
|
|
113
|
+
import { ToolBtn } from '@blueking/chat-x';
|
|
114
|
+
import type { IToolBtn } from '@blueking/chat-x';
|
|
115
|
+
|
|
116
|
+
const handleClick = (data: IToolBtn & { active?: boolean; disabled?: boolean }, event: MouseEvent) => {
|
|
117
|
+
console.log('点击了:', data.id, data.name);
|
|
118
|
+
};
|
|
119
|
+
</script>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## 激活态与图标切换(点赞/踩)
|
|
123
|
+
|
|
124
|
+
`active` 只控制 `.is-active` 背景高亮,不自动切换图标。若需要填充图标,需在 `:id` 绑定中主动切换 `activeLike` / `activeUnLike`:
|
|
125
|
+
|
|
126
|
+
```vue
|
|
127
|
+
<template>
|
|
128
|
+
<div style="display: flex; gap: 6px;">
|
|
129
|
+
<!-- 切换 id 实现图标填充 -->
|
|
130
|
+
<ToolBtn
|
|
131
|
+
:id="activeId === 'like' ? 'activeLike' : 'like'"
|
|
132
|
+
name="点赞"
|
|
133
|
+
description="点赞"
|
|
134
|
+
:active="activeId === 'like'"
|
|
135
|
+
@click="toggleActive"
|
|
136
|
+
/>
|
|
137
|
+
<ToolBtn
|
|
138
|
+
:id="activeId === 'unlike' ? 'activeUnLike' : 'unlike'"
|
|
139
|
+
name="不满意"
|
|
140
|
+
description="不满意"
|
|
141
|
+
:active="activeId === 'unlike'"
|
|
142
|
+
@click="toggleActive"
|
|
143
|
+
/>
|
|
144
|
+
</div>
|
|
145
|
+
</template>
|
|
146
|
+
|
|
147
|
+
<script setup lang="ts">
|
|
148
|
+
import { ref } from 'vue';
|
|
149
|
+
import { ToolBtn } from '@blueking/chat-x';
|
|
150
|
+
import type { IToolBtn } from '@blueking/chat-x';
|
|
151
|
+
|
|
152
|
+
const activeId = ref<string | null>(null);
|
|
153
|
+
|
|
154
|
+
const toggleActive = (data: IToolBtn) => {
|
|
155
|
+
// 规范化 id(activeLike → like)后再比较
|
|
156
|
+
const baseId = data.id.replace(/^active/, '').replace(/^./, c => c.toLowerCase());
|
|
157
|
+
activeId.value = activeId.value === baseId ? null : baseId;
|
|
158
|
+
};
|
|
159
|
+
</script>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## 禁用状态
|
|
163
|
+
|
|
164
|
+
`disabled=true` 时:JS 拦截 click 不触发事件 + Tippy 的 `onShow` 返回 `false` 不显示 tooltip:
|
|
165
|
+
|
|
166
|
+
```vue
|
|
167
|
+
<template>
|
|
168
|
+
<div style="display: flex; gap: 6px; align-items: center;">
|
|
169
|
+
<ToolBtn
|
|
170
|
+
id="copy"
|
|
171
|
+
name="复制"
|
|
172
|
+
description="复制"
|
|
173
|
+
:disabled="isDisabled"
|
|
174
|
+
@click="handleClick"
|
|
175
|
+
/>
|
|
176
|
+
<ToolBtn
|
|
177
|
+
id="edit"
|
|
178
|
+
name="编辑"
|
|
179
|
+
description="编辑"
|
|
180
|
+
:disabled="isDisabled"
|
|
181
|
+
@click="handleClick"
|
|
182
|
+
/>
|
|
183
|
+
<button @click="isDisabled = !isDisabled">{{ isDisabled ? '启用' : '禁用' }}</button>
|
|
184
|
+
</div>
|
|
185
|
+
</template>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## 未知 ID 的文本回退
|
|
189
|
+
|
|
190
|
+
`id` 不在 `ToolIconsMap` 时渲染 `name` 文本,适用于自定义扩展场景(注意 TypeScript 会报类型错误):
|
|
191
|
+
|
|
192
|
+
## API
|
|
193
|
+
|
|
194
|
+
### Props
|
|
195
|
+
|
|
196
|
+
| 属性名 | 类型 | 必填 | 默认值 | 说明 |
|
|
197
|
+
| ------------ | -------------------------------------------------------------------------- | ---- | ------ | ------------------------------------------------------------------------------------------------------------------ |
|
|
198
|
+
| id | `keyof typeof ToolIconsMap` | 是 | — | 按钮标识;在 `ToolIconsMap` 中时渲染对应 SVG 图标,否则渲染 `name` 文本 |
|
|
199
|
+
| name | `string` | 否 | — | 按钮名称;`id` 无对应图标时作为文本内容渲染 |
|
|
200
|
+
| description | `string` | 否 | — | Tippy tooltip 内容;`disabled=true` 时不显示 tooltip |
|
|
201
|
+
| active | `boolean` | 否 | — | 激活态;`true` 时追加 `.is-active`(字色由 `id` 决定:`like`/`activeLike` 为蓝色 `#3a84ff`,其他为红色 `#E71818`) |
|
|
202
|
+
| disabled | `boolean` | 否 | — | 禁用态;`true` 时追加 `.is-disabled`,阻止 click 事件,隐藏 tooltip |
|
|
203
|
+
| tippyOptions | `Partial<Omit<TippyOptions, 'getReferenceClientRect' \| 'triggerTarget'>>` | 否 | — | 自定义 Tippy 配置,与内部默认配置合并;可用于控制 `content`、`appendTo`、`placement` 等 |
|
|
204
|
+
|
|
205
|
+
### Events
|
|
206
|
+
|
|
207
|
+
| 事件名 | 参数 | 说明 |
|
|
208
|
+
| ------ | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
|
|
209
|
+
| click | `(data: IToolBtn & { active?: boolean; disabled?: boolean }, event: MouseEvent)` | 点击时触发;`data` 为组件当前全量 props(含 `active`/`disabled`);`disabled=true` 时不触发 |
|
|
210
|
+
|
|
211
|
+
## 类型定义
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
// 来自 @blueking/chat-x 导出
|
|
215
|
+
interface IToolBtn {
|
|
216
|
+
id: keyof typeof ToolIconsMap; // 限定为预置 ID
|
|
217
|
+
name?: string;
|
|
218
|
+
description?: string;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// ToolBtn 完整 Props
|
|
222
|
+
type ToolBtnProps = IToolBtn & {
|
|
223
|
+
active?: boolean;
|
|
224
|
+
disabled?: boolean;
|
|
225
|
+
tippyOptions?: Partial<Omit<TippyOptions, 'getReferenceClientRect' | 'triggerTarget'>>;
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
// 预置 ID 枚举
|
|
229
|
+
type ToolIcons =
|
|
230
|
+
| 'copy'
|
|
231
|
+
| 'cite'
|
|
232
|
+
| 'rebuild'
|
|
233
|
+
| 'share'
|
|
234
|
+
| 'like'
|
|
235
|
+
| 'unlike'
|
|
236
|
+
| 'delete'
|
|
237
|
+
| 'edit'
|
|
238
|
+
| 'activeLike'
|
|
239
|
+
| 'activeUnLike';
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## 注意事项
|
|
243
|
+
|
|
244
|
+
1. **`click` 事件的 `data` 参数**是组件的完整 props 对象(含 `active`、`disabled`),并非单纯的 `IToolBtn`
|
|
245
|
+
2. **`activeLike` / `activeUnLike`**:是单独的填充版图标 ID,并非 `active=true` 时自动切换,需要手动在 `:id` 绑定中控制
|
|
246
|
+
3. **根元素是 `<div>` 而非 `<button>`**:没有原生按钮语义,键盘无障碍访问需外部额外处理
|
|
247
|
+
4. **`description` 可选**:不传时 tooltip 内容为 `undefined`,Tippy 不显示提示
|
|
248
|
+
5. **`disabled` 的 CSS**:`pointer-events: hover` 为无效 CSS 值(应为 `none`),鼠标事件实际由 JS 层拦截,CSS 层仍可触发 hover 样式
|
|
249
|
+
6. **`tippyOptions` 优先级**:`tippyOptions` 中的配置会覆盖内部默认值(包括 `content`、`theme`),但 `onShow` 始终保留内部逻辑(禁用时不显示)。`getReferenceClientRect`、`triggerTarget` 两个字段被 Omit 排除,不可通过此 prop 覆盖;`content` 已可通过 `tippyOptions.content` 覆盖
|
|
250
|
+
|
|
251
|
+
## 关联组件
|
|
252
|
+
|
|
253
|
+
- [MessageTools](../molecular/message-tools.md) — 工具栏容器
|
|
254
|
+
- [DeleteTool](../molecular/delete-tool.md) — 删除确认内嵌触发
|