leptos_components/
progress_bar.rs1use components_core::concat;
2use leptos::prelude::*;
3use leptos::{IntoView, component, view};
4
5use crate::icons::Ferris;
6
7const BASE_CLASS: &str = concat!(components_core::BASE_CLASS, "-progress-bar");
8
9#[component]
10pub fn ProgressBar(#[prop(into)] percentage: ReadSignal<usize>) -> impl IntoView {
11 let percentage = percentage.get();
12 let progress_in_limit = percentage == 0 || percentage == 100;
13 let progress_in_min_limit = percentage < 25;
14
15 let min_limit_class = crate::tw!(
16 concat!("text-overline ", BASE_CLASS, "__percentage"),
17 progress_in_min_limit.then_some(concat!(
18 "text-overline ",
19 BASE_CLASS,
20 "__percentage--invert"
21 ))
22 );
23
24 let max_limit_class = crate::tw!(
25 concat!(BASE_CLASS, "__fill"),
26 progress_in_limit.then_some(concat!(BASE_CLASS, "__fill--limit"))
27 );
28
29 let percentage_str = format!("{percentage}%");
30
31 view! {
32 <div class={concat!(BASE_CLASS, "__container")}>
33 <div class={BASE_CLASS}>
34 <span
35 class=min_limit_class
36 style:right={progress_in_min_limit.then_some("auto".to_string()).unwrap_or_else(|| format!("{}%", 100 - percentage))}
37 style:left={progress_in_min_limit.then_some(percentage_str.clone()).unwrap_or_else(|| "auto".into())}
38 >
39 {percentage_str.clone()}
40 <Ferris size=15 />
41 </span>
42 <div
43 class=max_limit_class
44 style:width=percentage_str
45 />
46 </div>
47 </div>
48 }
49}