mirror of
https://github.com/adoyle0/leptos-use.git
synced 2025-01-23 09:09:21 -05:00
added cookie support to use_color_mode
This commit is contained in:
parent
ce2799c57d
commit
98dbdf8f86
7 changed files with 112 additions and 17 deletions
|
@ -3,12 +3,16 @@
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
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).
|
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`
|
- `sync_signal`
|
||||||
|
|
||||||
|
### Change 🔥
|
||||||
|
|
||||||
|
- `use_color_mode` now supports cookies.
|
||||||
|
|
||||||
## [0.10.6] - 2024-04-02
|
## [0.10.6] - 2024-04-02
|
||||||
|
|
||||||
### Fixes 🍕
|
### Fixes 🍕
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "leptos-use"
|
name = "leptos-use"
|
||||||
version = "0.10.6"
|
version = "0.10.7"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["Marc-Stefan Cassola"]
|
authors = ["Marc-Stefan Cassola"]
|
||||||
categories = ["gui", "web-programming"]
|
categories = ["gui", "web-programming"]
|
||||||
|
@ -131,8 +131,9 @@ features = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand = "0.8"
|
|
||||||
getrandom = { version = "0.2", features = ["js"] }
|
getrandom = { version = "0.2", features = ["js"] }
|
||||||
|
leptos_meta = "0.6"
|
||||||
|
rand = "0.8"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
actix = ["dep:actix-web", "dep:leptos_actix", "dep:http0_2"]
|
actix = ["dep:actix-web", "dep:leptos_actix", "dep:http0_2"]
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<a href="https://crates.io/crates/leptos-use"><img src="https://img.shields.io/crates/v/leptos-use.svg?label=&color=%232C1275" alt="Crates.io"/></a>
|
<a href="https://crates.io/crates/leptos-use"><img src="https://img.shields.io/crates/v/leptos-use.svg?label=&color=%232C1275" alt="Crates.io"/></a>
|
||||||
<a href="https://leptos-use.rs/server_side_rendering.html"><img src="https://img.shields.io/badge/-SSR-%236a214b" alt="SSR"></a>
|
<a href="https://leptos-use.rs/server_side_rendering.html"><img src="https://img.shields.io/badge/-SSR-%236a214b" alt="SSR"></a>
|
||||||
<a href="https://leptos-use.rs"><img src="https://img.shields.io/badge/-docs%20%26%20demos-%239A233F" alt="Docs & Demos"></a>
|
<a href="https://leptos-use.rs"><img src="https://img.shields.io/badge/-docs%20%26%20demos-%239A233F" alt="Docs & Demos"></a>
|
||||||
<a href="https://leptos-use.rs"><img src="https://img.shields.io/badge/-76%20functions-%23EF3939" alt="76 Functions" /></a>
|
<a href="https://leptos-use.rs"><img src="https://img.shields.io/badge/-77%20functions-%23EF3939" alt="77 Functions" /></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
|
@ -12,6 +12,6 @@
|
||||||
<a href="https://crates.io/crates/leptos-use"><img src="https://img.shields.io/crates/v/leptos-use.svg?label=&color=%232C1275" alt="Crates.io"/></a>
|
<a href="https://crates.io/crates/leptos-use"><img src="https://img.shields.io/crates/v/leptos-use.svg?label=&color=%232C1275" alt="Crates.io"/></a>
|
||||||
<a href="https://leptos-use.rs/server_side_rendering.html"><img src="https://img.shields.io/badge/-SSR-%236a214b" alt="SSR"></a>
|
<a href="https://leptos-use.rs/server_side_rendering.html"><img src="https://img.shields.io/badge/-SSR-%236a214b" alt="SSR"></a>
|
||||||
<a href="./get_started.html"><img src="https://img.shields.io/badge/-docs%20%26%20demos-%239A233F" alt="Docs & Demos"></a>
|
<a href="./get_started.html"><img src="https://img.shields.io/badge/-docs%20%26%20demos-%239A233F" alt="Docs & Demos"></a>
|
||||||
<a href="./functions.html"><img src="https://img.shields.io/badge/-76%20functions-%23EF3939" alt="76 Functions" /></a>
|
<a href="./functions.html"><img src="https://img.shields.io/badge/-77%20functions-%23EF3939" alt="77 Functions" /></a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
|
@ -21,7 +21,7 @@ simple_logger = "4"
|
||||||
tokio = { version = "1", features = ["full"], optional = true }
|
tokio = { version = "1", features = ["full"], optional = true }
|
||||||
tower = { version = "0.4", optional = true }
|
tower = { version = "0.4", optional = true }
|
||||||
tower-http = { version = "0.5", features = ["fs"], 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"
|
thiserror = "1.0.38"
|
||||||
tracing = { version = "0.1.37", optional = true }
|
tracing = { version = "0.1.37", optional = true }
|
||||||
http = "1"
|
http = "1"
|
||||||
|
|
|
@ -6,9 +6,10 @@ use leptos_router::*;
|
||||||
use leptos_use::storage::use_local_storage;
|
use leptos_use::storage::use_local_storage;
|
||||||
use leptos_use::utils::FromToStringCodec;
|
use leptos_use::utils::FromToStringCodec;
|
||||||
use leptos_use::{
|
use leptos_use::{
|
||||||
use_color_mode, use_cookie_with_options, use_debounce_fn, use_event_listener, use_interval,
|
use_color_mode_with_options, use_cookie_with_options, use_debounce_fn, use_event_listener,
|
||||||
use_intl_number_format, use_preferred_dark, use_timestamp, use_window, ColorMode,
|
use_interval, use_intl_number_format, use_preferred_dark, use_timestamp, use_window, ColorMode,
|
||||||
UseColorModeReturn, UseCookieOptions, UseIntervalReturn, UseIntlNumberFormatOptions,
|
UseColorModeOptions, UseColorModeReturn, UseCookieOptions, UseIntervalReturn,
|
||||||
|
UseIntlNumberFormatOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
|
@ -65,7 +66,8 @@ fn HomePage() -> impl IntoView {
|
||||||
);
|
);
|
||||||
debounced_fn();
|
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();
|
let timestamp = use_timestamp();
|
||||||
|
|
||||||
|
@ -79,6 +81,8 @@ fn HomePage() -> impl IntoView {
|
||||||
);
|
);
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
|
<Html class=move || mode.get().to_string()/>
|
||||||
|
|
||||||
<h1>Leptos-Use SSR Example</h1>
|
<h1>Leptos-Use SSR Example</h1>
|
||||||
<button on:click=on_click>Click Me: {count}</button>
|
<button on:click=on_click>Click Me: {count}</button>
|
||||||
<p>Locale zh-Hans-CN-u-nu-hanidec: {zh_count}</p>
|
<p>Locale zh-Hans-CN-u-nu-hanidec: {zh_count}</p>
|
||||||
|
@ -98,7 +102,6 @@ fn HomePage() -> impl IntoView {
|
||||||
#[component]
|
#[component]
|
||||||
pub fn LocalStorageTest() -> impl IntoView {
|
pub fn LocalStorageTest() -> impl IntoView {
|
||||||
let UseIntervalReturn { counter, .. } = use_interval(1000);
|
let UseIntervalReturn { counter, .. } = use_interval(1000);
|
||||||
logging::log!("test log");
|
|
||||||
let (state, set_state, ..) = use_local_storage::<String, FromToStringCodec>("test-state");
|
let (state, set_state, ..) = use_local_storage::<String, FromToStringCodec>("test-state");
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
|
|
|
@ -2,8 +2,11 @@ use crate::core::url;
|
||||||
use crate::core::StorageType;
|
use crate::core::StorageType;
|
||||||
use crate::core::{ElementMaybeSignal, MaybeRwSignal};
|
use crate::core::{ElementMaybeSignal, MaybeRwSignal};
|
||||||
use crate::storage::{use_storage_with_options, UseStorageOptions};
|
use crate::storage::{use_storage_with_options, UseStorageOptions};
|
||||||
use crate::use_preferred_dark;
|
|
||||||
use crate::utils::FromToStringCodec;
|
use crate::utils::FromToStringCodec;
|
||||||
|
use crate::{
|
||||||
|
sync_signal_with_options, use_cookie_with_options, use_preferred_dark, SyncSignalOptions,
|
||||||
|
UseCookieOptions,
|
||||||
|
};
|
||||||
use default_struct_builder::DefaultBuilder;
|
use default_struct_builder::DefaultBuilder;
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
@ -83,15 +86,47 @@ use wasm_bindgen::JsCast;
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// ### Cookies
|
||||||
|
///
|
||||||
|
/// To persist color mode in a cookie, use `use_cookie_with_options` and specify `.cookie_enabled(true)`.
|
||||||
|
///
|
||||||
|
/// > 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 `<html>` element even with SSR
|
||||||
|
/// view! {
|
||||||
|
/// <Html class=move || mode.get().to_string()/>
|
||||||
|
/// }
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// 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
|
/// ## 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
|
/// ## See also
|
||||||
///
|
///
|
||||||
/// * [`use_dark`]
|
/// * [`use_dark`]
|
||||||
/// * [`use_preferred_dark`]
|
/// * [`use_preferred_dark`]
|
||||||
/// * [`use_storage`]
|
/// * [`use_storage`]
|
||||||
|
/// * [`use_cookie`]
|
||||||
pub fn use_color_mode() -> UseColorModeReturn {
|
pub fn use_color_mode() -> UseColorModeReturn {
|
||||||
use_color_mode_with_options(UseColorModeOptions::default())
|
use_color_mode_with_options(UseColorModeOptions::default())
|
||||||
}
|
}
|
||||||
|
@ -115,6 +150,8 @@ where
|
||||||
storage_key,
|
storage_key,
|
||||||
storage,
|
storage,
|
||||||
storage_enabled,
|
storage_enabled,
|
||||||
|
cookie_name,
|
||||||
|
cookie_enabled,
|
||||||
emit_auto,
|
emit_auto,
|
||||||
transition_enabled,
|
transition_enabled,
|
||||||
listen_to_storage_changes,
|
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(
|
let (store, set_store) = get_store_signal(
|
||||||
initial_value_from_url.clone().unwrap_or(initial_value),
|
initial_stored_value.clone(),
|
||||||
storage_signal,
|
storage_signal,
|
||||||
&storage_key,
|
&storage_key,
|
||||||
storage_enabled,
|
storage_enabled,
|
||||||
|
@ -155,6 +193,28 @@ where
|
||||||
listen_to_storage_changes,
|
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<ColorMode>| {
|
||||||
|
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 {
|
if let Some(initial_value_from_url) = initial_value_from_url {
|
||||||
let value = initial_value_from_url.into_signal().0.get_untracked();
|
let value = initial_value_from_url.into_signal().0.get_untracked();
|
||||||
if initial_value_from_url_param_to_storage {
|
if initial_value_from_url_param_to_storage {
|
||||||
|
@ -267,6 +327,22 @@ pub enum ColorMode {
|
||||||
Custom(String),
|
Custom(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_cookie_signal(
|
||||||
|
initial_value: ColorMode,
|
||||||
|
cookie_name: &str,
|
||||||
|
cookie_enabled: bool,
|
||||||
|
) -> (Signal<Option<ColorMode>>, WriteSignal<Option<ColorMode>>) {
|
||||||
|
if cookie_enabled {
|
||||||
|
use_cookie_with_options::<ColorMode, FromToStringCodec>(
|
||||||
|
cookie_name,
|
||||||
|
UseCookieOptions::<ColorMode, _>::default().default_value(Some(initial_value)),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
let (value, set_value) = create_signal(Some(initial_value));
|
||||||
|
(value.into(), set_value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_store_signal(
|
fn get_store_signal(
|
||||||
initial_value: MaybeRwSignal<ColorMode>,
|
initial_value: MaybeRwSignal<ColorMode>,
|
||||||
storage_signal: Option<RwSignal<ColorMode>>,
|
storage_signal: Option<RwSignal<ColorMode>>,
|
||||||
|
@ -383,10 +459,19 @@ where
|
||||||
/// Defaults to `Local`.
|
/// Defaults to `Local`.
|
||||||
storage: StorageType,
|
storage: StorageType,
|
||||||
|
|
||||||
/// If the color mode should be persisted. If `true` this required the
|
/// If the color mode should be persisted.
|
||||||
/// Defaults to `true`.
|
/// Defaults to `true`.
|
||||||
storage_enabled: bool,
|
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
|
/// Emit `auto` mode from state
|
||||||
///
|
///
|
||||||
/// When set to `true`, preferred mode won't be translated into `light` or `dark`.
|
/// 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_key: "leptos-use-color-scheme".into(),
|
||||||
storage: StorageType::default(),
|
storage: StorageType::default(),
|
||||||
storage_enabled: true,
|
storage_enabled: true,
|
||||||
|
cookie_name: "leptos-use-color-scheme".into(),
|
||||||
|
cookie_enabled: false,
|
||||||
emit_auto: false,
|
emit_auto: false,
|
||||||
transition_enabled: false,
|
transition_enabled: false,
|
||||||
listen_to_storage_changes: true,
|
listen_to_storage_changes: true,
|
||||||
|
|
Loading…
Add table
Reference in a new issue