vertigo_forms/select/
multi_drop_down.rs

1use 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}