UNPKG

element-plus

Version:

A Component Library for Vue3.0

106 lines (94 loc) 2.17 kB
import { watch, isRef, onMounted, computed, unref, inject, onUnmounted, provide, ref, } from 'vue' import type { Ref, WatchStopHandle, InjectionKey } from 'vue' type VarsType = Ref<Record<string, string>> | Record<string, string> const VAR_PREFIX = '--el-' const setVars = ( target: HTMLElement, val: Record<string, string>, ) => { Object.keys(val).forEach(key => { if (key.startsWith(VAR_PREFIX)) { target?.style.setProperty(key, val[key]) } else { target?.style.setProperty(VAR_PREFIX + key, val[key]) } }) } export const themeVarsKey: InjectionKey<VarsType> = 'themeVars' as any /** * @param vars * @param target * @returns stopWatchHandler * @example * * If you pass a Ref vars param, it will generate a watch handler. * * In main.ts: * * ```ts * const themeVars = { * '--el-color-primary': '#f44336', * '--el-color-white': '#2196f3', * } * app.provide(themeVarsKey, themeVars) * ``` * Usually you need to use this function in the root component. * In components' steup: * * ```ts * setup() { * const themeVars = ref({ * '--el-button-default-background-color': '#f44336', * '--el-button-default-font-color': '#2196f3', * }) * useCssVar(themeVars) * } * ``` */ export function useCssVar( vars: VarsType, target?: Ref<HTMLElement> | HTMLElement, ) { let stopWatchCssVar: WatchStopHandle | null = null const elRef = computed( () => unref(target) || window?.document?.documentElement, ) const themeVars = useThemeVars() const customVars = { ...themeVars, ...unref(vars) } provide(themeVarsKey, ref(customVars)) onMounted(() => { isRef(vars) ? (stopWatchCssVar = watch( vars, val => { setVars(elRef.value, { ...unref(themeVars), ...val, }) }, { immediate: true, deep: true, }, )) : setVars(elRef.value, { ...unref(themeVars), ...vars, }) }) onUnmounted(() => stopWatchCssVar && stopWatchCssVar()) } export const useThemeVars = () => { const themeVars = inject(themeVarsKey, {}) return themeVars }