import { get } from 'lodash-es' import { setClass, removeClass, setStyle, colorToRgba, getStorage, } from '@/utils' import { useSettingGetters } from '@/store' import { APP_CATCH_KEY, THEME_CLASS_NAMES } from '@/app-config' import { useWindowSize } from '@vueuse/core' import type { SettingState } from '@/store/modules/setting/types' export default defineComponent({ name: 'AppStyleProvider', setup(_, { expose }) { const { getAppTheme } = useSettingGetters() const { height, width } = useWindowSize() // 同步主题色变量至 html,如果未获取到缓存值则已默认值填充 const syncPrimaryColorToBody = () => { const { appPrimaryColor: { primaryColor, primaryFadeColor }, } = __APP_CFG__ // 默认主题色 const html = document.documentElement // 获取缓存 naive ui 配置项 const primaryColorOverride = getStorage( APP_CATCH_KEY.appPiniaSettingStore, 'localStorage', ) if (primaryColorOverride) { // 获取主色调 const p = get( primaryColorOverride, 'primaryColorOverride.common.primaryColor', primaryColor, ) // 将主色调任意颜色转换为 rgba 格式 const fp = colorToRgba(p, 0.38) // 设置全局主题色 css 变量 html.style.setProperty('--ray-theme-primary-color', p) // 主色调 html.style.setProperty( '--ray-theme-primary-fade-color', fp || primaryFadeColor, ) // 降低透明度后的主色调 } } // 隐藏加载动画 const hiddenLoadingAnimation = () => { // pre-loading-animation 是默认 id const el = document.getElementById('pre-loading-animation') if (el) { setStyle(el, { display: 'none', }) } } // 切换主题时,同步更新 html class 以便于进行自定义 css 配置 const updateGlobalThemeClass = (bool: boolean) => { const html = document.documentElement const { darkClassName, lightClassName } = THEME_CLASS_NAMES bool ? removeClass(html, lightClassName) : removeClass(html, darkClassName) setClass(html, bool ? darkClassName : lightClassName) } syncPrimaryColorToBody() hiddenLoadingAnimation() watchEffect(() => { // 当切换主题时,更新 html 当前的注入 class updateGlobalThemeClass(getAppTheme.value) // 注入全局宽高尺寸 setStyle(document.documentElement, { '--html-height': `${height.value}px`, '--html-width': `${width.value}px`, }) }) expose() }, render() { return
}, })