From 98dbdf8f86ee6992edd7b84a4850698a23eee16c Mon Sep 17 00:00:00 2001 From: Maccesch Date: Wed, 10 Apr 2024 22:51:01 +0100 Subject: [PATCH] added cookie support to use_color_mode --- CHANGELOG.md | 8 ++- Cargo.toml | 5 +- README.md | 2 +- docs/book/src/introduction.md | 2 +- examples/ssr/Cargo.toml | 2 +- examples/ssr/src/app.rs | 15 +++--- src/use_color_mode.rs | 95 +++++++++++++++++++++++++++++++++-- 7 files changed, 112 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6150878..a1dfddd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,12 +3,16 @@ 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). -## [Unreleased] - +## [0.10.7] - 2024-04-10 -### New Functions 🚀 +### New Function 🚀 - `sync_signal` +### Change 🔥 + +- `use_color_mode` now supports cookies. + ## [0.10.6] - 2024-04-02 ### Fixes 🍕 diff --git a/Cargo.toml b/Cargo.toml index 6016717..0f7bfd0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leptos-use" -version = "0.10.6" +version = "0.10.7" edition = "2021" authors = ["Marc-Stefan Cassola"] categories = ["gui", "web-programming"] @@ -131,8 +131,9 @@ features = [ ] [dev-dependencies] -rand = "0.8" getrandom = { version = "0.2", features = ["js"] } +leptos_meta = "0.6" +rand = "0.8" [features] actix = ["dep:actix-web", "dep:leptos_actix", "dep:http0_2"] diff --git a/README.md b/README.md index 95ab332..57516cc 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Crates.io SSR Docs & Demos - 76 Functions + 77 Functions


diff --git a/docs/book/src/introduction.md b/docs/book/src/introduction.md index 2796c28..f12ec1b 100644 --- a/docs/book/src/introduction.md +++ b/docs/book/src/introduction.md @@ -12,6 +12,6 @@ Crates.io SSR Docs & Demos - 76 Functions + 77 Functions

\ No newline at end of file diff --git a/examples/ssr/Cargo.toml b/examples/ssr/Cargo.toml index 6b657b8..d0b6e6a 100644 --- a/examples/ssr/Cargo.toml +++ b/examples/ssr/Cargo.toml @@ -21,7 +21,7 @@ simple_logger = "4" tokio = { version = "1", features = ["full"], optional = true } tower = { version = "0.4", optional = true } tower-http = { version = "0.5", features = ["fs"], optional = true } -wasm-bindgen = "0.2.88" +wasm-bindgen = "0.2.92" thiserror = "1.0.38" tracing = { version = "0.1.37", optional = true } http = "1" diff --git a/examples/ssr/src/app.rs b/examples/ssr/src/app.rs index fa44443..9b4e6f0 100644 --- a/examples/ssr/src/app.rs +++ b/examples/ssr/src/app.rs @@ -6,9 +6,10 @@ use leptos_router::*; use leptos_use::storage::use_local_storage; use leptos_use::utils::FromToStringCodec; use leptos_use::{ - use_color_mode, use_cookie_with_options, use_debounce_fn, use_event_listener, use_interval, - use_intl_number_format, use_preferred_dark, use_timestamp, use_window, ColorMode, - UseColorModeReturn, UseCookieOptions, UseIntervalReturn, UseIntlNumberFormatOptions, + use_color_mode_with_options, use_cookie_with_options, use_debounce_fn, use_event_listener, + use_interval, use_intl_number_format, use_preferred_dark, use_timestamp, use_window, ColorMode, + UseColorModeOptions, UseColorModeReturn, UseCookieOptions, UseIntervalReturn, + UseIntlNumberFormatOptions, }; #[component] @@ -65,7 +66,8 @@ fn HomePage() -> impl IntoView { ); debounced_fn(); - let UseColorModeReturn { mode, set_mode, .. } = use_color_mode(); + let UseColorModeReturn { mode, set_mode, .. } = + use_color_mode_with_options(UseColorModeOptions::default().cookie_enabled(true)); let timestamp = use_timestamp(); @@ -79,6 +81,8 @@ fn HomePage() -> impl IntoView { ); view! { + +

Leptos-Use SSR Example

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

@@ -98,12 +102,11 @@ fn HomePage() -> impl IntoView { #[component] pub fn LocalStorageTest() -> impl IntoView { let UseIntervalReturn { counter, .. } = use_interval(1000); - logging::log!("test log"); let (state, set_state, ..) = use_local_storage::("test-state"); view! {

{counter}

- Note: To work with SSR you have to add the `axum` or `actix` feature as described in [`use_cookie`]. +/// +/// ```rust +/// # use leptos::*; +/// # use leptos_meta::*; +/// # use leptos_use::{use_color_mode_with_options, UseColorModeOptions, UseColorModeReturn}; +/// # +/// # #[component] +/// # fn Demo() -> impl IntoView { +/// let UseColorModeReturn { mode, set_mode, .. } = use_color_mode_with_options( +/// UseColorModeOptions::default() +/// .cookie_enabled(true), +/// ); +/// +/// // This adds the color mode class to the `` element even with SSR +/// view! { +/// +/// } +/// # } +/// ``` +/// +/// For a working example please check out the [ssr example](https://github.com/Synphonyte/leptos-use/blob/main/examples/ssr/src/app.rs). +/// /// ## Server-Side Rendering /// -/// On the server this will by default return `ColorMode::Light`. Persistence is disabled, of course. +/// On the server this will by default return `ColorMode::Light`. Persistence with storage is disabled. +/// +/// If `cookie_enabled` is set to `true`, cookies will be used and if present this value will be used +/// on the server as well as on the client. Please note that you have to add the `axum` or `actix` +/// feature as described in [`use_cookie`]. /// /// ## See also /// /// * [`use_dark`] /// * [`use_preferred_dark`] /// * [`use_storage`] +/// * [`use_cookie`] pub fn use_color_mode() -> UseColorModeReturn { use_color_mode_with_options(UseColorModeOptions::default()) } @@ -115,6 +150,8 @@ where storage_key, storage, storage_enabled, + cookie_name, + cookie_enabled, emit_auto, transition_enabled, listen_to_storage_changes, @@ -146,8 +183,9 @@ where } } + let initial_stored_value = initial_value_from_url.clone().unwrap_or(initial_value); let (store, set_store) = get_store_signal( - initial_value_from_url.clone().unwrap_or(initial_value), + initial_stored_value.clone(), storage_signal, &storage_key, storage_enabled, @@ -155,6 +193,28 @@ where listen_to_storage_changes, ); + let (initial_stored_value, _) = initial_stored_value.into_signal(); + let initial_stored_value = initial_stored_value.get_untracked(); + let (cookie, set_cookie) = + get_cookie_signal(initial_stored_value.clone(), &cookie_name, cookie_enabled); + + let _ = sync_signal_with_options( + (cookie, set_cookie), + (store, set_store), + SyncSignalOptions::with_transforms( + { + let initial_stored_value = initial_stored_value.clone(); + + move |cookie: &Option| { + cookie + .clone() + .unwrap_or_else(|| initial_stored_value.clone()) + } + }, + move |store: &ColorMode| Some(store.clone()), + ), + ); + if let Some(initial_value_from_url) = initial_value_from_url { let value = initial_value_from_url.into_signal().0.get_untracked(); if initial_value_from_url_param_to_storage { @@ -267,6 +327,22 @@ pub enum ColorMode { Custom(String), } +fn get_cookie_signal( + initial_value: ColorMode, + cookie_name: &str, + cookie_enabled: bool, +) -> (Signal>, WriteSignal>) { + if cookie_enabled { + use_cookie_with_options::( + cookie_name, + UseCookieOptions::::default().default_value(Some(initial_value)), + ) + } else { + let (value, set_value) = create_signal(Some(initial_value)); + (value.into(), set_value) + } +} + fn get_store_signal( initial_value: MaybeRwSignal, storage_signal: Option>, @@ -383,10 +459,19 @@ where /// Defaults to `Local`. storage: StorageType, - /// If the color mode should be persisted. If `true` this required the + /// If the color mode should be persisted. /// Defaults to `true`. storage_enabled: bool, + /// Name of the cookie that should be used to persist the color mode. + /// Defaults to `"leptos-use-color-scheme"`. + #[builder(into)] + cookie_name: String, + + /// If the color mode should be persisted through a cookie. + /// Defaults to `false`. + cookie_enabled: bool, + /// Emit `auto` mode from state /// /// When set to `true`, preferred mode won't be translated into `light` or `dark`. @@ -422,6 +507,8 @@ impl Default for UseColorModeOptions<&'static str, web_sys::Element> { storage_key: "leptos-use-color-scheme".into(), storage: StorageType::default(), storage_enabled: true, + cookie_name: "leptos-use-color-scheme".into(), + cookie_enabled: false, emit_auto: false, transition_enabled: false, listen_to_storage_changes: true,