fix: LoadingBar error

This commit is contained in:
luoxiao 2024-07-18 23:05:44 +08:00
parent 5dc62c8244
commit 769f69c069

View file

@ -1,6 +1,9 @@
mod loading_bar_provider; mod loading_bar_provider;
use std::sync::Arc;
pub use loading_bar_provider::*; pub use loading_bar_provider::*;
use tachys::renderer::DomRenderer;
use crate::ConfigInjection; use crate::ConfigInjection;
use leptos::{html, prelude::*}; use leptos::{html, prelude::*};
@ -8,70 +11,85 @@ use thaw_utils::{mount_style, ComponentRef};
#[derive(Clone)] #[derive(Clone)]
pub(crate) struct LoadingBarRef { pub(crate) struct LoadingBarRef {
start: Callback<()>, start: Arc<dyn Fn() + Send + Sync + 'static>,
finish: Callback<()>, finish: Arc<dyn Fn() + Send + Sync + 'static>,
error: Callback<()>, error: Arc<dyn Fn() + Send + Sync + 'static>,
} }
impl LoadingBarRef { impl LoadingBarRef {
#[inline]
pub fn start(&self) { pub fn start(&self) {
self.start.call(()); (self.start)();
} }
#[inline]
pub fn finish(&self) { pub fn finish(&self) {
self.finish.call(()); (self.finish)();
} }
#[inline]
pub fn error(&self) { pub fn error(&self) {
self.error.call(()); (self.error)();
} }
} }
#[component] #[component]
fn LoadingBar(#[prop(optional)] comp_ref: ComponentRef<LoadingBarRef>) -> impl IntoView { fn LoadingBar(#[prop(optional)] comp_ref: ComponentRef<LoadingBarRef>) -> impl IntoView {
mount_style("loading-bar", include_str!("./loading-bar.css")); mount_style("loading-bar", include_str!("./loading-bar.css"));
let config_provider = ConfigInjection::use_(); let config_provider = ConfigInjection::expect_context();
let container_ref = NodeRef::<html::Div>::new();
let loading_bar_ref = NodeRef::<html::Div>::new(); let loading_bar_ref = NodeRef::<html::Div>::new();
let loading = RwSignal::new(false);
let start = Callback::new(move |_| { let start = Arc::new(move || {
loading.set(true); let Some(container_el) = container_ref.get_untracked() else {
if let Some(loading_bar_ref) = loading_bar_ref.get_untracked() { return;
loading_bar_ref.style(("background-color", "var(--colorStatusSuccessForeground1)")); };
loading_bar_ref.style(("transition", "none")); let Some(loading_bar_el) = loading_bar_ref.get_untracked() else {
loading_bar_ref.style(("max-width", "0")); return;
_ = loading_bar_ref.offset_width(); };
loading_bar_ref.style(("transition", "max-width 4s linear")); let _ = container_el.set_attribute("style", "");
loading_bar_ref.style(("max-width", "80%")); loading_bar_el.style(("background-color", "var(--colorStatusSuccessForeground1)"));
} loading_bar_el.style(("transition", "none"));
loading_bar_el.style(("max-width", "0"));
let _ = loading_bar_el.offset_width();
loading_bar_el.style(("transition", "max-width 4s linear"));
loading_bar_el.style(("max-width", "80%"));
}); });
let is_on_transitionend = StoredValue::new(false);
let on_transitionend = move |_| { let on_transitionend = move |_| {
if is_on_transitionend.get_value() { let Some(container_el) = container_ref.get_untracked() else {
is_on_transitionend.set_value(false); return;
loading.set(false); };
let Some(loading_bar_el) = loading_bar_ref.get_untracked() else {
return;
};
if let Ok(max_width) = Dom::style(&loading_bar_el).get_property_value("max-width") {
if max_width == "100%" {
let _ = container_el.set_attribute("style", "display: none");
}
} }
}; };
let finish = Callback::new(move |_| { let finish = Arc::new(move || {
if let Some(loading_bar_ref) = loading_bar_ref.get_untracked() { let Some(loading_bar_el) = loading_bar_ref.get_untracked() else {
loading_bar_ref.style(("background-color", "var(--colorStatusSuccessForeground1)")); return;
loading_bar_ref.style(("transition", "max-width 0.5s linear")); };
loading_bar_ref.style(("max-width", "100%")); loading_bar_el.style(("background-color", "var(--colorStatusSuccessForeground1)"));
is_on_transitionend.set_value(true); loading_bar_el.style(("transition", "max-width 0.5s linear"));
} loading_bar_el.style(("max-width", "100%"));
}); });
let error = Callback::new(move |_| { let error = Arc::new(move || {
if let Some(loading_bar_ref) = loading_bar_ref.get_untracked() { let Some(container_el) = container_ref.get_untracked() else {
if !loading.get() { return;
loading.set(true); };
let loading_bar_ref = loading_bar_ref.clone(); let Some(loading_bar_el) = loading_bar_ref.get_untracked() else {
loading_bar_ref.style(("transition", "none")); return;
loading_bar_ref.style(("max-width", "0")); };
_ = loading_bar_ref.offset_width(); if container_el.get_attribute("style") != Some(String::new()) {
} let _ = container_el.set_attribute("style", "");
loading_bar_ref.style(("background-color", "var(--colorStatusDangerForeground1)")); loading_bar_el.style(("transition", "none"));
loading_bar_ref.style(("transition", "max-width 0.5s linear")); loading_bar_el.style(("max-width", "0"));
loading_bar_ref.style(("max-width", "100%")); let _ = loading_bar_el.offset_width();
is_on_transitionend.set_value(true);
} }
loading_bar_el.style(("background-color", "var(--colorStatusDangerForeground1)"));
loading_bar_el.style(("transition", "max-width 0.5s linear"));
loading_bar_el.style(("max-width", "100%"));
}); });
comp_ref.load(LoadingBarRef { comp_ref.load(LoadingBarRef {
@ -83,7 +101,8 @@ fn LoadingBar(#[prop(optional)] comp_ref: ComponentRef<LoadingBarRef>) -> impl I
<div <div
class="thaw-config-provider thaw-loading-bar-container" class="thaw-config-provider thaw-loading-bar-container"
data-thaw-id=config_provider.id().clone() data-thaw-id=config_provider.id().clone()
style=move || if loading.get() { "" } else { "display: none;" } style="display: none"
node_ref=container_ref
> >
<div <div
class="thaw-loading-bar" class="thaw-loading-bar"