Skip to main content

orbital_base_components/form/rules/
input.rs

1use std::ops::Deref;
2
3use leptos::prelude::*;
4
5use super::{FieldValidationState, Rule};
6
7#[derive(Debug, Default, PartialEq, Clone, Copy)]
8pub enum InputRuleTrigger {
9    #[default]
10    Blur,
11    Focus,
12    Input,
13    Change,
14}
15
16pub struct InputRule(Rule<String, InputRuleTrigger>);
17
18impl InputRule {
19    pub fn required(required: Signal<bool>) -> Self {
20        Self::validator(move |value, name| {
21            if required.get_untracked() && value.is_empty() {
22                let message = name.get_untracked().map_or_else(
23                    || String::from("Please input!"),
24                    |name| format!("Please input {name}!"),
25                );
26                Err(FieldValidationState::Error(message))
27            } else {
28                Ok(())
29            }
30        })
31    }
32
33    pub fn required_with_message(required: Signal<bool>, message: Signal<String>) -> Self {
34        Self::validator(move |value, _| {
35            if required.get_untracked() && value.is_empty() {
36                Err(FieldValidationState::Error(message.get_untracked()))
37            } else {
38                Ok(())
39            }
40        })
41    }
42
43    pub fn validator(
44        f: impl Fn(&String, Signal<Option<String>>) -> Result<(), FieldValidationState>
45            + Send
46            + Sync
47            + 'static,
48    ) -> Self {
49        Self(Rule::validator(f))
50    }
51
52    pub fn with_trigger(self, trigger: InputRuleTrigger) -> Self {
53        Self(Rule::with_trigger(self.0, trigger))
54    }
55}
56
57impl Deref for InputRule {
58    type Target = Rule<String, InputRuleTrigger>;
59
60    fn deref(&self) -> &Self::Target {
61        &self.0
62    }
63}