左右侧栏宽度与收起状态

左右侧栏共用同一套宽度、拖拽和收起行为。各侧栏只负责自己的导航、状态来源和主体内容。

状态约束

状态宽度规则行为
左侧展开180–480px从右边缘拖拽;超出范围时停止变化
右侧展开240–720px从左边缘拖拽;超出范围时停止变化
收起固定 49px左右使用同一 150ms 宽度动画
重新展开恢复收起前的合法宽度使用同一宽度动画,不丢弃刚调整的宽度

实现边界

components/layout/use-resizable-rail.ts 是唯一的宽度行为实现:保存展开宽度、限制范围、处理指针捕获、生成展开/收起样式并控制 transition。左、右侧栏分别提供范围和增长方向,不再各自维护事件监听器。手柄共用 base.css 中的 rail-resize-handle 样式,命中范围以分隔线为中心,向两侧各延伸约 8px,不改变布局宽度;外壳允许手柄溢出,内部内容容器继续裁切;仅主按钮启动拖动,并禁用手柄上的触摸平移与文字选择。

组件边界

文件职责
sidebar/sidebar.tsx左栏外壳、开关持久化、New chat、收藏和会话组合
sidebar/sidebar-primary-nav.tsx固定导航、路由高亮、导航图标动画和 Programs 刷新
right-sidebar/right-sidebar.tsx右栏外壳、文件入口和视图容器
right-sidebar/detail-panel.tsxDAG 选中节点的 Details/Context 切换和详情渲染

不在本次结构调整中拆分会话列表或 AppShell;它们有独立状态和交互边界,不能与侧栏外壳移动混在同一次变更中。

验收

分别将左右侧栏拖到边界后收起,应在 150ms 内平滑变为 49px;再次展开应恢复各自之前的宽度。分隔线两侧约 8px 均可触发拖动,悬停和拖动时只改变鼠标光标,不增加高亮;拖动过程中离开手柄仍应继续响应,释放、取消指针或窗口失去焦点后必须恢复收起动画;窗口级结束事件补充手柄的捕获事件,移动时发现按钮已释放也结束拖动。

实现状态

已实现:左右侧栏使用同一宽度行为模块;固定导航和详情渲染分别离开外壳文件,外壳组件只负责组合。