// Menu and MenuItem - Dropdown menu components
pub struct Menu {
items: Vec<string>,
trigger: string,
class: string,
}
impl Menu {
pub fn new(trigger: string) -> Menu {
Menu {
items: Vec::new(),
trigger,
class: String::new(),
}
}
pub fn item(item: string) -> Menu {
self.items.push(item)
self
}
pub fn class(class: string) -> Menu {
self.class = class
self
}
pub fn render() -> string {
let mut html = String::new()
html.push_str("<div class=\"wj-menu ")
html.push_str(self.class.as_str())
html.push_str("\" style=\"position: relative; display: inline-block;\">")
// Trigger button
html.push_str(self.trigger.as_str())
// Menu items
html.push_str("<div class=\"wj-menu-items\" style=\"position: absolute; top: 100%; left: 0; margin-top: 4px; background: white; border: 1px solid #e5e7eb; border-radius: 8px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); min-width: 200px; z-index: 1000; display: none;\">")
for item in self.items {
html.push_str(item.as_str())
}
html.push_str("</div>")
html.push_str("</div>")
// Add hover behavior
html.push_str("<style>.wj-menu:hover .wj-menu-items { display: block; }</style>")
html
}
}
pub struct MenuItem {
label: string,
icon: string,
href: string,
disabled: bool,
class: string,
}
impl MenuItem {
pub fn new(label: string) -> MenuItem {
MenuItem {
label,
icon: String::new(),
href: "#".to_string(),
disabled: false,
class: String::new(),
}
}
pub fn icon(icon: string) -> MenuItem {
self.icon = icon
self
}
pub fn href(href: string) -> MenuItem {
self.href = href
self
}
pub fn disabled(disabled: bool) -> MenuItem {
self.disabled = disabled
self
}
pub fn class(class: string) -> MenuItem {
self.class = class
self
}
pub fn render() -> string {
let disabled_style = if self.disabled {
" opacity: 0.5; cursor: not-allowed;"
} else {
" cursor: pointer;"
}
let mut html = String::new()
html.push_str("<a href=\"")
html.push_str(self.href.as_str())
html.push_str("\" class=\"wj-menu-item ")
html.push_str(self.class.as_str())
html.push_str("\" style=\"display: flex; align-items: center; gap: 8px; padding: 10px 16px; color: #374151; text-decoration: none;")
html.push_str(disabled_style)
html.push_str(" transition: background-color 0.2s;\">")
if !self.icon.is_empty() {
html.push_str("<span>")
html.push_str(self.icon.as_str())
html.push_str("</span>")
}
html.push_str("<span>")
html.push_str(self.label.as_str())
html.push_str("</span>")
html.push_str("</a>")
// Add hover effect
html.push_str("<style>.wj-menu-item:hover:not([style*='cursor: not-allowed']) { background-color: #f3f4f6; }</style>")
html
}
}