jl-frontend/src/components/dropdown.rs

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,
}