Files
nx9-auth/ui/src/theme/mod.rs
T

92 lines
2.2 KiB
Rust

//! Theme management (light / dark / system) with localStorage persistence.
use gloo_storage::{LocalStorage, Storage};
use std::fmt;
const STORAGE_KEY: &str = "nx9-auth-theme";
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum ThemeMode {
Light,
Dark,
#[default]
System,
}
impl ThemeMode {
pub fn as_str(self) -> &'static str {
match self {
Self::Light => "light",
Self::Dark => "dark",
Self::System => "system",
}
}
pub fn from_str(s: &str) -> Self {
match s {
"light" => Self::Light,
"dark" => Self::Dark,
_ => Self::System,
}
}
pub fn cycle(self) -> Self {
match self {
Self::Light => Self::Dark,
Self::Dark => Self::System,
Self::System => Self::Light,
}
}
pub fn label(self) -> &'static str {
match self {
Self::Light => "Light",
Self::Dark => "Dark",
Self::System => "System",
}
}
pub fn icon(self) -> &'static str {
match self {
Self::Light => "☀",
Self::Dark => "☾",
Self::System => "◐",
}
}
}
impl fmt::Display for ThemeMode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
pub fn load_theme() -> ThemeMode {
LocalStorage::get::<String>(STORAGE_KEY)
.map(|s| ThemeMode::from_str(&s))
.unwrap_or_default()
}
pub fn save_theme(mode: ThemeMode) {
let _ = LocalStorage::set(STORAGE_KEY, mode.as_str());
}
/// Apply theme to `<html data-theme="...">`.
pub fn apply_theme(mode: ThemeMode) {
if let Some(document) = web_sys::window().and_then(|w| w.document()) {
if let Some(el) = document.document_element() {
match mode {
ThemeMode::Light => {
let _ = el.set_attribute("data-theme", "light");
}
ThemeMode::Dark => {
let _ = el.set_attribute("data-theme", "dark");
}
ThemeMode::System => {
let _ = el.remove_attribute("data-theme");
}
}
}
}
}