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