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}