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