feat: add theme toggle functionality and update localization files
- Implemented a theme toggle feature allowing users to switch between light and dark modes. - Added a new ThemeToggle component for the theme switching button. - Updated theme CSS to support dark mode variables and system preference detection. - Enhanced localization files to include translations for the "toggleTheme" key across multiple languages.
This commit is contained in:
parent
1f850dd926
commit
db5f47586e
72 changed files with 338 additions and 77 deletions
102
public/theme.js
Normal file
102
public/theme.js
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
// ===== Theme Toggle Script =====
|
||||
// Handles dark/light mode switching with localStorage persistence
|
||||
// and system preference detection
|
||||
|
||||
(function () {
|
||||
const THEME_KEY = "theme";
|
||||
|
||||
// Get stored theme or detect system preference
|
||||
function getPreferredTheme() {
|
||||
const storedTheme = localStorage.getItem(THEME_KEY);
|
||||
if (storedTheme) {
|
||||
return storedTheme;
|
||||
}
|
||||
// Return null to let CSS handle system preference
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get current effective theme (what's actually being displayed)
|
||||
function getEffectiveTheme() {
|
||||
const storedTheme = localStorage.getItem(THEME_KEY);
|
||||
if (storedTheme) {
|
||||
return storedTheme;
|
||||
}
|
||||
// Check system preference
|
||||
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
||||
}
|
||||
|
||||
// Apply theme to document
|
||||
function applyTheme(theme) {
|
||||
const root = document.documentElement;
|
||||
if (theme === "dark") {
|
||||
root.setAttribute("data-theme", "dark");
|
||||
} else if (theme === "light") {
|
||||
root.setAttribute("data-theme", "light");
|
||||
} else {
|
||||
// Remove attribute to follow system preference
|
||||
root.removeAttribute("data-theme");
|
||||
}
|
||||
updateThemeIcons();
|
||||
}
|
||||
|
||||
// Update theme toggle icons visibility
|
||||
function updateThemeIcons() {
|
||||
const effectiveTheme = getEffectiveTheme();
|
||||
const lightIcon = document.getElementById("theme-icon-light");
|
||||
const darkIcon = document.getElementById("theme-icon-dark");
|
||||
|
||||
if (lightIcon && darkIcon) {
|
||||
if (effectiveTheme === "dark") {
|
||||
// In dark mode, show sun icon (to switch to light)
|
||||
lightIcon.classList.remove("hidden");
|
||||
darkIcon.classList.add("hidden");
|
||||
} else {
|
||||
// In light mode, show moon icon (to switch to dark)
|
||||
lightIcon.classList.add("hidden");
|
||||
darkIcon.classList.remove("hidden");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle theme
|
||||
function toggleTheme() {
|
||||
const currentTheme = getEffectiveTheme();
|
||||
const newTheme = currentTheme === "dark" ? "light" : "dark";
|
||||
localStorage.setItem(THEME_KEY, newTheme);
|
||||
applyTheme(newTheme);
|
||||
}
|
||||
|
||||
// Initialize theme on page load
|
||||
function initTheme() {
|
||||
const preferredTheme = getPreferredTheme();
|
||||
applyTheme(preferredTheme);
|
||||
|
||||
// Listen for system preference changes
|
||||
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", (e) => {
|
||||
// Only update if no manual preference is set
|
||||
if (!localStorage.getItem(THEME_KEY)) {
|
||||
applyTheme(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Apply theme immediately to prevent flash
|
||||
const preferredTheme = getPreferredTheme();
|
||||
if (preferredTheme) {
|
||||
document.documentElement.setAttribute("data-theme", preferredTheme);
|
||||
}
|
||||
|
||||
// Set up event listener when DOM is ready
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
initTheme();
|
||||
|
||||
const themeToggle = document.getElementById("theme-toggle");
|
||||
if (themeToggle) {
|
||||
themeToggle.addEventListener("click", toggleTheme);
|
||||
}
|
||||
});
|
||||
|
||||
// Expose toggle function globally for programmatic access
|
||||
window.toggleTheme = toggleTheme;
|
||||
window.getEffectiveTheme = getEffectiveTheme;
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue