dioxus_element_plug/components/
menu.rs1use dioxus::prelude::*;
2
3#[derive(Clone, PartialEq)]
5pub enum MenuMode {
6 Horizontal,
7 Vertical,
8}
9
10impl MenuMode {
11 pub fn as_str(&self) -> &'static str {
12 match self {
13 MenuMode::Horizontal => "horizontal",
14 MenuMode::Vertical => "vertical",
15 }
16 }
17}
18
19#[derive(Props, Clone, PartialEq)]
21pub struct MenuProps {
22 #[props(default)]
23 pub children: Element,
24
25 #[props(default = MenuMode::Vertical)]
26 pub mode: MenuMode,
27
28 #[props(default)]
30 pub default_active: Option<String>,
31
32 #[props(default = false)]
34 pub collapse: bool,
35
36 #[props(default)]
38 pub background_color: Option<String>,
39
40 #[props(default)]
42 pub text_color: Option<String>,
43
44 #[props(default)]
46 pub active_text_color: Option<String>,
47
48 #[props(default = false)]
50 pub unique_opened: bool,
51
52 #[props(default)]
54 pub on_select: Option<EventHandler<String>>,
55
56 #[props(default)]
57 pub class: Option<String>,
58
59 #[props(default)]
60 pub style: Option<String>,
61}
62
63#[component]
65pub fn Menu(props: MenuProps) -> Element {
66 let mut class_names = vec!["el-menu".to_string()];
67 class_names.push(format!("el-menu--{}", props.mode.as_str()));
68 if props.collapse { class_names.push("el-menu--collapse".to_string()); }
69 if let Some(ref c) = props.class { class_names.push(c.clone()); }
70
71 let mut style = props.style.clone().unwrap_or_default();
72 if let Some(ref bg) = props.background_color { style = format!("background-color: {}; {}", bg, style); }
73
74 rsx! {
75 ul {
76 class: "{class_names.join(\" \")}",
77 style: "{style}",
78 role: "menubar",
79 {props.children}
80 }
81 }
82}
83
84#[derive(Props, Clone, PartialEq)]
86pub struct MenuItemProps {
87 #[props(default)]
88 pub children: Option<Element>,
89
90 pub index: String,
92
93 #[props(default)]
95 pub route: Option<String>,
96
97 #[props(default = false)]
99 pub disabled: bool,
100
101 #[props(default)]
103 pub on_click: Option<EventHandler<String>>,
104
105 #[props(default)]
106 pub class: Option<String>,
107}
108
109#[component]
111pub fn MenuItem(props: MenuItemProps) -> Element {
112 let mut class_names = vec!["el-menu-item".to_string()];
113 if props.disabled { class_names.push("is-disabled".to_string()); }
114 if let Some(ref c) = props.class { class_names.push(c.clone()); }
115
116 let index_clone = props.index.clone();
117
118 rsx! {
119 li {
120 class: "{class_names.join(\" \")}",
121 role: "menuitem",
122 onclick: move |_| {
123 if !props.disabled {
124 if let Some(handler) = props.on_click {
125 handler.call(index_clone.clone());
126 }
127 }
128 },
129 {props.children}
130 }
131 }
132}
133
134#[derive(Props, Clone, PartialEq)]
136pub struct MenuItemGroupProps {
137 #[props(default)]
138 pub children: Element,
139
140 #[props(default)]
141 pub title: Option<String>,
142
143 #[props(default)]
144 pub class: Option<String>,
145}
146
147#[component]
149pub fn MenuItemGroup(props: MenuItemGroupProps) -> Element {
150 let mut class_names = vec!["el-menu-item-group".to_string()];
151 if let Some(ref c) = props.class { class_names.push(c.clone()); }
152
153 rsx! {
154 li {
155 class: "{class_names.join(\" \")}",
156 role: "menuitemgroup",
157 if let Some(ref title) = props.title {
158 div { class: "el-menu-item-group__title", "{title}" }
159 }
160 ul {
161 class: "el-menu-item-group__content",
162 {props.children}
163 }
164 }
165 }
166}
167
168#[derive(Props, Clone, PartialEq)]
170pub struct SubMenuProps {
171 #[props(default)]
172 pub children: Element,
173
174 pub index: String,
175
176 #[props(default)]
177 pub title: Option<String>,
178
179 #[props(default)]
180 pub icon: Option<String>,
181
182 #[props(default = false)]
183 pub disabled: bool,
184
185 #[props(default)]
186 pub class: Option<String>,
187}
188
189#[component]
191pub fn SubMenu(props: SubMenuProps) -> Element {
192 let mut class_names = vec!["el-sub-menu".to_string()];
193 if props.disabled { class_names.push("is-disabled".to_string()); }
194 if let Some(ref c) = props.class { class_names.push(c.clone()); }
195
196 rsx! {
197 li {
198 class: "{class_names.join(\" \")}",
199 role: "menuitem",
200 div {
201 class: "el-sub-menu__title",
202 if let Some(ref icon) = props.icon {
203 i { class: "{icon}" }
204 }
205 if let Some(ref title) = props.title {
206 span { "{title}" }
207 }
208 i { class: "el-sub-menu__icon-arrow el-icon-arrow-down" }
209 }
210 ul {
211 class: "el-menu el-menu--inline",
212 role: "menu",
213 {props.children}
214 }
215 }
216 }
217}