WebShell 侧边栏 — 自定义指南
WebShellSidebar 是在 web-shell App 组件中渲染的会话列表和导航面板。本文档将每个可视区域映射到其当前的自定义能力,并标识没有外部注入点的区域。
启用侧边栏
侧边栏默认禁用。传递 sidebar prop 以启用:
import { WebShellWithProviders } from '@qwen-code/web-shell';
<WebShellWithProviders
baseUrl="http://localhost:4170"
sidebar={true} // 简单启用
// 或使用细粒度选项:
// sidebar={{ enabled: true, defaultCollapsed: false, ... }}
/>;布局概览
┌─────────────────────────────────────┐
│ ① 品牌区(topRow) │ ✅ 可自定义
├─────────────────────────────────────┤
│ ② 主导航 │ ✅ 可自定义
│ [+ 新任务] [🧩 插件] │
│ [📅 定时任务] [🎯 目标] │
│ [自定义渲染...] │
├─────────────────────────────────────┤
│ ③ 项目头部 │ ✅ 显示/隐藏
│ 📁 项目 ▼ [🔍] [+] │
│ 会话列表条目... │
│ 📦 已归档会话 │
├─────────────────────────────────────┤
│ ④ 底部操作栏 │ ✅ 可自定义
│ [⚙ 设置] v0.19 [☀] [▦] [◧] │
├─────────────────────────────────────┤
│ ⑤ 拖拽手柄 │ ❌ 不可自定义
└─────────────────────────────────────┘可自定义区域
① 品牌区 — branding
interface WebShellSidebarBranding {
render?: () => ReactNode; // 替换整个品牌行
hideWhenCompact?: boolean; // 侧边栏折叠时隐藏(默认:true)
}| 值 | 效果 |
|---|---|
undefined(默认) | Qwen logo + “Qwen Code” 文本 |
false | 完全隐藏品牌行 |
{ render: () => <MyHeader /> } | 使用自定义内容完全替换 |
{ hideWhenCompact: false } | 在折叠的图标栏模式下保持品牌区可见 |
sidebar={{
branding: {
render: () => (
<div style={{ display: 'flex', gap: 8 }}>
<img src="/my-logo.svg" alt="" width={24} />
<span>My App</span>
</div>
),
},
}}② 主导航 — primaryNav
type WebShellSidebarPrimaryNavItem =
| 'newTask' // ✏️ 新任务按钮
| 'plugins' // 🧩 插件按钮
| 'scheduledTasks' // 📅 定时任务按钮
| 'goals'; // 🎯 目标按钮
interface WebShellSidebarPrimaryNavOptions {
items?: readonly WebShellSidebarPrimaryNavItem[]; // 显示哪些内置按钮(默认:全部)
render?: () => ReactNode; // 内置按钮之后的额外自定义内容
}主导航区域包含由 items 控制的内置按钮:
- 未指定
items时默认显示所有按钮 - 提供
items时仅显示列出的按钮 - 可通过
render()在内置按钮之后添加自定义内容
| 值 | 效果 |
|---|---|
undefined(默认) | 显示所有内置按钮 |
{ items: ['plugins'] } | 仅插件按钮 |
{ items: ['plugins', 'scheduledTasks'] } | 插件 + 定时任务 |
{ items: [], render: () => ... } | 隐藏所有内置按钮,仅显示自定义内容 |
sidebar={{
primaryNav: {
items: ['plugins', 'scheduledTasks'], // 隐藏 newTask 和 goals
render: () => (
<button onClick={() => console.log('custom action')}>
🔗 数据同步
</button>
),
},
}}④ 底部栏 — footer
type WebShellSidebarFooterItem =
| 'settings' // ⚙ 设置面板
| 'version' // 版本标签(例如 "v0.19.10")
| 'theme' // ☀/🌙 亮色/暗色切换
| 'sessionsOverview' // ▦ 会话概览面板(仅大屏幕)
| 'splitView' // ◧ 分屏视图(仅大屏幕)
| 'daemonStatus' // 📊 daemon 状态面板
| 'collapse'; // ◁/▷ 折叠/展开切换
interface WebShellSidebarFooterOptions {
items?: readonly WebShellSidebarFooterItem[]; // 显示哪些内置项(默认:全部)
render?: () => ReactNode; // 在左侧、内置项之前渲染的自定义内容
}| 值 | 效果 |
|---|---|
undefined(默认) | 显示所有项 |
false | 完全隐藏底部栏 |
{ items: ['settings', 'theme', 'collapse'] } | 仅显示列出的项 |
底部栏会自动适应窄宽度:标签会被隐藏,版本信息在某些阈值以下会被移除。
sidebar={{
footer: { items: ['theme', 'collapse'] }, // 极简底部栏
}}通过 render() 添加的自定义内容出现在底部栏的左侧,在内置项之前:
sidebar={{
footer: {
items: ['collapse'],
render: () => (
<button onClick={() => openHelpCenter()}>
❓ 帮助
</button>
),
},
}}注意: 'scheduledTasks' 和 'goals' 已移至主导航区域(②),默认显示。它们由 primaryNav.items 控制,而非 footer.items。
其他顶级选项
interface WebShellSidebarOptions {
enabled?: boolean; // 显示/隐藏侧边栏(传入时为 true)
defaultCollapsed?: boolean; // 初始折叠状态(持久化到 localStorage)
showCompactToggle?: boolean; // 在聊天区域显示折叠按钮(默认:true)
branding?: false | WebShellSidebarBranding;
primaryNav?: WebShellSidebarPrimaryNavOptions;
hideProjectHeader?: boolean; // 隐藏"项目"头部行(默认:false = 显示)
sessionActions?: WebShellSidebarSessionActionsOptions;
footer?: false | WebShellSidebarFooterOptions;
}③ 项目头部 — hideProjectHeader
控制”项目”头部行的可见性(包含折叠切换、搜索图标和添加 workspace 按钮的那一行)。默认为 false(显示)。
sidebar={{
hideProjectHeader: true, // 隐藏"项目 ▼ [🔍] [+]"行
}}隐藏后,会话列表条目和已归档会话仍然显示——带有操作按钮的头部行和会话搜索栏会被移除。
会话行操作 — sessionActions
type WebShellSidebarSessionActionItem =
| 'details' // 📝 详情(下拉子菜单)
| 'rename' // ✏️ 重命名(下拉菜单)
| 'group' // 📁 分组/移动到文件夹(下拉菜单)
| 'export' // 📤 导出聊天记录(下拉菜单)
| 'delete' // 🗑 删除会话(下拉菜单)
| 'pin' // 📌 置顶/取消置顶(内联按钮)
| 'archive'; // 📦 归档(内联按钮)
/** 具有可用内联(hover 按钮)处理程序的子集。 */
type WebShellSidebarSessionInlineActionItem =
| 'pin'
| 'archive'
| 'rename'
| 'export'
| 'delete';
interface WebShellSidebarSessionActionsOptions {
items?: readonly WebShellSidebarSessionActionItem[]; // 显示哪些操作(默认:全部)
inlineItems?: readonly WebShellSidebarSessionInlineActionItem[]; // 哪些项作为内联按钮显示(默认:['pin', 'archive'])
}控制会话行上显示哪些操作按钮:
items:所有操作的主控(包括内联和下拉)。如果某项不在items中,则在各处隐藏。inlineItems:控制哪些项作为内联按钮(hover 时)显示。默认为['pin', 'archive']。只有具有可用内联处理程序的项才能使用:'pin'、'archive'、'rename'、'export'、'delete'。'details'和'group'仅支持下拉。
可见性优先级:items AND 该项的内置条件 AND inlineItems 三者都必须通过,内联按钮才会显示。例如,delete 作为内联按钮需要 items 包含 'delete' AND inlineItems 包含 'delete'。
| 值 | 效果 |
|---|---|
undefined(默认) | 显示所有操作,pin + archive 作为内联按钮 |
{ inlineItems: ['pin', 'delete'] } | Pin + delete 作为内联按钮 |
{ inlineItems: [] } | 完全没有内联按钮 |
{ inlineItems: ['archive', 'export'] } | Archive + export 作为内联按钮 |
当没有启用下拉项时,下拉触发器(⋮)会自动隐藏。内联按钮(pin、archive)仅在其能力条件和 items 都包含它们时才会显示。
sidebar={{
sessionActions: {
items: ['details', 'rename', 'export', 'delete', 'pin'], // 显示哪些操作(主控)
inlineItems: ['pin', 'delete'], // pin + delete 作为内联按钮
},
}}不可自定义区域
项目 / Workspaces(会话列表内部)
当会话列表可见时,以下子区域会被渲染但不可单独自定义:
| 方面 | 详情 |
|---|---|
| 数据来源 | useSessions() hook → daemon API(/sessions 端点) |
| 会话列表排序 | 按创建时间降序 |
| 会话行渲染 | 内部 renderSessionRow useCallback — 不可注入 |
| 搜索 / 过滤 | 内置搜索栏,客户端文本匹配 |
| 会话分组 | SessionGroupSection 组件,6 种预设颜色 + 自定义 hex |
| Workspace 分区 | 每个 daemon workspace 一个 WorkspaceSection,不可替换 |
| 添加 workspace 对话框 | 内置 AddWorkspaceDialog |
⑤ 拖拽手柄
- 右侧边缘的拖拽手柄,用于调整侧边栏宽度
- 宽度持久化到 localStorage
- 不可配置
运行时行为 props
这些 WebShellProps 间接影响侧边栏行为:
| Prop | 效果 |
|---|---|
onNewSession | 覆盖新建会话处理程序 |
onLoadSession | 覆盖会话加载逻辑 |
onSessionIdChange | 响应会话切换 |
splitSessionIds | 从外部控制分屏会话 |
theme / onThemeChange | 控制 / 观察主题 |
language / onLanguageChange | 控制 / 观察 UI 语言 |
折叠和移动端状态
| 状态 | 行为 |
|---|---|
| 展开 | 带有文本标签的完整侧边栏 |
| 折叠 | 图标栏模式(仅 logo、笔图标、操作图标) |
| 移动端 | 从左侧滑入的抽屉,带有背景遮罩 |
折叠状态持久化在 localStorage 中,键名为 qwen-code-web-shell-sidebar-collapsed。
源码位置
| 组件 | 文件 |
|---|---|
| WebShellSidebar | packages/web-shell/client/components/sidebar/WebShellSidebar.tsx |
| SessionGroupSection | packages/web-shell/client/components/sidebar/SessionGroupSection.tsx |
| WorkspaceSection | packages/web-shell/client/components/sidebar/WorkspaceSection.tsx |
| Sidebar styles | packages/web-shell/client/components/sidebar/WebShellSidebar.module.css |
| App integration | packages/web-shell/client/App.tsx(搜索 WebShellSidebar) |
| Entry point (dev) | packages/web-shell/client/main.tsx(sidebar: true) |
Last updated on