euv_ui/component/progress/view/fn.rs
1use super::*;
2
3/// A determinate progress bar component bound to a percentage signal.
4///
5/// Renders a `c_progress_container` track holding a
6/// `c_progress_bar_fill` element whose inline `width` is driven by the
7/// `percent` signal, plus the label and a numeric readout. A running bar
8/// adds the animated `c_progress_bar_running` class; a settled one falls
9/// back to `c_progress_bar_stopped` so the fill keeps its inline width
10/// without re-running the keyframe animation.
11///
12/// # Arguments
13///
14/// - `VirtualNode<EuvProgressProps>` - The props node containing bar configuration.
15///
16/// # Returns
17///
18/// - `VirtualNode` - A styled progress bar.
19#[component]
20pub fn euv_progress(node: VirtualNode<EuvProgressProps>) -> VirtualNode {
21 let EuvProgressProps {
22 percent,
23 label: label_text,
24 active,
25 }: EuvProgressProps = node.try_get_props().unwrap_or_default();
26 let clamped: f64 = progress_percent_clamp(percent.get());
27 let fill_style: String = format!("width: {clamped}%;");
28 let fill_style_ref: &str = fill_style.as_str();
29 let readout: String = format!("{clamped:.0}%");
30 html! {
31 div {
32 div {
33 class: c_progress_container()
34 div {
35 class: c_progress_bar_fill()
36 class: if { active } {
37 c_progress_bar_running()
38 } else {
39 c_progress_bar_stopped()
40 }
41 style: fill_style_ref
42 }
43 }
44 div {
45 class: c_euv_slider_header()
46 span {
47 class: c_form_label()
48 label_text
49 }
50 span {
51 class: c_binding_slider_value()
52 readout
53 }
54 }
55 }
56 }
57}
58
59/// Clamps a raw percentage into the `0.0..=100.0` range a bar can render.
60///
61/// NaN collapses to `0.0` — a `Signal<f64>` carrying NaN (an
62/// unreported upload size, a `0.0 / 0.0` ratio) would otherwise emit a
63/// `width: NaN%` declaration the browser drops silently.
64///
65/// # Arguments
66///
67/// - `f64` - The raw percentage supplied by the caller.
68///
69/// # Returns
70///
71/// - `f64` - The percentage clamped into the `0.0..=100.0` range.
72pub fn progress_percent_clamp(percent: f64) -> f64 {
73 if percent.is_nan() {
74 return 0.0;
75 }
76 percent.clamp(0.0, PERCENT_MAX)
77}