feat: 全站视觉焕新与悬浮玻璃 TabBar 迁移

This commit is contained in:
2026-08-07 23:29:19 +08:00
parent 19408e5a8c
commit 61f1217384
97 changed files with 4007 additions and 2024 deletions
+45 -15
View File
@@ -1,7 +1,7 @@
import { View, Text, Image } from '@tarojs/components'
import Taro from '@tarojs/taro'
import { useEffect, useState } from 'react'
import { getTheme, resolveTheme } from '../utils/store'
import { getTheme, resolveTheme, setDetectedSystemTheme } from '../utils/store'
import { THEME_CHANGE_EVENT } from '../context/ThemeContext'
import { applyPageBackground } from '../utils/themeBackground'
import { assetUrl } from '../utils/asset'
@@ -26,6 +26,11 @@ function currentTabPath(): string {
return matchTab(path)
}
type ThemeChangeApi = {
onThemeChange?: (listener: (res: { theme?: string }) => void) => void
offThemeChange?: (listener: (res: { theme?: string }) => void) => void
}
export default function CustomTabBar() {
const [resolvedTheme, setResolvedTheme] = useState<'light' | 'dark'>(resolveTheme(getTheme()))
@@ -40,6 +45,27 @@ export default function CustomTabBar() {
}
}, [])
// 自定义 tabBar 不处在 React Tree 里,额外直接监听系统主题,保证“跟随系统”时也即时切换
useEffect(() => {
const handler = (res: { theme?: string }) => {
if (res && (res.theme === 'dark' || res.theme === 'light')) {
setDetectedSystemTheme(res.theme)
if (getTheme() === 'auto') {
setResolvedTheme(res.theme)
}
}
}
const themeApi = Taro as typeof Taro & ThemeChangeApi
if (themeApi.onThemeChange) {
themeApi.onThemeChange(handler)
}
return () => {
if (themeApi.offThemeChange) {
themeApi.offThemeChange(handler)
}
}
}, [])
// 其它入口(如页面内部调用 switchTab)也会回到 tabBar,收到事件后重新同步选中态
useEffect(() => {
const handler = (path?: string) => {
@@ -66,20 +92,24 @@ export default function CustomTabBar() {
}
return (
<View className={`custom-tab-bar theme-${resolvedTheme}`}>
{TABS.map((tab) => {
const isActive = tab.pagePath === activeTab
return (
<View
key={tab.pagePath}
className={`tab-item ${isActive ? 'active' : ''}`}
onTap={() => switchTab(tab.pagePath)}
>
<Image className={`tab-icon-img ${isActive ? 'active' : ''}`} src={isActive ? tab.iconActive : tab.icon} mode='aspectFit' />
<Text className='tab-label'>{tab.label}</Text>
</View>
)
})}
<View className={`tab-bar-root theme-${resolvedTheme}`}>
<View className='tab-bar-gradient' />
<View className={`custom-tab-bar theme-${resolvedTheme}`}>
{TABS.map((tab) => {
const isActive = tab.pagePath === activeTab
return (
<View
key={tab.pagePath}
className={`tab-item ${isActive ? 'active' : ''}`}
onTap={() => switchTab(tab.pagePath)}
>
{isActive && <View className='tab-indicator' />}
<Image className={`tab-icon-img ${isActive ? 'active' : ''}`} src={isActive ? tab.iconActive : tab.icon} mode='aspectFit' />
<Text className='tab-label'>{tab.label}</Text>
</View>
)
})}
</View>
</View>
)
}