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,94 +1,49 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<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>
|
<script>
|
||||||
;(() => {
|
;(() => {
|
||||||
const storageKey = "vite-ui-theme"
|
const storageKey = "vite-ui-theme"
|
||||||
const theme = localStorage.getItem(storageKey) || "system"
|
|
||||||
const root = document.documentElement
|
const root = document.documentElement
|
||||||
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)")
|
||||||
|
|
||||||
function updateThemeColor(isDark) {
|
const resolveTheme = (theme) =>
|
||||||
const themeColor = isDark ? "#242424" : "#fafafa"
|
theme === "system" ? (mediaQuery.matches ? "dark" : "light") : theme
|
||||||
document.querySelector('meta[name="theme-color"]')?.setAttribute("content", themeColor)
|
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
function setTheme(newTheme) {
|
meta.setAttribute("content", themeColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyResolvedTheme(resolvedTheme) {
|
||||||
root.classList.remove("light", "dark")
|
root.classList.remove("light", "dark")
|
||||||
root.classList.add(newTheme)
|
root.classList.add(resolvedTheme)
|
||||||
updateThemeColor(newTheme === "dark")
|
root.style.colorScheme = resolvedTheme
|
||||||
|
root.style.backgroundColor =
|
||||||
|
resolvedTheme === "dark" ? "hsl(30 15% 8%)" : "hsl(0 0% 98%)"
|
||||||
|
updateThemeColor(resolvedTheme)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theme === "system") {
|
let theme = "system"
|
||||||
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"
|
|
||||||
setTheme(systemTheme)
|
|
||||||
|
|
||||||
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", (e) => {
|
try {
|
||||||
setTheme(e.matches ? "dark" : "light")
|
const storedTheme = localStorage.getItem(storageKey)
|
||||||
})
|
if (storedTheme === "light" || storedTheme === "dark" || storedTheme === "system") {
|
||||||
} else {
|
theme = storedTheme
|
||||||
setTheme(theme)
|
|
||||||
}
|
}
|
||||||
|
} catch (_e) {
|
||||||
|
theme = "system"
|
||||||
|
}
|
||||||
|
|
||||||
|
applyResolvedTheme(resolveTheme(theme))
|
||||||
|
|
||||||
// Add loaded class after React has mounted
|
// Add loaded class after React has mounted
|
||||||
window.addEventListener("load", () => {
|
window.addEventListener("load", () => {
|
||||||
|
|||||||
@@ -8,7 +8,12 @@ export function ThemeColorManager() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const updateThemeColor = () => {
|
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"]');
|
const meta = document.querySelector('meta[name="theme-color"]');
|
||||||
|
|
||||||
if (!meta) {
|
if (!meta) {
|
||||||
|
|||||||
@@ -30,37 +30,50 @@ export function ThemeProvider({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const root = window.document.documentElement;
|
const root = window.document.documentElement;
|
||||||
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
||||||
|
|
||||||
|
const updateThemeColor = (nextTheme: "light" | "dark") => {
|
||||||
|
const themeColor =
|
||||||
|
nextTheme === "dark" ? "hsl(30 15% 8%)" : "hsl(0 0% 98%)";
|
||||||
|
document
|
||||||
|
.querySelector('meta[name="theme-color"]')
|
||||||
|
?.setAttribute("content", themeColor);
|
||||||
|
};
|
||||||
|
|
||||||
|
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");
|
root.classList.add("disable-transitions");
|
||||||
root.classList.remove("light", "dark");
|
|
||||||
|
let cleanupMediaListener: (() => void) | undefined;
|
||||||
|
|
||||||
if (theme === "system") {
|
if (theme === "system") {
|
||||||
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)")
|
const applySystemTheme = () => {
|
||||||
.matches
|
applyTheme(mediaQuery.matches ? "dark" : "light");
|
||||||
? "dark"
|
};
|
||||||
: "light";
|
|
||||||
|
|
||||||
root.classList.add(systemTheme);
|
applySystemTheme();
|
||||||
const themeColor =
|
mediaQuery.addEventListener("change", applySystemTheme);
|
||||||
systemTheme === "dark" ? "hsl(30 15% 8%)" : "hsl(0 0% 98%)";
|
cleanupMediaListener = () =>
|
||||||
document
|
mediaQuery.removeEventListener("change", applySystemTheme);
|
||||||
.querySelector('meta[name="theme-color"]')
|
} else {
|
||||||
?.setAttribute("content", themeColor);
|
applyTheme(theme);
|
||||||
const timeoutId = window.setTimeout(() => {
|
|
||||||
root.classList.remove("disable-transitions");
|
|
||||||
}, 0);
|
|
||||||
return () => window.clearTimeout(timeoutId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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(() => {
|
const timeoutId = window.setTimeout(() => {
|
||||||
root.classList.remove("disable-transitions");
|
root.classList.remove("disable-transitions");
|
||||||
}, 0);
|
}, 0);
|
||||||
return () => window.clearTimeout(timeoutId);
|
|
||||||
|
return () => {
|
||||||
|
window.clearTimeout(timeoutId);
|
||||||
|
cleanupMediaListener?.();
|
||||||
|
};
|
||||||
}, [theme]);
|
}, [theme]);
|
||||||
|
|
||||||
const value = {
|
const value = {
|
||||||
|
|||||||
+6
-4
@@ -100,10 +100,6 @@
|
|||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
|
||||||
color-scheme: light dark;
|
|
||||||
color: rgba(255, 255, 255, 0.87);
|
|
||||||
background-color: #242424;
|
|
||||||
|
|
||||||
font-synthesis: none;
|
font-synthesis: none;
|
||||||
text-rendering: optimizeLegibility;
|
text-rendering: optimizeLegibility;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
@@ -192,6 +188,12 @@
|
|||||||
}
|
}
|
||||||
html {
|
html {
|
||||||
@apply scroll-smooth;
|
@apply scroll-smooth;
|
||||||
|
background-color: hsl(0 0% 98%);
|
||||||
|
color-scheme: light;
|
||||||
|
}
|
||||||
|
html.dark {
|
||||||
|
background-color: hsl(30 15% 8%);
|
||||||
|
color-scheme: dark;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
@apply bg-background text-foreground;
|
@apply bg-background text-foreground;
|
||||||
|
|||||||
Reference in New Issue
Block a user