Add initial_value_from_url_param option to UseColorModeOptions

This commit is contained in:
Álvaro Mondéjar Rubio 2024-02-11 01:03:12 +01:00
parent 710419404c
commit 2c36bf0ff6
5 changed files with 61 additions and 4 deletions

View file

@ -38,6 +38,7 @@ serde_json = { version = "1", optional = true }
thiserror = "1"
wasm-bindgen = "0.2.88"
wasm-bindgen-futures = "0.4"
log = "0.4"
[dependencies.web-sys]
version = "0.3"
@ -70,6 +71,7 @@ features = [
"IntersectionObserver",
"IntersectionObserverInit",
"IntersectionObserverEntry",
"Location",
"MediaDevices",
"MediaQueryList",
"MediaStream",
@ -112,6 +114,8 @@ features = [
"Touch",
"TouchEvent",
"TouchList",
"Url",
"UrlSearchParams",
"VisibilityState",
"WebSocket",
"WebTransport",

View file

@ -9,6 +9,7 @@ mod position;
mod size;
mod ssr_safe_method;
mod storage;
pub(crate) mod url;
pub use connection_ready_state::*;
pub(crate) use datetime::*;

20
src/core/url.rs Normal file
View file

@ -0,0 +1,20 @@
use leptos::window;
fn get() -> web_sys::Url {
web_sys::Url::new(
&window()
.location()
.href()
.expect("Failed to get location.href from the browser"),
)
.expect("Failed to parse location.href from the browser")
}
pub mod params {
use super::get as current_url;
/// Get a URL param value from the URL of the browser
pub fn get(k: &str) -> Option<String> {
current_url().search_params().get(k)
}
}

View file

@ -67,7 +67,7 @@ const INTERNAL_STORAGE_EVENT: &str = "leptos-use-storage";
/// pub greeting: String,
/// }
///
/// // Default can be used to implement intial or deleted values.
/// // Default can be used to implement initial or deleted values.
/// // You can also use a signal via UseStorageOptions::default_value`
/// impl Default for MyState {
/// fn default() -> Self {

View file

@ -1,3 +1,4 @@
use crate::core::url;
use crate::core::StorageType;
use crate::core::{ElementMaybeSignal, MaybeRwSignal};
use crate::storage::{use_storage_with_options, UseStorageOptions};
@ -106,6 +107,7 @@ where
target,
attribute,
initial_value,
initial_value_from_url_param,
on_changed,
storage_signal,
custom_modes,
@ -136,13 +138,26 @@ where
}
});
let initial_value_from_url = match initial_value_from_url_param {
Some(param) => match url::params::get(&param) {
Some(value) => match ColorMode::from_str(&value) {
Ok(mode) => Some(MaybeRwSignal::Static(mode)),
Err(_) => None,
},
None => None,
},
None => None,
};
let update_previous_value = initial_value_from_url.is_some();
let (store, set_store) = get_store_signal(
initial_value,
initial_value_from_url.unwrap_or(initial_value),
storage_signal,
&storage_key,
storage_enabled,
storage,
listen_to_storage_changes,
update_previous_value,
);
let state = Signal::derive(move || {
@ -255,22 +270,34 @@ fn get_store_signal(
storage_enabled: bool,
storage: StorageType,
listen_to_storage_changes: bool,
update_previous_value: bool,
) -> (Signal<ColorMode>, WriteSignal<ColorMode>) {
if let Some(storage_signal) = storage_signal {
let initial_value_copy = initial_value.clone();
let (store, set_store) = if let Some(storage_signal) = storage_signal {
let (store, set_store) = storage_signal.split();
(store.into(), set_store)
} else if storage_enabled {
let (store, set_store, _) = use_storage_with_options::<ColorMode, FromToStringCodec>(
let (store, set_store, remove) = use_storage_with_options::<ColorMode, FromToStringCodec>(
storage,
storage_key,
UseStorageOptions::default()
.listen_to_storage_changes(listen_to_storage_changes)
.initial_value(initial_value),
);
if update_previous_value {
remove();
}
(store, set_store)
} else {
initial_value.into_signal()
};
if update_previous_value {
set_store.set(initial_value_copy.into_signal().0.get_untracked());
}
(store, set_store)
}
impl Display for ColorMode {
@ -330,6 +357,10 @@ where
#[builder(into)]
initial_value: MaybeRwSignal<ColorMode>,
/// Discover the initial value of the color mode from an URL parameter. Defaults to `None`.
#[builder(into)]
initial_value_from_url_param: Option<String>,
/// Custom modes that you plan to use as `ColorMode::Custom(x)`. Defaults to `vec![]`.
custom_modes: Vec<String>,
@ -386,6 +417,7 @@ impl Default for UseColorModeOptions<&'static str, web_sys::Element> {
target: "html",
attribute: "class".into(),
initial_value: ColorMode::Auto.into(),
initial_value_from_url_param: None,
custom_modes: vec![],
on_changed: Rc::new(move |mode, default_handler| (default_handler)(mode)),
storage_signal: None,