- P3 考试/作业/成绩 mutation + 详情页 + 批改界面 + 乐观更新 + 多 Tab 同步 - P4 知识图谱 SVG 可视化 + 学情分析仪表盘 + parent-portal Remote - P5 WebSocket 通知中心 + AI 出题(SSE) + AI 教案 + AI 学情报告 - P6 可观测性硬化:Sentry + WebVitals + OTel + A11y + 性能配置 + Cookie 迁移 - P7 参考项目差距闭环:新增 35 个页面覆盖 13 个缺失模块 - attendance(考勤 4 页)/questions(题库)/textbooks(教材 2 页) - classes/[id] 详情 + classes/schedule 课表 - course-plans(2 页)/diagnostic(2 页)/error-book/practice - exams/[id]/build 组卷 + exams/[id]/analytics 考后分析 - exams/[id]/edit-rich 富文本编辑 + exams/[id]/proctoring 监考 - grades/entry 批量录入 + grades/stats 统计 + grades/analytics 分析 + grades/report-card 报告卡 - homework/submissions 列表 + assignments/[id]/submissions 批量批改 - homework/submissions/[submissionId] 单份批改 + scan-grading 扫描批改 - lesson-plans 编辑器 + library + calendar + heatmap 5 页 - elective 选修课 3 页 /leave 请假 /schedule-changes 调课 - P7 基础设施:61 GraphQL operations + 5 handlers + 13 fixtures + 11 viewports - 集成 browser.ts/server.ts 注册所有 p7 handlers(fallthrough 顺序) - viewports.ts 扩展 11 个新导航项 - 验证:tsc --noEmit 零错误 + eslint 零错误 - 文档:workline.md 新增 §5 P7 参考项目差距闭环(含完整文件清单)
98 lines
3.1 KiB
JavaScript
98 lines
3.1 KiB
JavaScript
/**
|
||
* ESLint A11y 配置(P6 硬化)
|
||
*
|
||
* - 配置 eslint-plugin-jsx-a11y(error 级别)
|
||
* - 包含 WCAG 2.2 AA 规则集
|
||
*
|
||
* 这是独立配置文件,不修改主 eslint 配置。
|
||
* 使用方式:eslint -c .eslintrc.a11y.js src
|
||
*
|
||
* 注意:eslint-plugin-jsx-a11y 尚未安装,CI 统一安装后启用。
|
||
* 关联:02-architecture-design.md §12 可观测性 / WCAG 2.2 AA
|
||
*/
|
||
|
||
/** @type {import('eslint').Linter.Config} */
|
||
module.exports = {
|
||
root: true,
|
||
parserOptions: {
|
||
ecmaVersion: 2022,
|
||
sourceType: "module",
|
||
ecmaFeatures: { jsx: true },
|
||
},
|
||
plugins: ["jsx-a11y"],
|
||
rules: {
|
||
// WCAG 2.2 AA 规则集(全部 error 级别)
|
||
|
||
// 1.1.1 非文本内容:所有图片必须有 alt 属性
|
||
"jsx-a11y/alt-text": "error",
|
||
|
||
// 1.3.1 信息与关系:表单控件必须有 label
|
||
"jsx-a11y/label-has-associated-control": "error",
|
||
"jsx-a11y/control-has-associated-label": "error",
|
||
|
||
// 1.4.1 颜色使用:不仅依赖颜色传达信息
|
||
"jsx-a11y/no-noninteractive-element-interactions": "error",
|
||
|
||
// 2.1.1 键盘可达性:所有交互元素必须键盘可操作
|
||
"jsx-a11y/no-static-element-interactions": "error",
|
||
|
||
// 2.1.2 无键盘陷阱:焦点必须能移出组件
|
||
"jsx-a11y/no-autofocus": "error",
|
||
|
||
// 2.4.1 跳过块:提供跳过重复内容的机制
|
||
"jsx-a11y/anchor-is-valid": "error",
|
||
|
||
// 2.4.4 链接目的:链接文本必须有意义
|
||
"jsx-a11y/anchor-has-content": "error",
|
||
|
||
// 2.4.6 标题与标签:标题必须描述性
|
||
"jsx-a11y/heading-has-content": "error",
|
||
|
||
// 3.1.2 每种语言的部分:html lang 属性
|
||
"jsx-a11y/html-has-lang": "error",
|
||
"jsx-a11y/lang": "error",
|
||
|
||
// 3.2.2 输入时:表单提交可预测
|
||
"jsx-a11y/no-onchange": "error",
|
||
|
||
// 3.3.2 标签或指令:表单输入需要描述
|
||
"jsx-a11y/tabindex-no-positive": "error",
|
||
|
||
// 4.1.2 名称、角色、值:ARIA 属性正确使用
|
||
"jsx-a11y/aria-props": "error",
|
||
"jsx-a11y/aria-proptypes": "error",
|
||
"jsx-a11y/aria-unsupported-elements": "error",
|
||
"jsx-a11y/role-has-required-aria-props": "error",
|
||
"jsx-a11y/role-supports-aria-props": "error",
|
||
|
||
// 4.1.3 状态消息:ARIA live regions
|
||
"jsx-a11y/aria-activedescendant-has-tabindex": "error",
|
||
|
||
// 额外规则:交互元素的角色
|
||
"jsx-a11y/interactive-supports-focus": "error",
|
||
"jsx-a11y/no-interactive-element-to-noninteractive-role": "error",
|
||
"jsx-a11y/no-noninteractive-element-to-interactive-role": "error",
|
||
"jsx-a11y/no-redundant-roles": "error",
|
||
"jsx-a11y/role": "error",
|
||
|
||
// 媒体可访问性
|
||
"jsx-a11y/media-has-caption": "error",
|
||
|
||
// 鼠标/指针事件可访问性
|
||
"jsx-a11y/mouse-events-have-key-events": "error",
|
||
"jsx-a11y/click-events-have-key-events": "error",
|
||
|
||
// 分散元素(blink/marquee 禁用)
|
||
"jsx-a11y/no-distracting-elements": "error",
|
||
},
|
||
overrides: [
|
||
{
|
||
// 允许在测试文件中使用 jsx-a11y 断言
|
||
files: ["**/*.test.{ts,tsx}", "**/*.spec.{ts,tsx}"],
|
||
rules: {
|
||
"jsx-a11y/anchor-is-valid": "off",
|
||
},
|
||
},
|
||
],
|
||
};
|