左侧菜单配置
左侧菜单(NavigationRail)是场景 UI 的核心导航区域,用户通过点击图标切换不同的功能面板。
工作原理
sidebarItems 配置 → NavigationRail 渲染图标 → 用户点击 → 侧边栏显示对应面板1
- 场景激活时,客户端读取
ui.sidebarItems渲染左侧菜单图标 - 用户点击图标,客户端设置
activeSidePanel为该菜单项的id - 侧边栏根据
id查找面板组件并渲染
声明式场景菜单
在 scenario.json 的 ui.sidebarItems 中配置,仅支持内置面板:
json
{
"ui": {
"layout": "chat-centric",
"sidebarItems": [
{
"id": "explorer",
"icon": "Files",
"label": "Workspace",
"labelZh": "工作区",
"component": "ExplorerView",
"position": 0
},
{
"id": "knowledge",
"icon": "BookOpen",
"label": "Knowledge",
"labelZh": "知识库",
"component": "KnowledgeView",
"position": 1
},
{
"id": "history",
"icon": "History",
"label": "History",
"labelZh": "历史",
"component": "HistoryView",
"position": 2
},
{
"id": "tasks",
"icon": "CheckSquare",
"label": "Tasks",
"labelZh": "任务",
"component": "TasksView",
"position": 3
}
]
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
宽屏模式 (wideMode)
wideMode 是 SidebarItem 的可选字段,当设为 true 时,该菜单项对应的面板将占据主内容区域(而非侧边栏),同时侧边栏自动收起。
使用场景
- 设置面板:场景专属设置需要一个宽大的操作区域,不适合在狭窄侧边栏中展示
- 知识库:需要全屏展示的复杂面板
- 仪表盘:数据密集的统计面板
配置示例:场景专属设置
第一步:声明菜单项 + wideMode
typescript
getPlugin() {
return {
ui: {
sidebarItems: [
// ... 其他侧边栏项
{
id: 'settings',
icon: 'Settings',
label: 'Settings',
labelZh: '场景设置',
component: 'MySettingsView',
position: 8,
wideMode: true, // 宽屏模式
},
],
},
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
第二步:创建设置视图组件
tsx
// components/settings/MySettingsView.tsx
import { useCallback } from 'react'
import { useStore } from '@store'
import { MySettingsDialog } from './MySettingsDialog'
export default function MySettingsView() {
const closePanel = useCallback(() => {
// 关闭设置时回到文件管理器
useStore.getState().setActiveSidePanel('explorer')
}, [])
return <MySettingsDialog embedded onClose={closePanel} />
}1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
第三步:创建设置对话框组件
tsx
// components/settings/MySettingsDialog.tsx
export function MySettingsDialog({
embedded = false,
onClose,
}: {
embedded?: boolean
onClose?: () => void
}) {
const content = (
<div className={`flex h-full ${embedded ? '' : 'max-h-[800px]'}`}>
{/* 左侧导航 */}
<div className="w-56 bg-surface/30 backdrop-blur-xl pt-8 pb-6">
{/* 标签页导航 */}
</div>
{/* 右侧内容 */}
<div className="flex-1 overflow-auto">
{/* 设置表单 */}
</div>
</div>
)
if (embedded) {
return content // wideMode 下直接渲染,无弹窗遮罩
}
return (
<OverlayDialog onClose={onClose}>
{content}
</OverlayDialog>
)
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
关键点:
embedded模式下移除弹窗遮罩,onClose回调切换侧边栏面板回到 explorer。
工作原理
用户点击 wideMode 菜单项
→ 侧边栏收起 (sidebar hidden)
→ 面板组件渲染到 FullPageSlot(主内容区)
→ 用户点击关闭按钮 → setActiveSidePanel('explorer')
→ 侧边栏恢复,面板回到 explorer1
2
3
4
5
2
3
4
5
内置面板组件
| component 值 | 说明 |
|---|---|
ExplorerView | 文件浏览器 |
SearchView | 全局搜索 |
GitView | Git 源码管理 |
ProblemsView | 问题诊断 |
OutlineView | 符号大纲 |
HistoryView | 历史记录 |
ShellView | Shell 终端 |
KnowledgeView | 知识库 |
NotesView | 笔记 |
TasksView | 任务管理 |
BookmarksView | 书签 |
PromptsView | 提示词库 |
编程式场景菜单
编程式场景支持自定义面板组件,分两步:
第一步:声明菜单项
在 getPlugin() 的 ui.sidebarItems 中声明:
typescript
getPlugin() {
return {
ui: {
sidebarItems: [
// 自定义面板:component 对应 getComponents() 返回的 key
{
id: 'tasks',
icon: 'CheckSquare',
label: 'Tasks',
labelZh: '任务',
component: 'TaskListPanel',
position: 0,
},
{
id: 'stats',
icon: 'BarChart3',
label: 'Stats',
labelZh: '统计',
component: 'StatsPanel',
position: 1,
},
// 内置面板:直接引用内置组件名
{
id: 'explorer',
icon: 'Files',
label: 'Workspace',
labelZh: '工作区',
component: 'ExplorerView',
position: 2,
},
{
id: 'knowledge',
icon: 'BookOpen',
label: 'Knowledge',
labelZh: '知识库',
component: 'KnowledgeView',
position: 3,
},
],
defaultSidePanel: 'tasks',
},
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
第二步:注册自定义组件
在 getComponents() 中注册:
typescript
import { TaskListPanel } from './components/TaskListPanel.js'
import { StatsPanel } from './components/StatsPanel.js'
getComponents() {
return {
TaskListPanel,
StatsPanel,
}
}1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
关键:
sidebarItems中的component值必须与getComponents()返回的 key 一致。
字段说明
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 是 | 菜单项唯一标识,同时作为面板 ID |
icon | string | 是 | 图标名称,使用 lucide-react 图标名 |
label | string | 是 | 英文标签 |
labelZh | string | 是 | 中文标签 |
component | string | 是 | 面板组件名 |
position | number | 否 | 排序位置,从小到大 |
wideMode | boolean | 否 | 宽屏模式下是否作为主面板显示 |
常用图标参考
| 图标名 | 适用场景 |
|---|---|
Files | 文件/工作区 |
Search | 搜索 |
GitBranch | Git 管理 |
BookOpen | 知识库 |
History | 历史记录 |
Terminal | 终端 |
CheckSquare | 任务 |
BarChart3 | 统计/图表 |
Database | 数据源 |
Settings | 设置 |
Map | 地图/行程 |
Wallet | 预算/财务 |
Stethoscope | 诊断 |
Brain | AI/深度思考 |
Zap | 快速操作 |
FolderTree | 目录树 |
ListTree | 大纲 |
AlertCircle | 问题/告警 |
完整图标列表参考 lucide.dev
布局与菜单的关系
不同 layout 值对左侧菜单的显示策略不同:
| 布局 | 菜单显示 | 说明 |
|---|---|---|
chat-centric | 有 sidebarItems 时显示 | 无菜单项时隐藏侧边栏 |
editor-centric | 始终显示 | 左侧菜单 + 中间编辑器 + 右侧聊天 |
dashboard-centric | 始终显示 | 左侧菜单 + 中间仪表盘 + 右侧聊天 |
analytics-centric | 始终显示 | 左侧菜单 + 中间分析面板 + 右侧聊天 |
canvas-centric | 始终显示 | 左侧菜单 + 中间画布 + 右侧聊天 |
minimal | 不显示 | 仅聊天界面 |
focus-centric | 不显示 | 编辑器 + 聊天 |
research-centric | 有 sidebarItems 时显示 | 编辑器 + 聊天 + 可选菜单 |

