78 lines
2.2 KiB
TypeScript
78 lines
2.2 KiB
TypeScript
import type { App, ComputedRef, InjectionKey, Ref } from 'vue'
|
|
import type { ClientData, RouteLocale } from 'vuepress/client'
|
|
import type { ThemeData } from '../../shared/index.js'
|
|
import { themeData as themeDataRaw } from '@internal/themePlumeData'
|
|
import { computed, inject, ref } from 'vue'
|
|
import { clientDataSymbol } from 'vuepress/client'
|
|
|
|
declare const __VUE_HMR_RUNTIME__: Record<string, any>
|
|
|
|
export type ThemeDataRef<T extends ThemeData = ThemeData> = Ref<T>
|
|
|
|
export type ThemeLocaleDataRef<T extends ThemeData = ThemeData> = ComputedRef<T>
|
|
|
|
export const themeLocaleDataSymbol: InjectionKey<ThemeLocaleDataRef> = Symbol(
|
|
__VUEPRESS_DEV__ ? 'themeLocaleData' : '',
|
|
)
|
|
|
|
export const themeData: ThemeDataRef = ref(themeDataRaw)
|
|
|
|
export function useThemeData<
|
|
T extends ThemeData = ThemeData,
|
|
>(): ThemeDataRef<T> {
|
|
return themeData as ThemeDataRef<T>
|
|
}
|
|
|
|
if (__VUEPRESS_DEV__ && (import.meta.webpackHot || import.meta.hot)) {
|
|
__VUE_HMR_RUNTIME__.updateThemeData = (data: ThemeData) => {
|
|
themeData.value = data
|
|
}
|
|
}
|
|
|
|
export function useThemeLocaleData<
|
|
T extends ThemeData = ThemeData,
|
|
>(): ThemeLocaleDataRef<T> {
|
|
const themeLocaleData = inject(themeLocaleDataSymbol)
|
|
if (!themeLocaleData) {
|
|
throw new Error('useThemeLocaleData() is called without provider.')
|
|
}
|
|
return themeLocaleData as ThemeLocaleDataRef<T>
|
|
}
|
|
|
|
/**
|
|
* Merge the locales fields to the root fields
|
|
* according to the route path
|
|
*/
|
|
function resolveThemeLocaleData(theme: ThemeData, routeLocale: RouteLocale): ThemeData {
|
|
const { locales, ...baseOptions } = theme
|
|
|
|
return {
|
|
...baseOptions,
|
|
...locales?.[routeLocale],
|
|
}
|
|
}
|
|
|
|
export function setupThemeData(app: App): void {
|
|
// provide theme data & theme locale data
|
|
const themeData = useThemeData()
|
|
const clientData: ClientData
|
|
= app._context.provides[clientDataSymbol as unknown as symbol]
|
|
const themeLocaleData = computed(() =>
|
|
resolveThemeLocaleData(themeData.value, clientData.routeLocale.value),
|
|
)
|
|
app.provide(themeLocaleDataSymbol, themeLocaleData)
|
|
|
|
Object.defineProperties(app.config.globalProperties, {
|
|
$theme: {
|
|
get() {
|
|
return themeData.value
|
|
},
|
|
},
|
|
$themeLocale: {
|
|
get() {
|
|
return themeLocaleData.value
|
|
},
|
|
},
|
|
})
|
|
}
|