feat: add theme mode support with AppThemeMode enum and AppThemeState service
- Introduced AppThemeMode enum to define theme options: System, Light, Dark. - Updated AppSettingsDocument to include ThemeMode property. - Created AppThemeState service to manage current theme mode and handle changes. - Integrated theme mode handling in CouchbaseLiteAppSettingsService for persistence. - Added JavaScript for theme management in the frontend, supporting system preference detection. - Enhanced CSS with theme variables for consistent styling across light and dark modes. - Updated Playwright tests to ensure sidebar functionality and responsiveness.
This commit is contained in:
parent
b45eac8055
commit
158906fa28
19 changed files with 889 additions and 82 deletions
58
wwwroot/theme.js
Normal file
58
wwwroot/theme.js
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
window.workTrackerTheme = (() => {
|
||||
const storageKey = "worktracker.themeMode";
|
||||
const mediaQuery = window.matchMedia
|
||||
? window.matchMedia("(prefers-color-scheme: dark)")
|
||||
: null;
|
||||
|
||||
function normalize(mode) {
|
||||
const normalized = (mode || "system").toString().toLowerCase();
|
||||
return normalized === "light" || normalized === "dark" || normalized === "system"
|
||||
? normalized
|
||||
: "system";
|
||||
}
|
||||
|
||||
function resolve(mode) {
|
||||
if (mode === "system") {
|
||||
return mediaQuery && mediaQuery.matches ? "dark" : "light";
|
||||
}
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
function apply(mode) {
|
||||
const normalized = normalize(mode);
|
||||
const effectiveMode = resolve(normalized);
|
||||
|
||||
document.documentElement.setAttribute("data-bs-theme", effectiveMode);
|
||||
document.documentElement.setAttribute("data-theme-mode", normalized);
|
||||
document.documentElement.style.colorScheme = effectiveMode;
|
||||
localStorage.setItem(storageKey, normalized);
|
||||
}
|
||||
|
||||
function handleSystemThemeChange() {
|
||||
const currentMode = normalize(localStorage.getItem(storageKey) || document.documentElement.getAttribute("data-theme-mode"));
|
||||
if (currentMode === "system") {
|
||||
apply(currentMode);
|
||||
}
|
||||
}
|
||||
|
||||
if (mediaQuery) {
|
||||
if (typeof mediaQuery.addEventListener === "function") {
|
||||
mediaQuery.addEventListener("change", handleSystemThemeChange);
|
||||
}
|
||||
else if (typeof mediaQuery.addListener === "function") {
|
||||
mediaQuery.addListener(handleSystemThemeChange);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
init() {
|
||||
apply(localStorage.getItem(storageKey) || document.documentElement.getAttribute("data-theme-mode"));
|
||||
},
|
||||
setTheme(mode) {
|
||||
apply(mode);
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
window.workTrackerTheme.init();
|
||||
Loading…
Add table
Add a link
Reference in a new issue