use super::use_close_menu_callback;
use crate::prelude::Icon;
use yew::prelude::*;
#[derive(Clone, Debug, PartialEq, Properties)]
struct MenuItemProperties {
pub children: Html,
pub icon: Option<Html>,
pub danger: bool,
pub disabled: bool,
pub selected: bool,
pub r#type: MenuItemType,
pub description: Option<String>,
pub style: Option<AttrValue>,
pub class: Classes,
}
#[derive(Clone, PartialEq, Debug)]
enum MenuItemType {
Button(Callback<()>),
Link { href: AttrValue, target: AttrValue },
}
#[function_component(MenuItem)]
fn menu_item(props: &MenuItemProperties) -> Html {
let mut class = classes!("pf-v5-c-menu__list-item");
if props.danger {
class.push(classes!("pf-m-danger"));
}
if props.disabled {
class.push(classes!("pf-m-disabled"));
}
let onclose = use_close_menu_callback();
let mut item_class = classes!("pf-v5-c-menu__item");
if props.selected {
item_class.push(classes!("pf-m-selected"));
}
let element = |content: Html| match &props.r#type {
MenuItemType::Button(callback) => {
html!(
<button
class={item_class}
type="button"
role="menuitem"
tabindex="-1"
disabled={props.disabled}
onclick={callback.reform(move |_| {
onclose.emit(());
})}
>
{ content }
</button>
)
}
MenuItemType::Link { href, target } => {
let tabindex = match props.disabled {
true => Some("-1"),
false => None,
};
html!(
<a
class={item_class}
{href} {target}
onclick={onclose.reform(|_|())}
aria-disabled={props.disabled.to_string()}
{tabindex}
role="menuitem"
>
{ content }
</a>
)
}
};
class.extend(&props.class);
html!(
<li {class} style={&props.style}>
{ element(html!(
<>
<span class="pf-v5-c-menu__item-main">
if let Some(icon) = &props.icon {
<span class="pf-v5-c-menu__item-icon"> {icon.clone()} </span>
}
if props.danger {
<span class="pf-v5-screen-reader">{ "Danger Item:" }</span>
}
<span class="pf-v5-c-menu__item-text">{ props.children.clone() }</span>
if props.selected {
<span class="pf-v5-c-menu__item-select-icon">{ Icon::Check }</span>
}
</span>
if let Some(description) = &props.description {
<span class="pf-v5-c-menu__item-description"> {description} </span>
}
</>
)) }
</li>
)
}
#[derive(Clone, Debug, PartialEq, Properties)]
pub struct MenuActionProperties {
#[prop_or_default]
pub children: Html,
#[prop_or_default]
pub description: Option<String>,
#[prop_or_default]
pub icon: Option<Html>,
#[prop_or_default]
pub danger: bool,
#[prop_or_default]
pub disabled: bool,
#[prop_or_default]
pub onclick: Callback<()>,
#[prop_or_default]
pub selected: bool,
#[prop_or_default]
pub style: Option<AttrValue>,
#[prop_or_default]
pub class: Classes,
}
#[function_component(MenuAction)]
pub fn menu_action(props: &MenuActionProperties) -> Html {
let MenuActionProperties {
children,
icon,
danger,
disabled,
onclick,
description,
selected,
style,
class,
} = props.clone();
let props = MenuItemProperties {
children,
icon,
danger,
disabled,
r#type: MenuItemType::Button(onclick),
description,
selected,
style,
class,
};
html!(<MenuItem ..props />)
}
#[derive(Clone, Debug, PartialEq, Properties)]
pub struct MenuLinkProperties {
#[prop_or_default]
pub children: Html,
#[prop_or_default]
pub description: Option<String>,
#[prop_or_default]
pub icon: Option<Html>,
#[prop_or_default]
pub danger: bool,
#[prop_or_default]
pub disabled: bool,
pub href: AttrValue,
#[prop_or_default]
pub target: AttrValue,
#[prop_or_default]
pub selected: bool,
#[prop_or_default]
pub style: Option<AttrValue>,
#[prop_or_default]
pub class: Classes,
}
#[function_component(MenuLink)]
pub fn menu_link(props: &MenuLinkProperties) -> Html {
let MenuLinkProperties {
children,
icon,
danger,
disabled,
href,
target,
description,
selected,
style,
class,
} = props.clone();
let props = MenuItemProperties {
children,
icon,
danger,
disabled,
r#type: MenuItemType::Link { href, target },
description,
selected,
style,
class,
};
html!(<MenuItem ..props />)
}