61 lines
2.1 KiB
Rust
61 lines
2.1 KiB
Rust
use std::fmt::Display;
|
|
|
|
use jl_types::domain::option_wrapper::OptionWrapper;
|
|
use yew::prelude::*;
|
|
use yew_utils::vdom::comp_with;
|
|
|
|
/// Give this component a list of options
|
|
#[function_component(DropDown)]
|
|
pub fn dropdown<T: Display + std::cmp::PartialEq + Clone + 'static>(
|
|
props: &DropDownProps<T>,
|
|
) -> Html {
|
|
let selection_changed_cb = {
|
|
let onchange_cb = props.onchange.clone();
|
|
let selected = props.selected.clone();
|
|
Callback::from(move |option: OptionWrapper<T>| {
|
|
selected.set(option.option.clone());
|
|
match onchange_cb.clone() {
|
|
Some(additional_cb) => additional_cb.emit(option),
|
|
None => {}
|
|
};
|
|
})
|
|
};
|
|
let drop_down = comp_with::<yew_utils::components::drop_down::DropDown<OptionWrapper<T>>>(
|
|
yew_utils::components::drop_down::DropDownProps {
|
|
initial: { OptionWrapper::new((*props.selected).clone()) },
|
|
options: {
|
|
let mut options: Vec<OptionWrapper<T>> = props
|
|
.options
|
|
.clone()
|
|
.into_iter()
|
|
.map(|option| OptionWrapper::new(Some(option)))
|
|
.collect();
|
|
if props.has_none {
|
|
options.insert(0, OptionWrapper::new(None));
|
|
}
|
|
options
|
|
},
|
|
selection_changed: selection_changed_cb.clone(),
|
|
class_css: Some("admin-dropdown".into()),
|
|
},
|
|
);
|
|
//if (*props.selected).is_none() {selection_changed_cb.emit( OptionWrapper::new((*props.selected).clone()));}
|
|
html! {
|
|
{drop_down}
|
|
}
|
|
}
|
|
|
|
#[derive(PartialEq, Properties, Clone)]
|
|
pub struct DropDownProps<T: Display + std::cmp::PartialEq + Clone> {
|
|
#[prop_or_default]
|
|
pub options: Vec<T>,
|
|
/// in case that there is no selected option, this will reflect a None variant
|
|
pub selected: UseStateHandle<Option<T>>,
|
|
#[prop_or_default]
|
|
pub unpicked_text: String,
|
|
#[prop_or_default]
|
|
pub onchange: Option<Callback<OptionWrapper<T>>>,
|
|
#[prop_or_default]
|
|
pub has_none: bool,
|
|
}
|