dioxus_bulma/components/
menu.rs1use crate::utils::build_class;
2use dioxus::prelude::*;
3
4#[derive(Props, Clone, PartialEq)]
5pub struct MenuProps {
6 #[props(default)]
7 pub id: Option<String>,
8 #[props(default)]
9 pub class: Option<String>,
10 #[props(default)]
11 pub style: Option<String>,
12 pub children: Element,
13}
14
15#[component]
16pub fn Menu(props: MenuProps) -> Element {
17 let base_classes = vec!["menu"];
18 let optional_classes = vec![props.class.clone()];
19 let final_class = build_class(&base_classes, &optional_classes);
20 let menu_style = props.style.as_deref().unwrap_or("");
21
22 rsx! {
23 aside {
24 class: "{final_class}",
25 style: "{menu_style}",
26 id: props.id.clone(),
27 {props.children}
28 }
29 }
30}
31
32#[derive(Props, Clone, PartialEq)]
33pub struct MenuLabelProps {
34 #[props(default)]
35 pub id: Option<String>,
36 #[props(default)]
37 pub class: Option<String>,
38 #[props(default)]
39 pub style: Option<String>,
40 pub children: Element,
41}
42
43#[component]
44pub fn MenuLabel(props: MenuLabelProps) -> Element {
45 let base_classes = vec!["menu-label"];
46 let optional_classes = vec![props.class.clone()];
47 let final_class = build_class(&base_classes, &optional_classes);
48 let label_style = props.style.as_deref().unwrap_or("");
49
50 rsx! {
51 p {
52 class: "{final_class}",
53 style: "{label_style}",
54 id: props.id.clone(),
55 {props.children}
56 }
57 }
58}
59
60#[derive(Props, Clone, PartialEq)]
61pub struct MenuListProps {
62 #[props(default)]
63 pub id: Option<String>,
64 #[props(default)]
65 pub class: Option<String>,
66 #[props(default)]
67 pub style: Option<String>,
68 pub children: Element,
69}
70
71#[component]
72pub fn MenuList(props: MenuListProps) -> Element {
73 let base_classes = vec!["menu-list"];
74 let optional_classes = vec![props.class.clone()];
75 let final_class = build_class(&base_classes, &optional_classes);
76 let list_style = props.style.as_deref().unwrap_or("");
77
78 rsx! {
79 ul {
80 class: "{final_class}",
81 style: "{list_style}",
82 id: props.id.clone(),
83 {props.children}
84 }
85 }
86}
87
88#[derive(Props, Clone, PartialEq)]
89pub struct MenuItemProps {
90 #[props(default)]
91 pub active: Option<bool>,
92 #[props(default)]
93 pub href: Option<String>,
94 #[props(default)]
95 pub onclick: Option<EventHandler<MouseEvent>>,
96 #[cfg(feature = "router")]
98 #[props(default, into)]
99 pub to: crate::router_helpers::MaybeNav,
100 #[props(default)]
101 pub id: Option<String>,
102 #[props(default)]
103 pub class: Option<String>,
104 #[props(default)]
105 pub style: Option<String>,
106 pub children: Element,
107}
108
109#[component]
110pub fn MenuItem(props: MenuItemProps) -> Element {
111 let active = props.active.unwrap_or(false);
112
113 let base_classes = vec![];
114 let optional_classes = vec![
115 if active { Some("is-active".to_string()) } else { None },
116 props.class.clone(),
117 ];
118
119 let final_class = build_class(&base_classes, &optional_classes);
120 let item_style = props.style.as_deref().unwrap_or("");
121
122 #[cfg(feature = "router")]
123 if let Some(nav_target) = props.to.0 {
124 return rsx! {
125 li {
126 Link {
127 to: nav_target,
128 class: "{final_class}",
129 style: "{item_style}",
130 id: props.id.clone(),
131 onclick: move |evt| {
132 if let Some(handler) = &props.onclick {
133 handler.call(evt);
134 }
135 },
136 {props.children}
137 }
138 }
139 };
140 }
141
142 rsx! {
143 li {
144 if let Some(href) = props.href {
145 a {
146 class: "{final_class}",
147 style: "{item_style}",
148 id: props.id.clone(),
149 href: "{href}",
150 onclick: move |evt| {
151 if let Some(handler) = &props.onclick {
152 handler.call(evt);
153 }
154 },
155 {props.children}
156 }
157 } else {
158 a {
159 class: "{final_class}",
160 style: "{item_style}",
161 id: props.id.clone(),
162 onclick: move |evt| {
163 if let Some(handler) = &props.onclick {
164 handler.call(evt);
165 }
166 },
167 {props.children}
168 }
169 }
170 }
171 }
172}