@blueking/chat-x 0.0.51-beta.5 → 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 +4953 -4429
- 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-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 +3 -2
- 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,266 @@
|
|
|
1
|
+
# ShortcutBtns 快捷指令按钮组
|
|
2
|
+
|
|
3
|
+
> 能力域:输入交互 | 导入:`import { ShortcutBtns } from '@blueking/chat-x'` | since 1.0.0
|
|
4
|
+
|
|
5
|
+
快捷指令列表入口,内部组合多个 ShortcutBtn。 源码位置:src/components/ai-shortcut/shortcut-btns/shortcut-btns.vue。
|
|
6
|
+
|
|
7
|
+
**关联**:shortcut-btn(列表中每一项由 ShortcutBtn 渲染)、chat-input(默认嵌入输入框底部附件区)、shortcut-render(表单类快捷指令选中后的表单渲染)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# ShortcutBtns 快捷指令按钮组
|
|
12
|
+
## 源码事实
|
|
13
|
+
|
|
14
|
+
- **源码位置**:`src/components/ai-shortcut/shortcut-btns/shortcut-btns.vue`
|
|
15
|
+
- **能力域**:输入交互
|
|
16
|
+
- **能力说明**:快捷指令列表入口,内部组合多个 ShortcutBtn。
|
|
17
|
+
|
|
18
|
+
> **能力域**:输入交互
|
|
19
|
+
|
|
20
|
+
快捷指令按钮列表,内置**响应式溢出收起**:根据容器实际宽度动态计算可见数量,超出部分自动收入"更多"下拉菜单。
|
|
21
|
+
|
|
22
|
+
通常由 `ChatInput` 内部使用,一般不需要手动引入。
|
|
23
|
+
|
|
24
|
+
## 组件结构
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
div.ai-shortcut-btns(flex,gap: 4px,width: 100%,min-width: 168px,max-width: 1000px,overflow: hidden)
|
|
28
|
+
│
|
|
29
|
+
├── ShortcutBtn.ai-shortcut-btns-item × N(每个快捷指令)
|
|
30
|
+
│ height: 24px,padding: 0 6px,white-space: nowrap,background: #fff,border-radius: 4px
|
|
31
|
+
│ 溢出时追加 .ai-shortcut-btns-item-hidden(position: absolute; visibility: hidden; pointer-events: none; opacity: 0)
|
|
32
|
+
│ 注意:隐藏项仍在 DOM 中,仅通过 CSS 不可见,offsetWidth 仍可读
|
|
33
|
+
│
|
|
34
|
+
└── [hiddenShortcuts.length > 0] Tippy(trigger="manual",append-to="body",interactive)
|
|
35
|
+
│ offset=[0,6],z-index=SHORTCUT_MENU_Z_INDEX,theme="ai-chat-box-light light"
|
|
36
|
+
├── ShortcutBtn.ai-shortcut-btns-more(触发按钮)
|
|
37
|
+
│ MoreAgentIcon(rotate(90deg)) + "更多"
|
|
38
|
+
└── #content: div.ai-shortcut-menu
|
|
39
|
+
ShortcutBtn(mode="menu") × 隐藏数量
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## 响应式溢出机制(useObserverVisibleList)
|
|
43
|
+
|
|
44
|
+
组件使用 `ResizeObserver` 监听容器宽度变化,自动计算可见按钮列表:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
calculateVisibleMenuItems 执行逻辑:
|
|
48
|
+
1. 遍历 shortcuts(按顺序)
|
|
49
|
+
2. 每项计算:neededWidth = totalWidth + itemWidth + gap(非首项才加 gap)
|
|
50
|
+
3. 判断:neededWidth + gap + moreButtonWidth ≤ containerWidth
|
|
51
|
+
→ true:加入 visibleItems,更新 totalWidth
|
|
52
|
+
→ false:break(后续项全部进入"更多"菜单)
|
|
53
|
+
4. 触发时机:ResizeObserver 回调 / itemRefs 变化 / moreItemRef 变化
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
- `shortcuts` prop 通过 `computed(() => props.shortcuts)` 包装为 `ComputedRef` 传入 `useObserverVisibleList`,确保 items 变化时计算逻辑能访问到最新数据
|
|
57
|
+
- `shortcuts` prop 更新时(深度 watch),`itemRefs` 重置为同等长度的 null 数组,再等待下一帧重新计算
|
|
58
|
+
- 隐藏项 = `shortcuts.filter(s => !visibleItems.includes(s))`,保持原始顺序
|
|
59
|
+
- `ResizeObserver` 在 `onScopeDispose` 时断开,无内存泄漏
|
|
60
|
+
|
|
61
|
+
## 基础用法
|
|
62
|
+
|
|
63
|
+
```vue
|
|
64
|
+
<template>
|
|
65
|
+
<ShortcutBtns
|
|
66
|
+
:shortcuts="shortcuts"
|
|
67
|
+
@select-shortcut="handleSelectShortcut"
|
|
68
|
+
/>
|
|
69
|
+
</template>
|
|
70
|
+
|
|
71
|
+
<script setup lang="ts">
|
|
72
|
+
import { ShortcutBtns } from '@blueking/chat-x';
|
|
73
|
+
import type { Shortcut } from '@blueking/chat-x';
|
|
74
|
+
|
|
75
|
+
const shortcuts: Shortcut[] = [
|
|
76
|
+
{ id: 'ask', name: '问问小鲸' },
|
|
77
|
+
{ id: 'translate', name: '翻译' },
|
|
78
|
+
{ id: 'summarize', name: '总结' },
|
|
79
|
+
{ id: 'explain', name: '解释代码' },
|
|
80
|
+
{ id: 'code-review', name: '代码审查' },
|
|
81
|
+
];
|
|
82
|
+
|
|
83
|
+
const handleSelectShortcut = (shortcut: Shortcut) => {
|
|
84
|
+
console.log('选择了:', shortcut.name);
|
|
85
|
+
};
|
|
86
|
+
</script>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## 带描述的快捷指令
|
|
90
|
+
|
|
91
|
+
`description` 字段由 `ShortcutRender` 表单弹窗使用(悬浮提示或说明文字),本组件不直接渲染:
|
|
92
|
+
|
|
93
|
+
```vue
|
|
94
|
+
<template>
|
|
95
|
+
<ShortcutBtns
|
|
96
|
+
:shortcuts="shortcuts"
|
|
97
|
+
@select-shortcut="handleSelectShortcut"
|
|
98
|
+
/>
|
|
99
|
+
</template>
|
|
100
|
+
|
|
101
|
+
<script setup lang="ts">
|
|
102
|
+
import { ShortcutBtns } from '@blueking/chat-x';
|
|
103
|
+
import type { Shortcut } from '@blueking/chat-x';
|
|
104
|
+
|
|
105
|
+
const shortcuts: Shortcut[] = [
|
|
106
|
+
{ id: 'translate', name: '翻译', description: '将文本翻译成指定语言' },
|
|
107
|
+
{ id: 'summarize', name: '总结', description: '自动总结长文本的核心要点' },
|
|
108
|
+
{ id: 'explain', name: '解释', description: '解释代码或概念' },
|
|
109
|
+
];
|
|
110
|
+
</script>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## 带表单的快捷指令
|
|
114
|
+
|
|
115
|
+
配置 `components` 后,`@select-shortcut` 事件仍正常触发,**表单弹窗逻辑需由父组件配合 `ShortcutRender` 实现**:
|
|
116
|
+
|
|
117
|
+
```vue
|
|
118
|
+
<template>
|
|
119
|
+
<ShortcutBtns
|
|
120
|
+
:shortcuts="shortcuts"
|
|
121
|
+
@select-shortcut="handleSelectShortcut"
|
|
122
|
+
/>
|
|
123
|
+
<ShortcutRender
|
|
124
|
+
v-if="activeShortcut"
|
|
125
|
+
:shortcut="activeShortcut"
|
|
126
|
+
@submit="handleFormSubmit"
|
|
127
|
+
@cancel="activeShortcut = null"
|
|
128
|
+
/>
|
|
129
|
+
</template>
|
|
130
|
+
|
|
131
|
+
<script setup lang="ts">
|
|
132
|
+
import { ref } from 'vue';
|
|
133
|
+
import { ShortcutBtns, ShortcutRender } from '@blueking/chat-x';
|
|
134
|
+
import type { Shortcut } from '@blueking/chat-x';
|
|
135
|
+
|
|
136
|
+
const activeShortcut = ref<Shortcut | null>(null);
|
|
137
|
+
|
|
138
|
+
const shortcuts: Shortcut[] = [
|
|
139
|
+
{
|
|
140
|
+
id: 'translate',
|
|
141
|
+
name: '翻译',
|
|
142
|
+
description: '将文本翻译成指定语言',
|
|
143
|
+
components: [
|
|
144
|
+
{
|
|
145
|
+
type: 'select',
|
|
146
|
+
key: 'targetLang',
|
|
147
|
+
name: '目标语言',
|
|
148
|
+
props: {
|
|
149
|
+
options: [
|
|
150
|
+
{ label: '英文', value: 'en' },
|
|
151
|
+
{ label: '中文', value: 'zh' },
|
|
152
|
+
],
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
{ type: 'textarea', key: 'content', name: '翻译内容', fillBack: true },
|
|
156
|
+
],
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
id: 'code-gen',
|
|
160
|
+
name: '代码生成',
|
|
161
|
+
components: [
|
|
162
|
+
{ type: 'input', key: 'language', name: '编程语言' },
|
|
163
|
+
{ type: 'textarea', key: 'description', name: '功能描述', fillBack: true },
|
|
164
|
+
],
|
|
165
|
+
},
|
|
166
|
+
];
|
|
167
|
+
|
|
168
|
+
const handleSelectShortcut = (shortcut: Shortcut) => {
|
|
169
|
+
if (shortcut.components?.length) {
|
|
170
|
+
activeShortcut.value = shortcut; // 打开表单弹窗
|
|
171
|
+
} else {
|
|
172
|
+
sendMessage(shortcut); // 直接发送
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
</script>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## 响应式溢出("更多"菜单)
|
|
179
|
+
|
|
180
|
+
当按钮数量超出容器可用宽度时,自动显示"更多"按钮,点击展开下拉菜单:
|
|
181
|
+
|
|
182
|
+
> 该 Demo 容器较窄时会自动触发溢出收起效果。`manyShortcuts` 共 12 项,超出容器宽度的按钮进入"更多"下拉菜单。
|
|
183
|
+
|
|
184
|
+
## API
|
|
185
|
+
|
|
186
|
+
### Props
|
|
187
|
+
|
|
188
|
+
| 属性名 | 类型 | 必填 | 说明 |
|
|
189
|
+
| --------- | ------------ | ---- | ------------------------------------------------------------------- |
|
|
190
|
+
| shortcuts | `Shortcut[]` | 是 | 快捷指令列表;`v-for` 使用 `shortcut.key \|\| shortcut.id` 作为 key |
|
|
191
|
+
|
|
192
|
+
### Events
|
|
193
|
+
|
|
194
|
+
| 事件名 | 参数 | 说明 |
|
|
195
|
+
| --------------- | ---------------------- | ---------------------------------------------------------------------------- |
|
|
196
|
+
| select-shortcut | `(shortcut: Shortcut)` | 点击任意快捷指令(含"更多"菜单中的项)时触发;从"更多"菜单选择后菜单自动关闭 |
|
|
197
|
+
|
|
198
|
+
## 类型定义
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
interface Shortcut {
|
|
202
|
+
id: string;
|
|
203
|
+
name: string;
|
|
204
|
+
key?: string; // 自定义 v-for key,优先于 id
|
|
205
|
+
description?: string;
|
|
206
|
+
icon?: string | VNode | ((h: typeof h) => Component | VNode);
|
|
207
|
+
components?: ShortcutComponent[];
|
|
208
|
+
formModel?: Record<string, unknown>;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
type ShortcutComponent =
|
|
212
|
+
| InputShortcutComponent // type: 'input'
|
|
213
|
+
| TextareaShortcutComponent // type: 'textarea'
|
|
214
|
+
| NumberShortcutComponent // type: 'number'
|
|
215
|
+
| SelectShortcutComponent // type: 'select'
|
|
216
|
+
| CheckboxGroupShortcutComponent // type: 'checkboxGroup'
|
|
217
|
+
| RadioGroupShortcutComponent // type: 'radioGroup'
|
|
218
|
+
| SwitcherShortcutComponent // type: 'switcher'
|
|
219
|
+
| TextShortcutComponent; // type: 'text'(纯文本展示)
|
|
220
|
+
|
|
221
|
+
interface BaseShortcutComponent<T> {
|
|
222
|
+
type: T;
|
|
223
|
+
key: string; // 表单字段 key,对应 formModel 中的属性名
|
|
224
|
+
name?: string; // 表单项 label
|
|
225
|
+
fillBack?: boolean; // true 时,该字段值在提交后回填至聊天输入框
|
|
226
|
+
props?: Record<string, any>; // 传给底层 bkui-vue 组件的 props
|
|
227
|
+
formItemProps?: Record<string, any>; // 传给 bkui-vue Form.Item 的 props
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### 表单组件类型
|
|
232
|
+
|
|
233
|
+
| type 值 | 底层组件 | 说明 |
|
|
234
|
+
| --------------- | ------------------------- | --------------------------------------- |
|
|
235
|
+
| `input` | bkui-vue Input | 单行文本输入 |
|
|
236
|
+
| `textarea` | bkui-vue Input (textarea) | 多行文本输入 |
|
|
237
|
+
| `number` | bkui-vue Input (number) | 数字输入 |
|
|
238
|
+
| `select` | bkui-vue Select | 下拉选择,通过 `props.options` 配置选项 |
|
|
239
|
+
| `checkboxGroup` | bkui-vue Checkbox.Group | 多选框组 |
|
|
240
|
+
| `radioGroup` | bkui-vue Radio.Group | 单选框组 |
|
|
241
|
+
| `switcher` | bkui-vue Switcher | 开关 |
|
|
242
|
+
| `text` | 纯文本 | 仅展示说明文字,不收集值 |
|
|
243
|
+
|
|
244
|
+
## 样式说明
|
|
245
|
+
|
|
246
|
+
| 类名 | 样式 | 说明 |
|
|
247
|
+
| ---------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------- |
|
|
248
|
+
| `.ai-shortcut-btns` | `width: 100%; min-width: 168px; max-width: 1000px; overflow: hidden` | 容器,宽度撑满父元素,超出 1000px 截断 |
|
|
249
|
+
| `.ai-shortcut-btns-item` | `height: 24px; padding: 0 6px; background: #fff; border-radius: 4px` | 每个快捷指令按钮的外层包装 class |
|
|
250
|
+
| `.ai-shortcut-btns-item-hidden` | `position: absolute; visibility: hidden; pointer-events: none; opacity: 0` | 溢出按钮的隐藏态;仍在 DOM 中以便 offsetWidth 计算 |
|
|
251
|
+
| `.ai-shortcut-btns-more` | `flex-shrink: 0; padding: 0 6px` | "更多"按钮,`MoreAgentIcon` 旋转 90° |
|
|
252
|
+
| `.ai-shortcut-menu` | `@include menu.ai-common-menu-style` | 下拉菜单容器样式 |
|
|
253
|
+
|
|
254
|
+
## 注意事项
|
|
255
|
+
|
|
256
|
+
1. **`key` 字段优先于 `id`**:`v-for` 使用 `shortcut.key || shortcut.id`,当多个指令 `id` 相同但代表不同实例时,可通过 `key` 字段区分
|
|
257
|
+
2. **溢出项不可交互**:`.ai-shortcut-btns-item-hidden` 通过 `pointer-events: none` 屏蔽点击,不会误触发事件
|
|
258
|
+
3. **"更多"菜单 Teleport 至 body**:Tippy 使用 `append-to="body"`,避免被父容器的 `overflow: hidden` 裁剪
|
|
259
|
+
4. **容器宽度限制**:`min-width: 168px` 和 `max-width: 1000px` 来自 `$chat-input-min-width` / `$chat-input-max-width` 变量,与输入框宽度保持一致
|
|
260
|
+
5. **表单流程在外部**:`ShortcutBtns` 只负责显示和触发事件,`components` 的表单弹窗逻辑需配合 `ShortcutRender` 实现(`ChatInput` 已内置此流程)
|
|
261
|
+
|
|
262
|
+
## 关联组件
|
|
263
|
+
|
|
264
|
+
- [ShortcutBtn](/components/input/shortcut-btn) — 列表项基础组件
|
|
265
|
+
- [ChatInput](/components/input/chat-input) — 默认嵌入输入框底部
|
|
266
|
+
- [ShortcutRender](/components/input/shortcut-render) — 表单类快捷指令的表单渲染
|
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
# ShortcutRender 快捷指令表单
|
|
2
|
+
|
|
3
|
+
> 能力域:输入交互 | 导入:`import { ShortcutRender } from '@blueking/chat-x'` | since 1.0.0
|
|
4
|
+
|
|
5
|
+
渲染快捷指令 components 表单并回传确认数据。 源码位置:src/components/ai-shortcut/shortcut-render/shortcut-render.vue。
|
|
6
|
+
|
|
7
|
+
**关联**:shortcut-btn(与快捷指令 Shortcut 元数据一致,表单提交前在列表中选中入口)、chat-input(提交或取消后与输入框内容与状态联动)、chat-container(顶层聊天布局中承载快捷表单区域)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# ShortcutRender 快捷指令渲染器
|
|
12
|
+
## 源码事实
|
|
13
|
+
|
|
14
|
+
- **源码位置**:`src/components/ai-shortcut/shortcut-render/shortcut-render.vue`
|
|
15
|
+
- **能力域**:输入交互
|
|
16
|
+
- **能力说明**:渲染快捷指令 components 表单并回传确认数据。
|
|
17
|
+
|
|
18
|
+
> **能力域**:输入交互
|
|
19
|
+
|
|
20
|
+
快捷指令表单渲染组件,将 `Shortcut.components` 配置自动渲染为可交互表单(基于 bkui-vue 的 `Form`),支持 8 种控件类型、两列网格布局、必填校验和内置提交/取消操作。
|
|
21
|
+
|
|
22
|
+
## 组件结构
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
┌─────────────────────────────────────────────────┐
|
|
26
|
+
│ .ai-shortcut-render-header(渐变左边框) │
|
|
27
|
+
│ ✧ ThinkingIcon 快捷指令名称 ✕ Close │
|
|
28
|
+
├─────────────────────────────────────────────────┤
|
|
29
|
+
│ .ai-shortcut-render-content(max-height: 424px, │
|
|
30
|
+
│ overflow-y: auto) │
|
|
31
|
+
│ ┌─────────────┬─────────────┐ │
|
|
32
|
+
│ │ FormItem │ FormItem │ ← 两列网格 │
|
|
33
|
+
│ ├─────────────┴─────────────┤ │
|
|
34
|
+
│ │ textarea(span 2) │ ← 独占一行 │
|
|
35
|
+
│ ├─────────────────────────── ┤ │
|
|
36
|
+
│ │ 提交 取消(sticky) │ ← 底部始终可见 │
|
|
37
|
+
│ └─────────────────────────── ┘ │
|
|
38
|
+
└─────────────────────────────────────────────────┘
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
> 底部操作栏使用 `position: sticky; bottom: 1px`,滚动长表单时始终固定在底部可见区域。
|
|
42
|
+
|
|
43
|
+
## 基础用法
|
|
44
|
+
|
|
45
|
+
传入 `name` 和 `components` 即可渲染一个快捷指令表单:
|
|
46
|
+
|
|
47
|
+
```vue
|
|
48
|
+
<template>
|
|
49
|
+
<ShortcutRender
|
|
50
|
+
:name="shortcut.name"
|
|
51
|
+
:components="shortcut.components"
|
|
52
|
+
@close="handleClose"
|
|
53
|
+
@submit="handleSubmit"
|
|
54
|
+
/>
|
|
55
|
+
</template>
|
|
56
|
+
|
|
57
|
+
<script setup lang="ts">
|
|
58
|
+
import { ShortcutRender, type Shortcut } from '@blueking/chat-x';
|
|
59
|
+
|
|
60
|
+
const shortcut: Shortcut = {
|
|
61
|
+
id: 'translate',
|
|
62
|
+
name: '翻译',
|
|
63
|
+
components: [
|
|
64
|
+
{
|
|
65
|
+
type: 'select',
|
|
66
|
+
key: 'targetLang',
|
|
67
|
+
name: '目标语言',
|
|
68
|
+
default: 'en',
|
|
69
|
+
options: [
|
|
70
|
+
{ label: '英文', value: 'en' },
|
|
71
|
+
{ label: '中文', value: 'zh' },
|
|
72
|
+
{ label: '日文', value: 'ja' },
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
type: 'textarea',
|
|
77
|
+
key: 'content',
|
|
78
|
+
name: '翻译内容',
|
|
79
|
+
fillBack: true,
|
|
80
|
+
placeholder: '请输入要翻译的内容',
|
|
81
|
+
rows: 4,
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const handleClose = () => console.log('关闭');
|
|
87
|
+
const handleSubmit = (formModel: Record<string, unknown>) => {
|
|
88
|
+
// { targetLang: 'en', content: '...' }
|
|
89
|
+
console.log('提交:', formModel);
|
|
90
|
+
};
|
|
91
|
+
</script>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**渲染效果**
|
|
95
|
+
|
|
96
|
+
## 全部表单类型
|
|
97
|
+
|
|
98
|
+
`ShortcutRender` 支持 8 种控件类型,通过 `type` 字段指定:
|
|
99
|
+
|
|
100
|
+
```vue
|
|
101
|
+
<script setup lang="ts">
|
|
102
|
+
import { type ShortcutComponent } from '@blueking/chat-x';
|
|
103
|
+
|
|
104
|
+
const components: ShortcutComponent[] = [
|
|
105
|
+
// 单行文本输入
|
|
106
|
+
{ type: 'input', key: 'language', name: '编程语言', placeholder: '如:TypeScript、Python' },
|
|
107
|
+
// 数字输入(支持 min/max)
|
|
108
|
+
{ type: 'number', key: 'maxLines', name: '最大行数', default: '50', min: 1, max: 500 },
|
|
109
|
+
// 下拉选择
|
|
110
|
+
{
|
|
111
|
+
type: 'select',
|
|
112
|
+
key: 'style',
|
|
113
|
+
name: '代码风格',
|
|
114
|
+
default: 'concise',
|
|
115
|
+
options: [
|
|
116
|
+
{ label: '简洁', value: 'concise' },
|
|
117
|
+
{ label: '详细注释', value: 'detailed' },
|
|
118
|
+
],
|
|
119
|
+
},
|
|
120
|
+
// 单选组
|
|
121
|
+
{
|
|
122
|
+
type: 'radioGroup',
|
|
123
|
+
key: 'outputFormat',
|
|
124
|
+
name: '输出格式',
|
|
125
|
+
default: 'code',
|
|
126
|
+
options: [
|
|
127
|
+
{ label: '代码块', value: 'code' },
|
|
128
|
+
{ label: '文件', value: 'file' },
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
// 多选组
|
|
132
|
+
{
|
|
133
|
+
type: 'checkboxGroup',
|
|
134
|
+
key: 'features',
|
|
135
|
+
name: '包含功能',
|
|
136
|
+
options: [
|
|
137
|
+
{ label: '注释', value: 'comments' },
|
|
138
|
+
{ label: '错误处理', value: 'error-handling' },
|
|
139
|
+
],
|
|
140
|
+
},
|
|
141
|
+
// 开关
|
|
142
|
+
{ type: 'switcher', key: 'async', name: '异步函数' },
|
|
143
|
+
// 多行文本(独占一行)
|
|
144
|
+
{
|
|
145
|
+
type: 'textarea',
|
|
146
|
+
key: 'description',
|
|
147
|
+
name: '功能描述',
|
|
148
|
+
fillBack: true,
|
|
149
|
+
rows: 3,
|
|
150
|
+
placeholder: '请详细描述需要生成的代码功能',
|
|
151
|
+
},
|
|
152
|
+
];
|
|
153
|
+
</script>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**渲染效果**
|
|
157
|
+
|
|
158
|
+
## 表单初始值
|
|
159
|
+
|
|
160
|
+
### 通过 `component.default`(推荐)
|
|
161
|
+
|
|
162
|
+
直接在 `ShortcutComponent` 上设置 `default`,该字段在表单初始化时被优先使用:
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
const components: ShortcutComponent[] = [
|
|
166
|
+
{
|
|
167
|
+
type: 'select',
|
|
168
|
+
key: 'lang',
|
|
169
|
+
name: '语言',
|
|
170
|
+
default: 'zh', // ← 初始选中"中文"
|
|
171
|
+
options: [
|
|
172
|
+
{ label: '中文', value: 'zh' },
|
|
173
|
+
{ label: '英文', value: 'en' },
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
];
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### 通过 `formModel` prop
|
|
180
|
+
|
|
181
|
+
`formModel` 适合传入**不在 `components` 中的额外字段**,或特殊场景下的外部初始值。
|
|
182
|
+
|
|
183
|
+
```vue
|
|
184
|
+
<template>
|
|
185
|
+
<ShortcutRender
|
|
186
|
+
name="搜索"
|
|
187
|
+
:components="components"
|
|
188
|
+
:form-model="initialValues"
|
|
189
|
+
@submit="handleSubmit"
|
|
190
|
+
/>
|
|
191
|
+
</template>
|
|
192
|
+
|
|
193
|
+
<script setup lang="ts">
|
|
194
|
+
const components = [
|
|
195
|
+
{ type: 'input', key: 'keyword', name: '关键词' },
|
|
196
|
+
{
|
|
197
|
+
type: 'select',
|
|
198
|
+
key: 'scope',
|
|
199
|
+
name: '范围',
|
|
200
|
+
options: [
|
|
201
|
+
{ label: '全部', value: 'all' },
|
|
202
|
+
{ label: '标题', value: 'title' },
|
|
203
|
+
],
|
|
204
|
+
},
|
|
205
|
+
];
|
|
206
|
+
|
|
207
|
+
// formModel 中与 components 同名的 key 会被 component.default 覆盖
|
|
208
|
+
// 若 component 没有设置 default,对应 formModel 的值也会被 undefined 覆盖
|
|
209
|
+
const initialValues = { keyword: 'Vue 3', scope: 'title' };
|
|
210
|
+
</script>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**初始化优先级(`watchEffect` 执行顺序)**:
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
① 先写入 formModel 中的所有 key-value
|
|
217
|
+
② 再遍历 components,对每个 component.key 写入:
|
|
218
|
+
component.default ?? component.props?.default ?? component.props?.modelValue
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
> **注意**:步骤 ② 会覆盖步骤 ① 的值。若某个 component 没有设置 `default`,该 key 会被写入 `undefined`,**formModel 中对应的值会丢失**。因此,当 component 和 formModel 存在同名 key 时,应在 component 上设置 `default`,而非依赖 `formModel`。
|
|
222
|
+
|
|
223
|
+
## 必填校验(fillBack)
|
|
224
|
+
|
|
225
|
+
`fillBack: true` 将表单项映射为 bkui-vue `Form.FormItem` 的 `required: true`,提交时若为空则阻止提交并展示错误提示:
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
const components: ShortcutComponent[] = [
|
|
229
|
+
{
|
|
230
|
+
type: 'input',
|
|
231
|
+
key: 'title',
|
|
232
|
+
name: '标题',
|
|
233
|
+
fillBack: true, // 必填
|
|
234
|
+
placeholder: '请输入标题',
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
type: 'textarea',
|
|
238
|
+
key: 'content',
|
|
239
|
+
name: '内容',
|
|
240
|
+
fillBack: true, // 必填
|
|
241
|
+
rows: 5,
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
type: 'select',
|
|
245
|
+
key: 'category',
|
|
246
|
+
name: '分类', // 选填(无 fillBack)
|
|
247
|
+
options: [
|
|
248
|
+
{ label: '技术', value: 'tech' },
|
|
249
|
+
{ label: '业务', value: 'biz' },
|
|
250
|
+
],
|
|
251
|
+
},
|
|
252
|
+
];
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
> `fillBack` 同时具有语义作用:在 `ChatInput`/`UserMessage` 场景下,标记了 `fillBack: true` 的字段内容会被回填到对话输入框中。
|
|
256
|
+
|
|
257
|
+
## 布局规则
|
|
258
|
+
|
|
259
|
+
表单使用 **两列网格**(`grid-template-columns: repeat(2, 1fr)`)排列:
|
|
260
|
+
|
|
261
|
+
| 情况 | 占列数 |
|
|
262
|
+
| --------------------------------------------------------- | ------------------------- |
|
|
263
|
+
| `type === 'textarea'` | 始终 `span 2`(独占一行) |
|
|
264
|
+
| 最后一个 item,且前面所有 item 累计列数为偶数(独占新行) | `span 2` |
|
|
265
|
+
| 其他 | `auto`(占 1 列) |
|
|
266
|
+
|
|
267
|
+
```
|
|
268
|
+
┌─────────────┬─────────────┐
|
|
269
|
+
│ input │ number │ ← 各占半行
|
|
270
|
+
├─────────────┴─────────────┤
|
|
271
|
+
│ textarea │ ← 独占一行
|
|
272
|
+
├─────────────┬─────────────┤
|
|
273
|
+
│ select │ switcher │ ← 各占半行
|
|
274
|
+
├─────────────┴─────────────┤
|
|
275
|
+
│ 最后一个(奇数起新行) │ ← 自动独占
|
|
276
|
+
└───────────────────────────┘
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## 透传底层组件 props
|
|
280
|
+
|
|
281
|
+
通过 `component.props` 可直接透传给 bkui-vue 底层控件,`component.props.options` 优先于 `component.options`:
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
const components: ShortcutComponent[] = [
|
|
285
|
+
{
|
|
286
|
+
type: 'select',
|
|
287
|
+
key: 'lang',
|
|
288
|
+
name: '语言',
|
|
289
|
+
// 方式一:通过 component.options(常规)
|
|
290
|
+
options: [{ label: '中文', value: 'zh' }],
|
|
291
|
+
// 方式二:通过 component.props(优先级更高,覆盖 options)
|
|
292
|
+
props: {
|
|
293
|
+
options: [{ label: '英文', value: 'en' }], // 此处会覆盖上面的 options
|
|
294
|
+
clearable: true, // 透传给 bkui-vue Select 的其他 prop
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
type: 'input',
|
|
299
|
+
key: 'text',
|
|
300
|
+
name: '文本',
|
|
301
|
+
props: {
|
|
302
|
+
clearable: true, // 透传给 bkui-vue Input
|
|
303
|
+
maxlength: 100,
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
];
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
通过 `component.formItemProps` 透传给 `Form.FormItem`:
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
{
|
|
313
|
+
type: 'input',
|
|
314
|
+
key: 'email',
|
|
315
|
+
name: '邮箱',
|
|
316
|
+
formItemProps: {
|
|
317
|
+
description: '请输入有效的邮箱地址', // bkui-vue FormItem 的 description prop
|
|
318
|
+
},
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## API
|
|
323
|
+
|
|
324
|
+
### Props
|
|
325
|
+
|
|
326
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
327
|
+
| ----------- | ------------------------- | ------ | -------------------------------------------------------------------- |
|
|
328
|
+
| id | `string` | — | 快捷指令唯一标识(透传,不影响表单渲染) |
|
|
329
|
+
| name | `string` | — | 表单标题,显示在头部栏 |
|
|
330
|
+
| description | `string` | — | 快捷指令描述(透传,组件内部不渲染) |
|
|
331
|
+
| components | `ShortcutComponent[]` | — | 表单控件配置列表 |
|
|
332
|
+
| formModel | `Record<string, unknown>` | — | 外部初始值;与 `components` 同名 key 时,以 `component.default` 为准 |
|
|
333
|
+
|
|
334
|
+
### Events
|
|
335
|
+
|
|
336
|
+
| 事件名 | 参数 | 触发时机 |
|
|
337
|
+
| ------ | -------------------------------------- | ------------------------------------------ |
|
|
338
|
+
| close | — | 点击头部关闭图标 **或** 底部取消按钮时触发 |
|
|
339
|
+
| submit | `(formModel: Record<string, unknown>)` | 表单校验通过后点击提交按钮触发 |
|
|
340
|
+
|
|
341
|
+
## ShortcutComponent 配置项
|
|
342
|
+
|
|
343
|
+
### 通用字段
|
|
344
|
+
|
|
345
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
346
|
+
| ------------- | ------------------------------------ | ---- | ------------------------------------------------------------------------------------------ |
|
|
347
|
+
| type | 见[表单类型](#表单组件类型) | ✓ | 控件类型;未知类型返回 `null`,不渲染 |
|
|
348
|
+
| key | `string` | ✓ | 表单字段名;`submit` 事件返回对象以此为 key;同时作为校验 property |
|
|
349
|
+
| name | `string` | — | 表单项标签;优先于 `formItemProps.label`,通过 `#label` 插槽渲染为 `.shortcut-render-form-label` |
|
|
350
|
+
| default | `string` | — | 字段初始值;优先于 `formModel`,在 `watchEffect` 中覆盖写入 |
|
|
351
|
+
| fillBack | `boolean` | — | `true` 时映射为 `required: true`(必填校验),同时标记回填语义 |
|
|
352
|
+
| placeholder | `string` | — | 占位文本(`input` / `textarea` / `number` 可用) |
|
|
353
|
+
| rows | `number` | — | 文本行数(`textarea` 可用) |
|
|
354
|
+
| min | `number` | — | 最小值(`number` 可用) |
|
|
355
|
+
| max | `number` | — | 最大值(`number` 可用) |
|
|
356
|
+
| options | `{ label: string; value: string }[]` | — | 选项列表(`select` / `radioGroup` / `checkboxGroup` 需要);`component.props.options` 优先 |
|
|
357
|
+
| props | `object` | — | 直接透传给底层 bkui-vue 控件的 props;`options` 优先于 `component.options` |
|
|
358
|
+
| formItemProps | `object` | — | 直接透传给 `Form.FormItem` 的 props |
|
|
359
|
+
|
|
360
|
+
### 表单组件类型
|
|
361
|
+
|
|
362
|
+
| `type` | 底层控件 | 说明 |
|
|
363
|
+
| --------------- | ---------------------- | ---------------------------- |
|
|
364
|
+
| `input` | `Input` | 单行文本输入框 |
|
|
365
|
+
| `text` | `Input` | 同 `input`,兼容旧版写法 |
|
|
366
|
+
| `textarea` | `Input[type=textarea]` | 多行文本,**始终独占一行** |
|
|
367
|
+
| `number` | `Input[type=number]` | 数字输入,支持 `min` / `max` |
|
|
368
|
+
| `select` | `Select` | 下拉选择,需配置 `options` |
|
|
369
|
+
| `radioGroup` | `Radio.Group` | 单选组,需配置 `options` |
|
|
370
|
+
| `checkboxGroup` | `Checkbox.Group` | 多选组,需配置 `options` |
|
|
371
|
+
| `switcher` | `Switcher` | 开关,值为 `boolean` |
|
|
372
|
+
| 其他 | — | 返回 `null`,不渲染任何控件 |
|
|
373
|
+
|
|
374
|
+
## 类型定义
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
import type { Shortcut, ShortcutComponent } from '@blueking/chat-x';
|
|
378
|
+
|
|
379
|
+
interface Shortcut {
|
|
380
|
+
id?: string;
|
|
381
|
+
name?: string;
|
|
382
|
+
description?: string;
|
|
383
|
+
icon?: string | VNode | ((h: typeof h) => Component | VNode);
|
|
384
|
+
components?: ShortcutComponent[];
|
|
385
|
+
formModel?: Record<string, unknown>;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// ShortcutComponent 是各具体类型的联合类型
|
|
389
|
+
type ShortcutComponent =
|
|
390
|
+
| InputShortcutComponent
|
|
391
|
+
| TextShortcutComponent
|
|
392
|
+
| TextareaShortcutComponent
|
|
393
|
+
| NumberShortcutComponent
|
|
394
|
+
| SelectShortcutComponent
|
|
395
|
+
| RadioGroupShortcutComponent
|
|
396
|
+
| CheckboxGroupShortcutComponent
|
|
397
|
+
| SwitcherShortcutComponent;
|
|
398
|
+
|
|
399
|
+
// 所有类型共有字段(BaseShortcutComponent)
|
|
400
|
+
interface BaseShortcutComponent {
|
|
401
|
+
type: string;
|
|
402
|
+
key: string;
|
|
403
|
+
name?: string;
|
|
404
|
+
default?: string;
|
|
405
|
+
fillBack?: boolean;
|
|
406
|
+
placeholder?: string;
|
|
407
|
+
rows?: number;
|
|
408
|
+
min?: number;
|
|
409
|
+
max?: number;
|
|
410
|
+
options?: { label: string; value: string }[];
|
|
411
|
+
props?: Record<string, unknown>; // 透传给底层控件
|
|
412
|
+
formItemProps?: Record<string, unknown>; // 透传给 Form.FormItem
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
## 样式说明
|
|
417
|
+
|
|
418
|
+
表单项与控件会附加类型化 class,便于样式覆盖:`shortcut-render-form-item_{type}`(如 `_radio`、`_checkbox`),单选/多选项子项为 `shortcut-render-form-item_radio` / `shortcut-render-form-item_checkbox`。表单项标签使用 BEM 风格类名 `shortcut-render-form-label`。
|
|
419
|
+
|
|
420
|
+
## 关联组件
|
|
421
|
+
|
|
422
|
+
- [ShortcutBtn](/components/input/shortcut-btn) — 与 Shortcut 数据模型一致的入口按钮
|
|
423
|
+
- [ChatInput](/components/input/chat-input) — 输入区与快捷指令流程联动
|
|
424
|
+
- [ChatContainer](/components/setup/chat-container) — 顶层布局中挂载快捷表单
|