mirror of
https://github.com/Buriburizaem0n/nezha-dash-v1.git
synced 2026-09-19 09:40:14 +00:00
fix: improve theme management and styling for better user experience
This commit is contained in:
+31
-76
@@ -1,95 +1,50 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<script>
|
||||
// 在页面渲染前就执行主题初始化
|
||||
try {
|
||||
const storageKey = "vite-ui-theme"
|
||||
let theme = localStorage.getItem(storageKey)
|
||||
if (theme === "system" || !theme) {
|
||||
theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"
|
||||
}
|
||||
document.documentElement.classList.add(theme)
|
||||
} catch (_e) {
|
||||
document.documentElement.classList.add("light")
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
/* Prevent FOUC in Safari */
|
||||
html:not(.dark):not(.light) * {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
:root {
|
||||
color-scheme: light;
|
||||
--bg: #ffffff;
|
||||
}
|
||||
|
||||
html.dark {
|
||||
color-scheme: dark;
|
||||
--bg: #242424;
|
||||
}
|
||||
|
||||
html.light {
|
||||
color-scheme: light;
|
||||
--bg: #ffffff;
|
||||
}
|
||||
|
||||
html {
|
||||
background-color: var(--bg);
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--bg);
|
||||
}
|
||||
|
||||
#root {
|
||||
background-color: var(--bg);
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#root.loaded {
|
||||
visibility: visible;
|
||||
animation: fadein 0.2s;
|
||||
}
|
||||
|
||||
@keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
;(() => {
|
||||
const storageKey = "vite-ui-theme"
|
||||
const theme = localStorage.getItem(storageKey) || "system"
|
||||
const root = document.documentElement
|
||||
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)")
|
||||
|
||||
function updateThemeColor(isDark) {
|
||||
const themeColor = isDark ? "#242424" : "#fafafa"
|
||||
document.querySelector('meta[name="theme-color"]')?.setAttribute("content", themeColor)
|
||||
const resolveTheme = (theme) =>
|
||||
theme === "system" ? (mediaQuery.matches ? "dark" : "light") : theme
|
||||
|
||||
function updateThemeColor(nextTheme) {
|
||||
const themeColor = nextTheme === "dark" ? "hsl(30 15% 8%)" : "hsl(0 0% 98%)"
|
||||
let meta = document.querySelector('meta[name="theme-color"]')
|
||||
|
||||
if (!meta) {
|
||||
meta = document.createElement("meta")
|
||||
meta.setAttribute("name", "theme-color")
|
||||
document.head.appendChild(meta)
|
||||
}
|
||||
|
||||
meta.setAttribute("content", themeColor)
|
||||
}
|
||||
|
||||
function setTheme(newTheme) {
|
||||
function applyResolvedTheme(resolvedTheme) {
|
||||
root.classList.remove("light", "dark")
|
||||
root.classList.add(newTheme)
|
||||
updateThemeColor(newTheme === "dark")
|
||||
root.classList.add(resolvedTheme)
|
||||
root.style.colorScheme = resolvedTheme
|
||||
root.style.backgroundColor =
|
||||
resolvedTheme === "dark" ? "hsl(30 15% 8%)" : "hsl(0 0% 98%)"
|
||||
updateThemeColor(resolvedTheme)
|
||||
}
|
||||
|
||||
if (theme === "system") {
|
||||
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"
|
||||
setTheme(systemTheme)
|
||||
let theme = "system"
|
||||
|
||||
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", (e) => {
|
||||
setTheme(e.matches ? "dark" : "light")
|
||||
})
|
||||
} else {
|
||||
setTheme(theme)
|
||||
try {
|
||||
const storedTheme = localStorage.getItem(storageKey)
|
||||
if (storedTheme === "light" || storedTheme === "dark" || storedTheme === "system") {
|
||||
theme = storedTheme
|
||||
}
|
||||
} catch (_e) {
|
||||
theme = "system"
|
||||
}
|
||||
|
||||
applyResolvedTheme(resolveTheme(theme))
|
||||
|
||||
// Add loaded class after React has mounted
|
||||
window.addEventListener("load", () => {
|
||||
const root = document.getElementById("root")
|
||||
|
||||
@@ -8,7 +8,12 @@ export function ThemeColorManager() {
|
||||
|
||||
useEffect(() => {
|
||||
const updateThemeColor = () => {
|
||||
const currentTheme = theme;
|
||||
const currentTheme =
|
||||
theme === "system"
|
||||
? window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||
? "dark"
|
||||
: "light"
|
||||
: theme;
|
||||
const meta = document.querySelector('meta[name="theme-color"]');
|
||||
|
||||
if (!meta) {
|
||||
|
||||
@@ -30,37 +30,50 @@ export function ThemeProvider({
|
||||
|
||||
useEffect(() => {
|
||||
const root = window.document.documentElement;
|
||||
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
|
||||
root.classList.add("disable-transitions");
|
||||
root.classList.remove("light", "dark");
|
||||
|
||||
if (theme === "system") {
|
||||
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)")
|
||||
.matches
|
||||
? "dark"
|
||||
: "light";
|
||||
|
||||
root.classList.add(systemTheme);
|
||||
const updateThemeColor = (nextTheme: "light" | "dark") => {
|
||||
const themeColor =
|
||||
systemTheme === "dark" ? "hsl(30 15% 8%)" : "hsl(0 0% 98%)";
|
||||
nextTheme === "dark" ? "hsl(30 15% 8%)" : "hsl(0 0% 98%)";
|
||||
document
|
||||
.querySelector('meta[name="theme-color"]')
|
||||
?.setAttribute("content", themeColor);
|
||||
const timeoutId = window.setTimeout(() => {
|
||||
root.classList.remove("disable-transitions");
|
||||
}, 0);
|
||||
return () => window.clearTimeout(timeoutId);
|
||||
};
|
||||
|
||||
const applyTheme = (nextTheme: "light" | "dark") => {
|
||||
root.classList.remove("light", "dark");
|
||||
root.classList.add(nextTheme);
|
||||
root.style.colorScheme = nextTheme;
|
||||
root.style.backgroundColor =
|
||||
nextTheme === "dark" ? "hsl(30 15% 8%)" : "hsl(0 0% 98%)";
|
||||
updateThemeColor(nextTheme);
|
||||
};
|
||||
|
||||
root.classList.add("disable-transitions");
|
||||
|
||||
let cleanupMediaListener: (() => void) | undefined;
|
||||
|
||||
if (theme === "system") {
|
||||
const applySystemTheme = () => {
|
||||
applyTheme(mediaQuery.matches ? "dark" : "light");
|
||||
};
|
||||
|
||||
applySystemTheme();
|
||||
mediaQuery.addEventListener("change", applySystemTheme);
|
||||
cleanupMediaListener = () =>
|
||||
mediaQuery.removeEventListener("change", applySystemTheme);
|
||||
} else {
|
||||
applyTheme(theme);
|
||||
}
|
||||
|
||||
root.classList.add(theme);
|
||||
const themeColor = theme === "dark" ? "hsl(30 15% 8%)" : "hsl(0 0% 98%)";
|
||||
document
|
||||
.querySelector('meta[name="theme-color"]')
|
||||
?.setAttribute("content", themeColor);
|
||||
const timeoutId = window.setTimeout(() => {
|
||||
root.classList.remove("disable-transitions");
|
||||
}, 0);
|
||||
return () => window.clearTimeout(timeoutId);
|
||||
|
||||
return () => {
|
||||
window.clearTimeout(timeoutId);
|
||||
cleanupMediaListener?.();
|
||||
};
|
||||
}, [theme]);
|
||||
|
||||
const value = {
|
||||
|
||||
+6
-4
@@ -100,10 +100,6 @@
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
@@ -192,6 +188,12 @@
|
||||
}
|
||||
html {
|
||||
@apply scroll-smooth;
|
||||
background-color: hsl(0 0% 98%);
|
||||
color-scheme: light;
|
||||
}
|
||||
html.dark {
|
||||
background-color: hsl(30 15% 8%);
|
||||
color-scheme: dark;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
|
||||
Reference in New Issue
Block a user