From c3dd4da11b68c82807282843e0c5977f82b457d7 Mon Sep 17 00:00:00 2001 From: Will Miao <13051207myq@gmail.com> Date: Sat, 21 Jun 2025 20:43:44 +0800 Subject: [PATCH] feat: enhance theme toggle functionality with auto theme support and icon updates. Fix #243 --- static/css/components/header.css | 30 +++++++++++++++++++++++++++--- static/js/components/Header.js | 14 +++++++++++++- static/js/utils/uiHelpers.js | 24 +++++++++++++++++++++--- templates/components/header.html | 1 + 4 files changed, 62 insertions(+), 7 deletions(-) diff --git a/static/css/components/header.css b/static/css/components/header.css index f6a5ee68..da864529 100644 --- a/static/css/components/header.css +++ b/static/css/components/header.css @@ -115,7 +115,8 @@ } .theme-toggle .light-icon, -.theme-toggle .dark-icon { +.theme-toggle .dark-icon, +.theme-toggle .auto-icon { position: absolute; top: 50%; left: 50%; @@ -124,15 +125,38 @@ transition: opacity 0.3s ease; } +/* Default state shows dark icon */ .theme-toggle .dark-icon { opacity: 1; } -[data-theme="light"] .theme-toggle .light-icon { +/* Light theme shows light icon */ +.theme-toggle.theme-light .light-icon { opacity: 1; } -[data-theme="light"] .theme-toggle .dark-icon { +.theme-toggle.theme-light .dark-icon, +.theme-toggle.theme-light .auto-icon { + opacity: 0; +} + +/* Dark theme shows dark icon */ +.theme-toggle.theme-dark .dark-icon { + opacity: 1; +} + +.theme-toggle.theme-dark .light-icon, +.theme-toggle.theme-dark .auto-icon { + opacity: 0; +} + +/* Auto theme shows auto icon */ +.theme-toggle.theme-auto .auto-icon { + opacity: 1; +} + +.theme-toggle.theme-auto .light-icon, +.theme-toggle.theme-auto .dark-icon { opacity: 0; } diff --git a/static/js/components/Header.js b/static/js/components/Header.js index 17f4129f..4d8c7fa7 100644 --- a/static/js/components/Header.js +++ b/static/js/components/Header.js @@ -46,9 +46,21 @@ export class HeaderManager { // Handle theme toggle const themeToggle = document.querySelector('.theme-toggle'); if (themeToggle) { + // Set initial state based on current theme + const currentTheme = localStorage.getItem('lm_theme') || 'auto'; + themeToggle.classList.add(`theme-${currentTheme}`); + themeToggle.addEventListener('click', () => { if (typeof toggleTheme === 'function') { - toggleTheme(); + const newTheme = toggleTheme(); + // Update tooltip based on next toggle action + if (newTheme === 'light') { + themeToggle.title = "Switch to dark theme"; + } else if (newTheme === 'dark') { + themeToggle.title = "Switch to auto theme"; + } else { + themeToggle.title = "Switch to light theme"; + } } }); } diff --git a/static/js/utils/uiHelpers.js b/static/js/utils/uiHelpers.js index 9265df9e..5cb405ab 100644 --- a/static/js/utils/uiHelpers.js +++ b/static/js/utils/uiHelpers.js @@ -118,10 +118,13 @@ export function toggleTheme() { const currentTheme = getStorageItem('theme') || 'auto'; let newTheme; - if (currentTheme === 'dark') { - newTheme = 'light'; - } else { + // Cycle through themes: light → dark → auto → light + if (currentTheme === 'light') { newTheme = 'dark'; + } else if (currentTheme === 'dark') { + newTheme = 'auto'; + } else { + newTheme = 'light'; } setStorageItem('theme', newTheme); @@ -151,6 +154,21 @@ function applyTheme(theme) { htmlElement.setAttribute('data-theme', 'light'); document.body.dataset.theme = 'light'; } + + // Update the theme-toggle icon state + updateThemeToggleIcons(theme); +} + +// New function to update theme toggle icons +function updateThemeToggleIcons(theme) { + const themeToggle = document.querySelector('.theme-toggle'); + if (!themeToggle) return; + + // Remove any existing active classes + themeToggle.classList.remove('theme-light', 'theme-dark', 'theme-auto'); + + // Add the appropriate class based on current theme + themeToggle.classList.add(`theme-${theme}`); } export function toggleFolder(tag) { diff --git a/templates/components/header.html b/templates/components/header.html index 91373d15..a16a75e1 100644 --- a/templates/components/header.html +++ b/templates/components/header.html @@ -39,6 +39,7 @@