From 643a54185cf9a046d298d64add5f1aa6e33f1637 Mon Sep 17 00:00:00 2001 From: luoxiao Date: Thu, 23 May 2024 17:44:00 +0800 Subject: [PATCH] feat: ConfigProvider CSSVars --- thaw/src/config_provider/mod.rs | 21 ++++++------- thaw_utils/src/dom/mod.rs | 2 +- thaw_utils/src/dom/mount_style.rs | 50 +++++++++++++++++++++++++++++-- thaw_utils/src/lib.rs | 2 +- 4 files changed, 60 insertions(+), 15 deletions(-) diff --git a/thaw/src/config_provider/mod.rs b/thaw/src/config_provider/mod.rs index 2f1086d..44bf67d 100644 --- a/thaw/src/config_provider/mod.rs +++ b/thaw/src/config_provider/mod.rs @@ -1,6 +1,6 @@ use crate::Theme; use leptos::*; -use thaw_utils::mount_style; +use thaw_utils::{mount_dynamic_style, mount_style}; #[component] pub fn ConfigProvider( @@ -15,25 +15,26 @@ pub fn ConfigProvider( mount_style("config-provider", include_str!("./config-provider.css")); let theme = theme.unwrap_or_else(|| RwSignal::new(Theme::light())); - let css_vars = Memo::new(move |_| { + let id = StoredValue::new(uuid::Uuid::new_v4().to_string()); + mount_dynamic_style(id.get_value(), move || { let mut css_vars = String::new(); theme.with(|theme| { theme.common.write_css_vars(&mut css_vars); theme.color.write_css_vars(&mut css_vars); }); - css_vars + format!( + ".thaw-config-provider[data-thaw-id=\"{}\"]{{{css_vars}}}", + id.get_value() + ) }); - let config_injection = ConfigInjection { - theme, - dir: dir.clone(), - }; + let config_injection = ConfigInjection { theme, dir }; view! {
{children()} @@ -44,8 +45,8 @@ pub fn ConfigProvider( #[derive(Clone)] pub struct ConfigInjection { - theme: RwSignal, - dir: RwSignal>, + pub theme: RwSignal, + pub dir: RwSignal>, } #[derive(Clone)] diff --git a/thaw_utils/src/dom/mod.rs b/thaw_utils/src/dom/mod.rs index d1fc0b6..c5e3111 100644 --- a/thaw_utils/src/dom/mod.rs +++ b/thaw_utils/src/dom/mod.rs @@ -2,4 +2,4 @@ mod get_scroll_parent; mod mount_style; pub use get_scroll_parent::get_scroll_parent; -pub use mount_style::mount_style; +pub use mount_style::{mount_dynamic_style, mount_style}; diff --git a/thaw_utils/src/dom/mount_style.rs b/thaw_utils/src/dom/mount_style.rs index b57571e..461b972 100644 --- a/thaw_utils/src/dom/mount_style.rs +++ b/thaw_utils/src/dom/mount_style.rs @@ -6,13 +6,13 @@ pub fn mount_style(id: &str, content: &'static str) { use leptos::html::style; use leptos_meta::use_head; let meta = use_head(); - let style_el = style().attr("csr-id", format!("thaw-{id}")).child(content); + let style_el = style().attr("data-thaw-id", id).child(content); meta.tags.register(format!("leptos-thaw-{id}").into(), style_el.into_any()); } else { use leptos::document; let head = document().head().expect("head no exist"); let style = head - .query_selector(&format!("style[csr-id=\"thaw-{id}\"]")) + .query_selector(&format!("style[data-thaw-id=\"{id}\"]")) .expect("query style element error"); #[cfg(feature = "hydrate")] @@ -25,9 +25,53 @@ pub fn mount_style(id: &str, content: &'static str) { let style = document() .create_element("style") .expect("create style element error"); - _ = style.set_attribute("csr-id", &format!("thaw-{id}")); + _ = style.set_attribute("data-thaw-id", id); style.set_text_content(Some(content)); _ = head.prepend_with_node_1(&style); } } } + +pub fn mount_dynamic_style String + 'static>(id: String, f: T) { + cfg_if! { + if #[cfg(feature = "ssr")] { + use leptos::html::style; + use leptos_meta::use_head; + let meta = use_head(); + let content = leptos::untrack(|| f()); + let style_el = style().attr("data-thaw-id", id).child(content); + meta.tags.register(format!("leptos-thaw-{id}").into(), style_el.into_any()); + } else { + use leptos::document; + let head = document().head().expect("head no exist"); + let style = head + .query_selector(&format!("style[data-thaw-id=\"{id}\"]")) + .expect("query style element error"); + + #[cfg(feature = "hydrate")] + let _ = leptos::leptos_dom::HydrationCtx::id(); + + + leptos::Effect::new_isomorphic(move |prev: Option>| { + let content = f(); + + if let Some(style) = style.as_ref() { + style.set_text_content(Some(&content)); + None + } else if let Some(style) = prev.flatten() { + style.set_text_content(Some(&content)); + Some(style) + } else { + let style = document() + .create_element("style") + .expect("create style element error"); + _ = style.set_attribute("data-thaw-id", &id); + style.set_text_content(Some(&content)); + _ = head.prepend_with_node_1(&style); + + Some(style) + } + }); + } + } +} diff --git a/thaw_utils/src/lib.rs b/thaw_utils/src/lib.rs index 2b6d071..3a80f60 100644 --- a/thaw_utils/src/lib.rs +++ b/thaw_utils/src/lib.rs @@ -7,7 +7,7 @@ mod signals; mod throttle; mod time; -pub use dom::{get_scroll_parent, mount_style}; +pub use dom::{get_scroll_parent, mount_dynamic_style, mount_style}; pub use event_listener::{ add_event_listener, add_event_listener_with_bool, EventListenerHandle, IntoEventTarget, };