mirror of
https://github.com/adoyle0/thaw.git
synced 2025-03-13 05:59:49 -04:00
feat: add loading bar component
This commit is contained in:
parent
29068acd1a
commit
a05cda35d7
5 changed files with 208 additions and 40 deletions
|
@ -24,6 +24,14 @@ pub fn App() -> impl IntoView {
|
|||
provide_context(theme);
|
||||
view! {
|
||||
<Provider theme>
|
||||
<TheRouter />
|
||||
</Provider>
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn TheRouter() -> impl IntoView {
|
||||
view! {
|
||||
<Router base="/thaw">
|
||||
<Routes base="/thaw".to_string()>
|
||||
<Route path="/" view=Home/>
|
||||
|
@ -64,7 +72,6 @@ pub fn App() -> impl IntoView {
|
|||
<Route path="/mobile/toast" view=ToastDemoPage/>
|
||||
</Routes>
|
||||
</Router>
|
||||
</Provider>
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ mod image;
|
|||
mod input;
|
||||
mod input_number;
|
||||
mod layout;
|
||||
mod loading_bar;
|
||||
mod menu;
|
||||
mod message;
|
||||
pub mod mobile;
|
||||
|
@ -53,6 +54,7 @@ pub use image::*;
|
|||
pub use input::*;
|
||||
pub use input_number::*;
|
||||
pub use layout::*;
|
||||
pub use loading_bar::*;
|
||||
pub use menu::*;
|
||||
pub use message::*;
|
||||
pub use modal::*;
|
||||
|
|
11
src/loading_bar/loading-bar.css
Normal file
11
src/loading_bar/loading-bar.css
Normal file
|
@ -0,0 +1,11 @@
|
|||
.thaw-loading-bar-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
.thaw-loading-bar {
|
||||
height: 2px;
|
||||
max-width: 0;
|
||||
}
|
46
src/loading_bar/loading_bar_provider.rs
Normal file
46
src/loading_bar/loading_bar_provider.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
use super::{LoadingBar, LoadingBarRef};
|
||||
use crate::{teleport::Teleport, utils::ComponentRef};
|
||||
use leptos::*;
|
||||
|
||||
#[component]
|
||||
pub fn LoadingBarProvider(children: Children) -> impl IntoView {
|
||||
let loading_bar_ref = ComponentRef::<LoadingBarRef>::default();
|
||||
provide_context(LoadingBarInjection { loading_bar_ref });
|
||||
|
||||
view! {
|
||||
{children()}
|
||||
<Teleport>
|
||||
<LoadingBar comp_ref=loading_bar_ref/>
|
||||
</Teleport>
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct LoadingBarInjection {
|
||||
loading_bar_ref: ComponentRef<LoadingBarRef>,
|
||||
}
|
||||
impl Copy for LoadingBarInjection {}
|
||||
|
||||
impl LoadingBarInjection {
|
||||
pub fn start(&self) {
|
||||
if let Some(loading_bar_ref) = self.loading_bar_ref.get_untracked() {
|
||||
loading_bar_ref.start();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn finish(&self) {
|
||||
if let Some(loading_bar_ref) = self.loading_bar_ref.get_untracked() {
|
||||
loading_bar_ref.finish();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn error(&self) {
|
||||
if let Some(loading_bar_ref) = self.loading_bar_ref.get_untracked() {
|
||||
loading_bar_ref.error();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn use_loading_bar() -> LoadingBarInjection {
|
||||
expect_context::<LoadingBarInjection>()
|
||||
}
|
102
src/loading_bar/mod.rs
Normal file
102
src/loading_bar/mod.rs
Normal file
|
@ -0,0 +1,102 @@
|
|||
mod loading_bar_provider;
|
||||
|
||||
use crate::{mount_style, use_theme, utils::ComponentRef, Theme};
|
||||
use leptos::*;
|
||||
pub use loading_bar_provider::{use_loading_bar, LoadingBarProvider};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct LoadingBarRef {
|
||||
start: Callback<()>,
|
||||
finish: Callback<()>,
|
||||
error: Callback<()>,
|
||||
}
|
||||
|
||||
impl LoadingBarRef {
|
||||
pub fn start(&self) {
|
||||
self.start.call(());
|
||||
}
|
||||
pub fn finish(&self) {
|
||||
self.finish.call(());
|
||||
}
|
||||
pub fn error(&self) {
|
||||
self.error.call(());
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn LoadingBar(#[prop(optional)] comp_ref: ComponentRef<LoadingBarRef>) -> impl IntoView {
|
||||
mount_style("loading-bar", include_str!("./loading-bar.css"));
|
||||
let theme = use_theme(Theme::light);
|
||||
let css_vars = create_memo(move |_| {
|
||||
let mut css_vars = String::new();
|
||||
theme.with(|theme| {
|
||||
css_vars.push_str(&format!(
|
||||
"--thaw-background-color: {};",
|
||||
theme.common.color_success
|
||||
));
|
||||
css_vars.push_str(&format!(
|
||||
"--thaw-background-color-error: {};",
|
||||
theme.common.color_error
|
||||
));
|
||||
});
|
||||
css_vars
|
||||
});
|
||||
let loading_bar_ref = create_node_ref::<html::Div>();
|
||||
let loading = create_rw_signal(false);
|
||||
|
||||
let start = Callback::new(move |_| {
|
||||
loading.set(true);
|
||||
if let Some(loading_bar_ref) = loading_bar_ref.get_untracked() {
|
||||
let loading_bar_ref = loading_bar_ref
|
||||
.style("background-color", "var(--thaw-background-color)")
|
||||
.style("transition", "none")
|
||||
.style("max-width", "0");
|
||||
_ = loading_bar_ref.offset_width();
|
||||
loading_bar_ref
|
||||
.style("transition", "max-width 4s linear")
|
||||
.style("max-width", "80%");
|
||||
}
|
||||
});
|
||||
let finish = Callback::new(move |_| {
|
||||
if let Some(loading_bar_ref) = loading_bar_ref.get_untracked() {
|
||||
let loading_bar_ref = loading_bar_ref
|
||||
.style("background-color", "var(--thaw-background-color)")
|
||||
.style("transition", "max-width 0.5s linear")
|
||||
.style("max-width", "1000%");
|
||||
loading_bar_ref.on(ev::transitionend, move |_| {
|
||||
loading.set(false);
|
||||
});
|
||||
}
|
||||
});
|
||||
let error = Callback::new(move |_| {
|
||||
if let Some(loading_bar_ref) = loading_bar_ref.get_untracked() {
|
||||
if !loading.get() {
|
||||
loading.set(true);
|
||||
let loading_bar_ref = loading_bar_ref.clone();
|
||||
let loading_bar_ref = loading_bar_ref
|
||||
.style("transition", "none")
|
||||
.style("max-width", "0");
|
||||
_ = loading_bar_ref.offset_width();
|
||||
}
|
||||
let loading_bar_ref = loading_bar_ref
|
||||
.style("background-color", "var(--thaw-background-color-error)")
|
||||
.style("transition", "max-width 0.5s linear")
|
||||
.style("max-width", "100%");
|
||||
loading_bar_ref.on(ev::transitionend, move |_| {
|
||||
loading.set(false);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
comp_ref.load(LoadingBarRef {
|
||||
start,
|
||||
finish,
|
||||
error,
|
||||
});
|
||||
view! {
|
||||
<div class="thaw-loading-bar-container">
|
||||
<div class="thaw-loading-bar" ref=loading_bar_ref style=move || css_vars.get()>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue