83 lines
2.3 KiB
Rust
83 lines
2.3 KiB
Rust
use std::collections::HashMap;
|
|
|
|
use dioxus::prelude::*;
|
|
use dioxus_elements::input_data::keyboard_types::Key;
|
|
use dioxus_html as dioxus_elements;
|
|
use dioxus_html::FormData;
|
|
|
|
#[derive(Props)]
|
|
pub(crate) struct CheckBoxProps<'a> {
|
|
#[props(!optional)]
|
|
raw_oninput: Option<&'a EventHandler<'a, FormData>>,
|
|
#[props(!optional)]
|
|
value: Option<&'a str>,
|
|
#[props(!optional)]
|
|
width: Option<&'a str>,
|
|
#[props(!optional)]
|
|
height: Option<&'a str>,
|
|
#[props(!optional)]
|
|
checked: Option<&'a str>,
|
|
}
|
|
|
|
#[allow(non_snake_case)]
|
|
pub(crate) fn CheckBox<'a>(cx: Scope<'a, CheckBoxProps>) -> Element<'a> {
|
|
let state = use_state(cx, || cx.props.checked.filter(|&c| c == "true").is_some());
|
|
let width = cx.props.width.unwrap_or("1px");
|
|
let height = cx.props.height.unwrap_or("1px");
|
|
|
|
let single_char = width == "1px" && height == "1px";
|
|
let text = if single_char {
|
|
if *state.get() {
|
|
"☑"
|
|
} else {
|
|
"☐"
|
|
}
|
|
} else if *state.get() {
|
|
"✓"
|
|
} else {
|
|
" "
|
|
};
|
|
let border_style = if width == "1px" || height == "1px" {
|
|
"none"
|
|
} else {
|
|
"solid"
|
|
};
|
|
let update = move || {
|
|
let new_state = !state.get();
|
|
if let Some(callback) = cx.props.raw_oninput {
|
|
callback.call(FormData {
|
|
value: if let Some(value) = &cx.props.value {
|
|
if new_state {
|
|
value.to_string()
|
|
} else {
|
|
String::new()
|
|
}
|
|
} else {
|
|
"on".to_string()
|
|
},
|
|
values: HashMap::new(),
|
|
files: None,
|
|
});
|
|
}
|
|
state.set(new_state);
|
|
};
|
|
cx.render(rsx! {
|
|
div {
|
|
width: "{width}",
|
|
height: "{height}",
|
|
border_style: "{border_style}",
|
|
align_items: "center",
|
|
justify_content: "center",
|
|
onclick: move |_| {
|
|
update();
|
|
},
|
|
onkeydown: move |evt| {
|
|
if !evt.is_auto_repeating() && match evt.key(){ Key::Character(c) if c == " " =>true, Key::Enter=>true, _=>false } {
|
|
update();
|
|
}
|
|
},
|
|
"{text}"
|
|
}
|
|
})
|
|
}
|