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();