perspective_viewer/components/containers/
dropdown_menu.rs1use std::marker::PhantomData;
14use std::rc::Rc;
15
16use web_sys::*;
17use yew::prelude::*;
18
19use super::select::SelectItem;
20use crate::components::style::LocalStyle;
21use crate::*;
22
23pub type DropDownMenuItem<T> = SelectItem<T>;
24
25pub type DropDownMenuMsg = ();
26
27#[derive(Properties, PartialEq)]
28pub struct DropDownMenuProps<T>
29where
30 T: Into<Html> + Clone + PartialEq + 'static,
31{
32 pub values: Rc<Vec<DropDownMenuItem<T>>>,
33 pub callback: Callback<T>,
34}
35
36pub struct DropDownMenu<T>
37where
38 T: Into<Html> + Clone + PartialEq + 'static,
39{
40 _props: PhantomData<T>,
41}
42
43impl<T> Component for DropDownMenu<T>
44where
45 T: Into<Html> + Clone + PartialEq + 'static,
46{
47 type Message = DropDownMenuMsg;
48 type Properties = DropDownMenuProps<T>;
49
50 fn create(_ctx: &Context<Self>) -> Self {
51 Self {
52 _props: Default::default(),
53 }
54 }
55
56 fn update(&mut self, _ctx: &Context<Self>, _msg: Self::Message) -> bool {
57 false
58 }
59
60 fn view(&self, ctx: &Context<Self>) -> Html {
61 let values = &ctx.props().values;
62 let body = if !values.is_empty() {
63 values
64 .iter()
65 .map(|value| match value {
66 DropDownMenuItem::Option(x) => {
67 let click = ctx.props().callback.reform({
68 let value = x.clone();
69 move |_: MouseEvent| value.clone()
70 });
71
72 html! {
73 <span onmousedown={click} class="selected">{ x.clone().into() }</span>
74 }
75 },
76 DropDownMenuItem::OptGroup(name, xs) => {
77 html! {
78 <>
79 <span class="dropdown-group-label">{ name }</span>
80 <div class="dropdown-group-container">
81 { xs.iter().map(|x| {
82 let click = ctx.props().callback.reform({
83 let value = x.clone();
84 move |_: MouseEvent| value.clone()
85 });
86 html! {
87 <span onmousedown={ click }>
88 { x.clone().into() }
89 </span>
90 }
91 }).collect::<Html>() }
92 </div>
93 </>
94 }
95 },
96 })
97 .collect::<Html>()
98 } else {
99 html! { <span class="no-results">{ "No Completions" }</span> }
100 };
101
102 html! { <><LocalStyle href={css!("containers/dropdown-menu")} />{ body }</> }
103 }
104}