关于 ui-doctor
供 AI Agent 使用的 UI 审查技能,可检查 IDS 合规性、无障碍性、易用性和认知负荷,并生成按优先级排列的建议。支持快速 UX 审查、无障碍检查及针对指定文件或页面的完整合规审计。
主要功能
- 01快速 UX 审查
- 02WCAG 2.1 AA 无障碍检查
- 03Nielsen 易用性原则审查
- 04IDS 组件与设计令牌检查
- 05认知负荷评估
- 06生成优先级审计报告
适用场景
- 01检查页面的无障碍问题
- 02核对应用 UI 是否符合 IDS
- 03发现信息密度过高的问题
- 04审计指定组件或文件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ iress/ design-system --skill ui-doctor安装后在 Claude Code 中输入/ui-doctor确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/audit-checklist.mdreplacement-tables.mdreport-template.md详细介绍
技能:UI Doctor
审查并检查应用 UI 是否符合 IDS、无障碍、易用性和认知负荷方面的要求。此技能可帮助 AI Agent 全面审查 UI,涵盖组件使用、无障碍(WCAG)、易用性启发式原则(Nielsen 的 10 项原则)、认知负荷和渐进式披露,然后生成包含优先级建议的可执行报告。
适用场景
用户提出以下请求时,启用此技能:
- “检查此页面/组件/文件的无障碍情况”
- “检查此 UI 的易用性”
- “检查是否符合 IDS 要求”
- “感觉认知负荷太重了”
- “我们是否遵循了 IDS 指南?”
- “检查是否存在无障碍问题”
- “审查此 UI”
- “此表单是否无障碍?”
- “可以做一次 UX 审查吗?”
或者更一般地说:
- 检查应用 UI 代码是否符合 IDS 要求
- 验证无障碍情况(WCAG 2.1 AA)
- 评估易用性和认知负荷
- 评估设计令牌的使用情况和一致性
- 生成带有合规评分的 UI 健康报告
- 提供改善 UX、无障碍和 IDS 采用情况的建议
审查模式
默认:快速 UX 审查。 除非用户明确要求无障碍检查或全面合规审查,否则使用此模式。如果快速审查发现重大问题,则升级到更全面的模式。
快速 UX 审查(默认)
用户要求进行一般 UI 审查、易用性检查或询问“看起来对吗?”时使用。
- 认知负荷与信息架构 — UI 是否让人应接不暇?是否同时显示了过多项目、选项或操作?
- 易用性启发式原则 — 根据 Nielsen 的 10 项原则进行评估(参见审查清单 § 易用性启发式原则)
- 按钮层级与布局一致性 — 每个区域只有一个主要按钮,间距保持一致
- 快速组件检查 — 是否在已有 IDS 组件的情况下使用了明显的原生 HTML 元素?
无障碍审查
用户询问无障碍、WCAG、键盘导航或屏幕阅读器支持时使用。
- 表单无障碍 — 标签、必填项指示、验证消息、id/htmlFor 配对
- 键盘与焦点 — 跳过链接、模态框/滑出面板中的焦点捕获、可见的焦点指示器
- 屏幕阅读器 — ARIA 地标、动态内容播报、交互元素的无障碍名称
- 颜色与对比度 — WCAG AA 对比度、不能仅依赖颜色传达信息
- 认知负荷 — 渐进式披露、信息密度(参见审查清单 § 认知负荷)
全面合规审查
用户要求进行完整的 IDS 审查或合规报告时使用。
限定范围的审查
如果用户询问特定文件、组件或页面,则仅针对该范围进行审查。应用相同的检查清单,但只检查相关文件。除非用户要求,否则不要扫描整个应用。
示例:“检查 UserProfileForm.tsx 的无障碍情况” → 对该文件单独运行无障碍审查模式。
审查范围
开始前,确定要扫描哪些文件。
要扫描的文件
src/(或应用程序源代码目录)中的所有.tsx、.jsx、.ts、.js文件- 用于检查硬编码设计值的 CSS/SCSS/styled-component 文件
- 用于检查 Provider 和 CSS 导入的应用程序入口点
重要提示: 在评估 Provider 和设置之前,务必从实际挂载点(例如 main.tsx、index.tsx)追踪组件树。入口点可能不是路由文件,也可能是自定义元素包装器、Shadow DOM 宿主,或负责渲染路由器的独立引导文件。如果父级入口点已处理相关设置,则不要因缺少 Provider/CSS 而扣分。
排除的文件
- 测试文件(
*.test.tsx、*.spec.tsx、__tests__/)——测试模拟可能会合理地使用原始 HTML - Storybook 故事文件(
*.stories.tsx)——可能会有意展示原始 HTML 以供比较 - 配置文件(
*.config.ts、*.config.js)——不是 UI 代码 - 类型定义(
*.d.ts)——不包含运行时 UI 代码 - 第三方代码(
node_modules/、供应商库)——不受应用程序控制 - 构建产物(
dist/、build/)——生成的代码
版本感知审查
IDS 当前使用 版本 6。审查时:
- 检查已安装的版本——查看
package.json中的@iress-oss/ids-components - v6——按原样应用所有规则
- v5——将 v5 特有模式标记为“迁移机会”(主要差异:
IressForm使用rules属性,react-hook-form是对等依赖项,通过useWatch/ref获取表单状态) - v5 之前的版本——标记为需要重大迁移;优先处理 Provider/CSS 设置
- 始终在审查报告标题中注明版本
审查流程
1. 评估用户体验、无障碍性和认知负荷
从用户体验入手——在检查组件合规性之前,先评估 UI 的可用性、无障碍性和信息密度。
a. 可用性启发式原则(Nielsen 的 10 项原则)
根据全部 10 项启发式原则评估应用程序。每项原则都有 IDS 专属指南,详见审查清单 §“可用性启发式原则”。重点领域:
- 系统状态的可见性——加载状态使用
IressLoading(首选),或使用IressSkeleton(适用于自定义内容占位模式);标签页、导航、面包屑中的活动状态清晰可见 - 系统与现实世界的匹配——标签使用通俗易懂的语言;图标配有文字;状态颜色遵循惯例
- 用户控制权和自由度——模态框/侧滑面板可以关闭;破坏性操作需要确认;表单提供取消选项
- 一致性和标准——所有组件均来自 IDS;统一使用设计令牌;相同操作采用相同模式
- 错误预防——使用声明式
rules验证;标明必填字段;通过hint说明限制条件 - 识别优于回忆——导航保持可见;面包屑清晰可见;标签始终显示(不应只显示占位符)
- 灵活性和效率——键盘快捷键;跳转链接;可搜索的选择框;自动补全
- 美观且简约的设计——视觉层级清晰;间距一致;每个区域只有一个主要操作
- 帮助用户识别并解决错误——验证信息通俗易懂;错误信息显示在行内;长表单使用
IressValidationSummary - 帮助和文档——提示文本;为不明显的 UI 提供工具提示;占位符仅作为标签的补充
b. 认知负荷与信息架构
评估 UI 是否一次呈现过多信息或过多选项。
- 项目数量阈值 — 包含超过 10 个项目的菜单/下拉菜单应使用
searchable;字段超过 8 个的长表单应使用IressForm pattern="long";顶层导航项超过 7 个时应进行分组 - 渐进式披露 — 使用
IressExpander或IressTabSet隐藏次要内容,直到需要时再显示;将复杂任务拆分为多个阶段的多步骤流程 - 信息密度 — 屏幕是否令人应接不暇?使用
IressCard/IressPanel对相关内容进行分组;使用间距充足的IressStack - 批量操作安全性 — 批量操作(全选 + 删除)需要通过
IressModal明确确认;显示受影响项目的数量 - 状态变更后的焦点管理 — 关闭模态框后,焦点返回触发控件;删除项目后,焦点移至下一项/上一项;提交表单后,焦点移至结果或错误信息
- 视觉层次 — 突出显示主要内容,弱化次要内容;使用
IressText textStyle建立层次
c. 无障碍(WCAG 2.1 AA)
检查表单无障碍、键盘与焦点、屏幕阅读器支持以及颜色/对比度。完整清单请参见审查清单 § 无障碍。重点检查:
- 所有表单输入项都有标签(通过
IressField或IressFormField) - 提供跳过链接(
IressSkipLink) - 在模态框/滑出面板中锁定焦点(IDS 会自动处理)
- ARIA 地标(
<nav>、<main>、<aside>) - 向屏幕阅读器播报动态内容 — 选择合适的级别:
IressAlert— 持续显示的内联状态消息(没有aria-live;已处于阅读流程中)IressToaster— 需要引起注意的短暂通知(aria-live="assertive");避免过度使用- 配有就近
aria-live="polite"的微动画/交互 — 用于细微的、由用户触发的更新(保存指示器、数量徽标、状态变更),这些更新无需使用 toast;将 live 区域放在组件附近,而非全局放置
- 颜色对比度符合 WCAG AA;不能仅依赖颜色传达信息
d. 按钮层级
- 每个逻辑分区使用一个
mode="primary"按钮 - 危险操作使用
status="danger",而非自定义红色样式 - 仅图标按钮包含无障碍文本
e. 布局一致性
- 垂直堆叠 →
IressStack;水平行 →IressInline;网格 →IressRow/IressCol - 间距使用
gap属性中的 token 值(0–10) - 使用
IressCSSProps(m、mx、p、px)而非内联样式 - 响应式布局:使用
hideFrom/hideBelow属性或useBreakpointhook;网格布局使用响应式span(例如span={{ xs: 12, md: 6 }});移动端视图聚焦于主要任务,将次要内容放入IressSlideout或可折叠分区中
2. 验证 IDS 组件用法
扫描原始 HTML、第三方组件以及存在 IDS 对应组件的自定义实现。完整映射请使用替换表。
快速检查:
- 不使用原始
<button>、<input>、<select>、<form>、<table>— 使用 IDS 对应组件 - 存在 IDS 对应组件时,不导入第三方 UI 库(MUI、Ant、Chakra、Bootstrap、Radix、Headless UI)
- 不使用自定义模态框、抽屉、标签页、工具提示、警报 — 使用 IDS 模式
- 不使用自定义加载指示器 — 使用
IressLoading(首选),或使用IressSkeleton实现自定义内容占位模式 - 使用 flex/grid 样式的布局 div →
IressStack、IressInline、IressRow/IressCol
可接受的例外(不要标记):测试文件中的原始元素、应用无法控制的第三方小组件、<input type="hidden">、内部封装 IDS 的自定义组件。参见替换表 § 可接受的例外。
3. 验证 IDS 原则与设置
a. Provider 与 CSS 设置
- IressProvider 必须包裹应用根节点 — 字体、CSS 变量和主题设置都依赖它。
IressProvider已包含IressModalProvider、IressSlideoutProvider、IressToasterProvider、IressPopoverProvider和IressIconProvider,无需单独添加这些 Provider。同样,IressShadow内部已包含IressProvider,因此使用IressShadow时无需额外添加 Provider。 - 必须导入 IDS 组件 CSS —
@iress-oss/ids-components/dist/style.css包含所有组件样式 - 用户只需安装
@iress-oss/ids-components@beta— 令牌已打包在组件库中,无需单独安装。IDS v6 目前处于 beta 阶段,因此必须使用@beta标签(例如:npm install @iress-oss/ids-components@beta) - CSP 必须将 IDS 外部来源列入允许列表 — 如果应用启用了内容安全策略,
fonts.googleapis.com和fonts.gstatic.com必须列入style-src/font-src。如果使用旧版 Font Awesome 图标或IressTheme,请添加cdn.iress.com。如果使用IressShadow且内联样式被阻止,请在<head>中添加<meta name="csp-nonce" content="...">。详情请参阅node_modules/@iress-oss/ids-components/.ai/guides/get-started-content-security-policy.md中的 CSP 指南(需要先安装@iress-oss/ids-components)。 - 如果要在应用代码中直接使用设计令牌(用于自定义样式),还应安装
@iress-oss/ids-tokens@beta并导入@iress-oss/ids-tokens/build/css-vars.css
// ✅ Minimum required setup (option A — standard)
import '@iress-oss/ids-components/dist/style.css';
import { IressProvider } from '@iress-oss/ids-components';
function App() {
return <IressProvider>{/* app content */}</IressProvider>;
}
// ✅ Minimum required setup (option B — IressShadow)
// IressShadow is a superset of IressProvider — it wraps children in a shadow DOM,
// injects style.css automatically, and provides the IressProvider context.
// No separate IressProvider or CSS import is needed when using IressShadow.
import { IressShadow } from '@iress-oss/ids-components';
function App() {
return <IressShadow>{/* app content */}</IressShadow>;
}
// ✅ With direct token usage in application code (optional)
import '@iress-oss/ids-components/dist/style.css';
import '@iress-oss/ids-tokens/build/css-vars.css';
import { IressProvider } from '@iress-oss/ids-components';
import { cssVars } from '@iress-oss/ids-tokens';
function App() {
return (
<IressProvider>
<div style={{ padding: cssVars.spacing[4] }}>{/* app content */}</div>
</IressProvider>
);
}
// ❌ Incorrect — missing component CSS
import { IressProvider } from '@iress-oss/ids-components';
// Components will render without styles!
// ❌ Incorrect — installing tokens separately just for provider setup
yarn add @iress-oss/ids-tokens@beta // Not needed unless using tokens directly
// ❌ Incorrect — installing without @beta tag (will not resolve to v6)
yarn add @iress-oss/ids-components // Must use @beta tag
b. 设计令牌用法
- 不要硬编码颜色的十六进制值或 RGB 值 — 使用 IDS 颜色令牌
- 不要硬编码像素间距 — 使用 IDS 间距令牌
- 不要硬编码字体属性 — 使用 IDS 排版令牌
- 不要硬编码边框圆角 — 使用 IDS 圆角令牌
// ❌ Hardcoded values
<div style={{ color: '#003271', padding: '16px', borderRadius: '4px' }}>
// ✅ IDS tokens
import { cssVars } from '@iress-oss/ids-tokens';
<div style={{
color: cssVars.colour.primary.fill,
padding: cssVars.spacing[4],
borderRadius: cssVars.radius[1]
}}>
c. 表单与模式合规性
IDS 提供了确保 UI 一致性的模式。请在适当情况下验证其用法。
表单模式(IressForm):
- 所有表单均使用
IressForm+IressFormField - 使用
rules属性进行验证;使用useWatch实现条件字段 - 字段数 >8 的表单使用
pattern="long" react-hook-form作为对等依赖
加载模式(IressLoading / IressSkeleton):
- 支持
page、component、start-up、validate、long模式 - 自动处理时间阈值(<500ms 不显示指示器,500ms 显示微调器,2s 显示消息)
- 标准加载状态优先使用
IressLoading——它会自动处理时间、消息和无障碍功能 - 对于需要与页面布局相呼应的骨架屏等自定义内容占位模式,可以使用
IressSkeleton;如条件允许,请使用IressLoading - 当页面从预填充缓存读取数据时(例如由前一页面填充的 SWR、React Query 或 TanStack Query 缓存),可能不需要单独的加载状态——标记问题之前,请确认数据源是读取缓存还是重新获取数据
导航模式:
- 使用
IressDropdownMenu触发筛选/操作(不要放在表单内) - 使用
IressContextualMenu提供行级操作,并设置ariaLabel - 使用
IressSideNav实现应用外壳导航 - 使用
IressBreadcrumbs实现层级导航
错误边界模式:
React 错误边界会捕获组件崩溃,回退 UI 应使用 IDS 组件渲染,而不是自定义错误页面或原始 HTML。
| 错误范围 | IDS 组件 | 原因 |
|---|---|---|
| 整页崩溃(根错误边界) | IressModal status="danger",提供重试/重新加载操作 | 阻止交互、引起注意,并提供结构化的恢复方式 |
| 区块/功能崩溃(局部边界) | IressAlert status="danger",作为内联回退 | 持续显示且位于上下文中——页面其余部分仍可正常使用 |
| 暂时性 API/网络故障(非崩溃) | IressToaster | 可重试,且不会阻止 UI |
- 不要将
IressToaster用于错误边界——Toast 是临时且可关闭的;如果用户将其关闭,损坏的组件树就没有恢复 UI - 根级错误边界的首选方案是
IressModal status="danger"——使用actions属性提供“重试”或“重新加载”按钮 - 对于包裹单项功能的局部边界,优先使用
IressAlert status="danger"——它会以内联形式显示在损坏组件原本所在的位置
**标记错误处理缺失之前:**请检查父组件或布局路由是否已提供覆盖被审计文件的错误边界。错误边界是应用级模式——如果父级边界已捕获错误并渲染基于 IDS 的回退 UI(例如带有导航感知恢复方式的 IressModal status="danger"),页面组件就不需要自行处理错误/空状态。只有在没有任何祖先组件提供错误处理时才标记。
Shadow DOM 模式(IressShadow):
IressShadow是IressProvider的超集——它会创建 Shadow Root、向其中注入style.css,并自动提供IressProvider上下文。当应用在入口处使用IressShadow时,无需单独使用IressProvider或导入 CSS。- 常用于微前端 CSS 隔离,也可作为任何应用唯一的 Provider + CSS 配置
- 在
<div>上创建 Shadow Root——子元素是标准 React 组件 slot属性无关紧要;始终使用 React 属性(prepend、append、footer等)
4. 提供建议
按以下级别确定问题的优先级:
| 优先级 | 说明 | 操作 |
|---|---|---|
| Critical | 缺少 Provider/CSS、原始输入框未设置标签、缺少跳转链接、表单未使用 IressForm | 必须立即修复 |
| High | 存在 IDS 等效组件的原始 HTML 元素、自定义表单处理、无障碍访问失败、认知负荷过高的问题 | 在当前迭代中修复 |
| Medium | 硬编码的设计令牌、缺少 IressText、自定义布局、缺少 ARIA 地标、信息密度问题 | 安排在下个迭代中 |
| Low | 缺少 IressImage、自定义徽章、轻微的设计令牌不一致、非关键的用户体验改进 | 纳入待办事项 |
对于每项发现,请提供:(1) 发现了什么;(2) 为什么重要;(3) 如何修复(附修复前后的代码);(4) 优先级。
5. 生成合规报告
使用报告模板生成结构化报告。
审计输出示例
快速扫描摘要
IDS UI Doctor — Quick Scan
================================
Files scanned: 42
Components found: 18 IDS / 7 raw HTML
Patterns used: 3/7 available
Token compliance: 73%
Accessibility: 82%
Top Issues:
⚠ 3× raw <button> found (should be IressButton)
⚠ 2× hardcoded colours found (#333, #f5f5f5)
⚠ 1× <input> without IressField wrapper
⚠ 2× custom <form> found (should use IressForm)
⚠ 1× custom loading spinner (should use IressLoading)
⚠ 1× missing skip link for keyboard navigation
✓ IressProvider correctly configured
✓ Component CSS imported
✓ IressBreadcrumbs used for navigation hierarchy
✓ Colour contrast passes WCAG AA
参考
**注意:**组件文档、模式文档和清单均位于软件包本身中。
- 组件文档:
node_modules/@iress-oss/ids-components/.ai/components/ - 模式文档:
node_modules/@iress-oss/ids-components/.ai/patterns/ - 索引(完整组件列表):
node_modules/@iress-oss/ids-components/.ai/index.json - 设计令牌用法技能:
.agents/skills/token-usage/SKILL.md - Figma 映射技能:
.agents/skills/figma-to-ids/SKILL.md - UI 翻译技能:
.agents/skills/ui-translation/SKILL.md - Storybook 和指南: https://main--691abcc79dfa560a36d0a74f.chromatic.com
- 常见错误指南:
node_modules/@iress-oss/ids-components/.ai/guides/foundations-common-mistakes.md(需要安装@iress-oss/ids-components)
审计中应标记的常见错误
如需查看包含代码示例的完整常见反模式列表,请阅读 node_modules/@iress-oss/ids-components/.ai/guides/foundations-common-mistakes.md 中的常见错误指南(需要安装 @iress-oss/ids-components)。审计时,请根据以下优先级和审计规则标记这些问题:
IressButton 上的 disabled 属性 — High 优先级
**审计规则:**搜索任何 <IressButton> 上的 disabled。每个匹配项都属于一项发现。
IressText 上冗余的 textStyle — Medium 优先级
**审计规则:**搜索同时设置了 element 和 textStyle 的 IressText,且 textStyle 与该元素的默认样式相匹配的情况(例如 element="h1" textStyle="typography.heading.1")。
旧版 slot 属性(v4 模式)— High 优先级
**审计规则:**搜索任何 <Iress*> 组件中的 slot="。每个匹配项都属于一项发现。