vertigo_forms/select/
multi_drop_down.rs1use vertigo::{Computed, Css, DomNode, Value, bind, css, dom};
2
3use super::multi_select::MultiSelect;
4
5#[derive(Clone, Default)]
6pub struct MultiDropDownParams {
7 pub drop_down_content_css: Css,
8}
9
10#[derive(Clone)]
11pub struct MultiDropDown<T: Clone + 'static> {
12 pub value: Value<Vec<T>>,
13 pub options: Computed<Vec<T>>,
14 pub params: MultiDropDownParams,
15}
16
17impl<T> MultiDropDown<T>
18where
19 T: Clone + From<String> + PartialEq + ToString + 'static,
20{
21 pub fn into_component(self) -> Self {
22 self
23 }
24
25 pub fn mount(self) -> DomNode {
26 let opened = Value::new(false);
27 let button_label = opened.render_value(|opened| {
28 if opened {
29 dom! { <span>"^"</span> }
30 } else {
31 dom! { <span>"V"</span> }
32 }
33 });
34 let content_css = css! {"
35 position: absolute;
36 z-index: 1;
37 "};
38 let drop_down_content_css = content_css + self.params.drop_down_content_css;
39
40 let content = opened.render_value(move |opened| {
41 if opened {
42 dom! {
43 <div css={&drop_down_content_css}>
44 <MultiSelect
45 value={&self.value}
46 options={&self.options}
47 />
48 </div>
49 }
50 } else {
51 dom! { <div/> }
52 }
53 });
54
55 let on_click = bind!(opened, |_| opened.change(|o| *o = !*o));
56
57 let base_css = css! {"
58 position: relative;
59 display: inline-block;
60 "};
61
62 dom! {
63 <div>
64 <button {on_click}>{button_label}</button>
65 <div css={base_css}>{content}</div>
66 </div>
67 }
68 }
69}