use dioxus::prelude::*;
#[derive(Clone, PartialEq)]
pub enum MenuMode {
Horizontal,
Vertical,
}
impl MenuMode {
pub fn as_str(&self) -> &'static str {
match self {
MenuMode::Horizontal => "horizontal",
MenuMode::Vertical => "vertical",
}
}
}
#[derive(Props, Clone, PartialEq)]
pub struct MenuProps {
#[props(default)]
pub children: Element,
#[props(default = MenuMode::Vertical)]
pub mode: MenuMode,
#[props(default)]
pub default_active: Option<String>,
#[props(default = false)]
pub collapse: bool,
#[props(default)]
pub background_color: Option<String>,
#[props(default)]
pub text_color: Option<String>,
#[props(default)]
pub active_text_color: Option<String>,
#[props(default = false)]
pub unique_opened: bool,
#[props(default)]
pub on_select: Option<EventHandler<String>>,
#[props(default)]
pub class: Option<String>,
#[props(default)]
pub style: Option<String>,
}
#[component]
pub fn Menu(props: MenuProps) -> Element {
let mut class_names = vec!["el-menu".to_string()];
class_names.push(format!("el-menu--{}", props.mode.as_str()));
if props.collapse { class_names.push("el-menu--collapse".to_string()); }
if let Some(ref c) = props.class { class_names.push(c.clone()); }
let mut style = props.style.clone().unwrap_or_default();
if let Some(ref bg) = props.background_color { style = format!("background-color: {}; {}", bg, style); }
rsx! {
ul {
class: "{class_names.join(\" \")}",
style: "{style}",
role: "menubar",
{props.children}
}
}
}
#[derive(Props, Clone, PartialEq)]
pub struct MenuItemProps {
#[props(default)]
pub children: Option<Element>,
pub index: String,
#[props(default)]
pub route: Option<String>,
#[props(default = false)]
pub disabled: bool,
#[props(default)]
pub on_click: Option<EventHandler<String>>,
#[props(default)]
pub class: Option<String>,
}
#[component]
pub fn MenuItem(props: MenuItemProps) -> Element {
let mut class_names = vec!["el-menu-item".to_string()];
if props.disabled { class_names.push("is-disabled".to_string()); }
if let Some(ref c) = props.class { class_names.push(c.clone()); }
let index_clone = props.index.clone();
rsx! {
li {
class: "{class_names.join(\" \")}",
role: "menuitem",
onclick: move |_| {
if !props.disabled {
if let Some(handler) = props.on_click {
handler.call(index_clone.clone());
}
}
},
{props.children}
}
}
}
#[derive(Props, Clone, PartialEq)]
pub struct MenuItemGroupProps {
#[props(default)]
pub children: Element,
#[props(default)]
pub title: Option<String>,
#[props(default)]
pub class: Option<String>,
}
#[component]
pub fn MenuItemGroup(props: MenuItemGroupProps) -> Element {
let mut class_names = vec!["el-menu-item-group".to_string()];
if let Some(ref c) = props.class { class_names.push(c.clone()); }
rsx! {
li {
class: "{class_names.join(\" \")}",
role: "menuitemgroup",
if let Some(ref title) = props.title {
div { class: "el-menu-item-group__title", "{title}" }
}
ul {
class: "el-menu-item-group__content",
{props.children}
}
}
}
}
#[derive(Props, Clone, PartialEq)]
pub struct SubMenuProps {
#[props(default)]
pub children: Element,
pub index: String,
#[props(default)]
pub title: Option<String>,
#[props(default)]
pub icon: Option<String>,
#[props(default = false)]
pub disabled: bool,
#[props(default)]
pub class: Option<String>,
}
#[component]
pub fn SubMenu(props: SubMenuProps) -> Element {
let mut class_names = vec!["el-sub-menu".to_string()];
if props.disabled { class_names.push("is-disabled".to_string()); }
if let Some(ref c) = props.class { class_names.push(c.clone()); }
rsx! {
li {
class: "{class_names.join(\" \")}",
role: "menuitem",
div {
class: "el-sub-menu__title",
if let Some(ref icon) = props.icon {
i { class: "{icon}" }
}
if let Some(ref title) = props.title {
span { "{title}" }
}
i { class: "el-sub-menu__icon-arrow el-icon-arrow-down" }
}
ul {
class: "el-menu el-menu--inline",
role: "menu",
{props.children}
}
}
}
}