1#[cfg(feature = "csr")]
6use leptos::ReadSignal;
7
8pub struct ReactiveStyle {
10 pub class_name: String,
11 pub base_css: String,
12}
13
14impl ReactiveStyle {
15 pub fn new(class_name: String, base_css: String) -> Self {
17 Self {
18 class_name,
19 base_css,
20 }
21 }
22
23 pub fn class(&self) -> &str {
25 &self.class_name
26 }
27}
28
29#[cfg(feature = "csr")]
31pub struct ReactiveStyleBuilder {
32 base_css: String,
33 dynamic_props: Vec<(String, Box<dyn Fn() -> String>)>,
34}
35
36#[cfg(feature = "csr")]
37impl ReactiveStyleBuilder {
38 pub fn new(base_css: &str) -> Self {
40 Self {
41 base_css: base_css.to_string(),
42 dynamic_props: Vec::new(),
43 }
44 }
45
46 pub fn property<T: 'static + Clone + std::fmt::Display>(
48 mut self,
49 property: &str,
50 signal: ReadSignal<T>,
51 ) -> Self {
52 let prop = property.to_string();
53 self.dynamic_props.push((
54 prop.clone(),
55 Box::new(move || format!("{}: {};", prop, signal.get())),
56 ));
57 self
58 }
59
60 pub fn build(self) -> String {
62 let mut css = self.base_css.clone();
63
64 for (_, prop_fn) in &self.dynamic_props {
65 css.push_str(&prop_fn());
66 css.push_str(" ");
67 }
68
69 css
70 }
71}
72
73#[cfg(feature = "csr")]
75pub fn create_reactive_style<T: 'static + Clone + std::fmt::Display>(
76 base_css: &str,
77 properties: Vec<(&str, ReadSignal<T>)>,
78) -> String {
79 let mut css = base_css.to_string();
80
81 for (prop, signal) in properties {
82 css.push_str(&format!("{}: {}; ", prop, signal.get()));
83 }
84
85 css
86}
87
88#[cfg(all(feature = "csr", target_arch = "wasm32"))]
90pub fn inject_reactive_style(class_name: &str, css: &str) {
91 use wasm_bindgen::prelude::*;
92 use web_sys::window;
93
94 if let Some(window) = window() {
95 if let Some(document) = window.document() {
96 let element_id = format!("rustyle-reactive-{}", class_name);
98 if let Ok(Some(existing)) = document.get_element_by_id(&element_id) {
99 existing.set_text_content(Some(css));
100 return;
101 }
102
103 if let Ok(style_element) = document.create_element("style") {
105 style_element.set_id(&element_id);
106 style_element.set_text_content(Some(css));
107
108 if let Some(head) = document.head() {
109 let _ = head.append_child(&style_element);
110 }
111 }
112 }
113 }
114}
115
116#[cfg(not(all(feature = "csr", target_arch = "wasm32")))]
118pub fn inject_reactive_style(_class_name: &str, _css: &str) {
119 }