jinya_ui/widgets/menu/
item.rs

1use yew::prelude::*;
2use yew::{Component, ComponentLink, Html};
3use yew_router::{prelude::*, Switch};
4
5pub fn get_css<'a>() -> &'a str {
6    // language=CSS
7    "
8.jinya-menu__item {
9    padding: 1rem;
10    display: inline-block;
11    cursor: pointer;
12    position: relative;
13}
14
15.jinya-menu__flyout {
16    background: var(--primary-color);
17    margin-top: 1rem;
18    padding: 1rem;
19    border-radius: 5px;
20    display: none;
21    cursor: default;
22    position: absolute;
23    grid-auto-columns: auto;
24    grid-auto-flow: column;
25    grid-gap: 1rem;
26    transform: translateX(-50%);
27    left: 50%;
28    z-index: 2;
29}
30
31.jinya-menu__flyout::before {
32    content: '';
33    border: 1rem solid transparent;
34    border-bottom-color: var(--primary-color);
35    position: absolute;
36    top: -1rem;
37    left: 50%;
38    transform: translateX(-50%);
39    border-bottom-width: 0.5rem;
40    border-top-width: 0.5rem;
41}
42
43.jinya-menu__item:hover > .jinya-menu__flyout {
44    display: grid;
45}
46
47.jinya-menu__subitem {
48    font-size: var(--font-size-16);
49    color: var(--white);
50    font-weight: var(--font-weight-light);
51    cursor: pointer;
52    text-decoration: none;
53    white-space: pre;
54}
55
56.jinya-menu__group {
57    display: flex;
58    flex-flow: column wrap;
59    align-items: center;
60}
61
62.jinya-menu__group-header {
63    font-size: var(--font-size-24);
64    color: var(--white);
65    font-weight: var(--font-style-light);
66    margin-bottom: 0.5rem;
67    white-space: pre;
68}
69"
70}
71
72#[derive(Clone, PartialEq, Properties)]
73pub struct SubItem<RouteType: Switch + Clone + 'static> {
74    pub label: String,
75    #[prop_or_default]
76    pub route: Option<&'static RouteType>,
77    #[prop_or_default]
78    pub on_click: Option<Callback<MouseEvent>>,
79}
80
81#[derive(Clone, PartialEq, Properties)]
82pub struct SubItemGroup<RouteType: Switch + Clone + 'static> {
83    pub title: String,
84    pub items: Vec<SubItem<RouteType>>,
85}
86
87#[derive(Clone, PartialEq, Properties)]
88pub struct MenuItem<RouteType: Switch + Clone + 'static> {
89    pub label: String,
90    pub groups: Vec<SubItemGroup<RouteType>>,
91}
92
93#[derive(Clone, PartialEq, Properties)]
94pub struct MenuItemProps<RouteType: Switch + Clone + 'static> {
95    pub groups: Vec<SubItemGroup<RouteType>>,
96    pub label: String,
97}
98
99impl<RouteType: Switch + Clone + 'static> Component for MenuItem<RouteType> {
100    type Message = ();
101    type Properties = MenuItemProps<RouteType>;
102
103    fn create(props: Self::Properties, _link: ComponentLink<Self>) -> Self {
104        MenuItem {
105            groups: props.groups,
106            label: props.label,
107        }
108    }
109
110    fn update(&mut self, _msg: Self::Message) -> bool {
111        false
112    }
113
114    fn change(&mut self, _props: Self::Properties) -> bool {
115        self.groups = _props.groups;
116        self.label = _props.label;
117        true
118    }
119
120    fn view(&self) -> Html {
121        html! {
122            <li href="#" class="jinya-menu__item">
123                {&self.label}
124                <div class="jinya-menu__flyout">
125                    {for self.groups.iter().enumerate().map(|(_, mut group)| {
126                        html! {
127                            <div class="jinya-menu__group">
128                                <span class="jinya-menu__group-header">{&group.title}</span>
129                                {for group.items.iter().enumerate().map(|(_, mut subitem)| {
130                                    if subitem.route.is_some() {
131                                        html! {
132                                            <RouterAnchor<RouteType> classes="jinya-menu__subitem" route=subitem.route.unwrap()>{&subitem.label}</RouterAnchor<RouteType>>
133                                        }
134                                    } else {
135                                        html! {
136                                            <a href="#" class="jinya-menu__subitem" onclick=subitem.on_click.as_ref().unwrap()>{&subitem.label}</a>
137                                        }
138                                    }
139                                })}
140                            </div>
141                        }
142                    })}
143                </div>
144            </li>
145        }
146    }
147}