分别定义hover与pressed,检查AI没有覆盖默认按钮
本页展示随包原生输入和验收参考。目标产品运行状态:未运行。表格与图片不代表产品已经生成的结果。
input.csv / practice-data.json
本课实际输入字段
| component | backgroundColor | pseudoClass |
|---|---|---|
| button-primary | #184A45 | default |
| button-primary-hover | #123A36 | :hover |
| button-primary-pressed | #0C2A27 | :active |
复用语义色引用
reference.csv:作者验收映射,不是目标API回包
| action | expected | shape |
|---|---|---|
| pointer leaves | default restored | |
| key released | default restored | |
| three related component keys | state entries |
规则与输入文件原文
{
"inputRows": [
{
"component": "button-primary",
"backgroundColor": "#184A45",
"pseudoClass": "default"
},
{
"component": "button-primary-hover",
"backgroundColor": "#123A36",
"pseudoClass": ":hover"
},
{
"component": "button-primary-pressed",
"backgroundColor": "#0C2A27",
"pseudoClass": ":active"
}
],
"referenceRows": [
{
"action": "pointer leaves",
"expected": "default restored"
},
{
"action": "key released",
"expected": "default restored"
},
{
"shape": "state entries",
"expected": "three related component keys"
}
],
"invalidRows": [
{
"component": "button-primary",
"states": {
"hover": "#123A36"
},
"error": "not standard component state syntax"
},
{
"pseudoClass": ":hover",
"mappedKey": "button-primary-pressed",
"error": "wrong state map"
}
],
"notes": [
"作者自制可编辑输入与验收参考,非官方CLI或云端返回。",
"完整合法基础稿采用官方frontmatter schema;仅按本课故意更改对应字段。"
],
"designMdTemplate": "---\nversion: alpha\nname: Field Kit\ncolors:\n primary: \"#184A45\"\n surface: \"#F7F4EC\"\ntypography:\n body-md:\n fontFamily: Arial\n fontSize: 16px\n fontWeight: 400\n lineHeight: 1.6\nrounded:\n sm: 8px\nspacing:\n sm: 8px\ncomponents:\n button-primary:\n backgroundColor: \"{colors.primary}\"\n textColor: \"#FFFFFF\"\n typography: \"{typography.body-md}\"\n rounded: \"{rounded.sm}\"\n padding: \"{spacing.sm}\"\n---\n## Overview\nField Kit的预约界面。\n## Colors\n主色用于主要操作。\n## Typography\n正文使用body-md。\n## Layout\n使用8px间距。\n## Shapes\n使用8px圆角。\n## Components\n主要按钮统一消费语义引用。\n",
"officialSchemaUrl": "https://github.com/google-labs-code/design.md/blob/main/docs/spec.md",
"files": {
"input.json": "[\n {\n \"component\": \"button-primary\",\n \"backgroundColor\": \"#184A45\",\n \"pseudoClass\": \"default\"\n },\n {\n \"component\": \"button-primary-hover\",\n \"backgroundColor\": \"#123A36\",\n \"pseudoClass\": \":hover\"\n },\n {\n \"component\": \"button-primary-pressed\",\n \"backgroundColor\": \"#0C2A27\",\n \"pseudoClass\": \":active\"\n }\n]\n",
"reference.json": "{\n \"identity\": \"作者验收参考,非模型返回\",\n \"rows\": [\n {\n \"action\": \"pointer leaves\",\n \"expected\": \"default restored\"\n },\n {\n \"action\": \"key released\",\n \"expected\": \"default restored\"\n },\n {\n \"shape\": \"state entries\",\n \"expected\": \"three related component keys\"\n }\n ]\n}\n",
"invalid.json": "{\n \"identity\": \"作者构造负例,非实际错误回包\",\n \"rows\": [\n {\n \"component\": \"button-primary\",\n \"states\": {\n \"hover\": \"#123A36\"\n },\n \"error\": \"not standard component state syntax\"\n },\n {\n \"pseudoClass\": \":hover\",\n \"mappedKey\": \"button-primary-pressed\",\n \"error\": \"wrong state map\"\n }\n ]\n}\n",
"case.md": "# DESIGN.md按钮状态:分别定义hover与pressed,检查AI没有覆盖默认按钮\n\nDESIGN.md按钮状态先把数据结构写对,再看动画和外观。本课将button-primary-hover与button-primary-pressed独立命名,让下游实现可以清楚读出每个状态而不误改默认样式。\n\n## 画出三状态目标\n\n准备同一只“加入清单”按钮的默认、hover和pressed示例,不改变文字与宽度。\n\n先注明状态差别仅限背景与边框,避免把三张图当三个按钮类型。\n\n## 创建独立组件条目\n\n在components中分别写button-primary、button-primary-hover和button-primary-pressed。\n\n官方建议状态用相关名称的独立条目,不假定存在任意嵌套states语法。\n\n## 复用语义色引用\n\n为三个状态连接已定义的primary及状态色,检查每个路径。\n\n不要在一个条目里反复覆盖backgroundColor,导致最终只有最后一值。\n\n## 读取解析与警告\n\n运行lint,查看组件条目和未知属性提示。\n\n若为状态添加了自定义说明,单独注明那不是标准可消费属性。\n\n## 在作者页面实现映射\n\n让演示页的:hover和:active读取各自状态token,并用键盘触发按钮。\n\n这部分是消费端实现,不能说单写DESIGN.md就自动完成交互。\n\n## 确认默认状态可恢复\n\n鼠标离开、按键释放后检查默认色是否回来。\n\n若状态粘住,先查页面事件或CSS映射,不把问题归给颜色生成。\n\n## 交付状态对照表\n\n打包规则、状态映射和三张真实界面截图,逐项记录交互。\n\n若只制作了静态示意图,必须写示意,不标鼠标键盘测试通过。\n\n身份:输入与参考为作者材料;localCli有实测记录时仅证明对应CLI运行,目标云端与模型推理未执行。\n",
"DESIGN.md": "---\nversion: alpha\nname: Field Kit\ncolors:\n primary: \"#184A45\"\n surface: \"#F7F4EC\"\n hover: \"#123A36\"\n pressed: \"#0C2A27\"\ntypography:\n body-md:\n fontFamily: Arial\n fontSize: 16px\n fontWeight: 400\n lineHeight: 1.6\nrounded:\n sm: 8px\nspacing:\n sm: 8px\ncomponents:\n button-primary:\n backgroundColor: \"{colors.primary}\"\n textColor: \"#FFFFFF\"\n typography: \"{typography.body-md}\"\n rounded: \"{rounded.sm}\"\n padding: \"{spacing.sm}\"\n button-primary-hover:\n backgroundColor: \"{colors.hover}\"\n textColor: \"#FFFFFF\"\n button-primary-pressed:\n backgroundColor: \"{colors.pressed}\"\n textColor: \"#FFFFFF\"\n---\n## Overview\nField Kit的预约界面。\n## Colors\n主色用于主要操作。\n## Typography\n正文使用body-md。\n## Layout\n使用8px间距。\n## Shapes\n使用8px圆角。\n## Components\n主要按钮统一消费语义引用。\n",
"state-map.json": "{\n \"default\": \"button-primary\",\n \":hover\": \"button-primary-hover\",\n \":active\": \"button-primary-pressed\"\n}\n",
"states.html": "<!doctype html><html lang=\"zh-CN\"><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>按钮状态映射</title><style>body{font:16px/1.6 Arial,sans-serif;background:#f7f4ec;color:#183b39;margin:32px;max-width:1100px}h1{font-size:32px}article{padding:24px;border:1px solid #cbd4cc;background:white;margin:16px 0}button{background:#184a45;color:white;padding:12px 20px;border:0;border-radius:8px}table{border-collapse:collapse;width:100%}th,td{padding:10px;border:1px solid #cbd4cc;text-align:left}pre{white-space:pre-wrap;overflow-wrap:anywhere}button:hover{background:#123a36}button:active{background:#0c2a27}button:focus-visible{outline:3px solid #a74718;outline-offset:4px}</style><h1>按钮状态</h1><button>加入清单</button><p>用鼠标悬浮、按下,或Tab聚焦后按空格。</p></html>",
"nested-states.stdout.txt": "{\n \"findings\": [\n {\n \"severity\": \"warning\",\n \"path\": \"components.button-primary.states\",\n \"message\": \"'states' is not a recognized component sub-token. Valid sub-tokens: backgroundColor, textColor, typography, rounded, padding, size, height, width.\",\n \"rule\": \"broken-ref\"\n },\n {\n \"severity\": \"info\",\n \"message\": \"Design system defines 2 colors, 1 typography scale, 1 rounding level, 1 spacing token, 1 component.\",\n \"rule\": \"token-summary\"\n }\n ],\n \"summary\": {\n \"errors\": 0,\n \"warnings\": 1,\n \"infos\": 1\n }\n}\n",
"nested-states.stderr.txt": "",
"local-cli-receipt.json": "{\n \"status\": \"executed\",\n \"package\": \"@google/design.md\",\n \"version\": \"0.4.0\",\n \"cases\": [\n {\n \"case\": \"nested-states\",\n \"exitCode\": 0,\n \"stdoutSha256\": \"bbd4df5454d9d620279ddc72f982db828481050a549ee7b8b306e1723ba1ccf6\"\n }\n ]\n}\n"
}
}应当保留的约束
| action | expected | shape |
|---|---|---|
| pointer leaves | default restored | |
| key released | default restored | |
| three related component keys | state entries |
故意构造的错误样例
| component | states | error | pseudoClass | mappedKey |
|---|---|---|---|---|
| button-primary | {"hover": "#123A36"} | not standard component state syntax | ||
| wrong state map | :hover | button-primary-pressed |
先保存真实产品输出,再逐项对照。actualOutput / actualResult 在未执行时保持 not_run,不能把这里的期望值复制成已测结果。