impulse_thaw/config_provider/
mod.rs1use crate::Theme;
2use leptos::{context::Provider, prelude::*};
3use thaw_utils::{class_list, mount_dynamic_style, mount_style};
4
5#[component]
6pub fn ConfigProvider(
7 #[prop(optional, into)] class: MaybeProp<String>,
8 #[prop(optional, into)]
10 theme: Option<RwSignal<Theme>>,
11 #[prop(optional, into)]
13 theme_id: Option<String>,
14 #[prop(optional, into)]
16 dir: Option<RwSignal<ConfigDirection>>,
17 children: Children,
18) -> impl IntoView {
19 mount_style("config-provider", include_str!("./config-provider.css"));
20
21 let theme = theme.unwrap_or_else(|| RwSignal::new(Theme::light()));
22 let theme_id = theme_id.unwrap_or_else(|| uuid::Uuid::new_v4().to_string());
23 let id = StoredValue::new(theme_id);
24
25 mount_dynamic_style(id.get_value(), move || {
26 let mut css_vars = String::new();
27 theme.with(|theme| {
28 theme.common.write_css_vars(&mut css_vars);
29 theme.color.write_css_vars(&mut css_vars);
30 });
31 format!(
32 ".thaw-config-provider[data-thaw-id=\"{}\"]{{{css_vars}}}",
33 id.get_value()
34 )
35 });
36
37 #[cfg(not(feature = "ssr"))]
38 Owner::on_cleanup(move || {
39 if let Ok(Some(style)) =
40 document().query_selector(&format!("head style[data-thaw-id=\"{}\"]", id.get_value()))
41 {
42 style.remove();
43 }
44 });
45
46 let config_injection = ConfigInjection { theme, dir, id };
47
48 view! {
49 <Provider value=config_injection>
50 <div
51 class=class_list!["thaw-config-provider", class]
52 data-thaw-id=id.get_value()
53 dir=move || dir.map(move |dir| dir.get().as_str())
54 >
55 {children()}
56 </div>
57 </Provider>
58 }
59}
60
61#[derive(Clone)]
62pub struct ConfigInjection {
63 pub theme: RwSignal<Theme>,
64 pub dir: Option<RwSignal<ConfigDirection>>,
65 id: StoredValue<String>,
66}
67
68impl ConfigInjection {
69 pub fn id(&self) -> String {
70 self.id.get_value()
71 }
72
73 pub fn expect_context() -> Self {
74 expect_context()
75 }
76}
77
78#[derive(Debug, Clone, Copy, Default)]
79pub enum ConfigDirection {
80 Ltr,
81 Rtl,
82 #[default]
83 Auto,
84}
85
86impl ConfigDirection {
87 pub fn as_str(&self) -> &'static str {
88 match self {
89 ConfigDirection::Ltr => "ltr",
90 ConfigDirection::Rtl => "rtl",
91 ConfigDirection::Auto => "auto",
92 }
93 }
94}