Files
Unlucky-Launcher/crates/app-iced/src/components/feedback/mod.rs
T
AskaEth 36f58d7904 feat(iced): 反馈类家族四件(Progress / Snackbar / Dialog / EmptyState)
D39 五家族并行的反馈类线(M78 / COMPFEED)。全部对消息类型泛型、不 import app::Message,
数值来自令牌或登记为 G17(令牌层没有反馈类的 ComponentMetrics 与骨架位)。

- Progress:linear(确定态 FillPortion 占比 + 官方 1750ms 双段不定态 keyframes)与
  circular(40/4 环,弧长 = 数值×360°,不定态走官方 6000ms 弧长+旋转 keyframes)。
  环形用几何 SVG(canvas feature 没开),组件不计时,相位由调用方给。
- Snackbar:48/68 两种高、上限宽 600(A1 ContainerMaxWidth)、12 外边距、贴顶/贴底、
  action(InversePrimary)+ 关闭键(InverseOnSurface);**组件不计时**,超时归调用方。
  iced 的 Length 没有 min-width ⇒ 344 的最小宽由宿主保证(登记 G17-d,与按钮 G15 同墙)。
- Dialog:scrim(黑@0.32 预合成实色,D27)+ R28 + SurfaceContainerHigh + pad 24 +
  标题/正文/动作三区 + 无动作/单动作/双动作;官方 280..560 区间内取 480。
- EmptyState:**官方没有这个组件**,96 图标块/32 图标/HeadlineSmall 全部标 [估]。
- action.rs:Dialog/Snackbar 共用的文字/图标动作(内容角色作参数,状态层仍走 interaction)。
- gallery/feedback.rs:状态矩阵;家族内再切一段 ULL_FEEDBACK_PART(all|progress|snackbar|
  dialog|empty),开关本身住在 feedback/gallery_parts.rs,不动 gallery/mod.rs。
- feedback/probe.rs:对着真截图量像素(渲染层断言),四类几何各逐项钉住。
- feedback/tests.rs:几何/节奏/角色/scrim 的纯函数断言。

gates: fmt --all --check · clippy -p unlucky-app-iced --all-targets -D warnings ·
test -p unlucky-app-iced(144 通过 / 0 失败)
2026-11-02 15:56:42 +08:00

84 lines
4.6 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! **反馈类家族**:Progress(§12)/ Snackbar(§14)/ Dialog(§7)/ EmptyState(§15)。
//!
//! ## 接口(契约 §2 + §8:官方名的小写形式,对消息类型泛型,不 import `app::Message`)
//!
//! | 组件 | 入口 | 消息要求 |
//! |---|---|---|
//! | 线性进度 | [`linear(ui, Progress::determinate(0.5))`](linear) | **无消息**(进度不可点) |
//! | 环形进度 | [`circular(ui, Progress::indeterminate(phase))`](circular) | **无消息** |
//! | 提示条 | [`snackbar(ui, Snackbar::new("…").action("撤销", msg))`](snackbar) | 有动作/关闭时才要 `M` |
//! | 对话框 | [`dialog(ui, Dialog::new("标题", "正文").double(..))`](dialog) | 有动作时要 `M` |
//! | 空态 | [`empty_state(ui, EmptyState::new(icon, "标题", "说明"))`](empty_state) | 有 CTA 时要 `M` |
//!
//! 全部 `M: Clone + 'a`(与按钮家族同一口径),`Ui` 一律 `&'a Ui` 传入、组件内不 `Ui::new`。
//!
//! ## 三条硬口径(每个组件文件开头各有一套细则表)
//!
//! 1. **数值来自哪里**:颜色/字级/圆角/内距走令牌(`Role` / `TypeRole` / `ShapeScale` / `Space`),
//! 进度厚度、Snackbar 宽高、Dialog 宽、空态块这四组令牌层没有 → 登记 **G17**([`geometry`])。
//! 2. **状态层只有一处**:hover/pressed 的叠色一律经 [`interaction::overlay_color`],
//! 禁用内容一律经 [`interaction::disabled_content_over_role`];
//! 禁用是**状态**(`on_press: Option<M>` 为 `None`),不是另一个构造器(M77 之前 Chip 踩过)。
//! 3. **精确尺寸经 `layout`**:图标/几何图元一律 `layout::fixed` / `layout::centered_fixed`(Q9),
//! 居中一律父级 `align_x/align_y`(Q8,不许 `center_*`)。
//!
//! ## CPU 降级(D27)与「不画阴影」
//!
//! 本家族零模糊、零运行时半透明:进度条是实色、Dialog 的 scrim 是**预合成实色**
//! ([`scrim`]),两个浮层都不画阴影(`ShadowSpec` 还是 M63 占位值 + D27 禁模糊)。
//! 三条偏离逐条登记在报告里(D-1 无阴影 / D-2 scrim 预合成 / D-3 波浪未实现)。
//!
//! ## 逐项偏离登记(提交报告里同一份表)
//!
//! | 编号 | 参考 | 我们 | 理由 | 可修 |
//! |---|---|---|---|---|
//! | D-1 | Dialog L3 阴影 | 无阴影 | D27 CPU 禁模糊 + `ShadowSpec` 为 M63 占位 | 是(等 M63 阴影表 + 双档渲染) |
//! | D-2 | scrim 真半透明 @0.32 | 预合成实色 | D27 CPU 零半透明;遮罩下是底色时逐像素等价 | 是(GPU 档可切真 α) |
//! | D-3 | 线性波浪 3/40、环形 1.6/15 | 直线段 / 等弧长 | `12b §12.4` 明确允许,登记后用匀速替代 | 是 |
//! | D-4 | Snackbar L3 阴影 | 无阴影 | 同 D-1 | 是 |
//! | G17-d | Snackbar 最小宽 344 | 组件不强制(宿主保证) | iced `Length` 无 min-width(同按钮 G15) | 是(自定义 Widget) |
//!
//! ## 文件地图
//!
//! ```text
//! geometry.rs G17 常量 + 五组几何(含不定态 keyframes)
//! keyframes.rs 相位 → 进度 的纯函数求值器(组件不计时)
//! progress.rs linear / circular(含环形 SVG 图元)
//! snackbar.rs 提示条 + 贴顶/贴底
//! dialog.rs 对话框 + scrim
//! empty_state.rs 空态(项目自定,全部 [估])
//! action.rs 文字动作 / 图标动作(Dialog 与 Snackbar 共用)
//! gallery_parts.rs 家族自己的 gallery 段落开关(`ULL_FEEDBACK_PART`)
//! probe.rs 渲染层像素断言(对着 gallery 截图量,见其模块文档)
//! ```
//!
//! ## 桩期的 `demo()` 已删除(不是签名被改)
//!
//! M75 的占位 `demo()` 只画一行「pending」文字,没有任何验收价值;真组件的验收画面就是
//! `gallery/feedback.rs` 的四段矩阵。契约 §9.3「家族 `demo()` 签名是共享契约」约束的是
//! **别改别人的调用点**——`feedback::demo` 自始至终只有 `gallery/feedback.rs` 一个调用点,
//! 而那个文件就在本 mission 的 scope 内,所以这里连同调用点一起换成了真组件(不留死代码:
//! 一个没人调用的 `pub fn` 会直接触发 `dead_code`,`-D warnings` 门禁会红)。
mod action;
pub mod dialog;
pub mod empty_state;
pub mod gallery_parts;
pub mod geometry;
pub mod keyframes;
pub mod panel;
pub mod progress;
pub mod snackbar;
#[cfg(test)]
mod pixel;
#[cfg(test)]
mod probe;
#[cfg(test)]
mod tests;
pub use dialog::{dialog, scrimmed, Dialog};
pub use empty_state::{empty_state, EmptyState};
pub use progress::{circular, linear, Progress};
pub use snackbar::{snackbar, Placement, Snackbar};