fix(app-iced): 列表行圆角改从组件表取(M287)

`list_item.rs` 硬写 `ui.radius_dp(ShapeScale::None)`,旁边还写着「4.x:ListItem 的形状
是 `CornerNone`(直角),没有圆角档」——而令牌表 `component_map::table` 的 `ListItem`
是 `Small(8)`。产品侧根本没读表,注释在替错误站台。

改为 `row_border(ui)` → `ui.radius_dp(Component::ListItem.spec().shape)`,数值只留在
令牌表。变异实测(只改表的那一行 `Small→Large`):行圆角 8 → 16,240×60 选中行的顶行
缩进 6 → 13;改回后 11 张图逐字节复原(`DevDocs/artifacts/listradius/`,不入库)。

同 commit 改掉那条直角注释、模块文档补 4.9 行,并加两条单测:渲染路径的
`Border.radius` = 表值折算;源码里不许再出现硬编码的 `ShapeScale::*` 档。

外观影响的边界(写进取证报告):行只在 选中/悬停/按下 时有容器色,未选中静息与禁用
两态 `fill` 为 `None`,那两态逐字节不变是**正确**的,不是没生效。
This commit is contained in:
AskaEth committed 2026-11-12 23:38:56 +08:00
1 parent a07cda34cb
commit 5174845cda
2 files changed
+80 -5

No files matched your search

@@ -11,6 +11,7 @@
//! | 4.5 | 字级 | 主 `BodyLarge 16/24`、辅助 `BodyMedium 14/20`、overline `LabelSmall 11/16` | `TypeRole` |
//! | 4.7 | 状态 | hover/focus/pressed **文本与图标色不变**,只叠状态层(8/10/10%) | [`interaction`] |
//! | 4.8 | 选中 trailing | 图标 → **`Primary`** | `Role::Primary` |
//! | 4.9 | 圆角 | 官方 `ListTokens` 是 `CornerNone`(直角);本项目**登记偏离**取 **8**(`Small`) | `Component::ListItem.spec().shape`(M287) |
//!
//! ## 禁用是**修饰器**,不是构造函数(照 `selection/chip.rs` 复审 P2-1 的结论)
//!
@@ -44,6 +45,7 @@ use iced::widget::{button, container, text};
use iced::{Alignment, Background, Border, Color, Element, Length, Padding, Pixels, Shadow};
use unlucky_design::color::Role;
use unlucky_design::component_map::Component;
use unlucky_design::icons::IconKind;
use unlucky_design::shape::ShapeScale;
@@ -193,6 +195,28 @@ fn palette(ui: &Ui, base: Base, state: Interaction, selected: bool) -> ItemPalet
}
}
/// 一行的圆角档位:**只从组件表取**(`Component::ListItem.spec().shape`)。
///
/// 官方 `ListTokens` 是 `CornerNone`(直角行),本项目取 `Small`(8)——列表行在启动器里是
/// 卡片内的**独立可点块**,不是贴边通栏行,圆角与卡片同族更协调(偏离登记见
/// `crates/design/src/component_map/table.rs` 的 `ListItem` 条目)。
///
/// 数值归令牌表,**产品侧不许在这里再写一份**:改表值 ⇒ 行圆角跟着变(M287 的判据)。
fn shape_scale() -> ShapeScale {
Component::ListItem.spec().shape
}
/// 一行的描边:只画圆角,四边宽度与色都不画(`Border::default()` 的其余字段)。
///
/// 单独成函数是为了让「圆角真的来自组件表」可被单测直接量到
/// (`tests::row_corner_comes_from_the_component_table`)。
fn row_border(ui: &Ui) -> Border {
Border {
radius: ui.radius_dp(shape_scale()),
..Border::default()
}
}
/// 一行文本(显式行高:三行块的 16+24+20 必须能精确等于 60,靠的就是它)。
fn line<'a, M: 'a>(
ui: &'a Ui,
@@ -285,17 +309,14 @@ pub fn list_item<'a, M: Clone + 'a>(ui: &'a Ui, item: ListItem<'a, M>) -> Elemen
let selected = item.selected;
let base = item.base;
let border = row_border(ui);
let style = move |_theme: &iced::Theme, status: button::Status| {
let state = forced.unwrap_or_else(|| Interaction::from_status(status));
let colors = palette(ui, base, state, selected);
button::Style {
background: colors.fill.map(Background::Color),
text_color: colors.headline,
// 4.x:ListItem 的形状是 `CornerNone`(直角),没有圆角档
border: Border {
radius: ui.radius_dp(ShapeScale::None),
..Border::default()
},
border,
shadow: Shadow::default(),
snap: true,
}