diff --git a/CHANGELOG.md b/CHANGELOG.md index be42cc6..82633c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.8.1] - 2023-10-28 + +### Fixes 🍕 + +- Using strings for `ElementMaybeSignal` and `ElementsMaybeSignal` is now SSR safe. + - This fixes specifically `use_color_mode` to work on the server. + ## [0.8.0] - 2023-10-24 ### New Functions 🚀 diff --git a/Cargo.toml b/Cargo.toml index 9b19c02..5c557e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leptos-use" -version = "0.8.0" +version = "0.8.1" edition = "2021" authors = ["Marc-Stefan Cassola"] categories = ["gui", "web-programming"] diff --git a/examples/ssr/src/app.rs b/examples/ssr/src/app.rs index 29e62fc..20f3b91 100644 --- a/examples/ssr/src/app.rs +++ b/examples/ssr/src/app.rs @@ -5,8 +5,8 @@ use leptos_meta::*; use leptos_router::*; use leptos_use::storage::use_local_storage; use leptos_use::{ - use_debounce_fn, use_event_listener, use_intl_number_format, use_window, - UseIntlNumberFormatOptions, + use_color_mode, use_debounce_fn, use_event_listener, use_intl_number_format, use_window, + ColorMode, UseColorModeReturn, UseIntlNumberFormatOptions, }; #[component] @@ -63,11 +63,17 @@ fn HomePage() -> impl IntoView { ); debounced_fn(); + let UseColorModeReturn { mode, set_mode, .. } = use_color_mode(); + view! {

Leptos-Use SSR Example

Locale zh-Hans-CN-u-nu-hanidec: {zh_count}

Press any key: {key}

Debounced called: {debounce_value}

+

Color mode: {move || format!("{:?}", mode.get())}

+ + + } } diff --git a/examples/ssr/style/main.scss b/examples/ssr/style/main.scss index e4538e1..24ed267 100644 --- a/examples/ssr/style/main.scss +++ b/examples/ssr/style/main.scss @@ -1,4 +1,9 @@ body { - font-family: sans-serif; - text-align: center; + font-family: sans-serif; + text-align: center; +} + +.dark { + background-color: black; + color: white; } \ No newline at end of file diff --git a/src/core/element_maybe_signal.rs b/src/core/element_maybe_signal.rs index 9d972a7..20dd423 100644 --- a/src/core/element_maybe_signal.rs +++ b/src/core/element_maybe_signal.rs @@ -1,4 +1,5 @@ use crate::{UseDocument, UseWindow}; +use cfg_if::cfg_if; use leptos::html::ElementDescriptor; use leptos::*; use std::marker::PhantomData; @@ -177,7 +178,11 @@ where E: From + 'static, { fn from(target: &'a str) -> Self { - Self::Static(document().query_selector(target).unwrap_or_default()) + cfg_if! { if #[cfg(feature = "ssr")] { + Self::Static(None) + } else { + Self::Static(document().query_selector(target).unwrap_or_default()) + }} } } @@ -186,7 +191,7 @@ where E: From + 'static, { fn from(target: String) -> Self { - Self::Static(document().query_selector(&target).unwrap_or_default()) + Self::from(target.as_str()) } } @@ -195,10 +200,14 @@ where E: From + 'static, { fn from(signal: Signal) -> Self { - Self::Dynamic( - create_memo(move |_| document().query_selector(&signal.get()).unwrap_or_default()) - .into(), - ) + cfg_if! { if #[cfg(feature = "ssr")] { + Self::Dynamic(Signal::derive(|| None)) + } else { + Self::Dynamic( + create_memo(move |_| document().query_selector(&signal.get()).unwrap_or_default()) + .into(), + ) + }} } } diff --git a/src/core/elements_maybe_signal.rs b/src/core/elements_maybe_signal.rs index 8f5eff3..2770d48 100644 --- a/src/core/elements_maybe_signal.rs +++ b/src/core/elements_maybe_signal.rs @@ -1,5 +1,6 @@ use crate::core::ElementMaybeSignal; use crate::{UseDocument, UseWindow}; +use cfg_if::cfg_if; use leptos::html::ElementDescriptor; use leptos::*; use std::marker::PhantomData; @@ -178,17 +179,31 @@ where E: From + 'static, { fn from(target: &'a str) -> Self { - if let Ok(node_list) = document().query_selector_all(target) { - let mut list = Vec::with_capacity(node_list.length() as usize); - for i in 0..node_list.length() { - let node = node_list.get(i).expect("checked the range"); - list.push(Some(node)); - } + cfg_if! { if #[cfg(feature = "ssr")] { + if let Ok(node_list) = document().query_selector_all(target) { + let mut list = Vec::with_capacity(node_list.length() as usize); + for i in 0..node_list.length() { + let node = node_list.get(i).expect("checked the range"); + list.push(Some(node)); + } - Self::Static(list) + Self::Static(list) + } else { + Self::Static(vec![]) + } } else { + let _ = target; Self::Static(vec![]) - } + }} + } +} + +impl From for ElementsMaybeSignal +where + E: From + 'static, +{ + fn from(target: String) -> Self { + Self::from(target.as_str()) } } @@ -197,21 +212,26 @@ where E: From + 'static, { fn from(signal: Signal) -> Self { - Self::Dynamic( - create_memo(move |_| { - if let Ok(node_list) = document().query_selector_all(&signal.get()) { - let mut list = Vec::with_capacity(node_list.length() as usize); - for i in 0..node_list.length() { - let node = node_list.get(i).expect("checked the range"); - list.push(Some(node)); + cfg_if! { if #[cfg(feature = "ssr")] { + Self::Dynamic( + create_memo(move |_| { + if let Ok(node_list) = document().query_selector_all(&signal.get()) { + let mut list = Vec::with_capacity(node_list.length() as usize); + for i in 0..node_list.length() { + let node = node_list.get(i).expect("checked the range"); + list.push(Some(node)); + } + list + } else { + vec![] } - list - } else { - vec![] - } - }) - .into(), - ) + }) + .into(), + ) + } else { + let _ = signal; + Self::Dynamic(Signal::derive(Vec::new)) + }} } } diff --git a/src/on_click_outside.rs b/src/on_click_outside.rs index 1ac1cca..3d1a542 100644 --- a/src/on_click_outside.rs +++ b/src/on_click_outside.rs @@ -125,7 +125,7 @@ where }) }; - let target = (target).into(); + let target = target.into(); let listener = { let should_listen = Rc::clone(&should_listen); diff --git a/src/use_color_mode.rs b/src/use_color_mode.rs index 3bffcb5..1c65314 100644 --- a/src/use_color_mode.rs +++ b/src/use_color_mode.rs @@ -160,7 +160,7 @@ where } }); - let target = (target).into(); + let target = target.into(); let update_html_attrs = { move |target: ElementMaybeSignal, diff --git a/src/use_css_var.rs b/src/use_css_var.rs index 41f1d04..0b0a803 100644 --- a/src/use_css_var.rs +++ b/src/use_css_var.rs @@ -105,7 +105,7 @@ where let (variable, set_variable) = create_signal(initial_value.clone()); cfg_if! { if #[cfg(not(feature = "ssr"))] { - let el_signal = (target).into(); + let el_signal = target.into(); let prop = prop.into(); let update_css_var = { diff --git a/src/use_draggable.rs b/src/use_draggable.rs index 5954243..c44aef8 100644 --- a/src/use_draggable.rs +++ b/src/use_draggable.rs @@ -87,7 +87,7 @@ where .. } = options; - let target = (target).into(); + let target = target.into(); let dragging_handle = if let Some(handle) = handle { let handle = (handle).into(); diff --git a/src/use_event_listener.rs b/src/use_event_listener.rs index e8c218e..ec7c2a8 100644 --- a/src/use_event_listener.rs +++ b/src/use_event_listener.rs @@ -132,7 +132,7 @@ where let event_name = event.name(); - let signal = (target).into(); + let signal = target.into(); let prev_element = Rc::new(RefCell::new(None::)); diff --git a/src/use_intersection_observer.rs b/src/use_intersection_observer.rs index fda59bf..78c43fb 100644 --- a/src/use_intersection_observer.rs +++ b/src/use_intersection_observer.rs @@ -124,7 +124,7 @@ where } }; - let targets = (target).into(); + let targets = target.into(); let root = root.map(|root| (root).into()); let stop_watch = { diff --git a/src/use_mutation_observer.rs b/src/use_mutation_observer.rs index f518000..91f185a 100644 --- a/src/use_mutation_observer.rs +++ b/src/use_mutation_observer.rs @@ -109,7 +109,7 @@ where } }; - let targets = (target).into(); + let targets = target.into(); let stop_watch = { let cleanup = cleanup.clone(); diff --git a/src/use_resize_observer.rs b/src/use_resize_observer.rs index 1c61081..2e35e85 100644 --- a/src/use_resize_observer.rs +++ b/src/use_resize_observer.rs @@ -114,7 +114,7 @@ where } }; - let targets = (target).into(); + let targets = target.into(); let stop_watch = { let cleanup = cleanup.clone();