use crate::theme::prelude::*;
use dominator::{html, Dom};
use dwind::prelude::*;
use futures_signals::map_ref;
use futures_signals::signal::SignalExt;
use futures_signals_component_macro::component;
#[component(render_fn = progress)]
struct Progress {
#[signal]
#[default(0.0)]
value: f64,
#[signal]
#[default(false)]
indeterminate: bool,
#[signal]
#[default("Progress".to_string())]
label: String,
}
pub fn progress(props: ProgressProps) -> Dom {
let ProgressProps {
value,
indeterminate,
label,
apply,
} = props;
let value = value.map(|v| v.clamp(0.0, 100.0)).broadcast();
let indeterminate = indeterminate.broadcast();
let aria_valuenow = map_ref! {
let value = value.signal(),
let indeterminate = indeterminate.signal() => {
if *indeterminate {
None
} else {
Some(format!("{}", value))
}
}
};
html!("div", {
.attr("role", "progressbar")
.attr("aria-valuemin", "0")
.attr("aria-valuemax", "100")
.attr_signal("aria-valuenow", aria_valuenow)
.attr_signal("aria-label", label)
.dwclass!("w-full h-2 rounded-full overflow-hidden")
.dwclass!("dwui-bg-void-700 is(.light *):dwui-bg-void-200")
.child(html!("div", {
.dwclass!("h-full rounded-full")
.dwclass!("dwui-bg-primary-500 is(.light *):dwui-bg-primary-400")
.style("transition", "width 200ms ease-out")
.style_signal("width", map_ref! {
let value = value.signal(),
let indeterminate = indeterminate.signal() => {
if *indeterminate {
"40%".to_string()
} else {
format!("{}%", value)
}
}
})
.style_signal("animation", indeterminate.signal().map(|v| {
if v {
Some("dwui-progress-indeterminate 1.2s ease-in-out infinite")
} else {
None
}
}))
}))
.apply_if(apply.is_some(), |b| b.apply(apply.unwrap()))
})
}