✨ Add helper_text to TextInput (previously TextEdit)
This commit is contained in:
@@ -8,5 +8,5 @@ pub mod loading;
|
|||||||
pub mod login;
|
pub mod login;
|
||||||
pub mod main_window;
|
pub mod main_window;
|
||||||
pub mod spinner;
|
pub mod spinner;
|
||||||
pub mod text_field;
|
pub mod text_input;
|
||||||
pub mod wallpaper;
|
pub mod wallpaper;
|
||||||
|
@@ -1,45 +0,0 @@
|
|||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
turf::style_sheet!("src/components/text_field.scss");
|
|
||||||
|
|
||||||
#[derive(Props)]
|
|
||||||
pub struct TextFieldProps<'a> {
|
|
||||||
id: Option<&'a str>,
|
|
||||||
oninput: Option<EventHandler<'a, Event<FormData>>>,
|
|
||||||
placeholder: Option<&'a str>,
|
|
||||||
r#type: Option<&'a str>,
|
|
||||||
value: Option<&'a str>,
|
|
||||||
#[props(default = true)]
|
|
||||||
is_value_valid: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn TextField<'a>(cx: Scope<'a, TextFieldProps<'a>>) -> Element<'a> {
|
|
||||||
let classes = [
|
|
||||||
ClassName::ROOT,
|
|
||||||
if !cx.props.is_value_valid {
|
|
||||||
ClassName::INVALID_DATA
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
},
|
|
||||||
]
|
|
||||||
.join(" ");
|
|
||||||
|
|
||||||
cx.render(rsx! {
|
|
||||||
style { STYLE_SHEET },
|
|
||||||
|
|
||||||
input {
|
|
||||||
class: "{classes}",
|
|
||||||
|
|
||||||
id: cx.props.id.unwrap_or(""),
|
|
||||||
|
|
||||||
oninput: move |evt| {
|
|
||||||
if let Some(cb) = &cx.props.oninput {
|
|
||||||
cb.call(evt);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
r#type: cx.props.r#type,
|
|
||||||
placeholder: cx.props.placeholder,
|
|
||||||
value: cx.props.value,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
@@ -1,25 +0,0 @@
|
|||||||
@import "../_base.scss"
|
|
||||||
|
|
||||||
.root {
|
|
||||||
$horizontal-padding: 1vw;
|
|
||||||
|
|
||||||
padding-left: $horizontal-padding;
|
|
||||||
padding-right: $horizontal-padding;
|
|
||||||
padding-top: 0px;
|
|
||||||
padding-bottom: 0px;
|
|
||||||
|
|
||||||
height: calc(100% - (2 * ($border-normal-width)));
|
|
||||||
width: calc(100% - (2 * ($border-normal-width + $horizontal-padding)));
|
|
||||||
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
border: $border-normal;
|
|
||||||
border-color: $color-primary-90;
|
|
||||||
border-radius: $border-radius;
|
|
||||||
|
|
||||||
font-size: 2vh;
|
|
||||||
|
|
||||||
&.invalid-data {
|
|
||||||
border-color: $color-critical;
|
|
||||||
}
|
|
||||||
}
|
|
88
src/components/text_input.rs
Normal file
88
src/components/text_input.rs
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
turf::style_sheet!("src/components/text_input.scss");
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct TextInputState {
|
||||||
|
pub is_valid: bool,
|
||||||
|
pub helper_text: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TextInputState {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
TextInputState {
|
||||||
|
is_valid: true,
|
||||||
|
helper_text: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset(&mut self) {
|
||||||
|
self.is_valid = true;
|
||||||
|
self.helper_text = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn invalidate(&mut self, helper_text: String) {
|
||||||
|
self.is_valid = false;
|
||||||
|
self.helper_text = Some(helper_text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Props)]
|
||||||
|
pub struct TextInputProps<'a> {
|
||||||
|
id: Option<&'a str>,
|
||||||
|
r#type: Option<&'a str>,
|
||||||
|
value: Option<&'a str>,
|
||||||
|
placeholder: Option<&'a str>,
|
||||||
|
oninput: Option<EventHandler<'a, Event<FormData>>>,
|
||||||
|
state: Option<&'a UseRef<TextInputState>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn TextInput<'a>(cx: Scope<'a, TextInputProps<'a>>) -> Element<'a> {
|
||||||
|
let mut level_class = "";
|
||||||
|
let mut helper_text: String = "".to_string();
|
||||||
|
|
||||||
|
match cx.props.state {
|
||||||
|
Some(state) => {
|
||||||
|
if !state.read().is_valid {
|
||||||
|
level_class = ClassName::INVALID;
|
||||||
|
}
|
||||||
|
if let Some(text) = &state.read().helper_text {
|
||||||
|
helper_text = text.to_string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
cx.render(rsx! {
|
||||||
|
style { STYLE_SHEET },
|
||||||
|
|
||||||
|
div {
|
||||||
|
class: ClassName::ROOT,
|
||||||
|
|
||||||
|
input {
|
||||||
|
class: level_class,
|
||||||
|
|
||||||
|
id: cx.props.id.unwrap_or(""),
|
||||||
|
|
||||||
|
oninput: move |evt| {
|
||||||
|
if let Some(cb) = &cx.props.oninput {
|
||||||
|
cb.call(evt);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
r#type: cx.props.r#type,
|
||||||
|
placeholder: cx.props.placeholder,
|
||||||
|
value: cx.props.value,
|
||||||
|
},
|
||||||
|
|
||||||
|
div {
|
||||||
|
class: ClassName::HELPER_TEXT,
|
||||||
|
|
||||||
|
p {
|
||||||
|
class: level_class,
|
||||||
|
|
||||||
|
helper_text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
47
src/components/text_input.scss
Normal file
47
src/components/text_input.scss
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
@import "../_base.scss"
|
||||||
|
|
||||||
|
.root {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
input {
|
||||||
|
$horizontal-padding: 1vw;
|
||||||
|
|
||||||
|
padding-left: $horizontal-padding;
|
||||||
|
padding-right: $horizontal-padding;
|
||||||
|
padding-top: 0px;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
|
||||||
|
height: calc(100% - (2 * ($border-normal-width)));
|
||||||
|
width: calc(100% - (2 * ($border-normal-width + $horizontal-padding)));
|
||||||
|
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
border: $border-normal;
|
||||||
|
border-color: $color-primary-90;
|
||||||
|
border-radius: $border-radius;
|
||||||
|
|
||||||
|
font-size: 2vh;
|
||||||
|
|
||||||
|
&.invalid {
|
||||||
|
border-color: $color-critical;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.helper-text {
|
||||||
|
margin: 0;
|
||||||
|
margin-top: 0.3vh;
|
||||||
|
|
||||||
|
font-size: 1.2vh;
|
||||||
|
|
||||||
|
color: $color-primary-90;
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 1vw;
|
||||||
|
|
||||||
|
&.invalid {
|
||||||
|
color: $color-critical;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user