1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use crate::{AsClasses, HelperText, Icon, ValidationContext};
use yew::{Callback, Classes};
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub enum InputState {
Default,
Success,
Warning,
Error,
}
impl Default for InputState {
fn default() -> Self {
Self::Default
}
}
impl AsClasses for InputState {
fn extend(&self, classes: &mut Classes) {
match self {
Self::Default => {}
Self::Success => classes.push("pf-m-success"),
Self::Warning => classes.push("pf-m-warning"),
Self::Error => classes.push("pf-m-error"),
}
}
}
impl InputState {
pub fn convert(&self, mut classes: Classes) -> (Classes, bool) {
let mut aria_invalid = false;
match self {
InputState::Default => {}
InputState::Success => classes.push("pf-m-success"),
InputState::Warning => classes.push("pf-m-warning"),
InputState::Error => aria_invalid = true,
};
(classes, aria_invalid)
}
pub fn icon(&self) -> Icon {
match self {
Self::Default => Icon::Minus,
Self::Success => Icon::CheckCircle,
Self::Warning => Icon::ExclamationTriangle,
Self::Error => Icon::ExclamationCircle,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ValidationResult {
pub message: Option<String>,
pub state: InputState,
}
impl From<ValidationResult> for Option<HelperText> {
fn from(result: ValidationResult) -> Self {
if matches!(result.state, InputState::Default) && result.message.is_none() {
None
} else {
Some(HelperText {
message: result.message.unwrap_or_default(),
input_state: result.state,
custom_icon: None,
no_icon: match result.state {
InputState::Default => true,
_ => false,
},
is_dynamic: true,
})
}
}
}
impl Default for ValidationResult {
fn default() -> Self {
ValidationResult::ok()
}
}
impl ValidationResult {
pub fn ok() -> Self {
Self {
message: None,
state: Default::default(),
}
}
pub fn new<S: Into<String>>(state: InputState, message: S) -> Self {
Self {
state,
message: Some(message.into()),
}
}
pub fn help<S: Into<String>>(message: S) -> Self {
Self::new(InputState::Default, message)
}
pub fn error<S: Into<String>>(message: S) -> Self {
Self::new(InputState::Error, message)
}
pub fn warning<S: Into<String>>(message: S) -> Self {
Self::new(InputState::Warning, message)
}
}
pub trait ValidatingComponent {
type Value;
}
pub trait ValidatingComponentProperties<T> {
fn set_onvalidate(&mut self, onvalidate: Callback<ValidationContext<T>>);
fn set_input_state(&mut self, state: InputState);
}