patternfly_yew/components/menu/
item.rs1use super::use_close_menu_callback;
2use crate::prelude::Icon;
3use yew::prelude::*;
4
5#[derive(Clone, Debug, PartialEq, Properties)]
6struct MenuItemProperties {
7 pub children: Html,
8 pub icon: Option<Html>,
9 pub danger: bool,
10 pub disabled: bool,
11 pub selected: bool,
12 pub r#type: MenuItemType,
13 pub close_on_select: bool,
14 pub description: Option<String>,
15 pub style: Option<AttrValue>,
16 pub class: Classes,
17}
18
19#[derive(Clone, PartialEq, Debug)]
20enum MenuItemType {
21 Button(Callback<()>),
22 Link { href: AttrValue, target: AttrValue },
23}
24
25#[component]
26fn MenuItem(props: &MenuItemProperties) -> Html {
27 let mut class = classes!("pf-v6-c-menu__list-item");
28
29 if props.danger {
30 class.push(classes!("pf-m-danger"));
31 }
32
33 if props.disabled {
34 class.push(classes!("pf-m-disabled"));
35 }
36
37 let onclose = use_close_menu_callback();
38
39 let mut item_class = classes!("pf-v6-c-menu__item");
40 if props.selected {
41 item_class.push(classes!("pf-m-selected"));
42 }
43
44 let element = |content: Html| match &props.r#type {
45 MenuItemType::Button(callback) => {
46 let callback = callback.clone();
47 let close_on_select = props.close_on_select;
48
49 html!(
50 <button
51 class={item_class}
52 type="button"
53 role="menuitem"
54 tabindex="-1"
55 disabled={props.disabled}
56 onclick={callback.reform(move |_| {
57 if close_on_select {
58 onclose.emit(());
59 }
60 })}
61 >
62 { content }
63 </button>
64 )
65 }
66 MenuItemType::Link { href, target } => {
67 let tabindex = match props.disabled {
68 true => Some("-1"),
69 false => None,
70 };
71
72 let onclick = props.close_on_select.then(|| onclose.reform(|_| ()));
73
74 html!(
75 <a
76 class={item_class}
77 {href}
78 {target}
79 {onclick}
80 aria-disabled={props.disabled.to_string()}
81 {tabindex}
82 role="menuitem"
83 >
84 { content }
85 </a>
86 )
87 }
88 };
89
90 class.extend(&props.class);
91
92 html!(
93 <li {class} style={&props.style}>
94 { element(html!(
95 <>
96 <span class="pf-v6-c-menu__item-main">
97 if let Some(icon) = &props.icon {
98 <span class="pf-v6-c-menu__item-icon"> {icon.clone()} </span>
99 }
100 if props.danger {
101 <span class="pf-v6-screen-reader">{ "Danger Item:" }</span>
102 }
103
104 <span class="pf-v6-c-menu__item-text">{ props.children.clone() }</span>
105
106 if props.selected {
107 <span class="pf-v6-c-menu__item-select-icon">{ Icon::Check }</span>
108 }
109 </span>
110 if let Some(description) = &props.description {
111 <span class="pf-v6-c-menu__item-description"> {description} </span>
112 }
113 </>
114 )) }
115 </li>
116 )
117}
118
119#[derive(Clone, Debug, PartialEq, Properties)]
120pub struct MenuActionProperties {
121 #[prop_or_default]
122 pub children: Html,
123
124 #[prop_or_default]
125 pub description: Option<String>,
126
127 #[prop_or_default]
128 pub icon: Option<Html>,
129
130 #[prop_or_default]
131 pub danger: bool,
132
133 #[prop_or_default]
134 pub disabled: bool,
135
136 #[prop_or_default]
137 pub onclick: Callback<()>,
138
139 #[prop_or_default]
140 pub selected: bool,
141
142 #[prop_or(true)]
144 pub close_on_select: bool,
145
146 #[prop_or_default]
147 pub style: Option<AttrValue>,
148
149 #[prop_or_default]
150 pub class: Classes,
151}
152
153#[component]
154pub fn MenuAction(props: &MenuActionProperties) -> Html {
155 let MenuActionProperties {
158 children,
159 icon,
160 danger,
161 disabled,
162 onclick,
163 description,
164 selected,
165 close_on_select,
166 style,
167 class,
168 } = props.clone();
169
170 let props = MenuItemProperties {
171 children,
172 icon,
173 danger,
174 disabled,
175 r#type: MenuItemType::Button(onclick),
176 close_on_select,
177 description,
178 selected,
179 style,
180 class,
181 };
182
183 html!(<MenuItem ..props />)
184}
185
186#[derive(Clone, Debug, PartialEq, Properties)]
187pub struct MenuLinkProperties {
188 #[prop_or_default]
189 pub children: Html,
190
191 #[prop_or_default]
192 pub description: Option<String>,
193
194 #[prop_or_default]
195 pub icon: Option<Html>,
196
197 #[prop_or_default]
198 pub danger: bool,
199
200 #[prop_or_default]
201 pub disabled: bool,
202
203 pub href: AttrValue,
204
205 #[prop_or_default]
206 pub target: AttrValue,
207
208 #[prop_or_default]
209 pub selected: bool,
210
211 #[prop_or(true)]
213 pub close_on_select: bool,
214
215 #[prop_or_default]
216 pub style: Option<AttrValue>,
217
218 #[prop_or_default]
219 pub class: Classes,
220}
221
222#[component()]
223pub fn MenuLink(props: &MenuLinkProperties) -> Html {
224 let MenuLinkProperties {
227 children,
228 icon,
229 danger,
230 disabled,
231 href,
232 target,
233 description,
234 selected,
235 close_on_select,
236 style,
237 class,
238 } = props.clone();
239
240 let props = MenuItemProperties {
241 children,
242 icon,
243 danger,
244 disabled,
245 r#type: MenuItemType::Link { href, target },
246 close_on_select,
247 description,
248 selected,
249 style,
250 class,
251 };
252
253 html!(<MenuItem ..props />)
254}