fix: css var
parent
e7ec210451
commit
a1e029429f
|
@ -64,39 +64,24 @@ export interface DesignTokenProviderProps {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const useDesignTokenProvider = (value: ComputedRef<DesignTokenProviderProps>) => {
|
||||||
|
provide(DesignTokenContextKey, value);
|
||||||
|
watch(
|
||||||
|
value,
|
||||||
|
() => {
|
||||||
|
globalDesignTokenApi.value = unref(value);
|
||||||
|
triggerRef(globalDesignTokenApi);
|
||||||
|
},
|
||||||
|
{ immediate: true, deep: true },
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const useDesignTokenInject = () => {
|
export const useDesignTokenInject = () => {
|
||||||
return inject(
|
return inject(
|
||||||
DesignTokenContextKey,
|
DesignTokenContextKey,
|
||||||
computed(() => globalDesignTokenApi.value || defaultConfig),
|
computed(() => globalDesignTokenApi.value || defaultConfig),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useDesignTokenProvider = (props: ComputedRef<DesignTokenProviderProps>) => {
|
|
||||||
const parentContext = useDesignTokenInject();
|
|
||||||
const context = shallowRef<Partial<DesignTokenProviderProps>>(defaultConfig);
|
|
||||||
watch(
|
|
||||||
computed(() => [props.value, parentContext.value]),
|
|
||||||
([propsValue, parentContextValue]) => {
|
|
||||||
const mergedContext: Partial<DesignTokenProviderProps> = {
|
|
||||||
...parentContextValue,
|
|
||||||
};
|
|
||||||
Object.keys(propsValue).forEach(key => {
|
|
||||||
const value = propsValue[key];
|
|
||||||
if (propsValue[key] !== undefined) {
|
|
||||||
mergedContext[key] = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
context.value = mergedContext;
|
|
||||||
globalDesignTokenApi.value = unref(mergedContext as any);
|
|
||||||
triggerRef(globalDesignTokenApi);
|
|
||||||
},
|
|
||||||
{ immediate: true, deep: true },
|
|
||||||
);
|
|
||||||
provide(DesignTokenContextKey, context);
|
|
||||||
return context;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const DesignTokenProvider = defineComponent({
|
export const DesignTokenProvider = defineComponent({
|
||||||
props: {
|
props: {
|
||||||
value: objectType<DesignTokenProviderProps>(),
|
value: objectType<DesignTokenProviderProps>(),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { updateCSS } from '../../../vc-util/Dom/dynamicCSS';
|
import { removeCSS, updateCSS } from '../../../vc-util/Dom/dynamicCSS';
|
||||||
import { ATTR_MARK, ATTR_TOKEN, CSS_IN_JS_INSTANCE, useStyleInject } from '../StyleContext';
|
import { ATTR_MARK, ATTR_TOKEN, CSS_IN_JS_INSTANCE, useStyleInject } from '../StyleContext';
|
||||||
import { isClientSide, token2key, toStyleStr } from '../util';
|
import { isClientSide, toStyleStr } from '../util';
|
||||||
import type { TokenWithCSSVar } from '../util/css-variables';
|
import type { TokenWithCSSVar } from '../util/css-variables';
|
||||||
import { transformToken } from '../util/css-variables';
|
import { transformToken } from '../util/css-variables';
|
||||||
import type { ExtractStyle } from './useGlobalCache';
|
import type { ExtractStyle } from './useGlobalCache';
|
||||||
|
@ -14,50 +14,10 @@ export const CSS_VAR_PREFIX = 'cssVar';
|
||||||
type CSSVarCacheValue<V, T extends Record<string, V> = Record<string, V>> = [
|
type CSSVarCacheValue<V, T extends Record<string, V> = Record<string, V>> = [
|
||||||
cssVarToken: TokenWithCSSVar<V, T>,
|
cssVarToken: TokenWithCSSVar<V, T>,
|
||||||
cssVarStr: string,
|
cssVarStr: string,
|
||||||
tokenKey: string,
|
|
||||||
styleId: string,
|
styleId: string,
|
||||||
cssVarKey: string,
|
cssVarKey: string,
|
||||||
];
|
];
|
||||||
|
|
||||||
const tokenKeys = new Map<string, number>();
|
|
||||||
function recordCleanToken(tokenKey: string) {
|
|
||||||
tokenKeys.set(tokenKey, (tokenKeys.get(tokenKey) || 0) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeStyleTags(key: string, instanceId: string) {
|
|
||||||
if (typeof document !== 'undefined') {
|
|
||||||
const styles = document.querySelectorAll(`style[${ATTR_MARK}="${key}"]`);
|
|
||||||
|
|
||||||
styles.forEach(style => {
|
|
||||||
if ((style as any)[CSS_IN_JS_INSTANCE] === instanceId) {
|
|
||||||
style.parentNode?.removeChild(style);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const TOKEN_THRESHOLD = 0;
|
|
||||||
|
|
||||||
// Remove will check current keys first
|
|
||||||
function cleanTokenStyle(tokenKey: string, instanceId: string) {
|
|
||||||
tokenKeys.set(tokenKey, (tokenKeys.get(tokenKey) || 0) - 1);
|
|
||||||
|
|
||||||
const tokenKeyList = Array.from(tokenKeys.keys());
|
|
||||||
const cleanableKeyList = tokenKeyList.filter(key => {
|
|
||||||
const count = tokenKeys.get(key) || 0;
|
|
||||||
|
|
||||||
return count <= 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Should keep tokens under threshold for not to insert style too often
|
|
||||||
if (tokenKeyList.length - cleanableKeyList.length > TOKEN_THRESHOLD) {
|
|
||||||
cleanableKeyList.forEach(key => {
|
|
||||||
removeStyleTags(key, instanceId);
|
|
||||||
tokenKeys.delete(key);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const useCSSVarRegister = <V, T extends Record<string, V>>(
|
const useCSSVarRegister = <V, T extends Record<string, V>>(
|
||||||
config: ComputedRef<{
|
config: ComputedRef<{
|
||||||
path: string[];
|
path: string[];
|
||||||
|
@ -93,25 +53,20 @@ const useCSSVarRegister = <V, T extends Record<string, V>>(
|
||||||
scope: config.value.scope || '',
|
scope: config.value.scope || '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const tokenKey = token2key(mergedToken, '');
|
|
||||||
|
|
||||||
const styleId = uniqueHash(stylePath.value, cssVarsStr);
|
const styleId = uniqueHash(stylePath.value, cssVarsStr);
|
||||||
|
return [mergedToken, cssVarsStr, styleId, config.value.key];
|
||||||
recordCleanToken(tokenKey);
|
|
||||||
return [mergedToken, cssVarsStr, tokenKey, styleId, config.value.key];
|
|
||||||
},
|
},
|
||||||
([, , tokenKey]) => {
|
([, , styleId]) => {
|
||||||
if (isClientSide) {
|
if (isClientSide) {
|
||||||
// Remove token will remove all related style
|
removeCSS(styleId, { mark: ATTR_MARK });
|
||||||
cleanTokenStyle(tokenKey, styleContext.value?.cache?.instanceId);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
([, cssVarsStr, tokenKey]) => {
|
([, cssVarsStr, styleId]) => {
|
||||||
if (!cssVarsStr) {
|
if (!cssVarsStr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const style = updateCSS(cssVarsStr, tokenKey, {
|
const style = updateCSS(cssVarsStr, styleId, {
|
||||||
mark: ATTR_MARK,
|
mark: ATTR_MARK,
|
||||||
prepend: 'queue',
|
prepend: 'queue',
|
||||||
attachTo: styleContext.value.container,
|
attachTo: styleContext.value.container,
|
||||||
|
|
|
@ -49,9 +49,13 @@ export default function useGlobalCache<CacheType>(
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(deps, () => {
|
watch(
|
||||||
buildCache();
|
deps,
|
||||||
});
|
() => {
|
||||||
|
buildCache();
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
let cacheEntity = globalCache.value.get(deps.value);
|
let cacheEntity = globalCache.value.get(deps.value);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { useToken } from '../../_theme/internal';
|
import { useToken } from '../../_theme/internal';
|
||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
|
import { computed } from 'vue';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This hook is only for cssVar to add root className for components.
|
* This hook is only for cssVar to add root className for components.
|
||||||
|
@ -9,7 +10,7 @@ import type { Ref } from 'vue';
|
||||||
const useCSSVarCls = (prefixCls: Ref<string>) => {
|
const useCSSVarCls = (prefixCls: Ref<string>) => {
|
||||||
const [, , , , cssVar] = useToken();
|
const [, , , , cssVar] = useToken();
|
||||||
|
|
||||||
return cssVar.value ? `${prefixCls.value}-css-var` : '';
|
return computed(() => (cssVar.value ? `${prefixCls.value}-css-var` : ''));
|
||||||
};
|
};
|
||||||
|
|
||||||
export default useCSSVarCls;
|
export default useCSSVarCls;
|
||||||
|
|
|
@ -2,17 +2,14 @@ import type { ThemeConfig } from '../context';
|
||||||
import { defaultConfig } from '../../_theme/internal';
|
import { defaultConfig } from '../../_theme/internal';
|
||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import useThemeKey from './useThemeKey';
|
|
||||||
import devWarning from '../../vc-util/warning';
|
import devWarning from '../../vc-util/warning';
|
||||||
|
const themeKey = 'antdvtheme';
|
||||||
export default function useTheme(theme?: Ref<ThemeConfig>, parentTheme?: Ref<ThemeConfig>) {
|
export default function useTheme(theme?: Ref<ThemeConfig>, parentTheme?: Ref<ThemeConfig>) {
|
||||||
const themeConfig = computed(() => theme?.value || {});
|
const themeConfig = computed(() => theme?.value || {});
|
||||||
const parentThemeConfig = computed<ThemeConfig>(() =>
|
const parentThemeConfig = computed<ThemeConfig>(() =>
|
||||||
themeConfig.value.inherit === false || !parentTheme?.value ? defaultConfig : parentTheme.value,
|
themeConfig.value.inherit === false || !parentTheme?.value ? defaultConfig : parentTheme.value,
|
||||||
);
|
);
|
||||||
|
|
||||||
const themeKey = useThemeKey();
|
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
const cssVarEnabled = themeConfig.value.cssVar || parentThemeConfig.value.cssVar;
|
const cssVarEnabled = themeConfig.value.cssVar || parentThemeConfig.value.cssVar;
|
||||||
const validKey = !!(
|
const validKey = !!(
|
||||||
|
@ -43,6 +40,7 @@ export default function useTheme(theme?: Ref<ThemeConfig>, parentTheme?: Ref<The
|
||||||
});
|
});
|
||||||
|
|
||||||
const cssVarKey = `css-var-${themeKey.replace(/:/g, '')}`;
|
const cssVarKey = `css-var-${themeKey.replace(/:/g, '')}`;
|
||||||
|
|
||||||
const mergedCssVar = (themeConfig.value.cssVar ?? parentThemeConfig.value.cssVar) && {
|
const mergedCssVar = (themeConfig.value.cssVar ?? parentThemeConfig.value.cssVar) && {
|
||||||
prefix: 'ant', // Default to ant
|
prefix: 'ant', // Default to ant
|
||||||
...(typeof parentThemeConfig.value.cssVar === 'object' ? parentThemeConfig.value.cssVar : {}),
|
...(typeof parentThemeConfig.value.cssVar === 'object' ? parentThemeConfig.value.cssVar : {}),
|
||||||
|
|
|
@ -1,14 +1,6 @@
|
||||||
import { getCurrentInstance } from 'vue';
|
let uid = 0;
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
const useThemeKey = () => {
|
const useThemeKey = () => {
|
||||||
const instance = getCurrentInstance();
|
return 'themekey' + uid++;
|
||||||
|
|
||||||
if (!instance) {
|
|
||||||
return _.uniqueId() + '';
|
|
||||||
}
|
|
||||||
|
|
||||||
return instance.uid + '';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default useThemeKey;
|
export default useThemeKey;
|
||||||
|
|
|
@ -247,7 +247,7 @@
|
||||||
"tinycolor2": "^1.6.0",
|
"tinycolor2": "^1.6.0",
|
||||||
"ts-jest": "^28.0.5",
|
"ts-jest": "^28.0.5",
|
||||||
"ts-loader": "^9.1.0",
|
"ts-loader": "^9.1.0",
|
||||||
"tsx": "^3.12.10",
|
"tsx": "^4.0.0",
|
||||||
"typedoc": "^0.23.25",
|
"typedoc": "^0.23.25",
|
||||||
"typescript": "~4.9.3",
|
"typescript": "~4.9.3",
|
||||||
"umi-request": "^1.3.5",
|
"umi-request": "^1.3.5",
|
||||||
|
|
Loading…
Reference in New Issue