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