fix: InputRuleTrigger does not take effect

This commit is contained in:
luoxiao 2024-08-20 10:18:43 +08:00 committed by luoxiaozero
parent c0bd42ad60
commit 2ef47933b8
3 changed files with 30 additions and 13 deletions

View file

@ -41,6 +41,10 @@
color: var(--colorPaletteRedForeground1); color: var(--colorPaletteRedForeground1);
} }
.thaw-field--error .thaw-input:not(:focus-within) {
border-color: var(--colorPaletteRedBorder2);
}
.thaw-field__validation-message-icon { .thaw-field__validation-message-icon {
display: inline-block; display: inline-block;
font-size: 12px; font-size: 12px;

View file

@ -9,6 +9,8 @@ pub fn Field(
/// The label associated with the field. /// The label associated with the field.
#[prop(optional, into)] #[prop(optional, into)]
label: MaybeProp<String>, label: MaybeProp<String>,
/// A string specifying a name for the input control.
/// This name is submitted along with the control's value when the form data is submitted.
#[prop(optional, into)] name: MaybeProp<String>, #[prop(optional, into)] name: MaybeProp<String>,
/// The orientation of the label relative to the field component. /// The orientation of the label relative to the field component.
#[prop(optional, into)] #[prop(optional, into)]
@ -176,7 +178,8 @@ impl FieldInjection {
(id, name) (id, name)
} }
pub fn update_validation_state(&self, state: Option<FieldValidationState>) { pub fn update_validation_state(&self, state: Result<(), FieldValidationState>) {
let state = state.err();
self.validation_state.try_maybe_update(|validation_state| { self.validation_state.try_maybe_update(|validation_state| {
if validation_state == &state { if validation_state == &state {
(false, ()) (false, ())

View file

@ -63,25 +63,42 @@ pub fn Input(
let (id, name) = FieldInjection::use_id_and_name(id, name); let (id, name) = FieldInjection::use_id_and_name(id, name);
let field_injection = FieldInjection::use_context(); let field_injection = FieldInjection::use_context();
let rules = StoredValue::new(rules); let rules = StoredValue::new(rules);
let validate = Callback::new(move |trigger| { let validate = Callback::new(move |trigger: Option<InputRuleTrigger>| {
let state = rules.with_value(move |rules| { let state = rules.with_value(move |rules| {
if rules.is_empty() { if rules.is_empty() {
return None; return Some(Ok(()));
} }
let mut rules_iter = rules.iter(); let mut rules_iter = rules.iter();
let mut call_count = 0;
loop { loop {
let Some(rule) = rules_iter.next() else { let Some(rule) = rules_iter.next() else {
return None; if call_count == 0 {
return None;
} else {
return Some(Ok(()));
}
}; };
if let Err(state) = rule.call_validator(trigger, value, name) { if let Some(trigger) = trigger.as_ref() {
if &rule.trigger != trigger {
continue;
}
}
call_count += 1;
let state = rule.call_validator(value, name);
if state.is_err() {
return Some(state); return Some(state);
} }
} }
}); });
let rt = state.is_none(); let Some(state) = state else {
return true;
};
let rt = state.is_ok();
if let Some(field_injection) = field_injection.as_ref() { if let Some(field_injection) = field_injection.as_ref() {
field_injection.update_validation_state(state); field_injection.update_validation_state(state);
}; };
@ -335,16 +352,9 @@ impl InputRule {
fn call_validator( fn call_validator(
&self, &self,
trigger: Option<InputRuleTrigger>,
value: Model<String>, value: Model<String>,
name: Signal<Option<String>>, name: Signal<Option<String>>,
) -> Result<(), FieldValidationState> { ) -> Result<(), FieldValidationState> {
if let Some(trigger) = trigger {
if self.trigger != trigger {
return Ok(());
}
}
value.with_untracked(|value| match &self.validator { value.with_untracked(|value| match &self.validator {
InputRuleValidator::Required(required) => { InputRuleValidator::Required(required) => {
if required.get_untracked() && value.is_empty() { if required.get_untracked() && value.is_empty() {