# Popup 布局重构 — 功能导航与 Dashboard 移除 > 创建时间: 2026-07-05 > 状态: 待实施 > 关联模块: `src/entrypoints/popup/`、`src/layout/FeatureNav/`、`src/providers/RouterProvider.tsx` > 影响范围: 仅 popup 入口(tab / sidepanel 不在本次布局范围) ## 背景与目标 当前 popup 采用 **Dashboard 首页 + TopBar 搜索跳转** 模式:用户打开扩展后先看到仪表盘卡片网格,再点击进入具体工具。布局为固定 400×600(见 `src/entrypoints/popup/App.tsx` 与 `src/entrypoints/popup/index.html`),TopBar 在非 dashboard 页面显示「返回首页」按钮。 该模式增加了一步选工具操作。本次重构将 popup 改为 **工具直达 + 右侧常驻导航**,并移除 Dashboard 页面。 | 维度 | 现状 | 目标 | | ---------- | ----------------------------- | ----------------------------------------- | | 默认页 | `dashboard` | 新用户默认 `timestamp` | | 导航 | Dashboard 卡片网格 + 搜索跳转 | 右侧常驻纯图标导航栏 | | 首页 | Dashboard 独立页 | 移除 | | Popup 宽度 | 400px | 450px(内容区 ~402px + 导航栏 48px) | | 作用范围 | — | 仅 popup 改布局;tab / sidepanel 不加导航 | --- ## 布局设计 ### 结构示意 ```mermaid flowchart LR subgraph popup ["Popup 450x600"] subgraph mainCol ["主列 flex-1"] TopBar["TopBar"] Content["RouterContainer"] TopBar --> Content end NavCol["FeatureNav 48px"] end mainCol --- NavCol ``` ### 尺寸约束 | 属性 | 值 | 说明 | | -------- | ------ | ---------------------------------------------- | | 总宽度 | 450px | `App.tsx` 容器 + `index.html` 内联样式同步修改 | | 总高度 | 600px | 不变 | | 主内容列 | flex-1 | 约 402px,需 `min-w-0` 防止 flex 子项溢出 | | 导航栏 | 48px | Tailwind `w-12`,固定宽度,不参与 flex 收缩 | ### 视觉规范 - 导航栏:左侧 `border-l border-border`,垂直排列图标按钮 - 图标按钮:`h-9 w-9` 或 `h-10 w-10`,纯图标 - Tooltip:使用原生 `title` 属性 + `aria-label={feature.label}`,不引入 Tooltip 组件 - Active 态:背景 `bg-muted` + 左侧 `border-l-2 border-primary` - 导航列表超出高度时:`overflow-y-auto`(600px 高度下 9 个工具通常无需滚动) --- ## FeatureNav 组件规格 新建 `src/layout/FeatureNav/`,遵循 UI + Hook 分离模式(见 `.github/CODING_STANDARDS.md` §11)。 ### 文件结构 ``` src/layout/FeatureNav/ ├── index.tsx # 垂直图标按钮列表、active 高亮、无障碍属性 ├── useFeatureNav.ts # 读路由状态,暴露 navItems / navigateTo / currentPage ├── resolveNavFeatures.ts # 从 Dashboard 迁出的功能列表解析逻辑 └── __tests__/ ├── index.test.tsx └── resolveNavFeatures.test.ts ``` ### resolveNavFeatures.ts 从 `src/pages/Dashboard/dashboardFeatures.ts` 迁出并重命名: ```typescript export interface NavFeatureItem { key: PageType; feature: FeatureConfig & { icon: NonNullable }; } export function resolveNavFeatures(keys: PageType[], visiblePages: PageType[]): NavFeatureItem[]; ``` 逻辑与旧 `resolveDashboardFeatures` 一致: - 按 `keys`(即 `pageOrder`)顺序遍历 - 跳过不在 `visiblePages` 中的项 - 跳过无 `icon` 的 feature(dashboard 移除后不应出现) ### useFeatureNav.ts ```typescript export interface UseFeatureNavReturn { navItems: NavFeatureItem[]; currentPage: PageType; navigateTo: (page: PageType) => void; } ``` - 从 `useRouter()` 读取 `currentPage`、`pageOrder`、`visiblePages`、`navigateTo` - 用 `useMemo` 调用 `resolveNavFeatures(pageOrder, visiblePages)` 生成 `navItems` ### index.tsx - 渲染 `