use maud::{html, Markup};
#[derive(Debug, Clone)]
pub struct Props {
pub value: u32,
pub max: u32,
pub label: String,
pub indeterminate: bool,
}
impl Default for Props {
fn default() -> Self {
Self {
value: 0,
max: 100,
label: String::new(),
indeterminate: false,
}
}
}
pub fn render(props: Props) -> Markup {
let pct = if props.max == 0 { 0 } else { (props.value * 100) / props.max };
html! {
@if props.indeterminate {
div.mui-progress.mui-progress--indeterminate role="progressbar" aria-valuemin="0" aria-valuemax=(props.max) aria-label=(props.label) {
div.mui-progress__bar {}
}
} @else {
div.mui-progress role="progressbar" aria-valuenow=(props.value) aria-valuemin="0" aria-valuemax=(props.max) aria-label=(props.label) {
div.mui-progress__bar style=(format!("width: {}%", pct)) {}
}
}
}
}
pub fn showcase() -> Markup {
html! {
div.mui-showcase__grid {
div {
p.mui-showcase__caption { "File upload" }
div style="display:flex;flex-direction:column;gap:0.5rem" {
div style="display:flex;justify-content:space-between;align-items:center" {
span style="font-size:0.875rem;color:var(--mui-text)" { "Uploading file..." }
span style="font-size:0.875rem;font-weight:500;color:var(--mui-text)" { "65%" }
}
(render(Props {
value: 65,
max: 100,
label: "Uploading file, 65 percent".into(),
indeterminate: false,
}))
span style="font-size:0.75rem;color:var(--mui-text-muted)" { "report-2026.pdf — 3.2 MB of 4.9 MB" }
}
}
div {
p.mui-showcase__caption { "Stepped progress" }
div style="display:flex;flex-direction:column;gap:0.5rem" {
div style="display:flex;justify-content:space-between;align-items:center" {
span style="font-size:0.875rem;font-weight:500;color:var(--mui-text)" { "Step 2 of 4" }
span style="font-size:0.75rem;color:var(--mui-text-muted)" { "Account details" }
}
(render(Props {
value: 50,
max: 100,
label: "Step 2 of 4, account details".into(),
indeterminate: false,
}))
}
}
div {
p.mui-showcase__caption { "Indeterminate" }
div style="display:flex;flex-direction:column;gap:0.5rem" {
span style="font-size:0.875rem;color:var(--mui-text-muted)" { "Processing your request..." }
(render(Props {
value: 0,
max: 100,
label: "Processing request".into(),
indeterminate: true,
}))
}
}
div {
p.mui-showcase__caption { "Download complete" }
div style="display:flex;flex-direction:column;gap:0.5rem" {
div style="display:flex;justify-content:space-between;align-items:center" {
span style="font-size:0.875rem;color:var(--mui-text)" { "Download complete" }
span style="font-size:0.875rem;font-weight:500;color:var(--mui-accent,var(--mui-text))" { "100%" }
}
(render(Props {
value: 100,
max: 100,
label: "Download complete".into(),
indeterminate: false,
}))
span style="font-size:0.75rem;color:var(--mui-text-muted)" { "dataset.csv — 12.7 MB" }
}
}
}
}
}