跳转至

Component UI Spec Integration

📄 创建: 未记录

https://doc.xpku.com/raw/tech/frontend/theme/skill.md

本技能用于将业务组件接入项目 UI 规范,核心依据是 MCP 知识库文档 技术文档/前端/主题/业务组件 UI 规范接入指南.md

触发场景

当出现以下需求时应调用本技能:

  • 用户要求"组件接入 UI 规范"
  • 用户要求"按主题规范改造业务组件"
  • 用户要求"替换硬编码颜色为主题变量"
  • 用户要求"使用局部主题"
  • 用户要求"接入 var(--bams-*) 颜色体系"
  • 用户要求给组件增加局部主题能力

核心原则

  1. 业务组件只消费颜色变量,不直接操作主题状态。
  2. 优先使用全局 CSS 变量 var(--bams-*),不要直接写固定颜色值。
  3. 仅在确有必要时才引入局部主题变量。
  4. 改造时优先保持现有业务结构稳定,只调整样式接入方式。
  5. 颜色替换严谨性原则:将硬编码颜色替换为全局变量前,必须校验原色值与目标变量 Light 模式色值的相似度;若不相近,严禁强行替换,应采用局部主题方案。

执行前置

在开始改造前,必须先通过 MCP 知识库读取规范文档。

必读文档

  • MCP 服务:开发文档
  • 工具:get_doc
  • 文档路径:技术文档/前端/主题/业务组件 UI 规范接入指南.md

如果无法直接确认路径,可先使用 search_docs 搜索 业务组件 UI 规范接入指南,再用 get_doc 读取全文。

接入步骤

1. 识别组件现状

检查目标组件是否存在以下问题:

  • 样式中写死颜色值,如 #fff#333rgba(...)
  • 直接依赖主题状态而不是 CSS 变量
  • 弹层类组件未设置 getPopupContainer
  • 需要独立主题,但仍完全依赖全局变量

2. 优先接入全局变量(含颜色校验逻辑)

普通业务组件默认按以下方式处理,但在替换颜色时需严格执行校验:

颜色替换校验流程:

  1. 提取原色值:记录代码中现有的硬编码颜色(如 #F5F7FA)。
  2. 获取变量色值:查询 var(--bams-*)Light 风格下的实际色值。
  3. 对比判定
  4. 若两者色值相近(肉眼观察无明显视觉差异,或符合设计规范中的容差标准),则允许替换。
  5. 若两者色值差异较大,禁止替换,立即转入步骤 3(局部主题方案)。

变量映射参考:

  • 背景色改为 --bams-page-bg--bams-surface-bg--bams-content-bg
  • 文本色改为 --bams-text-color--bams-text-secondary
  • 边框色改为 --bams-border-color--bams-border-secondary
  • 主按钮或强调色改为 --bams-primary--bams-button-primary-bg
  • hover、active、selected 等交互态改为对应 --bams-* 变量

示例(校验通过):

<style scoped lang="less">
  .card {
    background: var(--bams-surface-bg); //  #F5F7FA 与变量 Light 色值一致
    color: var(--bams-text-color);
    border: 1px solid var(--bams-border-color);
    box-shadow: var(--bams-shadow-card);
  }
</style>

3. 局部主题方案(针对色值不匹配场景)

当全局变量无法满足颜色需求(即步骤 2 校验不通过)时,必须采用局部主题方案,并按以下规则定义颜色:

  1. 保留原色为 Light 模式:将当前的硬编码颜色定义为该组件的 Light 风格色值
  2. 推荐 Dark 风格色值:基于 Light 色值,参考项目色彩对比度规范,自动推荐一个合理的 Dark 风格色值(通常需考虑亮度反转、饱和度调整或对比度合规性)。
  3. 实现方式:优先使用 LocalThemeContaineruseLocalThemeVars,在上述工具中配置 lightdark 的颜色映射。

示例(校验不通过后的处理):

<script setup>
  // 原硬编码颜色 #C9E7FF 与 --bams-primary 差异大,采用局部主题
  const localVars = {
    light: {
      "--local-main-bg": "#C9E7FF", // 沿用原色作为 Light 色值
    },
    dark: {
      "--local-main-bg": "#2A4563", // 推荐的 Dark 风格色值(示例)
    },
  };
</script>

3.1 局部主题配置抽取

使用局部主题时自动遵循此规范。

使用局部主题时,必须将配置抽取到单独的文件中:

必须的文件结构:

src/
├── theme/                    # 必须放在此目录
│   ├── xxxTheme.js           # 必须使用此命名规范
│   └── yyyTheme.js
└── business/
    └── XxxComponent.vue  # 导入主题配置

配置文件示例:

// src/theme/xxxTheme.js
export const THEME_MODE_VARS = {
  light: {
    "--component-bg": "#ffffff",
    "--component-text": "#1e293b",
    colorScheme: "light",
  },
  dark: {
    "--component-bg": "#1e293b",
    "--component-text": "#f1f5f9",
    colorScheme: "dark",
  },
};

export const THEME_PRESET_VARS = {
  "material.blue": {
    "--component-primary": "#0d6cbd",
  },
};

组件中使用:

<script setup>
  import { LocalThemeContainer } from "@bams-app/theme";
  import { THEME_MODE_VARS, THEME_PRESET_VARS } from "../../theme/xxxTheme";
</script>

4. 处理弹出层继承问题

如果组件中存在弹窗、气泡卡片、下拉、提示等浮层,必须检查是否需要设置 getPopupContainer,确保弹层能继承局部主题变量。

5. 必要时补充 JS 侧变量读取

如果业务逻辑需要在 JavaScript 中读取当前主题变量,可使用:

  • getCssVar
  • getCssVars
  • getAllCssVars

但优先级仍低于直接在 CSS 中使用 var(--bams-*)

输出要求

完成改造时,输出内容应包含:

  1. 改造思路
  2. 具体文件修改点
  3. 关键变量替换说明(需特别标注颜色校验结果:说明原色值与全局变量色值的对比情况,以及判定依据)
  4. 是否引入局部主题方案及原因(如引入,需列出 Light 色值来源及推荐的 Dark 色值
  5. 是否将主题配置抽取到外部文件及文件结构说明
  6. 弹层继承处理说明(如适用)

自检清单

提交前检查以下内容:

  • 是否已读取知识库文档 业务组件 UI 规范接入指南
  • 是否移除了新增的硬编码颜色
  • 是否优先使用了语义化变量而非具体色值
  • 针对颜色替换:是否验证了原色值与 Light 变量的匹配度,未强行替换差异较大的色值
  • 针对局部主题:是否将原色值正确设置为 Light 模式,并提供了合理的 Dark 模式推荐值
  • 是否避免直接操作 useThemeStore
  • 弹出层组件是否处理了 getPopupContainer
  • 修改后是否保持原有业务交互不变
  • 主题配置是否按需抽取到外部文件(如适用)
  • 抽取后的配置文件命名和位置是否规范

工作方式

接到任务后,按以下顺序执行:

  1. 先读取 MCP 知识库规范文档
  2. 再分析目标组件当前实现,重点提取所有硬编码颜色值
  3. 逐一比对硬编码颜色与目标 var(--bams-*) 变量的 Light 风格色值
  4. 根据对比结果选择方案:
  5. 色值相近:采用"全局变量接入"
  6. 色值差异大:采用"局部主题接入",以原色为 Light 基准,推导 Dark 色值
  7. 如果选择局部主题接入,必须遵循配置抽取规范(见 3.1 节),将主题配置抽取到 src/theme/ 目录下
  8. 输出最小必要改动,避免无关重构
  9. 完成后做一轮规范自检

⛔ AI 执行红线(必须遵守)

  1. 关于局部主题:你只能使用 LocalThemeContaineruseLocalThemeVars 等文档中提到的方案实现局部主题。如果用户没有明确要求,不要使用其他技术方案。