File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 99 * ① 颜色一律 `var(--ed-*)`,**本文件零颜色字面量**(色值只许在 ui/tokens.css 与 token 生成器里)。
1010 * 这条也约束注释:本文件的注释里**不写任何色值**(写次数与 token 名即可)—— 守卫按文件文本判,
1111 * 注释里的色值会制造假红(先例:`Button.css` 连危险色 token 的字面名字都不写)。
12- * ② **本文件不写任何底色声明**(连该属性名都不出现):危险色是全站唯一非中性色,规格 §4.1 原文
13- * 写明「绝不用于按钮」⇒ 四档一律只写 `color:`。机器判据在本原语的测试里,与 Task 14 Step 1
12+ * ② **本文件不写任何底色声明**(连该属性名都不出现):危险色是全站唯一非中性色,其**真源注释**
13+ * (`app/scripts/gen-tokens.mjs:47` → `ui/tokens.css:19`)写明「绝不用于按钮」(规格 §4.1 那一行
14+ * 只写到「只用于状态戳」)⇒ 四档一律只写 `color:`。机器判据在本原语的测试里,与 Task 14 Step 1
1415 * 第 4 条**同向**(同一判据、同一方向,不另立标准)。
1516 * ③ 不写 `z-index`(层级走 `ui/zIndex.ts` 六档标尺);不写 `position`(定位是调用点的事)。
1617 * ④ **不写 `@keyframes`、不写循环动画**:环境层的「探针摆动」落在 `Loading` 的 `Probe`,而状态行
Original file line number Diff line number Diff line change 88 *
99 * 本文件钉住四件事:
1010 * ① 四档 kind 的类映射 + `role` **二值契约**(`error → alert` 立即播报,其余三档 → `status`);
11- * ② `detail` / `action` 两个槽的渲染与**缺席**行为(缺席时不得凭空出现按钮或空节点);
12- * ③ **危险语义用色**(控制方 2026-09-11 裁决③ · 规格 §4.1「绝不用于按钮」):危险色只作文字色
13- * —— 本原语 CSS 里连底色声明都没有,且**结构上不可能渲染按钮**(不 import `Button`);
14- * 与 Task 14 Step 1 第 4 条的批次守卫**同向**(同一判据、同一方向,不另立标准)。
11+ * ② `detail` / `action` 两个槽的渲染与**缺席**行为(缺席时不得凭空出现按钮、空节点或
12+ * `data-testid="undefined"`);
13+ * ③ **危险语义用色**(控制方 2026-09-11 裁决③):危险色只作文字色 —— 出处是 **token 真源注释**
14+ * (`app/scripts/gen-tokens.mjs:47` → `ui/tokens.css:19` 的「绝不用于按钮」;规格 §4.1 那一行
15+ * 只写到「只用于状态戳」)。本原语 CSS 里连底色声明都没有,且**结构上不可能渲染按钮**
16+ * (不 import `Button`);与 Task 14 Step 1 第 4 条的批次守卫**同向**(同一判据、同一方向)。
1517 * ④ 动效接缝与 reduced-motion:浮现过渡的可动画属性齐备、**无循环动画**(环境层不得抢注意力)、
1618 * `.ed-status` 已进 `motion.css` 那条唯一的媒体查询名单。
1719 *
@@ -102,6 +104,13 @@ describe("① 四档 kind 与 role 二值契约", () => {
102104 }
103105 } ) ;
104106
107+ it ( "testId 缺席 ⇒ 不产生 `data-testid` 属性(不得渲染成字符串 undefined)" , ( ) => {
108+ render ( < StatusLine > 已保存</ StatusLine > ) ;
109+ const root = screen . getByRole ( "status" ) ;
110+ expect ( root . hasAttribute ( "data-testid" ) ) . toBe ( false ) ;
111+ expect ( root . outerHTML ) . not . toContain ( "undefined" ) ;
112+ } ) ;
113+
105114 it ( "语义色只走类、不出内联 style(否则批 6 只能逐处改)" , ( ) => {
106115 render (
107116 < StatusLine kind = "error" testId = "st" detail = "检查网络后重试" >
Original file line number Diff line number Diff line change 1010 *
1111 * ★ 用色显式契约(控制方 2026-09-11 裁决③ · 规格 §4.1):
1212 * `error → var(--ed-stamp)`(**文字色**)· `warn → var(--ed-due)` · `ok → var(--ed-ok)` ·
13- * `info → var(--ed-ink-3)`。`--ed-stamp` 是**全站唯一非中性色**,规格原文写明「绝不用于按钮」
14- * ⇒ 本原语**不渲染任何按钮**:`action` 是纯 `ReactNode` 槽,由调用方传入 `Button` 原语节点
13+ * `info → var(--ed-ink-3)`。`--ed-stamp` 的真源注释(`app/scripts/gen-tokens.mjs:47` →
14+ * `ui/tokens.css:19`)原文是「状态戳 —— 全站唯一非中性色,绝不用于按钮」(规格 §4.1 那一行只写到
15+ * 「唯一非中性色,只用于状态戳」)⇒ 本原语**不渲染任何按钮**:`action` 是纯 `ReactNode` 槽,
16+ * 由调用方传入 `Button` 原语节点
1517 * (因此本文件**不 import `./Button`** —— 「不能有按钮底色」于是成为**结构保证**而不是纪律:
1618 * 本原语连一个按钮元素都产不出来)。同向守卫:`StatusLine.css` 里连底色属性名都不出现,
1719 * 与本原语测试、Task 14 Step 1 第 4 条按**同一判据**扫。
You can’t perform that action at this time.
0 commit comments