-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy paththeme.js
More file actions
154 lines (135 loc) · 5.38 KB
/
theme.js
File metadata and controls
154 lines (135 loc) · 5.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
window.themeManager = {
setTheme: function (theme) {
//console.log("Setting theme to:", theme);
document.documentElement.setAttribute("data-bs-theme", theme);
localStorage.setItem("theme", theme);
// Force browser to recalculate CSS custom properties
// by triggering a reflow on the root element
document.documentElement.style.display = "none";
void document.documentElement.offsetHeight; // Trigger reflow
document.documentElement.style.display = "";
// console.log(
// "Theme set. Current attribute:",
// document.documentElement.getAttribute("data-bs-theme")
// );
},
getTheme: function () {
const theme = localStorage.getItem("theme") || "light";
//console.log("Getting theme from localStorage:", theme);
return theme;
},
initTheme: function () {
const savedTheme = this.getTheme();
this.setTheme(savedTheme);
const savedBrandTheme = this.getBrandTheme();
this.setBrandTheme(savedBrandTheme);
return savedTheme;
},
setBrandTheme: function (brandTheme) {
console.log("setBrandTheme called with:", brandTheme);
document.documentElement.setAttribute("data-brand-theme", brandTheme);
localStorage.setItem("brandTheme", brandTheme);
console.log(
"Brand theme set. DOM attribute:",
document.documentElement.getAttribute("data-brand-theme"),
);
console.log("localStorage value:", localStorage.getItem("brandTheme"));
// Force browser to recalculate CSS custom properties
document.documentElement.style.display = "none";
void document.documentElement.offsetHeight; // Trigger reflow
document.documentElement.style.display = "";
},
getBrandTheme: function () {
const brandTheme = localStorage.getItem("brandTheme") || "bootstrap";
return brandTheme;
},
};
// Initialize theme IMMEDIATELY (before DOMContentLoaded) to prevent flash
if (typeof localStorage !== "undefined") {
const savedTheme = localStorage.getItem("theme") || "light";
const savedBrandTheme = localStorage.getItem("brandTheme") || "bootstrap";
console.log("Initial theme load:", savedTheme, "Brand:", savedBrandTheme);
document.documentElement.setAttribute("data-bs-theme", savedTheme);
document.documentElement.setAttribute("data-brand-theme", savedBrandTheme);
// Force multiple reflows to ensure CSS is applied
// Using requestAnimationFrame to ensure it happens after browser paint
document.documentElement.style.display = "none";
void document.documentElement.offsetHeight; // Trigger reflow
document.documentElement.style.display = "";
// Double-check on next frame
requestAnimationFrame(() => {
if (
document.documentElement.getAttribute("data-brand-theme") !==
savedBrandTheme
) {
document.documentElement.setAttribute(
"data-brand-theme",
savedBrandTheme,
);
}
console.log(
"Initial theme applied with reflow, verified:",
document.documentElement.getAttribute("data-brand-theme"),
);
});
// Watch for Blazor navigation and re-apply theme
// This handles Interactive Server mode where components persist
const observer = new MutationObserver(function (mutations) {
let currentTheme = document.documentElement.getAttribute("data-bs-theme");
let currentBrandTheme =
document.documentElement.getAttribute("data-brand-theme");
// If attributes are missing, restore from localStorage
if (!currentTheme) {
currentTheme = localStorage.getItem("theme") || "light";
document.documentElement.setAttribute("data-bs-theme", currentTheme);
console.log("Restored theme attribute:", currentTheme);
}
if (!currentBrandTheme) {
currentBrandTheme = localStorage.getItem("brandTheme") || "bootstrap";
document.documentElement.setAttribute(
"data-brand-theme",
currentBrandTheme,
);
console.log("Restored brand theme attribute:", currentBrandTheme);
}
// Re-trigger reflow to ensure CSS variables are applied
document.documentElement.style.display = "none";
void document.documentElement.offsetHeight;
document.documentElement.style.display = "";
//console.log("Theme re-applied after DOM mutation:", currentTheme, currentBrandTheme);
});
// Start observing after a short delay to let Blazor initialize
setTimeout(() => {
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ["data-bs-theme", "data-brand-theme"],
});
}, 1000);
// Also ensure theme is applied after DOM is fully loaded
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", () => {
const currentTheme =
document.documentElement.getAttribute("data-bs-theme") ||
localStorage.getItem("theme") ||
"light";
const currentBrandTheme =
document.documentElement.getAttribute("data-brand-theme") ||
localStorage.getItem("brandTheme") ||
"bootstrap";
document.documentElement.setAttribute("data-bs-theme", currentTheme);
document.documentElement.setAttribute(
"data-brand-theme",
currentBrandTheme,
);
// Force reflow
document.documentElement.style.display = "none";
void document.documentElement.offsetHeight;
document.documentElement.style.display = "";
console.log(
"DOMContentLoaded - Theme re-applied:",
currentTheme,
currentBrandTheme,
);
});
}
}