feat(web): save theme to localStorage

This commit is contained in:
Kristofers Solo 2025-11-26 18:59:55 +02:00
parent 3dc7187910
commit 01eac0bc85
Signed by: kristoferssolo
GPG Key ID: 8687F2D3EEE6F0ED
3 changed files with 52 additions and 15 deletions

View File

@ -21,7 +21,12 @@ leptos_router = { version = "0.8", features = ["nightly"] }
strum.workspace = true
tokio = { version = "1", features = ["rt-multi-thread"], optional = true }
wasm-bindgen = { version = "=0.2.104", optional = true }
web-sys = { version = "0.3", features = ["Navigator", "Window", "Clipboard"] }
web-sys = { version = "0.3", features = [
"Navigator",
"Window",
"Clipboard",
"Storage",
] }
[features]
hydrate = ["leptos/hydrate", "dep:console_error_panic_hook", "dep:wasm-bindgen"]

View File

@ -1,7 +1,7 @@
use crate::pages::{
aes::AesPage, des::DesPage, footer::Footer, header::Header, home::Home, not_found::NotFound,
};
use leptos::{prelude::*, svg::view};
use leptos::prelude::*;
use leptos_meta::{MetaTags, Stylesheet, Title, provide_meta_context};
use leptos_router::{
StaticSegment,

View File

@ -4,24 +4,26 @@ use std::fmt::Display;
#[component]
pub fn Header() -> impl IntoView {
let (theme, set_theme) = signal(Theme::Dark);
let initial_theme = {
if let Ok(Some(storage)) = window().local_storage()
&& let Ok(Some(saved)) = storage.get_item("theme")
{
Theme::from_local_storage(&saved)
} else {
Theme::Dark
}
};
let (theme, set_theme) = signal(initial_theme);
let toggle_theme = move |_| {
set_theme.update(|t| *t = t.inverse());
if let Some(body) = document().body() {
let class_list = body.class_list();
match theme.get() {
Theme::Light => {
let _ = class_list.remove_1("dark-theme");
let _ = class_list.add_1("light-theme");
}
Theme::Dark => {
let _ = class_list.remove_1("light-theme");
let _ = class_list.add_1("dark-theme");
}
}
if let Ok(Some(storage)) = window().local_storage() {
let _ = storage.set_item("theme", theme.get().to_local_storage());
}
apply_theme(theme.get());
};
view! {
@ -57,6 +59,20 @@ impl Theme {
Self::Dark => Self::Light,
}
}
fn from_local_storage(value: &str) -> Self {
match value.trim().to_lowercase().as_str() {
"light" => Self::Light,
_ => Self::Dark,
}
}
const fn to_local_storage(self) -> &'static str {
match self {
Self::Light => "light",
Self::Dark => "dark",
}
}
}
impl Display for Theme {
@ -68,3 +84,19 @@ impl Display for Theme {
f.write_str(s)
}
}
fn apply_theme(theme: Theme) {
if let Some(body) = document().body() {
let class_list = body.class_list();
match theme {
Theme::Light => {
let _ = class_list.remove_1("dark-theme");
let _ = class_list.add_1("light-theme");
}
Theme::Dark => {
let _ = class_list.remove_1("light-theme");
let _ = class_list.add_1("dark-theme");
}
}
}
}