agent-Specialization/doc/frontend/css_modularization_plan.md

9.2 KiB
Raw Blame History

前端样式模块化计划CSS

目标:在完全还原 static/old_version_backup/前端备份 视觉与交互的前提下,于 Vite + Vue 3 体系中重构 static/style.css,建立可维护、可组合的样式层。本文对应 doc/frontend/componentization_plan.md 的 CSS 版本,为后续拆分提供路径、里程碑与验证清单。

当前样式现状

  1. 单文件真值static/style.css 仍是唯一的设计源,static/src/main.ts 通过 import '../style.css'; 全局注入。内部含重置、变量、布局、组件、动画等所有样式,尚未按模块切分。
  2. 变量体系:顶层 :root 暴露 --claude-*(背景、阴影、按钮态等)并在所有组件复用,局部还混用硬编码色值,需要梳理。
  3. 全局依赖
    • DOM 结构来自 static/src/App.vue 及其子组件(ConversationSidebar.vueLeftPanel.vueChatArea.vueInputComposer.vueRightFocusPanel.vue 等)。
    • AppShell 提供 Toast/Confirm/EasterEgg/ContextMenu需要共享阴影与层级变量。
    • 彩蛋 CSSstatic/easter-eggs/*.css)仍单独引入,迁移不可破坏其优先级。

当前状态202511

  • static/src/styles/ 已完成 base/layout/components/utilities 分层;main.ts 仅导入 ./styles/index.scss
  • static/style.css 不再存放样式,而是 @import '/static/dist/assets/main.css',用于兼容历史入口(终端、登录等仍引用该路径)。
  • 旧版 CSS 原样保存于 static/old_version_backup/前端备份/style.css,便于对比 legacy 视觉。

拆分层级设计

static/src/styles/
├── base/          # 重置、字体、变量、icon 工具
├── layout/        # AppShell、主容器、面板栅格
├── components/    # 聊天/输入/侧栏/抽屉等模块
├── utilities/     # 动画、遮罩、z-index、辅助类
└── index.scss     # 汇总入口,由 main.ts 引入
  • Base Layer_reset.scss_tokens.scss_global.scss。负责 * { box-sizing }:root 变量、body 字体/背景、.icon 工具类等;对应当前 style.css 前 ~200 行。
  • Layout Layer_app-shell.scss_panels.scss。控制 .main-container.conversation-sidebar.sidebar-panel-card.chat-container.right-sidebar 的尺寸、flex 行为与响应式断点。
  • Component Layer:按照业务域划分子目录,例如:
    • components/sidebar/:历史列表、折叠按钮、搜索框、个人空间入口。
    • components/panels/:文件树/TODO/子智能体、TokenDrawer、ResourceStats。
    • components/chat/ChatArea + 各 ActionBlockThinking 动画、copy-code-btn
    • components/input/InputComposerQuickMenu、工具禁用菜单、设置子菜单。
    • components/overlays/Toast、Confirm、Quota Toast、ContextMenu、Personalization Drawer。
  • Utilities Layer:抽象 @keyframestransition 变量、.is-hidden.scrollbar.sr-only 等工具类,避免每个组件重复指定。

模块映射(示例)

模块文件 覆盖区域 对应组件/Store 说明
base/_tokens.scss :root 变量、阴影、字体 全局 拆出颜色/阴影/spacing map@use 复用,可额外导出 SCSS map 方便组件使用。
layout/_app-shell.scss .main-containerAppShell slot App.vue, AppShell.vue 负责 viewport 高度、自适应 inset、安全区 padding保留 --app-viewport
layout/_sidebar.scss .conversation-sidebar ~ .conversation-list ConversationSidebar.vue, useConversationStore 保留展开/折叠两套宽度,抽象 @mixin sidebar-button($size) 简化按钮样式。
components/chat/_message-list.scss .chat-area.message-item ChatArea.vue 子组件、useChatStore 细分 Thinking/Text/Tool/Summary 的背景、边框、动画。
components/input/_composer.scss .compact-input-area InputComposer.vue, useInputStore 控制多行自动高度、.action-buttons.quick-menu
components/panels/_token-drawer.scss .token-drawer, .usage-stat TokenDrawer.vue, useResourceStore legacy_ui_spec 的折叠动画、进度条变量保持一致。
components/overlays/_toast.scss .toast-stack, .quota-toast ToastStack.vue, QuotaToast.vue, useUiStore 拆分常规 Toast 与 quota 警告两种配色。
components/overlays/_personalization.scss .personal-page-overlay PersonalizationDrawer.vue, usePersonalizationStore Drawer 背景、拖拽 handle、Preset 卡片。

拆分时以 legacy_ui_spec.md + static/style.css 为真值,逐块复制到对应模块后,再删除旧片段,确保 diff 清晰。

迁移阶段

阶段 0建立骨架已完成

  1. 新建 static/src/styles/index.scss,依次 @use/@import 四层目录。
  2. static/src/main.tsimport '../style.css' 替换为 import './styles/index.scss';,暂留旧 style.css 以供对照。
  3. 引入 PostCSS/Sass 配置(若尚未启用 SCSS可先 npm install -D sass 并在 Vite 中开启预处理)。

阶段 1迁移 Base + Layout已完成

  1. 复制 style.css 中 reset/变量/body/header/main-container 相关片段到 base/layout 模块;style.css 里保留注释提示“已迁移”。
  2. 验证 viewport 高度、侧栏折叠、主容器滚动与之前一致。
  3. 为 CSS 变量补充 SCSS map例如 $colors: ( 'bg': var(--claude-bg), ... )),方便组件层调用。

阶段 2侧栏/面板组件(已完成)

  1. 以对话侧栏为起点,迁移 .conversation-sidebar.conversation-header.conversation-list 等块。
  2. LeftPanel 面板切换结构拆出 .sidebar-panel-card.panel-switcher.file-tree.todo-panel.subagent-panel
  3. 将 hover/active/disabled 态封装混入,消除硬编码颜色。

阶段 3聊天 + 输入域(已完成)

  1. 拆分 .chat-container.chat-scroll.message-item 及各 actionthinking/text/tool/append/modify/system的背景、边框、状态类.is-streaming, .is-collapsed)。
  2. .compact-input-area.input-actions.quick-menu.tool-settings-menu 拆到 input/ 目录,保留动画 @keyframes submenu-slide
  3. Chat/Input 共用的 code 块、.copy-code-btn.token-counter 等交叉样式放在 utilities 或共享 partial。

阶段 4Overlay/Drawer & 清理(已完成)

  1. 迁移 ToastStack、QuotaToast、ConfirmDialog、ContextMenu、Personalization Drawer、EasterEgg overlay 的样式,集中管理 z-index、backdrop-filter。
  2. FocusPanelTokenDrawerUsageDashboard 等右栏模块建立专属文件。
  3. static/style.css 改为 @import '/static/dist/assets/main.css',对外暴露单一入口,同时在 static/old_version_backup/前端备份/style.css 保留 legacy 真值以便比对。

验证清单

  1. npm run buildnpm run dev 均可正常注入 SCSS无额外 CSS 顺序冲突。
  2. 浏览器端逐项对照 doc/frontend/legacy_ui_spec.md
    • 侧栏展开/折叠宽度 & hover 状态。
    • 三合一 Panel 切换 & 文件树/右键菜单层级。
    • 聊天消息块的动效(思考流式、压缩动画、复制按钮)。
    • Quick Menu 子菜单、工具禁用对话框、设置二级菜单。
    • Toast/Quota 警告淡入淡出、个人空间 Drawer 背景模糊。
  3. 对彩蛋 CSSstatic/easter-eggs/*.css)做回归,确保 AppShell overlay 的 stacking context 不影响其覆盖。

后续维护建议

  1. 新模块接入:新增组件请优先在 static/src/styles/components/ 下创建局部 SCSS再通过 styles/index.scss 聚合,避免回落到全局样式。
  2. 主题扩展:如需暗色/高对比主题,可在 base/_tokens.scss 内维护多套 map并通过 @mixin 输出 CSS variables。
  3. 旧入口兼容:登录/终端等仍引用 /static/style.css,更新后务必同步 npm run build 以生成最新 dist/assets/main.css,否则旧入口将缺少样式。
  4. 快照对比:大规模改动前可先复制 static/old_version_backup/前端备份/style.css 为参考,再利用浏览器 devtools 对比差异,降低视觉回归风险。

注意事项

  • 优先级控制:使用 @layer base|layout|components|utilitiesVite 支持原生 CSS Layers保证与旧版 specificity 相匹配,避免引入 !important
  • 变量延续:保留 --app-viewport--app-bottom-inset 等运行时变量store/composable 仍通过 document.documentElement.style 更新这些值。
  • 资源路径mask-image、背景图标继续指向 /static/icons/*,拆分后请集中在 base/_icon.scss 管理。
  • 主题扩展:如需暗色或高对比方案,可在 _tokens.scss 中提供多套 map使用 data-theme 切换;现阶段仅实现 legacy 主题。
  • 发布节奏:每完成一个层级都应在 PR 中附对比截图侧栏、聊天、输入、Overlay并同步更新本文件进度记录。

完成上述阶段后CSS 将具备与组件结构一致的模块边界,便于日后按需维护、替换或添加主题,同时保持 legacy 品牌体验不变。