docs+test(design,app-iced): filled-tonal 的禁用容器偏离写进代码;禁用色断言去自指(M86 r1 P2)

r1 复审两条:
- 我在报告里说「filled-tonal 的 0.12 偏离已写进代码」,实际一个字都没写,而 state.rs:47 还把
  TonalButtonTokens 列进 0.1f 家族,等于让人误以为已对齐。现在 state.rs 的常量文档与
  disabled.rs 的模块文档都写清:官方 getDefaultFilledTonalButtonColors 硬编码 0.12f
  (FilledTonalButtonTokens 无该字段),我们的入口不区分变体、tonal 实际画 0.10,属已登记偏离。
- surface_family_disabled_colors_are_the_12_percent_class 的期望值原本从被测常量自己算,
  把 DISABLED_SURFACE_ALPHA 改成 0.10 也照样绿(自指断言)。现在期望值硬编码 0.12/0.38 并
  先钉常量本身;按钮族那条同改。
This commit is contained in:
AskaEth committed 2026-11-02 13:12:13 +08:00
1 parent b566097107
commit fa40d798e2
2 files changed
+49 -10

No files matched your search

@@ -17,6 +17,11 @@
//! ⚠️ TextField 的 **Filled 容器**不在这两族里:官方
//! `FilledTextFieldTokens.FieldDisabledContainerOpacity = 0.04f`,我们仍在用面状族的值
//! (既有 D10 偏离,未在本轮收口)。`inputs::field` 走 [`disabled_colors`] 的口径,行为未变。
//!
//! ⚠️ **filled-tonal 是另一条已知偏离**:官方 `ButtonDefaults.getDefaultFilledTonalButtonColors`
//! 里硬编码 `ldc_w 0.12f`(`FilledTonalButtonTokens` 没有 `DisabledContainerOpacity` 字段),
//! 而本模块的 `disabled_button_*` **不区分变体**,tonal 与 filled 共用 0.10 ⇒ tonal 实际画 10%。
//! 这不是对齐、是登记过的偏离;要修得让入口知道变体,本轮(M86)不做。
use iced::Color;
@@ -171,30 +176,40 @@ mod tests {
/// **面状控件族**的那一对颜色 = 0.12 预混合(chip / switch / slider / TextField 描边)。
///
/// `disabled_colors` 的名字是历史遗留,语义是这一族。谁把 12% 改成 10%,这条红。
/// ⚠️ 期望值**写死 0.12 / 0.38**,不从 `DISABLED_SURFACE_ALPHA` 取:
/// 从被测常量求期望是**自指断言**——常量一改,expected 跟着改,永远相等(复审 r1 P2-1 实测:
/// 把 `DISABLED_SURFACE_ALPHA` 改成 0.10,旧版这条照样绿)。现在常量改坏必红。
#[test]
fn surface_family_disabled_colors_are_the_12_percent_class() {
const EXPECTED_SURFACE_ALPHA: f32 = 0.12;
const EXPECTED_CONTENT_ALPHA: f32 = 0.38;
let actual_alpha = DISABLED_SURFACE_ALPHA;
assert_eq!(
actual_alpha, EXPECTED_SURFACE_ALPHA,
"面状控件族 α 必须是官方 0.12f;改常量会让下面每一条合成色断言同时红"
);
for flavor in [SchemeFlavor::Light, SchemeFlavor::Dark] {
let ui = ui(flavor);
let scheme = Scheme::baseline(flavor);
let base = scheme.get(Role::Surface);
let expected_container = scheme
.get(Role::OnSurface)
.with_alpha(DISABLED_SURFACE_ALPHA)
.with_alpha(EXPECTED_SURFACE_ALPHA)
.over(base);
let (surface, surface_content) = disabled_colors(&ui, Role::Surface);
assert_eq!(
surface,
to_iced(expected_container),
"{flavor:?}:面状控件容器 = on-surface@12% 叠表面"
"{flavor:?}:面状控件容器 = on-surface@12% 叠表面(期望值硬编码,不取自常量)"
);
assert_eq!(
surface_content,
to_iced(
scheme
.get(Role::OnSurfaceVariant)
.with_alpha(DISABLED_CONTENT_ALPHA)
.with_alpha(EXPECTED_CONTENT_ALPHA)
.over(expected_container)
),
"{flavor:?}:面状控件内容仍是 38%,只是叠的底不同"
@@ -208,27 +223,40 @@ mod tests {
to_iced(
scheme
.get(Role::OnSurfaceVariant)
.with_alpha(DISABLED_CONTENT_ALPHA)
.with_alpha(EXPECTED_CONTENT_ALPHA)
.over(base)
),
"{flavor:?}:内容必须叠在容器上"
);
// 跨族对照:面状族的合成色必须与按钮族不同(两族一旦合流,这条红)
let (button, _) = disabled_button_colors(&ui, Role::Surface);
assert_ne!(
surface, button,
"{flavor:?}:面状族 12% 与按钮族 10% 必须落在不同像素值上"
);
}
}
/// **按钮家族**的那一对颜色 = 0.10 预混合,且与面状控件族**必须落在不同像素值上**。
///
/// 这条是「拆族真的发生了」的判据:把 `disabled_button_colors` 改回 0.12,它在
/// `expected` 与 `assert_ne!` 上同时红;两个入口合并回一个常量,也只有它红。
/// 期望值同样写死(0.10 / 0.38),理由见上一条:自指断言抓不住常量被改坏。
#[test]
fn button_family_disabled_colors_are_the_10_percent_class() {
const EXPECTED_BUTTON_ALPHA: f32 = 0.10;
const EXPECTED_CONTENT_ALPHA: f32 = 0.38;
let actual_alpha = DISABLED_CONTAINER_ALPHA;
assert_eq!(
actual_alpha, EXPECTED_BUTTON_ALPHA,
"按钮族 α 必须是官方 0.1f(*ButtonTokens.DisabledContainerOpacity)"
);
for flavor in [SchemeFlavor::Light, SchemeFlavor::Dark] {
let ui = ui(flavor);
let scheme = Scheme::baseline(flavor);
let base = scheme.get(Role::Surface);
let expected_container = scheme
.get(Role::OnSurface)
.with_alpha(DISABLED_CONTAINER_ALPHA)
.with_alpha(EXPECTED_BUTTON_ALPHA)
.over(base);
let (button, button_content) = disabled_button_colors(&ui, Role::Surface);
@@ -242,7 +270,7 @@ mod tests {
to_iced(
scheme
.get(Role::OnSurfaceVariant)
.with_alpha(DISABLED_CONTENT_ALPHA)
.with_alpha(EXPECTED_CONTENT_ALPHA)
.over(expected_container)
),
);
+12 -1
View File
@@ -45,12 +45,23 @@ impl StateLayer {
/// ⚠️ 官方禁用 α 分**两类**,这个常量只属于第一类:
/// - **按钮容器 10%**:`BaselineButtonTokens` / `FilledButtonTokens` / `OutlinedButtonTokens` /
/// `TextButtonTokens` / `ElevatedButtonTokens` / `TonalButtonTokens` 的 `DisabledContainerOpacity`
/// = `0.1f`(AAR 字节码);
/// = `0.1f`(AAR 字节码 `<clinit>`);
/// - **面状控件(chip 容器/描边、slider 轨道、switch 轨道)12%**:那是另一类令牌
/// (`AssistChipTokens.FlatDisabledOutlineOpacity` / `SliderTokens.DisabledInactiveTrackOpacity` /
/// `SwitchTokens.DisabledTrackOpacity` = `0.12f`),口径在
/// `unlucky_app_iced::components::interaction::disabled_colors`。
///
/// ## ⚠️ 已知偏离:filled-tonal 的禁用容器**官方是 0.12f,我们走 0.10**
///
/// 上面那行把 `TonalButtonTokens` 列进 0.1f 家族**只陈述它 `<clinit>` 里写的 token 值**,
/// 不代表 tonal 的运行时行为是 10%:官方 `ButtonDefaults.getDefaultFilledTonalButtonColors`
/// 里**硬编码** `ldc_w 0.12f`(`FilledTonalButtonTokens` 根本没有 `DisabledContainerOpacity` 字段)。
/// 我们的实现在 tonal 与 filled 之间**没有区分**,两者共用本常量 ⇒ **tonal 实际画的是 10%**。
///
/// 这是**已登记的偏离,不是对齐**:将来若要修,需要按变体分派 α(`disabled_button_colors` 得长出
/// 一个「哪个变体」的参数),并同步 `gallery/probe` 的逐行断言;本轮(M86)只做令牌一致性收口,
/// 不扩到变体分派。
///
/// 曾经的缺陷不是「12 是错的」,而是**同一个常量同时服务这两类**:按钮那半边一直错、另半边一直对。
pub const DISABLED_CONTAINER_ALPHA: f32 = 0.10;
/// 禁用态内容(文字/图标)透明度。