use vertigo::{Computed, Css, DomNode, Value, bind, bind_rc, css, dom, render::render_list};
pub struct MultiSelect<T: Clone + PartialEq + 'static> {
pub value: Value<Vec<T>>,
pub options: Computed<Vec<T>>,
}
impl<T> MultiSelect<T>
where
T: Clone + From<String> + PartialEq + ToString + 'static,
{
pub fn into_component(self) -> Self {
self
}
pub fn mount(&self) -> DomNode {
let Self { value, options } = self;
let toggle = bind_rc!(value, |item: &T| {
value.change(|value| {
if let Some(idx) = value.iter().position(|i| i == item) {
value.remove(idx);
} else {
value.push(item.clone());
}
});
});
let list = bind!(
options,
toggle,
value.render_value(move |value| {
bind!(
toggle,
render_list(
&options,
|item| item.to_string(),
bind!(toggle, |item| {
let text_item = item.to_string();
let on_click = bind!(toggle, item, |_| toggle(&item));
let css = if value.contains(item) {
css! {"
border-style: inset;
font-weight: bold;
color: green;
"}
} else {
Css::default()
};
dom! {
<button {css} {on_click}>{text_item}</button>
}
})
)
)
})
);
let list_css = css! {"
display: flex;
flex-wrap: wrap;
"};
dom! {
<div css={list_css}>
{list}
</div>
}
}
}