// Modal Component - Overlay dialog with backdrop
use super::traits::Renderable
pub enum ModalSize {
Small,
Medium,
Large,
FullScreen,
}
pub struct Modal {
id: string,
title: string,
content: string,
footer: string,
size: ModalSize,
closeable: bool,
visible: bool,
}
impl Modal {
pub fn new(id: string, title: string) -> Modal {
Modal {
id: id,
title: title,
content: String::new(),
footer: String::new(),
size: ModalSize::Medium,
closeable: true,
visible: false,
}
}
pub fn content(self, content: string) -> Modal {
self.content = content;
self
}
pub fn footer(self, footer: string) -> Modal {
self.footer = footer;
self
}
pub fn size(self, size: ModalSize) -> Modal {
self.size = size;
self
}
pub fn closeable(self, closeable: bool) -> Modal {
self.closeable = closeable;
self
}
pub fn visible(self, visible: bool) -> Modal {
self.visible = visible;
self
}
}
impl Renderable for Modal {
pub fn render(self) -> string {
let width = match self.size {
ModalSize::Small => "400px",
ModalSize::Medium => "600px",
ModalSize::Large => "800px",
ModalSize::FullScreen => "100vw",
};
let height = match self.size {
ModalSize::FullScreen => "100vh",
_ => "auto",
};
let display = if self.visible {
"flex"
} else {
"none"
};
let mut html = String::new();
// Backdrop
html.push_str("<div id='");
html.push_str(&self.id);
html.push_str("-backdrop' style='position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.5); display: ");
html.push_str(display);
html.push_str("; align-items: center; justify-content: center; z-index: 1000;'>");
// Modal container
html.push_str("<div id='");
html.push_str(&self.id);
html.push_str("' style='background: white; border-radius: 8px; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1); max-width: ");
html.push_str(width);
html.push_str("; width: 100%; max-height: ");
html.push_str(height);
html.push_str("; display: flex; flex-direction: column; margin: 16px;'>");
// Header
html.push_str("<div style='padding: 16px 24px; border-bottom: 1px solid #e2e8f0; display: flex; align-items: center; justify-content: space-between;'>");
html.push_str("<h2 style='margin: 0; font-size: 18px; font-weight: 600; color: #1a202c;'>");
html.push_str(&self.title);
html.push_str("</h2>");
if self.closeable {
html.push_str("<button onclick='document.getElementById(\"");
html.push_str(&self.id);
html.push_str("-backdrop\").style.display=\"none\"' style='background: none; border: none; font-size: 24px; cursor: pointer; color: #718096; padding: 0; width: 32px; height: 32px; display: flex; align-items: center; justify-content: center;'>×</button>");
}
html.push_str("</div>");
// Content
html.push_str("<div style='padding: 24px; flex: 1; overflow-y: auto;'>");
html.push_str(&self.content);
html.push_str("</div>");
// Footer (if provided)
if self.footer.len() > 0 {
html.push_str("<div style='padding: 16px 24px; border-top: 1px solid #e2e8f0; display: flex; justify-content: flex-end; gap: 8px;'>");
html.push_str(&self.footer);
html.push_str("</div>");
}
html.push_str("</div>"); // End modal container
html.push_str("</div>"); // End backdrop
html
}
}