diff --git a/crates/components/src/lib.rs b/crates/components/src/lib.rs index 5b940ddbd..ae3ad2aab 100644 --- a/crates/components/src/lib.rs +++ b/crates/components/src/lib.rs @@ -13,6 +13,7 @@ mod graph; mod input; mod loader; mod network_image; +mod progress_bar; mod scroll_views; mod slider; mod switch; @@ -31,6 +32,7 @@ pub use graph::*; pub use input::*; pub use loader::*; pub use network_image::*; +pub use progress_bar::*; pub use scroll_views::*; pub use slider::*; pub use switch::*; diff --git a/crates/components/src/progress_bar.rs b/crates/components/src/progress_bar.rs new file mode 100644 index 000000000..934c97e52 --- /dev/null +++ b/crates/components/src/progress_bar.rs @@ -0,0 +1,86 @@ +use dioxus::prelude::*; +use freya_elements::elements as dioxus_elements; +use freya_hooks::{use_focus, use_get_theme}; + +/// [`ProgressBar`] component properties. +#[derive(Props, PartialEq)] +pub struct ProgressBarProps { + /// Show a label with the current progress. Default to false. + #[props(default = false)] + show_progress: bool, + + /// Width of the progress bar. Default to 100%. + #[props(default = "100%".to_string(), into)] + width: String, + + /// Height of the progress bar. Default to 20px. + #[props(default = "20".to_string(), into)] + height: String, + /// Percentage of the progress bar. + pub progress: f32, +} + +/// `ProgressBar` component. +/// +/// # Props +/// See [`ProgressBarProps`]. +/// +/// # Styling +/// Inherits the [`ProgressBarTheme`](freya_hooks::ProgressBarTheme) theme. +/// +/// # Example +/// +/// ```no_run +/// # use freya::prelude::*; +/// fn app(cx: Scope) -> Element { +/// render!( +/// ProgressBar { +/// progress: 75.0 +/// } +/// ) +/// } +/// ``` +/// +#[allow(non_snake_case)] +pub fn ProgressBar(cx: Scope) -> Element { + let width = &cx.props.width; + let height = &cx.props.height; + let show_progress = cx.props.show_progress; + let progress = cx.props.progress; + + render!( + rect { + width: "{width}", + height: "{height}", + padding: "2", + rect { + corner_radius: "999", + width: "100%", + height: "100%", + shadow: "0 2 10 1 rgb(0, 0, 0, 45)", + background: "rgb(210, 210, 210)", + font_size: "13", + direction: "horizontal", + rect { + corner_radius: "999", + width: "{progress}%", + height: "100%", + background: "rgb(103, 80, 164)", + display: "center", + overflow: "clip", + if show_progress { + rsx!( + label { + align: "center", + width: "100%", + color: "white", + max_lines: "1", + "{progress.ceil()}%" + } + ) + } + } + } + } + ) +} diff --git a/examples/progress_bar.rs b/examples/progress_bar.rs new file mode 100644 index 000000000..38885d0b6 --- /dev/null +++ b/examples/progress_bar.rs @@ -0,0 +1,76 @@ +#![cfg_attr( + all(not(debug_assertions), target_os = "windows"), + windows_subsystem = "windows" +)] + +use freya::prelude::*; + +fn main() { + launch(app); +} + +fn app(cx: Scope) -> Element { + let progress = use_state(cx, || 0f64); + + render!( + ProgressBar { + show_progress: true, + progress: *progress.get() as f32 + } + ProgressBar { + show_progress: true, + progress: *progress.get() as f32 * 0.75 + } + ProgressBar { + show_progress: true, + progress: *progress.get() as f32 * 0.50 + } + ProgressBar { + show_progress: true, + progress: *progress.get() as f32 * 0.35 + } + ProgressBar { + show_progress: true, + progress: *progress.get() as f32 * 0.15 + } + ProgressBar { + show_progress: true, + progress: *progress.get() as f32 * 0.90 + } + ProgressBar { + show_progress: true, + progress: *progress.get() as f32 * 0.70 + } + ProgressBar { + show_progress: true, + progress: *progress.get() as f32 * 0.65 + } + ProgressBar { + show_progress: true, + progress: *progress.get() as f32 * 0.30 + } + ProgressBar { + show_progress: true, + progress: *progress.get() as f32 * 0.85 + } + ProgressBar { + show_progress: true, + progress: *progress.get() as f32 * 0.60 + } + ProgressBar { + show_progress: true, + progress: *progress.get() as f32 * 0.45 + } + ProgressBar { + show_progress: true, + progress: *progress.get() as f32 * 0.20 + } + Slider { + width: 300.0, + value: *progress.get(), + onmoved: |v| { + progress.set(v) + } + } + ) +}