3.2 KiB
Frontend 上下文窗口 popover 主题适配 — Design Spec
日期: 2026-08-07 状态: Approved 范围: Bug 修复(CSS 变量 / Element Plus Teleport)
背景
src/views/frontend/components/InputArea.vue 中的"上下文窗口"指示器(.context-indicator)点击后弹出 el-popover,其中显示 token 使用量、阈值百分比等。当前问题是:该 popover 没有适配 frontend 的深 / 浅色主题。
根因
Element Plus 的 el-popover 默认 teleported: true(已确认,源码 element-plus/es/components/tooltip/src/content.mjs),弹出层被 Teleport 到 body 之外。
body[data-fe-theme="light"] 只覆盖了 --fe-* 系列变量,未覆盖 Element Plus 内部用到的 --el-bg-color-overlay、--el-border-color-lighter、--el-text-color-regular 等。结果是:
- popover 容器(
.el-popper)回退到 Element Plus 默认值(浅色背景 + 浅色文本) - 在深色主题下,与 frontend 整体深色风格不一致
- 而
.context-popover内部的--fe-*变量虽然继承自:root,但 popover 容器本身的背景 / 边框 / 文字色来自--el-*,这些没被覆盖
方案
给 el-popover 设置 :teleported="false",让 popover 容器保留在 .frontend-container DOM 树内,从而继承 .frontend-container 下的所有 --el-* / --fe-* 变量映射。
改动点
src/views/frontend/components/InputArea.vue 第 81-85 行的 el-popover 标签,新增 :teleported="false":
<el-popover
placement="top"
:width="280"
trigger="click"
:teleported="false"
>
.context-popover 现有的 scoped 样式(.popover-title / .popover-body / .popover-footer / .token-count)保持不变,因为它们使用 --fe-* 变量,本来就能工作。
不需要改动
theme.scss:.frontend-container已经把--el-bg-color-overlay、--el-text-color-regular、--el-color-success、--el-color-danger等都映射到--fe-*变量,只要 popover 在.frontend-container内就能自动生效- 浅色覆盖:
.frontend-container[data-theme="light"]同样完整覆盖了--el-*系列 .context-popover的 scoped 样式:因为.context-popover本身在 InputArea 模板中,scoped 的data-v-xxx仍会附加到元素上,popover 留在组件树内后所有选择器自然匹配
验证
- 切到深色主题,点击输入框右下角的"XX%"指示器 → popover 应为深色背景(
#252526/--fe-bg-elevated)、浅色文字 - 切到浅色主题,点击同一指示器 → popover 应为白色(
#ffffff/--el-bg-color)、深色文字 - 百分比
el-tag:深色主题下success是青色(#4ec9b0),danger是珊瑚红(#f48771);浅色主题下success是蓝色(#1890ff),danger是红色(#f56c6c) token-count文字:深色下青色,浅色下蓝色- 重复点击 / 多次切换主题,popover 位置不漂移、不被聊天内容遮挡
非目标
- 不改
el-popover的其它属性(placement、width、trigger) - 不改
theme.scss - 不改
.context-popover现有样式(变量已经够用) - 不动
el-tooltip(左下角@按钮的 tooltip,独立组件,独立处理)