fix(theme): 消除首帧主题闪动并柔化明暗过渡

- index.html 首帧按本机偏好设置 dark/light,避免先浅后深
- 实际 scheme 只写 dark/light(之前 auto 会覆盖成浅色)
- 切换时给所有表面加 240ms 颜色/边框/阴影过渡,结束后移除
- 背景图深色下淡出而不是 display:none
- 页头操作图标与分组导航等设置加载后再渲染,避免先显示后消失
This commit is contained in:
2026-11-03 20:09:24 +08:00
parent dacb30e548
commit 3330af818e
5 changed files with 94 additions and 37 deletions
+15 -6
View File
@@ -300,13 +300,21 @@ export default function AppNext() {
readThemeOverride(),
)
const effectiveTheme = themeOverride ?? site.site.theme
useEffect(() => {
document.documentElement.dataset.scheme = effectiveTheme
}, [effectiveTheme])
/** 当前实际是深色吗(auto 时按系统偏好算) */
const isDark = isDarkScheme(effectiveTheme)
const scheme = isDark ? 'dark' : 'light'
useEffect(() => {
const root = document.documentElement
if (root.dataset.scheme === scheme) return
root.classList.add('theme-transition')
root.dataset.scheme = scheme
const timer = window.setTimeout(() => root.classList.remove('theme-transition'), 260)
return () => {
window.clearTimeout(timer)
root.classList.remove('theme-transition')
}
}, [scheme])
/** 页头的明暗切换:只写本机偏好,不需要登录;站点默认值在后台改 */
const toggleTheme = () => {
@@ -663,6 +671,7 @@ export default function AppNext() {
headerSpeed={site.header.speed}
headerGap={site.header.gap}
site={site.site}
ready={settings !== null}
authenticated={session?.authenticated === true}
username={session?.username ?? undefined}
refreshing={refreshing}
@@ -707,7 +716,7 @@ export default function AppNext() {
onOpenApi={() => navigate('/interface')}
/>
)}
{settings !== null && site.sidebar.show_nav !== false && (
{settings !== null && !loading && site.sidebar.show_nav !== false && (
<div className="nav-card">
<Menu
items={sidebarItems}