@blueking/chat-x 0.0.51 → 0.0.52-dev.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.
- package/README.md +15 -8
- package/dist/ag-ui/types/contents.d.ts +2 -0
- package/dist/ag-ui/types/messages.d.ts +6 -1
- package/dist/common/constants.d.ts +2 -0
- package/dist/components/ai-buttons/add-menu-btn/add-menu-btn.vue.d.ts +24 -0
- package/dist/components/chat-content/collapsible-content/collapsible-content.vue.d.ts +28 -0
- package/dist/components/chat-content/file-content/upload-file-item.vue.d.ts +5 -2
- package/dist/components/chat-content/file-content/upload-image-item.vue.d.ts +1 -0
- package/dist/components/chat-content/flow-agent-content/use-flow-node-actions.d.ts +1 -1
- package/dist/components/chat-input/ai-slash-input/ai-slash-input.vue.d.ts +21 -10
- package/dist/components/chat-input/ai-slash-input/command.d.ts +6 -3
- package/dist/components/chat-input/ai-slash-input/constants.d.ts +2 -0
- package/dist/components/chat-input/ai-slash-input/use-menu-trigger.d.ts +17 -0
- package/dist/components/chat-input/build-default-placeholder.d.ts +9 -3
- package/dist/components/chat-input/chat-input.vue.d.ts +30 -18
- package/dist/components/chat-input/input-menu/constants.d.ts +60 -0
- package/dist/components/chat-input/input-menu/index.d.ts +4 -0
- package/dist/components/chat-input/input-menu/input-menu-option.vue.d.ts +14 -0
- package/dist/components/chat-input/input-menu/input-menu-panel.vue.d.ts +17 -0
- package/dist/components/chat-input/input-menu/use-input-menu.d.ts +22 -0
- package/dist/components/chat-input/model-selector/types.d.ts +3 -2
- package/dist/components/chat-message/message-container/message-container.vue.d.ts +1 -1
- package/dist/components/chat-message/user-message/user-message.vue.d.ts +1 -1
- package/dist/components/mention/create-mention-tippy.d.ts +27 -0
- package/dist/components/mention/index.d.ts +4 -0
- package/dist/components/{chat-input/ai-slash-input/ai-prompt-list/ai-prompt-list.vue.d.ts → mention/mention-popover.vue.d.ts} +3 -2
- package/dist/components/{chat-input/ai-slash-input/ai-skill-list/ai-skill-list.vue.d.ts → mention/mention-tag.vue.d.ts} +7 -3
- package/dist/components/{chat-input/ai-slash-input/ai-slash-menu/ai-slash-menu.vue.d.ts → mention/mention-text.vue.d.ts} +3 -3
- package/dist/components/resource-icon/index.d.ts +1 -0
- package/dist/components/resource-icon/resource-icon.vue.d.ts +11 -0
- package/dist/composables/index.d.ts +1 -0
- package/dist/composables/use-artifact-preview.d.ts +5 -2
- package/dist/composables/use-common.d.ts +0 -9
- package/dist/composables/use-global-config.d.ts +4 -0
- package/dist/composables/use-input-mention.d.ts +13 -0
- package/dist/composables/use-message-group.d.ts +1011 -72
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/input.d.ts +21 -0
- package/dist/icons/menu-item.d.ts +22 -0
- package/dist/index.css +1 -1
- package/dist/index.js +5116 -4595
- package/dist/index.js.map +1 -1
- package/dist/lang/lang.d.ts +13 -3
- package/dist/mcp/generated/docs/activity-message.md +3 -3
- package/dist/mcp/generated/docs/add-menu-btn.md +91 -0
- package/dist/mcp/generated/docs/ai-selection.md +1 -1
- package/dist/mcp/generated/docs/ai-slash-input.md +72 -26
- package/dist/mcp/generated/docs/assistant-message.md +7 -1
- package/dist/mcp/generated/docs/chat-container.md +45 -6
- package/dist/mcp/generated/docs/chat-input.md +327 -483
- package/dist/mcp/generated/docs/collapsible-content.md +78 -0
- package/dist/mcp/generated/docs/constants.md +36 -3
- package/dist/mcp/generated/docs/execution-summary.md +1 -23
- package/dist/mcp/generated/docs/file-artifact-panel.md +24 -5
- package/dist/mcp/generated/docs/file-content.md +4 -0
- package/dist/mcp/generated/docs/file-upload-btn.md +15 -12
- package/dist/mcp/generated/docs/flow-agent-content.md +10 -12
- package/dist/mcp/generated/docs/input-menu-panel.md +166 -0
- package/dist/mcp/generated/docs/mention-tag.md +83 -0
- package/dist/mcp/generated/docs/mention-text.md +86 -0
- package/dist/mcp/generated/docs/message-container.md +1 -1
- package/dist/mcp/generated/docs/message-render.md +1 -1
- package/dist/mcp/generated/docs/message-tools.md +15 -4
- package/dist/mcp/generated/docs/messages.md +3 -0
- package/dist/mcp/generated/docs/model-selector.md +4 -2
- package/dist/mcp/generated/docs/overflow-tips.md +3 -3
- package/dist/mcp/generated/docs/resource-icon.md +102 -0
- package/dist/mcp/generated/docs/text-content.md +7 -3
- package/dist/mcp/generated/docs/theme.md +27 -35
- package/dist/mcp/generated/docs/use-artifact-preview.md +7 -3
- package/dist/mcp/generated/docs/use-command-selection.md +1 -1
- package/dist/mcp/generated/docs/use-container-scroll.md +2 -1
- package/dist/mcp/generated/docs/use-flow-node-actions.md +8 -15
- package/dist/mcp/generated/docs/use-global-config.md +11 -4
- package/dist/mcp/generated/docs/use-input-mention.md +119 -0
- package/dist/mcp/generated/docs/use-menu-keydown.md +15 -16
- package/dist/mcp/generated/docs/use-message-group.md +3 -6
- package/dist/mcp/generated/docs/user-message.md +39 -17
- package/dist/mcp/generated/index.json +233 -81
- package/dist/types/editor.d.ts +0 -29
- package/dist/types/index.d.ts +1 -0
- package/dist/types/input-menu.d.ts +46 -0
- package/dist/utils/artifact-tags.d.ts +36 -0
- package/dist/utils/collect-message-artifacts.d.ts +14 -0
- package/dist/utils/file.d.ts +3 -3
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/upload-file.d.ts +6 -1
- package/package.json +4 -3
- package/skills/blueking-chat-x/SKILL.md +143 -0
- package/skills/blueking-chat-x/references/_index.md +153 -0
- package/skills/blueking-chat-x/references/components/activity-layout.md +134 -0
- package/skills/blueking-chat-x/references/components/activity-message.md +486 -0
- package/skills/blueking-chat-x/references/components/add-menu-btn.md +88 -0
- package/skills/blueking-chat-x/references/components/ai-image.md +230 -0
- package/skills/blueking-chat-x/references/components/ai-loading.md +131 -0
- package/skills/blueking-chat-x/references/components/ai-selection.md +439 -0
- package/skills/blueking-chat-x/references/components/ai-slash-input.md +102 -0
- package/skills/blueking-chat-x/references/components/animation-text.md +202 -0
- package/skills/blueking-chat-x/references/components/assistant-message.md +504 -0
- package/skills/blueking-chat-x/references/components/chat-container.md +912 -0
- package/skills/blueking-chat-x/references/components/chat-input.md +614 -0
- package/skills/blueking-chat-x/references/components/cite-content.md +142 -0
- package/skills/blueking-chat-x/references/components/code-content.md +211 -0
- package/skills/blueking-chat-x/references/components/collapsible-content.md +76 -0
- package/skills/blueking-chat-x/references/components/common-error-content.md +73 -0
- package/skills/blueking-chat-x/references/components/content-render.md +233 -0
- package/skills/blueking-chat-x/references/components/delete-tool.md +191 -0
- package/skills/blueking-chat-x/references/components/desc-panel.md +162 -0
- package/skills/blueking-chat-x/references/components/detail-section.md +91 -0
- package/skills/blueking-chat-x/references/components/execution-summary.md +150 -0
- package/skills/blueking-chat-x/references/components/file-artifact-panel.md +307 -0
- package/skills/blueking-chat-x/references/components/file-content.md +340 -0
- package/skills/blueking-chat-x/references/components/file-icon.md +109 -0
- package/skills/blueking-chat-x/references/components/file-upload-btn.md +162 -0
- package/skills/blueking-chat-x/references/components/flow-agent-content.md +266 -0
- package/skills/blueking-chat-x/references/components/flow-agent-node-detail.md +236 -0
- package/skills/blueking-chat-x/references/components/highlight-keyword.md +146 -0
- package/skills/blueking-chat-x/references/components/image-content.md +182 -0
- package/skills/blueking-chat-x/references/components/image-preview-group.md +184 -0
- package/skills/blueking-chat-x/references/components/image-preview.md +226 -0
- package/skills/blueking-chat-x/references/components/info-message.md +144 -0
- package/skills/blueking-chat-x/references/components/input-attachment.md +49 -0
- package/skills/blueking-chat-x/references/components/input-info-alert.md +42 -0
- package/skills/blueking-chat-x/references/components/input-menu-panel.md +162 -0
- package/skills/blueking-chat-x/references/components/interrupt-message.md +212 -0
- package/skills/blueking-chat-x/references/components/key-value-content.md +128 -0
- package/skills/blueking-chat-x/references/components/knowledge-rag-content.md +122 -0
- package/skills/blueking-chat-x/references/components/latex-content.md +200 -0
- package/skills/blueking-chat-x/references/components/loading-message.md +192 -0
- package/skills/blueking-chat-x/references/components/markdown-content.md +232 -0
- package/skills/blueking-chat-x/references/components/mention-tag.md +79 -0
- package/skills/blueking-chat-x/references/components/mention-text.md +83 -0
- package/skills/blueking-chat-x/references/components/mermaid-content.md +189 -0
- package/skills/blueking-chat-x/references/components/message-container.md +645 -0
- package/skills/blueking-chat-x/references/components/message-loading.md +118 -0
- package/skills/blueking-chat-x/references/components/message-render.md +327 -0
- package/skills/blueking-chat-x/references/components/message-time.md +177 -0
- package/skills/blueking-chat-x/references/components/message-tools.md +427 -0
- package/skills/blueking-chat-x/references/components/model-selector.md +157 -0
- package/skills/blueking-chat-x/references/components/preview-toolbar.md +42 -0
- package/skills/blueking-chat-x/references/components/questions-container.md +85 -0
- package/skills/blueking-chat-x/references/components/reasoning-message.md +232 -0
- package/skills/blueking-chat-x/references/components/reference-content.md +135 -0
- package/skills/blueking-chat-x/references/components/reference-doc-content.md +109 -0
- package/skills/blueking-chat-x/references/components/resource-icon.md +98 -0
- package/skills/blueking-chat-x/references/components/scroll-btn.md +159 -0
- package/skills/blueking-chat-x/references/components/selection-footer.md +78 -0
- package/skills/blueking-chat-x/references/components/selection-question.md +88 -0
- package/skills/blueking-chat-x/references/components/shortcut-btn.md +204 -0
- package/skills/blueking-chat-x/references/components/shortcut-btns.md +266 -0
- package/skills/blueking-chat-x/references/components/shortcut-render.md +424 -0
- package/skills/blueking-chat-x/references/components/simple-table.md +101 -0
- package/skills/blueking-chat-x/references/components/text-content.md +80 -0
- package/skills/blueking-chat-x/references/components/tool-approval-card.md +183 -0
- package/skills/blueking-chat-x/references/components/tool-btn.md +317 -0
- package/skills/blueking-chat-x/references/components/tool-message.md +235 -0
- package/skills/blueking-chat-x/references/components/toolcall-render.md +348 -0
- package/skills/blueking-chat-x/references/components/user-feedback.md +233 -0
- package/skills/blueking-chat-x/references/components/user-message.md +444 -0
- package/skills/blueking-chat-x/references/components/user-question-answered-card.md +104 -0
- package/skills/blueking-chat-x/references/components/user-question-card.md +231 -0
- package/skills/blueking-chat-x/references/components/user-question-choice.md +105 -0
- package/skills/blueking-chat-x/references/components/user-question-option.md +42 -0
- package/skills/blueking-chat-x/references/components/vnode-renderer.md +122 -0
- package/skills/blueking-chat-x/references/composables/use-animation-text.md +196 -0
- package/skills/blueking-chat-x/references/composables/use-artifact-preview.md +235 -0
- package/skills/blueking-chat-x/references/composables/use-clipboard.md +203 -0
- package/skills/blueking-chat-x/references/composables/use-command-selection.md +150 -0
- package/skills/blueking-chat-x/references/composables/use-container-scroll.md +57 -0
- package/skills/blueking-chat-x/references/composables/use-custom-tab.md +158 -0
- package/skills/blueking-chat-x/references/composables/use-flow-node-actions.md +164 -0
- package/skills/blueking-chat-x/references/composables/use-full-screen.md +112 -0
- package/skills/blueking-chat-x/references/composables/use-global-config.md +155 -0
- package/skills/blueking-chat-x/references/composables/use-input-mention.md +115 -0
- package/skills/blueking-chat-x/references/composables/use-menu-keydown.md +161 -0
- package/skills/blueking-chat-x/references/composables/use-message-group.md +244 -0
- package/skills/blueking-chat-x/references/composables/use-observer-visible-list.md +188 -0
- package/skills/blueking-chat-x/references/composables/use-parent-scrolling.md +46 -0
- package/skills/blueking-chat-x/references/directives/index.md +61 -0
- package/skills/blueking-chat-x/references/directives/overflow-tips.md +205 -0
- package/skills/blueking-chat-x/references/icons/index.md +185 -0
- package/skills/blueking-chat-x/references/plugins/index.md +56 -0
- package/skills/blueking-chat-x/references/plugins/markdown-container.md +55 -0
- package/skills/blueking-chat-x/references/plugins/markdown-latex.md +205 -0
- package/skills/blueking-chat-x/references/plugins/markdown-mermaid.md +247 -0
- package/skills/blueking-chat-x/references/theme/theme.md +423 -0
- package/skills/blueking-chat-x/references/types/constants.md +340 -0
- package/skills/blueking-chat-x/references/types/index.md +120 -0
- package/skills/blueking-chat-x/references/types/interrupt.md +379 -0
- package/skills/blueking-chat-x/references/types/messages.md +556 -0
- package/skills/blueking-chat-x/references/types/schema.md +91 -0
- package/skills/blueking-chat-x/references/utils/index.md +196 -0
- package/skills/blueking-chat-x/scripts/generate-references.mjs +536 -0
- package/dist/components/chat-input/ai-slash-editor/ai-slash-editor.vue.d.ts +0 -28
- package/dist/components/chat-input/ai-slash-editor/theme.d.ts +0 -24
- package/dist/mcp/generated/docs/ai-prompt-list.md +0 -45
- package/dist/mcp/generated/docs/ai-skill-list.md +0 -75
- package/dist/mcp/generated/docs/ai-slash-editor.md +0 -43
- package/dist/mcp/generated/docs/ai-slash-menu.md +0 -42
|
@@ -0,0 +1,188 @@
|
|
|
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) — 快捷指令条与「更多」
|
|
@@ -0,0 +1,46 @@
|
|
|
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
|
+
## 渲染示例
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# 指令总览
|
|
2
|
+
|
|
3
|
+
`@blueking/chat-x` 目前提供以下 Vue 自定义指令:
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 指令总览
|
|
8
|
+
|
|
9
|
+
`@blueking/chat-x` 目前提供以下 Vue 自定义指令:
|
|
10
|
+
|
|
11
|
+
| 指令 | 说明 | 关键特性 | 文档 |
|
|
12
|
+
| ----------------- | -------------------------- | ----------------------------------------------------------------------- | -------------------------- |
|
|
13
|
+
| `v-overflow-tips` | 水平溢出时悬浮显示完整内容 | `IntersectionObserver` 懒绑定,按需创建 Tippy 实例,`onHidden` 自动销毁 | [查看](./overflow-tips.md) |
|
|
14
|
+
|
|
15
|
+
## 引入方式
|
|
16
|
+
|
|
17
|
+
### 组件内局部使用(推荐)
|
|
18
|
+
|
|
19
|
+
```vue
|
|
20
|
+
<template>
|
|
21
|
+
<div
|
|
22
|
+
v-overflow-tips
|
|
23
|
+
class="ellipsis"
|
|
24
|
+
>
|
|
25
|
+
这是一段很长的文本,超出容器宽度时悬浮显示完整内容
|
|
26
|
+
</div>
|
|
27
|
+
</template>
|
|
28
|
+
|
|
29
|
+
<script setup lang="ts">
|
|
30
|
+
import { OverflowTips as vOverflowTips } from '@blueking/chat-x';
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<style scoped>
|
|
34
|
+
.ellipsis {
|
|
35
|
+
width: 200px;
|
|
36
|
+
overflow: hidden;
|
|
37
|
+
text-overflow: ellipsis;
|
|
38
|
+
white-space: nowrap;
|
|
39
|
+
}
|
|
40
|
+
</style>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 全局注册
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { createApp } from 'vue';
|
|
47
|
+
import { OverflowTips } from '@blueking/chat-x';
|
|
48
|
+
|
|
49
|
+
const app = createApp(App);
|
|
50
|
+
app.directive('overflow-tips', OverflowTips);
|
|
51
|
+
app.mount('#app');
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
全局注册后,所有组件可直接使用 `v-overflow-tips`,无需单独引入。
|
|
55
|
+
|
|
56
|
+
## 注意事项
|
|
57
|
+
|
|
58
|
+
- **仅检测水平溢出**:通过 `scrollWidth > clientWidth` 判断,多行 `-webkit-line-clamp` 截断不会触发 tooltip
|
|
59
|
+
- **无 `update` 钩子**:`binding.value` 运行时变化(如 `disabled` 切换)仅在下次 `mouseenter` 生效
|
|
60
|
+
- **勿覆盖 `onHidden`**:指令依赖 `onHidden` 回调自动销毁 Tippy 实例,覆盖会导致内存泄漏
|
|
61
|
+
- **默认主题**:`'ai-chat-box'`(组件库内置),替换为其他主题需引入对应 Tippy CSS
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# OverflowTips
|
|
2
|
+
|
|
3
|
+
> 导入:`import { OverflowTips } from '@blueking/chat-x'` | since 1.0.0
|
|
4
|
+
|
|
5
|
+
v-overflow-tips 在元素水平溢出(scrollWidth > clientWidth)时于 mouseenter 懒创建 Tippy,展示完整文本或自定义 text/content。 结合 IntersectionObserver 仅在可见时绑定悬停;隐藏时销毁实例。指令值为 Partial<TippyProps> 与 disabled 等。 DescPanel、ExecutionSummary、ToolcallRender、InputMenuPanel 等用于标题或列表溢出提示。
|
|
6
|
+
|
|
7
|
+
**关联**:desc-panel(工具描述面板溢出)、execution-summary(执行摘要标签溢出)、toolcall-render(工具标题行溢出)、input-menu-panel(菜单条目名称溢出)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# OverflowTips 溢出提示指令
|
|
12
|
+
|
|
13
|
+
> **分类**:directive
|
|
14
|
+
|
|
15
|
+
当元素文本**水平溢出**(`scrollWidth > clientWidth`)时,鼠标悬停自动弹出 Tippy tooltip 显示完整内容;未溢出时不创建实例,零性能损耗。
|
|
16
|
+
|
|
17
|
+
## 工作原理
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
元素挂载
|
|
21
|
+
│
|
|
22
|
+
▼
|
|
23
|
+
IntersectionObserver 监听可见性(threshold=0.1)
|
|
24
|
+
│
|
|
25
|
+
├─ 可见 → 绑定 mouseenter / mouseleave
|
|
26
|
+
└─ 不可见 → 解绑 mouseenter / mouseleave
|
|
27
|
+
│
|
|
28
|
+
▼ mouseenter 触发
|
|
29
|
+
scrollWidth > clientWidth ?
|
|
30
|
+
│ │
|
|
31
|
+
否 是
|
|
32
|
+
│ │
|
|
33
|
+
直接返回 创建 Tippy 实例
|
|
34
|
+
[trigger: mouseenter]
|
|
35
|
+
[delay: 300ms, 0ms]
|
|
36
|
+
│
|
|
37
|
+
┌──────────┴──────────┐
|
|
38
|
+
onShow onHidden
|
|
39
|
+
再次校验溢出 destroy() 销毁实例
|
|
40
|
+
false → 取消 instance = undefined
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## 基础用法
|
|
44
|
+
|
|
45
|
+
文本未溢出时不会弹出 tooltip;只有超出容器宽度才触发。元素需自行设置省略号 CSS。
|
|
46
|
+
|
|
47
|
+
```vue
|
|
48
|
+
<template>
|
|
49
|
+
<div
|
|
50
|
+
v-overflow-tips
|
|
51
|
+
class="ellipsis"
|
|
52
|
+
>
|
|
53
|
+
这是一段很长的文本内容,会触发溢出省略效果并弹出 tooltip 提示完整内容
|
|
54
|
+
</div>
|
|
55
|
+
</template>
|
|
56
|
+
|
|
57
|
+
<script setup lang="ts">
|
|
58
|
+
import { OverflowTips as vOverflowTips } from '@blueking/chat-x';
|
|
59
|
+
</script>
|
|
60
|
+
|
|
61
|
+
<style scoped>
|
|
62
|
+
.ellipsis {
|
|
63
|
+
width: 240px;
|
|
64
|
+
overflow: hidden;
|
|
65
|
+
text-overflow: ellipsis;
|
|
66
|
+
white-space: nowrap;
|
|
67
|
+
}
|
|
68
|
+
</style>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## 自定义提示内容
|
|
72
|
+
|
|
73
|
+
通过 `text` 或 `content`(别名)指定 tooltip 显示内容,优先级:`text > content > el.innerText`。
|
|
74
|
+
|
|
75
|
+
```vue
|
|
76
|
+
<template>
|
|
77
|
+
<div
|
|
78
|
+
v-overflow-tips="{ text: '自定义 tooltip 内容:完整的蓝鲸智云 AI 小鲸组件使用说明' }"
|
|
79
|
+
class="ellipsis"
|
|
80
|
+
>
|
|
81
|
+
悬浮查看自定义 tooltip 内容(与元素 innerText 不同)
|
|
82
|
+
</div>
|
|
83
|
+
</template>
|
|
84
|
+
|
|
85
|
+
<script setup lang="ts">
|
|
86
|
+
import { OverflowTips as vOverflowTips } from '@blueking/chat-x';
|
|
87
|
+
</script>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## 控制 placement 和禁用
|
|
91
|
+
|
|
92
|
+
`placement` 默认 `'auto'`(Tippy 自动选择最优方向);`disabled: true` 完全跳过 tooltip 创建。
|
|
93
|
+
|
|
94
|
+
```vue
|
|
95
|
+
<template>
|
|
96
|
+
<div
|
|
97
|
+
v-overflow-tips="{ placement: 'bottom', disabled: isDisabled }"
|
|
98
|
+
class="ellipsis"
|
|
99
|
+
>
|
|
100
|
+
可以切换弹出方向或禁用 tooltip
|
|
101
|
+
</div>
|
|
102
|
+
</template>
|
|
103
|
+
|
|
104
|
+
<script setup lang="ts">
|
|
105
|
+
import { ref } from 'vue';
|
|
106
|
+
import { OverflowTips as vOverflowTips } from '@blueking/chat-x';
|
|
107
|
+
|
|
108
|
+
const isDisabled = ref(false);
|
|
109
|
+
</script>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## API
|
|
113
|
+
|
|
114
|
+
### 指令值类型
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
type OverflowTipsValue = Partial<TippyProps> & {
|
|
118
|
+
disabled?: boolean; // 禁用 tooltip
|
|
119
|
+
text?: string; // 自定义提示内容(优先级最高)
|
|
120
|
+
content?: string; // text 的别名
|
|
121
|
+
};
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
指令值是 `Partial<TippyProps>` 的超集,所有 Tippy.js 配置均可透传,但覆盖 `onHidden` 会导致实例无法自动销毁。
|
|
125
|
+
|
|
126
|
+
### 常用配置项
|
|
127
|
+
|
|
128
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
129
|
+
| ----------- | ---------------------------- | --------------- | ----------------------------------------------- |
|
|
130
|
+
| `text` | `string` | `el.innerText` | 自定义提示内容,优先级最高 |
|
|
131
|
+
| `content` | `string` | `el.innerText` | `text` 的别名,`text` 存在时忽略 |
|
|
132
|
+
| `placement` | `Placement` | `'auto'` | tooltip 弹出方向,支持所有 Tippy placement 值 |
|
|
133
|
+
| `disabled` | `boolean` | `false` | `true` 时跳过 tooltip 创建,mouseenter 直接返回 |
|
|
134
|
+
| `delay` | `number \| [number, number]` | `[300, 0]` | 显示/隐藏延迟(ms) |
|
|
135
|
+
| `theme` | `string` | `'ai-chat-box'` | Tippy 主题,默认使用组件库内置主题 |
|
|
136
|
+
|
|
137
|
+
### 其他 Tippy.js 配置
|
|
138
|
+
|
|
139
|
+
可直接传入任何 `tippy.js` 的 `Props`,如 `arrow`、`maxWidth`、`offset` 等,会覆盖上述默认值(除内部的 `trigger`、`onShow`、`onHidden` 逻辑外)。
|
|
140
|
+
|
|
141
|
+
> **注意**:不要覆盖 `onHidden`,否则 Tippy 实例无法在隐藏后自动销毁,导致内存泄漏。
|
|
142
|
+
|
|
143
|
+
## 溢出检测规则
|
|
144
|
+
|
|
145
|
+
指令通过 `scrollWidth > clientWidth` 判断**水平溢出**:
|
|
146
|
+
|
|
147
|
+
- 仅检测水平方向,多行文本的垂直截断(`-webkit-line-clamp`)无法被检测到
|
|
148
|
+
- `onShow` 会在 tooltip 即将显示时**再次校验**溢出状态,动态缩放容器后同样有效
|
|
149
|
+
- 若两次校验均未溢出,tooltip 不会弹出
|
|
150
|
+
|
|
151
|
+
## 生命周期细节
|
|
152
|
+
|
|
153
|
+
| 时机 | 行为 |
|
|
154
|
+
| ------------------- | --------------------------------------------------------------------- |
|
|
155
|
+
| `mounted` | 创建 `IntersectionObserver`(阈值 10%),注册 `unObserverFunc` 到元素 |
|
|
156
|
+
| 元素进入视口 | 绑定 `mouseenter` / `mouseleave` 事件 |
|
|
157
|
+
| 元素离开视口 | 解绑 `mouseenter` / `mouseleave` |
|
|
158
|
+
| `mouseenter` + 溢出 | 创建 Tippy 实例;`DelayMs+16ms` 后补偿首次不显示的 bug |
|
|
159
|
+
| `onHidden` | 销毁实例(`destroy()`),`instance = undefined` |
|
|
160
|
+
| `beforeUnmount` | 解绑所有事件,调用 `unObserverFunc` 停止 Observer |
|
|
161
|
+
|
|
162
|
+
> **无 `update` 钩子**:`binding.value` 在运行时变化(如 `disabled` 切换)不会更新已创建的 Tippy 实例,只影响下一次 `mouseenter` 时的行为。
|
|
163
|
+
|
|
164
|
+
## 样式要求
|
|
165
|
+
|
|
166
|
+
指令不会自动设置省略号 CSS,需在元素上手动添加:
|
|
167
|
+
|
|
168
|
+
**单行截断**:
|
|
169
|
+
|
|
170
|
+
```css
|
|
171
|
+
.ellipsis {
|
|
172
|
+
overflow: hidden;
|
|
173
|
+
text-overflow: ellipsis;
|
|
174
|
+
white-space: nowrap;
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**多行截断(`-webkit-line-clamp`)**:
|
|
179
|
+
|
|
180
|
+
```css
|
|
181
|
+
/* 注意:多行截断时 scrollWidth <= clientWidth,tooltip 不会触发 */
|
|
182
|
+
.ellipsis-multiline {
|
|
183
|
+
display: -webkit-box;
|
|
184
|
+
-webkit-line-clamp: 2;
|
|
185
|
+
-webkit-box-orient: vertical;
|
|
186
|
+
overflow: hidden;
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
> 多行截断通过 `-webkit-line-clamp` 实现,`scrollWidth` 不变,指令**无法检测**此类溢出,tooltip 不会弹出。
|
|
191
|
+
|
|
192
|
+
## 注意事项
|
|
193
|
+
|
|
194
|
+
1. **仅检测水平溢出**:`scrollWidth > clientWidth`,多行 `line-clamp` 溢出无效
|
|
195
|
+
2. **无 `update` 钩子**:`disabled` 等状态变化仅在下次 `mouseenter` 生效
|
|
196
|
+
3. **勿覆盖 `onHidden`**:会导致 Tippy 实例无法自动销毁
|
|
197
|
+
4. **默认主题**:`'ai-chat-box'` 是组件库内置主题,替换为其他主题需引入对应 CSS
|
|
198
|
+
5. **事件冒泡**:`mouseenter` 内调用了 `stopPropagation()`,父元素不会收到该事件
|
|
199
|
+
|
|
200
|
+
## 关联组件
|
|
201
|
+
|
|
202
|
+
- [DescPanel](../components/rendering/desc-panel) — 描述区溢出
|
|
203
|
+
- [ExecutionSummary](../components/agent/execution-summary) — 侧栏摘要标签
|
|
204
|
+
- [ToolcallRender](../components/agent/toolcall-render) — 工具调用标题
|
|
205
|
+
- [InputMenuPanel](../components/input/input-menu-panel) — 菜单条目名称溢出
|