@blueking/chat-x 0.0.51-beta.2 → 0.0.51-beta.3
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/components/chat-content/file-content/upload-image-item.vue.d.ts +2 -0
- package/dist/components/chat-content/file-content/upload-spinner.vue.d.ts +3 -0
- package/dist/components/chat-input/chat-input.vue.d.ts +3 -0
- package/dist/index.css +1 -1
- package/dist/index.js +745 -712
- package/dist/index.js.map +1 -1
- package/dist/lang/lang.d.ts +4 -1
- package/dist/mcp/generated/docs/chat-container.md +1 -1
- package/dist/mcp/generated/docs/chat-input.md +3 -2
- package/dist/mcp/generated/docs/file-content.md +27 -10
- package/dist/mcp/generated/index.json +3 -3
- package/dist/mcp/index.js +0 -0
- package/package.json +21 -23
- package/skills/blueking-chat-x/SKILL.md +0 -139
- package/skills/blueking-chat-x/references/_index.md +0 -131
- package/skills/blueking-chat-x/references/components/activity-layout.md +0 -134
- package/skills/blueking-chat-x/references/components/activity-message.md +0 -486
- package/skills/blueking-chat-x/references/components/ai-image.md +0 -230
- package/skills/blueking-chat-x/references/components/ai-loading.md +0 -131
- package/skills/blueking-chat-x/references/components/ai-prompt-list.md +0 -44
- package/skills/blueking-chat-x/references/components/ai-selection.md +0 -439
- package/skills/blueking-chat-x/references/components/ai-skill-list.md +0 -73
- package/skills/blueking-chat-x/references/components/ai-slash-editor.md +0 -43
- package/skills/blueking-chat-x/references/components/ai-slash-input.md +0 -56
- package/skills/blueking-chat-x/references/components/ai-slash-menu.md +0 -42
- package/skills/blueking-chat-x/references/components/animation-text.md +0 -202
- package/skills/blueking-chat-x/references/components/assistant-message.md +0 -498
- package/skills/blueking-chat-x/references/components/chat-container.md +0 -869
- package/skills/blueking-chat-x/references/components/chat-input.md +0 -769
- package/skills/blueking-chat-x/references/components/cite-content.md +0 -142
- package/skills/blueking-chat-x/references/components/code-content.md +0 -211
- package/skills/blueking-chat-x/references/components/common-error-content.md +0 -73
- package/skills/blueking-chat-x/references/components/content-render.md +0 -233
- package/skills/blueking-chat-x/references/components/delete-tool.md +0 -191
- package/skills/blueking-chat-x/references/components/desc-panel.md +0 -162
- package/skills/blueking-chat-x/references/components/detail-section.md +0 -91
- package/skills/blueking-chat-x/references/components/execution-summary.md +0 -128
- package/skills/blueking-chat-x/references/components/file-artifact-panel.md +0 -289
- package/skills/blueking-chat-x/references/components/file-content.md +0 -319
- package/skills/blueking-chat-x/references/components/file-icon.md +0 -109
- package/skills/blueking-chat-x/references/components/file-upload-btn.md +0 -159
- package/skills/blueking-chat-x/references/components/flow-agent-content.md +0 -264
- package/skills/blueking-chat-x/references/components/flow-agent-node-detail.md +0 -236
- package/skills/blueking-chat-x/references/components/highlight-keyword.md +0 -146
- package/skills/blueking-chat-x/references/components/image-content.md +0 -182
- package/skills/blueking-chat-x/references/components/image-preview-group.md +0 -184
- package/skills/blueking-chat-x/references/components/image-preview.md +0 -226
- package/skills/blueking-chat-x/references/components/info-message.md +0 -144
- package/skills/blueking-chat-x/references/components/input-attachment.md +0 -49
- package/skills/blueking-chat-x/references/components/input-info-alert.md +0 -42
- package/skills/blueking-chat-x/references/components/interrupt-message.md +0 -212
- package/skills/blueking-chat-x/references/components/key-value-content.md +0 -128
- package/skills/blueking-chat-x/references/components/knowledge-rag-content.md +0 -122
- package/skills/blueking-chat-x/references/components/latex-content.md +0 -200
- package/skills/blueking-chat-x/references/components/loading-message.md +0 -192
- package/skills/blueking-chat-x/references/components/markdown-content.md +0 -232
- package/skills/blueking-chat-x/references/components/mermaid-content.md +0 -189
- package/skills/blueking-chat-x/references/components/message-container.md +0 -645
- package/skills/blueking-chat-x/references/components/message-loading.md +0 -118
- package/skills/blueking-chat-x/references/components/message-render.md +0 -327
- package/skills/blueking-chat-x/references/components/message-time.md +0 -177
- package/skills/blueking-chat-x/references/components/message-tools.md +0 -416
- package/skills/blueking-chat-x/references/components/model-selector.md +0 -155
- package/skills/blueking-chat-x/references/components/preview-toolbar.md +0 -42
- package/skills/blueking-chat-x/references/components/questions-container.md +0 -85
- package/skills/blueking-chat-x/references/components/reasoning-message.md +0 -232
- package/skills/blueking-chat-x/references/components/reference-content.md +0 -135
- package/skills/blueking-chat-x/references/components/reference-doc-content.md +0 -109
- package/skills/blueking-chat-x/references/components/scroll-btn.md +0 -159
- package/skills/blueking-chat-x/references/components/selection-footer.md +0 -78
- package/skills/blueking-chat-x/references/components/selection-question.md +0 -88
- package/skills/blueking-chat-x/references/components/shortcut-btn.md +0 -204
- package/skills/blueking-chat-x/references/components/shortcut-btns.md +0 -266
- package/skills/blueking-chat-x/references/components/shortcut-render.md +0 -424
- package/skills/blueking-chat-x/references/components/simple-table.md +0 -101
- package/skills/blueking-chat-x/references/components/text-content.md +0 -77
- package/skills/blueking-chat-x/references/components/tool-approval-card.md +0 -183
- package/skills/blueking-chat-x/references/components/tool-btn.md +0 -317
- package/skills/blueking-chat-x/references/components/tool-message.md +0 -235
- package/skills/blueking-chat-x/references/components/toolcall-render.md +0 -348
- package/skills/blueking-chat-x/references/components/user-feedback.md +0 -233
- package/skills/blueking-chat-x/references/components/user-message.md +0 -424
- package/skills/blueking-chat-x/references/components/user-question-answered-card.md +0 -104
- package/skills/blueking-chat-x/references/components/user-question-card.md +0 -231
- package/skills/blueking-chat-x/references/components/user-question-choice.md +0 -105
- package/skills/blueking-chat-x/references/components/user-question-option.md +0 -42
- package/skills/blueking-chat-x/references/components/vnode-renderer.md +0 -122
- package/skills/blueking-chat-x/references/composables/use-animation-text.md +0 -196
- package/skills/blueking-chat-x/references/composables/use-artifact-preview.md +0 -231
- package/skills/blueking-chat-x/references/composables/use-clipboard.md +0 -203
- package/skills/blueking-chat-x/references/composables/use-command-selection.md +0 -150
- package/skills/blueking-chat-x/references/composables/use-container-scroll.md +0 -57
- package/skills/blueking-chat-x/references/composables/use-custom-tab.md +0 -158
- package/skills/blueking-chat-x/references/composables/use-flow-node-actions.md +0 -157
- package/skills/blueking-chat-x/references/composables/use-full-screen.md +0 -112
- package/skills/blueking-chat-x/references/composables/use-global-config.md +0 -148
- package/skills/blueking-chat-x/references/composables/use-menu-keydown.md +0 -163
- package/skills/blueking-chat-x/references/composables/use-message-group.md +0 -247
- package/skills/blueking-chat-x/references/composables/use-observer-visible-list.md +0 -188
- package/skills/blueking-chat-x/references/composables/use-parent-scrolling.md +0 -46
- package/skills/blueking-chat-x/references/theme/theme.md +0 -431
- package/skills/blueking-chat-x/references/types/constants.md +0 -307
- package/skills/blueking-chat-x/references/types/interrupt.md +0 -379
- package/skills/blueking-chat-x/references/types/messages.md +0 -553
- package/skills/blueking-chat-x/references/types/schema.md +0 -91
- package/skills/blueking-chat-x/scripts/generate-references.mjs +0 -314
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
# useObserverVisibleList
|
|
2
|
-
|
|
3
|
-
> 导入:`import { useObserverVisibleList } from '@blueking/chat-x'` | since 1.0.0
|
|
4
|
-
|
|
5
|
-
useObserverVisibleList 根据 containerRef、itemRefs、gap、ComputedRef items 与可选 moreItemRef,用 ResizeObserver + 贪心算法得到 visibleItems。 依赖每项真实 offsetWidth,隐藏项需仍挂载于 DOM。返回 calculateVisibleMenuItems 供必要时手动触发。 ShortcutBtns 内部用于快捷指令溢出收入「更多」菜单。
|
|
6
|
-
|
|
7
|
-
**关联**:shortcut-btns(唯一内置使用方)
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# useObserverVisibleList 可见列表计算
|
|
12
|
-
|
|
13
|
-
> **分类**:composable
|
|
14
|
-
|
|
15
|
-
基于 `ResizeObserver` 的容器宽度感知组合式函数:遍历列表项的实际 `offsetWidth`,使用贪心算法计算在容器中能完整显示的项目子集,并为"更多"按钮动态预留空间。
|
|
16
|
-
|
|
17
|
-
> 该 composable 仅在 `ShortcutBtns` 内部使用,**通常直接使用 `ShortcutBtns` 组件即可**。
|
|
18
|
-
|
|
19
|
-
## 工作原理
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
calculateVisibleMenuItems():
|
|
23
|
-
await nextTick()
|
|
24
|
-
containerWidth = containerRef.value.offsetWidth
|
|
25
|
-
|
|
26
|
-
Set<T> list = {}
|
|
27
|
-
totalWidth = 0
|
|
28
|
-
|
|
29
|
-
for i in params.items.value: // items 是 ComputedRef<T[]>,通过 .value 访问
|
|
30
|
-
itemRef = itemRefs.value[i]
|
|
31
|
-
buttonWidth = itemRef.offsetWidth
|
|
32
|
-
gap = list.size > 0 ? params.gap : 0 // 首项不加 gap
|
|
33
|
-
neededWidth = totalWidth + buttonWidth + gap
|
|
34
|
-
moreItemWidth = moreItemRef?.value?.$el?.offsetWidth ?? 0 // 动态读取
|
|
35
|
-
|
|
36
|
-
if neededWidth + params.gap + moreItemWidth <= containerWidth:
|
|
37
|
-
list.add(item)
|
|
38
|
-
totalWidth = neededWidth
|
|
39
|
-
else:
|
|
40
|
-
break ← 立即中止,不跳过尝试后续项
|
|
41
|
-
|
|
42
|
-
visibleItems.value = Array.from(list)
|
|
43
|
-
|
|
44
|
-
触发时机:
|
|
45
|
-
├── onMounted:ResizeObserver.observe(containerRef) + nextTick 初始计算
|
|
46
|
-
├── watch([itemRefs, moreItemRef]):DOM 引用更新时(nextTick 后)重新计算
|
|
47
|
-
└── onScopeDispose:ResizeObserver.disconnect()
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
## 渲染示例
|
|
51
|
-
|
|
52
|
-
`ShortcutBtns` 内部使用 `useObserverVisibleList`,缩放浏览器窗口观察溢出效果:
|
|
53
|
-
|
|
54
|
-
## 直接使用示例
|
|
55
|
-
|
|
56
|
-
```vue
|
|
57
|
-
<template>
|
|
58
|
-
<div
|
|
59
|
-
ref="containerRef"
|
|
60
|
-
class="btn-bar"
|
|
61
|
-
>
|
|
62
|
-
<!-- 所有项始终渲染,溢出项用 CSS 隐藏(offsetWidth 仍可读) -->
|
|
63
|
-
<template
|
|
64
|
-
v-for="(item, i) in items"
|
|
65
|
-
:key="item.id"
|
|
66
|
-
>
|
|
67
|
-
<button
|
|
68
|
-
:ref="el => setItemRef(el as HTMLElement, i)"
|
|
69
|
-
:class="['btn-item', { 'btn-item--hidden': !visibleItems.includes(item) }]"
|
|
70
|
-
@click="handleClick(item)"
|
|
71
|
-
>
|
|
72
|
-
{{ item.name }}
|
|
73
|
-
</button>
|
|
74
|
-
</template>
|
|
75
|
-
|
|
76
|
-
<!-- 更多按钮:仅在有隐藏项时显示 -->
|
|
77
|
-
<MoreBtn
|
|
78
|
-
v-show="hiddenItems.length > 0"
|
|
79
|
-
ref="moreBtnRef"
|
|
80
|
-
@click="showMoreMenu"
|
|
81
|
-
/>
|
|
82
|
-
</div>
|
|
83
|
-
</template>
|
|
84
|
-
|
|
85
|
-
<script setup lang="ts">
|
|
86
|
-
import { computed, shallowRef, useTemplateRef } from 'vue';
|
|
87
|
-
import { useObserverVisibleList } from '@blueking/chat-x';
|
|
88
|
-
|
|
89
|
-
interface Item {
|
|
90
|
-
id: string;
|
|
91
|
-
name: string;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const containerRef = useTemplateRef<HTMLElement>('containerRef');
|
|
95
|
-
const moreBtnRef = useTemplateRef('moreBtnRef');
|
|
96
|
-
|
|
97
|
-
// 必须是 ShallowRef,由调用方维护(DOM 更新后写入)
|
|
98
|
-
const itemRefs = shallowRef<(HTMLElement | null)[]>([]);
|
|
99
|
-
|
|
100
|
-
const items = shallowRef<Item[]>([
|
|
101
|
-
{ id: '1', name: '按钮 1' },
|
|
102
|
-
{ id: '2', name: '按钮 2' },
|
|
103
|
-
{ id: '3', name: '按钮 3' },
|
|
104
|
-
{ id: '4', name: '按钮 4' },
|
|
105
|
-
{ id: '5', name: '按钮 5' },
|
|
106
|
-
]);
|
|
107
|
-
|
|
108
|
-
const { visibleItems, calculateVisibleMenuItems } = useObserverVisibleList<Item>(containerRef, itemRefs, {
|
|
109
|
-
gap: 4, // 按钮间距(必填)
|
|
110
|
-
items: computed(() => items.value), // 需传入 ComputedRef<T[]>,内部通过 .value 访问
|
|
111
|
-
moreItemRef: moreBtnRef, // 可选,动态读取"更多"按钮宽度
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
const hiddenItems = computed(() => items.value.filter(i => !visibleItems.value.includes(i)));
|
|
115
|
-
|
|
116
|
-
const setItemRef = (el: HTMLElement | null, index: number) => {
|
|
117
|
-
itemRefs.value[index] = el;
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
// items 变化时:重置 itemRefs(触发 watch → 重新计算)
|
|
121
|
-
watch(items, () => {
|
|
122
|
-
itemRefs.value = new Array(items.value.length).fill(null);
|
|
123
|
-
});
|
|
124
|
-
</script>
|
|
125
|
-
|
|
126
|
-
<style scoped>
|
|
127
|
-
.btn-bar {
|
|
128
|
-
display: flex;
|
|
129
|
-
gap: 4px;
|
|
130
|
-
overflow: hidden;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/* 隐藏项必须保持在 DOM 中(offsetWidth 才可读),用定位脱离文档流 */
|
|
134
|
-
.btn-item--hidden {
|
|
135
|
-
position: absolute;
|
|
136
|
-
visibility: hidden;
|
|
137
|
-
pointer-events: none;
|
|
138
|
-
opacity: 0;
|
|
139
|
-
}
|
|
140
|
-
</style>
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
## API
|
|
144
|
-
|
|
145
|
-
```typescript
|
|
146
|
-
function useObserverVisibleList<T>(
|
|
147
|
-
containerRef: TemplateRef<HTMLElement>,
|
|
148
|
-
itemRefs: ShallowRef<(HTMLElement | null)[]>,
|
|
149
|
-
params: {
|
|
150
|
-
gap: number; // 必填,按钮间距(px)
|
|
151
|
-
items: ComputedRef<T[]>; // 必填,响应式项目数组(ComputedRef)
|
|
152
|
-
moreItemRef?: TemplateRef<InstanceType<typeof ShortcutBtn>>; // 可选,"更多"按钮引用
|
|
153
|
-
},
|
|
154
|
-
): {
|
|
155
|
-
visibleItems: ShallowRef<T[]>;
|
|
156
|
-
calculateVisibleMenuItems: () => Promise<void>;
|
|
157
|
-
};
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### 参数说明
|
|
161
|
-
|
|
162
|
-
| 参数 | 类型 | 必填 | 说明 |
|
|
163
|
-
| -------------------- | ------------------------------------- | ---- | ----------------------------------------------------------------------------------------------------------- |
|
|
164
|
-
| `containerRef` | `TemplateRef<HTMLElement>` | 是 | 容器 DOM 引用;`ResizeObserver` 监听此元素宽度变化 |
|
|
165
|
-
| `itemRefs` | `ShallowRef<(HTMLElement \| null)[]>` | 是 | 各项 DOM 引用数组;`watch` 监听其变化触发重新计算 |
|
|
166
|
-
| `params.gap` | `number` | 是 | 相邻按钮间距(px);首项不加 gap |
|
|
167
|
-
| `params.items` | `ComputedRef<T[]>` | 是 | **响应式**项目数组,需传入 `ComputedRef`(如 `computed(() => list.value)`);内部通过 `.value` 访问最新数据 |
|
|
168
|
-
| `params.moreItemRef` | `TemplateRef<ShortcutBtn>` | 否 | "更多"按钮引用;每次计算从 `$el.offsetWidth` 动态读取宽度;缺省时按 0 计算 |
|
|
169
|
-
|
|
170
|
-
### 返回值
|
|
171
|
-
|
|
172
|
-
| 属性名 | 类型 | 说明 |
|
|
173
|
-
| --------------------------- | --------------------- | ------------------------------------------------------------------ |
|
|
174
|
-
| `visibleItems` | `ShallowRef<T[]>` | 当前能完整放入容器的项目子集(引用与 `params.items` 中的对象一致) |
|
|
175
|
-
| `calculateVisibleMenuItems` | `() => Promise<void>` | 手动触发计算(内部有 `await nextTick()`);一般无需调用 |
|
|
176
|
-
|
|
177
|
-
## 注意事项
|
|
178
|
-
|
|
179
|
-
1. **`items` 必须为 `ComputedRef`**:`params.items` 现在接受 `ComputedRef<T[]>` 类型,内部通过 `.value` 读取最新数据。建议使用 `computed(() => props.shortcuts)` 包装后传入,确保 items 变化时计算逻辑能访问到最新数据。注意 `itemRefs` 的重置仍需在外部维护(`itemRefs.value = new Array(items.value.length).fill(null)`),以触发 `watch([itemRefs, moreItemRef])` 重新计算
|
|
180
|
-
2. **隐藏项必须留在 DOM**:算法依赖 `itemRef.offsetWidth` 读取每项实际宽度;使用 `position: absolute; visibility: hidden` 隐藏而非 `display: none`
|
|
181
|
-
3. **算法贪心且单调**:遇到第一个放不下的项就立即 `break`,不跳过继续尝试后续较短的项
|
|
182
|
-
4. **`moreItemRef` 宽度动态读取**:每次计算循环中实时读取 `$el.offsetWidth`,宽度可以随内容变化(如显示隐藏数量文字时)
|
|
183
|
-
5. **`ResizeObserver` 仅在 `onMounted` 时绑定一次**:若 `containerRef.value` 在挂载时为 `null`,则不会监听容器宽度变化
|
|
184
|
-
6. **`moreItemRef` 类型限定为 `ShortcutBtn`**:强依赖内部 `$el` expose,若用于其他组件需确保 expose 了 `$el`
|
|
185
|
-
|
|
186
|
-
## 关联组件
|
|
187
|
-
|
|
188
|
-
- [ShortcutBtns](../components/input/shortcut-btns.md) — 快捷指令条与「更多」
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# useParentScrolling
|
|
2
|
-
|
|
3
|
-
> 导入:`import { useParentScrolling } from '@blueking/chat-x'` | since 1.0.0
|
|
4
|
-
|
|
5
|
-
useParentScrolling(domRef) 在挂载后通过 getScrollParent 找到最近可滚动祖先,监听 scroll 与 scrollend,返回 isScrolling 与 scrollParent。 scroll 时将 isScrolling 置 true,300ms 无滚动或 scrollend 时置 false,适合滚动时隐藏浮层等交互。getScrollParent 可单独导出使用。 当前源码无组件内引用,供业务或后续浮层组件按需集成。
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# useParentScrolling 父容器滚动监听
|
|
10
|
-
|
|
11
|
-
> **分类**:composable
|
|
12
|
-
|
|
13
|
-
向上递归查找**最近可滚动祖先**,监听其 `scroll` / `scrollend` 事件,提供 `isScrolling` 状态。常用于滚动时自动关闭浮层、禁用交互等场景。
|
|
14
|
-
|
|
15
|
-
同时导出辅助函数 `getScrollParent`,可单独使用。
|
|
16
|
-
|
|
17
|
-
## 工作原理
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
getScrollParent(node):
|
|
21
|
-
├── !node → null
|
|
22
|
-
├── !(node instanceof HTMLElement) → getScrollParent(parentElement) 或 document.body
|
|
23
|
-
├── scrollHeight > clientHeight
|
|
24
|
-
│ && overflowY in ['scroll', 'auto', 'overlay'] → return node(找到)
|
|
25
|
-
└── else → getScrollParent(parentElement) 或 document.body(fallback)
|
|
26
|
-
|
|
27
|
-
useParentScrolling(domRef):
|
|
28
|
-
onMounted:
|
|
29
|
-
scrollParent = getScrollParent(toValue(domRef))
|
|
30
|
-
removeEventListener(防御性清理)
|
|
31
|
-
addEventListener('scroll', handleScroll) ← 非 passive
|
|
32
|
-
addEventListener('scrollend', handleScrollEnd)
|
|
33
|
-
|
|
34
|
-
handleScroll:
|
|
35
|
-
isScrolling = true
|
|
36
|
-
clearTimeout(timer)
|
|
37
|
-
timer = setTimeout(() => isScrolling = false, 300) ← 300ms 无滚动后重置
|
|
38
|
-
|
|
39
|
-
handleScrollEnd:
|
|
40
|
-
isScrolling = false ← 原生 scrollend 事件立即重置(浏览器兼容性见下)
|
|
41
|
-
|
|
42
|
-
onScopeDispose:
|
|
43
|
-
removeEventListener(自动清理)
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## 渲染示例
|
|
@@ -1,431 +0,0 @@
|
|
|
1
|
-
# 主题配置
|
|
2
|
-
|
|
3
|
-
> since 1.0.0
|
|
4
|
-
|
|
5
|
-
说明通过 SCSS 变量(尺寸、颜色、z-index)、字号主题 CSS 变量(data-ai-size 切换 small/normal)与 CSS 类覆盖自定义主题。 ChatContainer.size 控制根节点 data-ai-size;浮层同步 document.body.dataset.aiSize。含渐变边框 mixin、骨架屏类 ai-skeleton-element 等。
|
|
6
|
-
|
|
7
|
-
**关联**:chat-container(整体布局与侧栏)、chat-input(输入区与渐变边框)、message-container(消息区样式上下文)
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# 主题配置
|
|
12
|
-
|
|
13
|
-
> **分类**:theme
|
|
14
|
-
|
|
15
|
-
`@blueking/chat-x` 使用 SCSS 变量和 CSS 类来控制样式,支持通过覆盖变量或样式来自定义主题。
|
|
16
|
-
|
|
17
|
-
## 样式引入
|
|
18
|
-
|
|
19
|
-
组件库的样式会在引入组件时自动加载,无需单独引入:
|
|
20
|
-
|
|
21
|
-
```typescript
|
|
22
|
-
// 引入组件时会自动引入样式
|
|
23
|
-
import { ChatInput, MessageContainer } from '@blueking/chat-x';
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## 字号主题
|
|
27
|
-
|
|
28
|
-
组件库通过根节点 `[data-ai-size]` 切换两档字号主题,内部组件统一引用 CSS 变量(均带兜底值,无 provider 时退回 `small`)。
|
|
29
|
-
|
|
30
|
-
### 切换方式
|
|
31
|
-
|
|
32
|
-
| 方式 | 说明 |
|
|
33
|
-
| ---- | ---- |
|
|
34
|
-
| `ChatContainer` 的 `size` prop | 推荐。根节点 `.ai-chat-container` 设置 `data-ai-size`;同时通过 `useGlobalConfig` 注入 `size` 供逻辑层读取 |
|
|
35
|
-
| 手动设置 `data-ai-size` | 在任意祖先元素上设置 `data-ai-size="small"` 或 `data-ai-size="normal"`,后代继承 CSS 变量 |
|
|
36
|
-
| `document.body.dataset.aiSize` | `ChatContainer` 会自动同步,供 Tippy / Teleport 等挂载到 `body` 的浮层继承字号变量;容器卸载时清理 |
|
|
37
|
-
|
|
38
|
-
```vue
|
|
39
|
-
<template>
|
|
40
|
-
<ChatContainer v-model="input" :messages="messages" size="normal" />
|
|
41
|
-
</template>
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
### CSS 变量
|
|
45
|
-
|
|
46
|
-
定义于 `src/styles/size-theme.scss`,随 `global.scss` 自动引入:
|
|
47
|
-
|
|
48
|
-
| 变量名 | `small`(默认) | `normal` | 说明 |
|
|
49
|
-
| ------ | --------------- | -------- | ---- |
|
|
50
|
-
| `--ai-font-size` | `12px` | `14px` | 基准字号 |
|
|
51
|
-
| `--ai-line-height` | `20px` | `24px` | 标准行高 |
|
|
52
|
-
| `--ai-line-height-compact` | `20px` | `22px` | 紧凑行高 |
|
|
53
|
-
| `--ai-spacing-comfortable` | `8px` | `12px` | 舒适间距(如消息气泡水平内边距) |
|
|
54
|
-
| `--ai-icon-size` | `16px` | `20px` | 标准图标尺寸 |
|
|
55
|
-
| `--ai-icon-size-sm` | `16px` | `18px` | 小号图标尺寸 |
|
|
56
|
-
|
|
57
|
-
组件样式中统一使用 `var(--ai-font-size, 12px)` 等形式引用,保证无 `data-ai-size` 时仍退回 small 档位。
|
|
58
|
-
|
|
59
|
-
```scss
|
|
60
|
-
// 示例:在自定义样式中复用字号主题变量
|
|
61
|
-
.my-custom-panel {
|
|
62
|
-
font-size: var(--ai-font-size, 12px);
|
|
63
|
-
line-height: var(--ai-line-height, 20px);
|
|
64
|
-
}
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### 骨架屏
|
|
68
|
-
|
|
69
|
-
全局类 `.ai-skeleton-element` 用于加载占位(如 FlowAgent 节点详情、UserFeedback 原因列表)。可通过 `.skeleton-element-lg` 修饰尺寸。详见各业务组件文档中的加载态说明。
|
|
70
|
-
|
|
71
|
-
## SCSS 变量
|
|
72
|
-
|
|
73
|
-
组件库使用以下 SCSS 变量,可以在项目中覆盖:
|
|
74
|
-
|
|
75
|
-
### 尺寸变量
|
|
76
|
-
|
|
77
|
-
```scss
|
|
78
|
-
// 输入框尺寸
|
|
79
|
-
$chat-input-min-width: 350px;
|
|
80
|
-
$chat-input-max-width: 700px;
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### 颜色变量
|
|
84
|
-
|
|
85
|
-
```scss
|
|
86
|
-
// 主题色
|
|
87
|
-
$primary-color: #3a84ff;
|
|
88
|
-
|
|
89
|
-
// 文字颜色
|
|
90
|
-
$text-color-primary: #313238;
|
|
91
|
-
$text-color-secondary: #4d4f56;
|
|
92
|
-
$text-color-placeholder: #979ba5;
|
|
93
|
-
|
|
94
|
-
// 背景色
|
|
95
|
-
$bg-color-white: #fff;
|
|
96
|
-
$bg-color-light: #f5f7fa;
|
|
97
|
-
$bg-color-hover: #f0f1f5;
|
|
98
|
-
|
|
99
|
-
// 边框色
|
|
100
|
-
$border-color: #dcdee5;
|
|
101
|
-
$border-color-hover: #c4c6cc;
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
### Z-Index 变量
|
|
105
|
-
|
|
106
|
-
组件库使用分层的 z-index 管理:
|
|
107
|
-
|
|
108
|
-
```scss
|
|
109
|
-
// 基础 z-index
|
|
110
|
-
$chat-z-index: 9999;
|
|
111
|
-
|
|
112
|
-
// 编辑器 z-index
|
|
113
|
-
$editor-z-index: $chat-z-index + 1;
|
|
114
|
-
|
|
115
|
-
// 编辑器菜单 z-index
|
|
116
|
-
$editor-menu-z-index: $editor-z-index + 1;
|
|
117
|
-
|
|
118
|
-
// 快捷指令菜单 z-index
|
|
119
|
-
$shortcut-menu-z-index: $editor-menu-z-index + 1;
|
|
120
|
-
|
|
121
|
-
// 划选弹窗 z-index
|
|
122
|
-
$selection-z-index: $shortcut-menu-z-index + 1;
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
## CSS 类覆盖
|
|
126
|
-
|
|
127
|
-
### 输入框样式
|
|
128
|
-
|
|
129
|
-
```scss
|
|
130
|
-
// 覆盖输入框容器样式
|
|
131
|
-
.ai-chat-input-container {
|
|
132
|
-
.chat-input {
|
|
133
|
-
min-height: 120px; // 自定义最小高度
|
|
134
|
-
max-height: 250px; // 自定义最大高度
|
|
135
|
-
background: #fafafa; // 自定义背景色
|
|
136
|
-
|
|
137
|
-
// 覆盖边框渐变
|
|
138
|
-
&::before {
|
|
139
|
-
background: linear-gradient(180deg, #ff6b6b, #ff8e53);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
### 消息样式
|
|
146
|
-
|
|
147
|
-
```scss
|
|
148
|
-
// 用户消息样式
|
|
149
|
-
.ai-user-message {
|
|
150
|
-
&-content {
|
|
151
|
-
background-color: #d4edda; // 自定义背景色
|
|
152
|
-
border-radius: 8px;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// AI 消息样式
|
|
157
|
-
.assistant-message {
|
|
158
|
-
&-content {
|
|
159
|
-
background-color: #f8f9fa;
|
|
160
|
-
border-left: 3px solid #3a84ff;
|
|
161
|
-
padding-left: 12px;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
### 快捷指令按钮样式
|
|
167
|
-
|
|
168
|
-
```scss
|
|
169
|
-
// 快捷指令按钮
|
|
170
|
-
.ai-shortcut-btns {
|
|
171
|
-
&-item {
|
|
172
|
-
background: linear-gradient(135deg, #667eea, #764ba2);
|
|
173
|
-
color: #fff;
|
|
174
|
-
|
|
175
|
-
&:hover {
|
|
176
|
-
transform: translateY(-2px);
|
|
177
|
-
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// 移除默认渐变边框
|
|
181
|
-
&::before {
|
|
182
|
-
display: none;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
### 消息工具栏样式
|
|
189
|
-
|
|
190
|
-
```scss
|
|
191
|
-
// 工具按钮
|
|
192
|
-
.tool-btn {
|
|
193
|
-
width: 24px;
|
|
194
|
-
height: 24px;
|
|
195
|
-
font-size: 16px;
|
|
196
|
-
|
|
197
|
-
&:hover {
|
|
198
|
-
background-color: #e1ecff;
|
|
199
|
-
color: #3a84ff;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
### Markdown 内容样式
|
|
205
|
-
|
|
206
|
-
```scss
|
|
207
|
-
// Markdown 内容
|
|
208
|
-
.ai-markdown-content {
|
|
209
|
-
.ai-markdown-body {
|
|
210
|
-
font-size: 14px;
|
|
211
|
-
line-height: 1.6;
|
|
212
|
-
|
|
213
|
-
// 代码块样式
|
|
214
|
-
pre code.hljs {
|
|
215
|
-
background-color: #1e1e1e;
|
|
216
|
-
border-radius: 8px;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// 表格样式
|
|
220
|
-
table {
|
|
221
|
-
border-collapse: collapse;
|
|
222
|
-
|
|
223
|
-
th,
|
|
224
|
-
td {
|
|
225
|
-
border: 1px solid #dcdee5;
|
|
226
|
-
padding: 8px 12px;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
th {
|
|
230
|
-
background-color: #f5f7fa;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
## 主题切换示例
|
|
238
|
-
|
|
239
|
-
### 暗色主题
|
|
240
|
-
|
|
241
|
-
```scss
|
|
242
|
-
// 暗色主题变量
|
|
243
|
-
.dark-theme {
|
|
244
|
-
// 输入框
|
|
245
|
-
.ai-chat-input-container .chat-input {
|
|
246
|
-
background: #2d2d2d;
|
|
247
|
-
|
|
248
|
-
&::before {
|
|
249
|
-
background: linear-gradient(180deg, #4a90d9, #357abd);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// 用户消息
|
|
254
|
-
.ai-user-message-content {
|
|
255
|
-
background-color: #3d5a80;
|
|
256
|
-
color: #fff;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// AI 消息
|
|
260
|
-
.assistant-message {
|
|
261
|
-
color: #e0e0e0;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Markdown 内容
|
|
265
|
-
.ai-markdown-content .ai-markdown-body {
|
|
266
|
-
color: #e0e0e0;
|
|
267
|
-
|
|
268
|
-
h1,
|
|
269
|
-
h2,
|
|
270
|
-
h3,
|
|
271
|
-
h4,
|
|
272
|
-
h5,
|
|
273
|
-
h6 {
|
|
274
|
-
color: #fff;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
a {
|
|
278
|
-
color: #6cb2eb;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
code {
|
|
282
|
-
background-color: #3d3d3d;
|
|
283
|
-
color: #e0e0e0;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// 快捷指令
|
|
288
|
-
.ai-shortcut-btns-item {
|
|
289
|
-
background: #3d3d3d;
|
|
290
|
-
color: #e0e0e0;
|
|
291
|
-
|
|
292
|
-
&::before {
|
|
293
|
-
background: linear-gradient(105deg, #4a90d940, #9b59b640);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// 工具按钮
|
|
298
|
-
.tool-btn {
|
|
299
|
-
color: #9e9e9e;
|
|
300
|
-
|
|
301
|
-
&:hover {
|
|
302
|
-
background-color: #424242;
|
|
303
|
-
color: #fff;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
### 使用暗色主题
|
|
310
|
-
|
|
311
|
-
```vue
|
|
312
|
-
<template>
|
|
313
|
-
<div :class="{ 'dark-theme': isDark }">
|
|
314
|
-
<ChatInput v-model="input" />
|
|
315
|
-
<MessageContainer :messages="messages" />
|
|
316
|
-
</div>
|
|
317
|
-
</template>
|
|
318
|
-
|
|
319
|
-
<script setup lang="ts">
|
|
320
|
-
import { ref } from 'vue';
|
|
321
|
-
import { ChatInput, MessageContainer } from '@blueking/chat-x';
|
|
322
|
-
|
|
323
|
-
const isDark = ref(false);
|
|
324
|
-
const input = ref('');
|
|
325
|
-
const messages = ref([]);
|
|
326
|
-
</script>
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
## 渐变边框
|
|
330
|
-
|
|
331
|
-
组件库使用 CSS mask 实现渐变边框效果:
|
|
332
|
-
|
|
333
|
-
```scss
|
|
334
|
-
// 渐变边框 mixin
|
|
335
|
-
@mixin linear-gradient-border($angle: 105deg, $start-color: #235dfa40, $end-color: #bc81ef40) {
|
|
336
|
-
content: '';
|
|
337
|
-
position: absolute;
|
|
338
|
-
inset: 0;
|
|
339
|
-
padding: 1px;
|
|
340
|
-
background: linear-gradient($angle, $start-color, $end-color);
|
|
341
|
-
mask:
|
|
342
|
-
linear-gradient(#fff 0 0) content-box,
|
|
343
|
-
linear-gradient(#fff 0 0);
|
|
344
|
-
mask-composite: xor;
|
|
345
|
-
mask-composite: exclude;
|
|
346
|
-
border-radius: inherit;
|
|
347
|
-
pointer-events: none;
|
|
348
|
-
}
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
使用示例:
|
|
352
|
-
|
|
353
|
-
```scss
|
|
354
|
-
.custom-card {
|
|
355
|
-
position: relative;
|
|
356
|
-
border-radius: 8px;
|
|
357
|
-
|
|
358
|
-
&::before {
|
|
359
|
-
@include linear-gradient-border(180deg, #6cbaff, #3a84ff);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
## 动画效果
|
|
365
|
-
|
|
366
|
-
### 淡入动画
|
|
367
|
-
|
|
368
|
-
```scss
|
|
369
|
-
// 全局淡入动画
|
|
370
|
-
@keyframes ai-markdown-fade-in {
|
|
371
|
-
from {
|
|
372
|
-
opacity: 0;
|
|
373
|
-
}
|
|
374
|
-
to {
|
|
375
|
-
opacity: 1;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
.ai-blueking-markdown-fade-in {
|
|
380
|
-
animation: ai-markdown-fade-in 0.2s ease-out forwards;
|
|
381
|
-
}
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
### 弹窗过渡
|
|
385
|
-
|
|
386
|
-
```scss
|
|
387
|
-
// 选择弹窗过渡
|
|
388
|
-
.ai-fade-enter-active,
|
|
389
|
-
.ai-fade-leave-active {
|
|
390
|
-
transition:
|
|
391
|
-
opacity 0.2s ease,
|
|
392
|
-
transform 0.2s ease;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
.ai-fade-enter-from,
|
|
396
|
-
.ai-fade-leave-to {
|
|
397
|
-
opacity: 0;
|
|
398
|
-
transform: translateY(4px);
|
|
399
|
-
}
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
## 响应式设计
|
|
403
|
-
|
|
404
|
-
```scss
|
|
405
|
-
// 移动端适配
|
|
406
|
-
@media (max-width: 768px) {
|
|
407
|
-
.ai-chat-input-container .chat-input {
|
|
408
|
-
min-width: 100%;
|
|
409
|
-
max-width: 100%;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
.ai-shortcut-btns {
|
|
413
|
-
min-width: 100%;
|
|
414
|
-
max-width: 100%;
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
## 注意事项
|
|
420
|
-
|
|
421
|
-
1. **样式优先级**:覆盖样式时可能需要使用更高优先级的选择器
|
|
422
|
-
2. **变量位置**:SCSS 变量需要在组件样式之前定义
|
|
423
|
-
3. **构建配置**:确保项目配置支持 SCSS 处理
|
|
424
|
-
4. **组件隔离**:使用 scoped 样式时,深度选择器 `::v-deep` 或 `:deep()` 可能需要
|
|
425
|
-
|
|
426
|
-
## 关联组件
|
|
427
|
-
|
|
428
|
-
- [ChatContainer](../components/setup/chat-container) — 布局与字号主题根节点(`size` prop)
|
|
429
|
-
- [useGlobalConfig](../composables/use-global-config) — 注入 `size` 供后代读取
|
|
430
|
-
- [ChatInput](../components/input/chat-input) — 输入区变量与类名
|
|
431
|
-
- [MessageContainer](../components/setup/message-container) — 消息列表区域
|