Darkmode implemented

There is now a darkmode button
This commit is contained in:
2026-05-28 17:26:56 +02:00
parent 6e836d9260
commit b9354f77b6
6 changed files with 151 additions and 7 deletions

65
frontend/src/dark_mode.rs Normal file
View File

@@ -0,0 +1,65 @@
use gloo_storage::{LocalStorage, Storage};
use web_sys::window;
use yew::prelude::*;
#[function_component(DarkModeToggle)]
pub fn dark_mode_toggle() -> Html {
// 1. Initialize state from LocalStorage or system preference
let is_dark = use_state(|| {
LocalStorage::get::<bool>("dark-mode").unwrap_or_else(|_| {
// Fallback to system preference if not set
window()
.and_then(|w| w.match_media("(prefers-color-scheme: dark)").ok().flatten())
.map(|m| m.matches())
.unwrap_or(false)
})
});
// 2. Synchronize the class on the body when the state changes
{
let is_dark = is_dark.clone();
use_effect_with(is_dark, |is_dark| {
if let Some(win) = window() {
if let Some(doc) = win.document() {
if let Some(body) = doc.body() {
if **is_dark {
let _ = body.class_list().add_1("theme-dark");
let _ = body.class_list().remove_1("theme-light");
let _ = LocalStorage::set("dark-mode", true);
} else {
let _ = body.class_list().add_1("theme-light");
let _ = body.class_list().remove_1("theme-dark");
let _ = LocalStorage::set("dark-mode", false);
}
}
}
}
|| ()
});
}
// 3. Toggle action
let onclick = {
let is_dark = is_dark.clone();
Callback::from(move |_| {
is_dark.set(!*is_dark);
})
};
html! {
<button class="dark-mode-toggle" {onclick}>
if *is_dark {
// Sun Icon for switching to light mode
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="4"/>
<path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/>
</svg>
} else {
// Moon Icon for switching to dark mode
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/>
</svg>
}
</button>
}
}