refactor(app-iced): 「禁用不提交」的规则收进 Field::submit_message

原来 text_field 里内联着 `if state.is_disabled() { None } else { field.submit_message() }`,
那条分支在 Element 上量不到(没有内省接口)⇒ 等于没验。现在把状态作为参数交给
Field::submit_message(state),规则本身可单测:submit_is_opt_in 多了 Disabled 那一档断言
(接了回调 + 禁用 ⇒ None),text_field 相应少 3 行。
This commit is contained in:
AskaEth committed 2026-11-11 19:55:21 +08:00
1 parent ebce41b2c5
commit 92a3c1bbc8
2 files changed
+23 -12

No files matched your search

+10 -9
View File
@@ -198,9 +198,14 @@ impl<'a, M> Field<'a, M> {
self
}
/// 回车那条消息(`None` = 没接 [`Field::on_submit`])。**唯一的读取口**:
/// `text_field` 只从这里取,于是「接没接」与「发不发」是同一个事实。
fn submit_message(&self) -> Option<M> {
/// 回车那条消息(`None` = 没接 [`Field::on_submit`],或这个状态不能交互)。
///
/// **唯一的读取口**:`text_field` 只从这里取,于是「接没接」「点不点得动」与「发不发」
/// 是同一个事实——禁用态里回车不提交(与 `on_input` 同一条规矩)。
fn submit_message(&self, state: Interaction) -> Option<M> {
if state.is_disabled() {
return None;
}
self.on_submit.as_ref().map(|on_submit| on_submit())
}
}
@@ -220,12 +225,8 @@ pub fn text_field<'a, M: Clone + 'a>(
let state = field.state.unwrap_or(Interaction::Enabled);
let colors = palette(ui, field.base, field.variant, state, field.error);
// 提交消息只在**可交互**时接:禁用字段与 `on_input` 一样被摘掉。
let submit = if state.is_disabled() {
None
} else {
field.submit_message()
};
// 提交消息只在**可交互**时接(禁用规则住在 `Field::submit_message` 里,可单测)。
let submit = field.submit_message(state);
let input_style = ui.style(TypeRole::BodyLarge);
let label_style = ui.style(TypeRole::BodySmall);
@@ -188,13 +188,23 @@ fn submit_is_opt_in() {
.secure(false)
.base(Base::CANVAS);
assert_eq!(
plain.submit_message(),
plain.submit_message(Interaction::Enabled),
None,
"没调 `.on_submit` ⇒ 回车不发消息(既有调用点的行为)"
);
let wired: Field<'_, u8> = Field::new("实例一").on_submit(|| 7_u8);
assert_eq!(wired.submit_message(), Some(7), "接上的回调要被原样取出来");
assert_eq!(
wired.submit_message(Interaction::Enabled),
Some(7),
"接上的回调要被原样取出来"
);
// 禁用态里回车不提交(与 `on_input` 同一条规矩:点不动的框也不该能提交)
assert_eq!(
wired.submit_message(Interaction::Disabled),
None,
"禁用字段不许回车提交"
);
}
/// 回归(T27 反例 ①):`text_field` 必须把 `Field` 上的提交回调**转发**给 `text_input`。
@@ -210,7 +220,7 @@ fn submit_is_opt_in() {
fn text_field_forwards_the_submit_callback() {
let body = crate::pages::layout::source::function_body(FIELD_SOURCE, "pub fn text_field");
assert!(
body.contains("submit_message()"),
body.contains("submit_message("),
"提交消息必须从 `Field::submit_message()` 取(唯一读取口),实际函数体:\n{body}"
);
assert!(