use windjammer_ui::components::generated::traits::Renderable;
use windjammer_ui::components::generated::{
button, checkbox, container, flex, input, slider, text,
};
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;
fn generate_demo_page() -> String {
let header = container::Container::new()
.max_width("1200px".to_string())
.padding("32px".to_string())
.background_color("#f8f9fa".to_string())
.child("<h1 style='margin:0; color:#2c3e50;'>🎨 Windjammer UI Component Gallery</h1>".to_string())
.child("<p style='margin:8px 0 0 0; color:#7f8c8d;'>All components written in pure Windjammer and transpiled to Rust!</p>".to_string())
.render();
let text_section = container::Container::new()
.max_width("1200px".to_string())
.padding("24px".to_string())
.child("<h2>Text Components</h2>".to_string())
.child(
text::Text::new("Small text example".to_string())
.size(text::TextSize::Small)
.render(),
)
.child(
text::Text::new("Medium text example".to_string())
.size(text::TextSize::Medium)
.render(),
)
.child(
text::Text::new("Large text example".to_string())
.size(text::TextSize::Large)
.render(),
)
.child(
text::Text::new("Bold large text".to_string())
.size(text::TextSize::XLarge)
.bold()
.render(),
)
.render();
let button_section = container::Container::new()
.max_width("1200px".to_string())
.padding("24px".to_string())
.child("<h2>Button Components</h2>".to_string())
.child(
flex::Flex::new()
.direction(flex::FlexDirection::Row)
.gap("16px".to_string())
.child(
button::Button::new("Primary".to_string())
.variant(button::ButtonVariant::Primary)
.render(),
)
.child(
button::Button::new("Secondary".to_string())
.variant(button::ButtonVariant::Secondary)
.render(),
)
.child(
button::Button::new("Success".to_string())
.variant(button::ButtonVariant::Success)
.render(),
)
.child(
button::Button::new("Danger".to_string())
.variant(button::ButtonVariant::Danger)
.render(),
)
.child(
button::Button::new("Ghost".to_string())
.variant(button::ButtonVariant::Ghost)
.render(),
)
.render(),
)
.child("<br/>".to_string())
.child(
flex::Flex::new()
.direction(flex::FlexDirection::Row)
.gap("16px".to_string())
.child(
button::Button::new("Small".to_string())
.size(button::ButtonSize::Small)
.render(),
)
.child(
button::Button::new("Medium".to_string())
.size(button::ButtonSize::Medium)
.render(),
)
.child(
button::Button::new("Large".to_string())
.size(button::ButtonSize::Large)
.render(),
)
.child(
button::Button::new("Disabled".to_string())
.disabled(true)
.render(),
)
.render(),
)
.render();
let form_section = container::Container::new()
.max_width("1200px".to_string())
.padding("24px".to_string())
.child("<h2>Form Components</h2>".to_string())
.child(
flex::Flex::new()
.direction(flex::FlexDirection::Column)
.gap("16px".to_string())
.child("<label>Username:</label>".to_string())
.child(
input::Input::new()
.placeholder("Enter your username".to_string())
.render(),
)
.child("<label>Email:</label>".to_string())
.child(
input::Input::new()
.placeholder("your@email.com".to_string())
.render(),
)
.child("<br/>".to_string())
.child(
checkbox::Checkbox::new("I agree to the terms".to_string())
.checked(false)
.render(),
)
.child(
checkbox::Checkbox::new("Subscribe to newsletter".to_string())
.checked(true)
.render(),
)
.child(
checkbox::Checkbox::new("Enable notifications".to_string())
.size(checkbox::CheckboxSize::Large)
.render(),
)
.render(),
)
.render();
let slider_section = container::Container::new()
.max_width("1200px".to_string())
.padding("24px".to_string())
.child("<h2>Slider Components</h2>".to_string())
.child(
slider::Slider::new()
.label("Volume".to_string())
.value(50.0)
.render(),
)
.child("<br/>".to_string())
.child(
slider::Slider::new()
.label("Brightness".to_string())
.min(0.0)
.max(100.0)
.value(75.0)
.render(),
)
.child("<br/>".to_string())
.child(
slider::Slider::new()
.label("Precision".to_string())
.min(0.0)
.max(10.0)
.step(0.1)
.value(5.5)
.render(),
)
.render();
let layout_section = container::Container::new()
.max_width("1200px".to_string())
.padding("24px".to_string())
.child("<h2>Layout Components</h2>".to_string())
.child("<h3>Flex Row:</h3>".to_string())
.child(
flex::Flex::new()
.direction(flex::FlexDirection::Row)
.gap("16px".to_string())
.padding("16px".to_string())
.background_color("#e3f2fd".to_string())
.child("<div style='padding:16px; background:#2196f3; color:white;'>Item 1</div>".to_string())
.child("<div style='padding:16px; background:#2196f3; color:white;'>Item 2</div>".to_string())
.child("<div style='padding:16px; background:#2196f3; color:white;'>Item 3</div>".to_string())
.render()
)
.child("<br/>".to_string())
.child("<h3>Flex Column:</h3>".to_string())
.child(
flex::Flex::new()
.direction(flex::FlexDirection::Column)
.gap("8px".to_string())
.padding("16px".to_string())
.background_color("#fff3e0".to_string())
.child("<div style='padding:16px; background:#ff9800; color:white;'>Column Item 1</div>".to_string())
.child("<div style='padding:16px; background:#ff9800; color:white;'>Column Item 2</div>".to_string())
.child("<div style='padding:16px; background:#ff9800; color:white;'>Column Item 3</div>".to_string())
.render()
)
.render();
let full_page = format!(
r#"<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Windjammer UI Gallery</title>
<style>
* {{ margin: 0; padding: 0; box-sizing: border-box; }}
body {{ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #ffffff; }}
/* Text styles */
.wj-text {{ display: inline-block; margin: 8px 0; }}
.wj-text.sm {{ font-size: 14px; }}
.wj-text.md {{ font-size: 16px; }}
.wj-text.lg {{ font-size: 20px; }}
.wj-text.xl {{ font-size: 24px; }}
.wj-text.bold {{ font-weight: bold; }}
/* Button styles */
.wj-button {{
border: none; padding: 8px 16px; cursor: pointer; border-radius: 4px;
font-size: 14px; font-weight: 500; transition: all 0.2s;
}}
.wj-button:hover {{ transform: translateY(-1px); box-shadow: 0 4px 8px rgba(0,0,0,0.1); }}
.wj-button-primary {{ background: #007bff; color: white; }}
.wj-button-secondary {{ background: #6c757d; color: white; }}
.wj-button-success {{ background: #28a745; color: white; }}
.wj-button-danger {{ background: #dc3545; color: white; }}
.wj-button-ghost {{ background: transparent; color: #007bff; border: 1px solid #007bff; }}
.wj-button-sm {{ padding: 4px 12px; font-size: 12px; }}
.wj-button-md {{ padding: 8px 16px; font-size: 14px; }}
.wj-button-lg {{ padding: 12px 24px; font-size: 16px; }}
.wj-button[disabled] {{ opacity: 0.5; cursor: not-allowed; }}
/* Input styles */
.wj-input {{
padding: 8px 12px; border: 1px solid #ced4da; border-radius: 4px;
font-size: 14px; width: 100%; max-width: 400px;
}}
.wj-input:focus {{ outline: none; border-color: #007bff; box-shadow: 0 0 0 3px rgba(0,123,255,0.1); }}
/* Checkbox styles */
.wj-checkbox {{ display: flex; align-items: center; gap: 8px; cursor: pointer; margin: 8px 0; }}
.wj-checkbox input {{ width: 16px; height: 16px; cursor: pointer; }}
.wj-checkbox-lg input {{ width: 20px; height: 20px; }}
.wj-checkbox-sm input {{ width: 14px; height: 14px; }}
/* Slider styles */
.wj-slider {{
width: 100%; max-width: 400px; height: 6px;
-webkit-appearance: none; appearance: none; background: #e0e0e0;
border-radius: 3px; outline: none;
}}
.wj-slider::-webkit-slider-thumb {{
-webkit-appearance: none; appearance: none;
width: 18px; height: 18px; background: #007bff;
border-radius: 50%; cursor: pointer;
}}
/* Container & Flex styles */
.wj-container {{ display: block; }}
.wj-flex {{ display: flex; }}
h2 {{ margin: 24px 0 16px 0; color: #2c3e50; font-size: 24px; }}
h3 {{ margin: 16px 0 8px 0; color: #34495e; font-size: 18px; }}
label {{ font-weight: 500; color: #495057; }}
</style>
</head>
<body>
{}
{}
{}
{}
{}
{}
<footer style="text-align:center; padding:48px; color:#7f8c8d; font-size:14px;">
<p>🚀 Built with <strong>Windjammer</strong> - 80% of Rust's power with 20% of the complexity!</p>
<p style="margin-top:8px;">All components compiled from <code>.wj</code> source files.</p>
</footer>
</body>
</html>"#,
header, text_section, button_section, form_section, slider_section, layout_section
);
full_page
}
fn main() {
let html = generate_demo_page();
std::fs::write("examples/gallery.html", &html).expect("Failed to write gallery.html");
println!("✅ Gallery generated: examples/gallery.html");
println!(
"📖 Open in browser: file://{}/examples/gallery.html",
std::env::current_dir().unwrap().display()
);
}
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen(start)]
pub fn run() {
let html = generate_demo_page();
web_sys::window()
.and_then(|win| win.document())
.map(|doc| doc.body().map(|body| body.set_inner_html(&html)));
}