import { ConfigProvider } from 'ant-design-vue' import type { Theme as AntTheme } from 'ant-design-vue/es/config-provider' import { useStorage } from '@vueuse/core' import { NOCO, hexToRGB, themeV2Colors, useCssVar, useInjectionState } from '#imports' interface ThemeConfig extends AntTheme { primaryColor: string accentColor: string } const [setup, use] = useInjectionState((config?: Partial<ThemeConfig>) => { const primaryColor = useCssVar('--color-primary', typeof document !== 'undefined' ? document.documentElement : null) const accentColor = useCssVar('--color-accent', typeof document !== 'undefined' ? document.documentElement : null) /** current theme config */ const currentTheme = useStorage<ThemeConfig>( `${NOCO}db-theme`, { primaryColor: themeV2Colors['royal-blue'].DEFAULT, accentColor: themeV2Colors.pink['500'], }, localStorage, { mergeDefaults: true }, ) /** set initial config */ setTheme(config ?? currentTheme.value) /** set theme (persists in localstorage) */ function setTheme(theme: Partial<ThemeConfig>) { // convert hex colors to rgb values if (theme.primaryColor) primaryColor.value = hexToRGB(theme.primaryColor) if (theme.accentColor) accentColor.value = hexToRGB(theme.accentColor) currentTheme.value = theme as ThemeConfig ConfigProvider.config({ theme, }) } return { theme: currentTheme, setTheme, } }) export const provideTheme = setup export function useTheme(config?: Partial<ThemeConfig>) { const theme = use() if (!theme) { return setup(config) } else { if (config) theme.setTheme(config) } return theme }