Skip to main content

freya_components/
progress_bar.rs

1use dioxus::prelude::*;
2use freya_elements as dioxus_elements;
3use freya_hooks::{
4    use_applied_theme,
5    ProgressBarTheme,
6    ProgressBarThemeWith,
7};
8
9/// Properties for the [`ProgressBar`] component.
10#[derive(Props, Clone, PartialEq)]
11pub struct ProgressBarProps {
12    /// Width of the progress bar. Default to `fill`.
13    #[props(default = "fill".into())]
14    pub width: String,
15    /// Theme override.
16    pub theme: Option<ProgressBarThemeWith>,
17    /// Show a label with the current progress. Default to false.
18    #[props(default = false)]
19    pub show_progress: bool,
20    /// Percentage of the progress bar.
21    pub progress: f32,
22}
23
24/// Display the progress of something visually. For example: downloading files, fetching data, etc.
25///
26/// # Styling
27/// Inherits the [`ProgressBarTheme`](freya_hooks::ProgressBarTheme) theme.
28///
29/// # Example
30///
31/// ```rust
32/// # use freya::prelude::*;
33/// fn app() -> Element {
34///     rsx!(ProgressBar {
35///         show_progress: true,
36///         progress: 50.0
37///     })
38/// }
39/// # use freya_testing::prelude::*;
40/// # launch_doc(|| {
41/// #   rsx!(
42/// #       Preview {
43/// #           ProgressBar {
44/// #               width: "50%",
45/// #               show_progress: true,
46/// #               progress: 50.0
47/// #           }
48/// #       }
49/// #   )
50/// # }, (250., 250.).into(), "./images/gallery_progress_bar.png");
51/// ```
52///
53/// # Preview
54/// ![ProgressBar Preview][progress_bar]
55#[cfg_attr(feature = "docs",
56    doc = embed_doc_image::embed_image!("progress_bar", "images/gallery_progress_bar.png")
57)]
58#[allow(non_snake_case)]
59pub fn ProgressBar(
60    ProgressBarProps {
61        width,
62        theme,
63        show_progress,
64        progress,
65    }: ProgressBarProps,
66) -> Element {
67    let ProgressBarTheme {
68        color,
69        background,
70        progress_background,
71        height,
72    } = use_applied_theme!(&theme, progress_bar);
73
74    let progress = progress.clamp(0., 100.);
75
76    rsx!(
77        rect {
78            width: "{width}",
79            height: "{height}",
80            padding: "2",
81            rect {
82                corner_radius: "999",
83                width: "100%",
84                height: "100%",
85                background: "{background}",
86                font_size: "13",
87                direction: "horizontal",
88                border: "1 outer {background}",
89                rect {
90                    corner_radius: "999",
91                    width: "{progress}%",
92                    height: "100%",
93                    background: "{progress_background}",
94                    main_align: "center",
95                    cross_align: "center",
96                    overflow: "clip",
97                    if show_progress {
98                        label {
99                            text_align: "center",
100                            width: "100%",
101                            color: "{color}",
102                            max_lines: "1",
103                            text_height: "disable-least-ascent",
104                            "{progress.floor()}%"
105                        }
106                    }
107                }
108            }
109        }
110    )
111}