import { inject, ref, computed, unref, provide, getCurrentInstance } from 'vue' import { configProviderContextKey } from '@element-plus/tokens' import { merge } from '@element-plus/utils/util' import { debugWarn } from '@element-plus/utils/error' import type { MaybeRef } from '@vueuse/core' import type { Ref, App } from 'vue' import type { ConfigProviderContext } from '@element-plus/tokens' // this is meant to fix global methods like `ElMessage(opts)`, this way we can inject current locale // into the component as default injection value. // refer to: https://github.com/element-plus/element-plus/issues/2610#issuecomment-887965266 const globalConfig = ref() export function useGlobalConfig< K extends keyof ConfigProviderContext, D extends ConfigProviderContext[K] >( key: K, defaultValue?: D ): Ref | D> export function useGlobalConfig(): Ref export function useGlobalConfig( key?: keyof ConfigProviderContext, defaultValue = undefined ) { const config = getCurrentInstance() ? inject(configProviderContextKey, globalConfig) : globalConfig if (key) { return computed(() => config.value?.[key] ?? defaultValue) } else { return config } } export const provideGlobalConfig = ( config: MaybeRef, app?: App, global = false ) => { const inSetup = !!getCurrentInstance() const oldConfig = inSetup ? useGlobalConfig() : undefined const provideFn = app?.provide ?? (inSetup ? provide : undefined) if (!provideFn) { debugWarn( 'provideGlobalConfig', 'provideGlobalConfig() can only be used inside setup().' ) return } const context = computed(() => { const cfg = unref(config) if (!oldConfig?.value) return cfg return merge(oldConfig.value, cfg) }) provideFn(configProviderContextKey, context) if (global || !globalConfig.value) { globalConfig.value = context.value } return context }