use wasm_bindgen::UnwrapThrowExt;
use web_sys::HtmlSelectElement;
use yew::prelude::*;
use crate::Size;
#[derive(Clone, Debug, Properties, PartialEq)]
pub struct SelectProps {
pub name: String,
pub value: String,
pub update: Callback<String>,
#[prop_or_default]
pub children: Children,
#[prop_or_default]
pub classes: Classes,
#[prop_or_default]
pub size: Option<Size>,
#[prop_or_default]
pub loading: bool,
#[prop_or_default]
pub disabled: bool,
}
#[function_component(Select)]
pub fn select(props: &SelectProps) -> Html {
let class = classes!(
"select",
props.classes.clone(),
props.size.as_ref().map(|size| size.to_string()),
props.loading.then_some("is-loading"),
);
let onchange = props.update.reform(|ev: web_sys::Event| {
let select: HtmlSelectElement = ev.target_dyn_into().expect_throw("event target should be a select");
select.value()
});
html! {
<div {class}>
<select
name={props.name.clone()}
value={props.value.clone()}
disabled={props.disabled}
{onchange}
>
{props.children.clone()}
</select>
</div>
}
}
#[derive(Properties, Clone, PartialEq)]
pub struct MultiSelectProps {
pub name: String,
pub value: Vec<String>,
pub update: Callback<Vec<String>>,
#[prop_or_default]
pub children: Children,
#[prop_or_default]
pub classes: Classes,
#[prop_or_default]
pub size: Option<Size>,
#[prop_or_else(|| 4)]
pub list_size: u32,
#[prop_or_default]
pub loading: bool,
#[prop_or_default]
pub disabled: bool,
}
#[function_component(MultiSelect)]
pub fn multi_select(props: &MultiSelectProps) -> Html {
let class = classes!(
"select",
"is-multiple",
props.classes.clone(),
props.size.as_ref().map(|size| size.to_string()),
props.loading.then_some("is-loading"),
);
let size = props.list_size.to_string();
let onchange = props.update.reform(|ev: web_sys::Event| {
let select: HtmlSelectElement = ev.target_dyn_into().expect_throw("event target should be a select");
let opts = select.selected_options();
(0..opts.length())
.into_iter()
.filter_map(|idx| opts.item(idx))
.filter_map(|elem| elem.get_attribute("value").or_else(|| elem.text_content()))
.collect::<Vec<_>>()
});
html! {
<div {class}>
<select
multiple=true
size={size}
name={props.name.clone()}
value={props.value.join(",")}
disabled={props.disabled}
{onchange}
>
{props.children.clone()}
</select>
</div>
}
}