Theming API: implement `$dt(tokenPath, 'value')` method

pull/5507/head
mertsincan 2024-03-19 12:50:54 +00:00
parent 14c6e47b32
commit 855be4bfa1
4 changed files with 78 additions and 9 deletions

View File

@ -5,7 +5,7 @@ export default {
variable: {
prefix: '',
selector: ':root',
excludedKeyRegex: /^(primitive|semantic|variables|colorscheme|light|dark|common|colors|root|states)$/gi
excludedKeyRegex: /^(primitive|semantic|variables|colorscheme|light|dark|common|colors|root|states|components|directives)$/gi
},
colorScheme: {
light: {
@ -29,11 +29,13 @@ export default {
_initialized: false,
_currentColorScheme: 'light',
_layerNames: new Set(),
_tokens: {},
init() {
if (!this._initialized) {
this.applyColorScheme();
}
this._tokens = ThemeUtils.createTokens(this.preset, this.getCurrentColorScheme(), this.defaults);
this._initialized = true;
},
get theme() {
@ -51,14 +53,21 @@ export default {
get extend() {
return this.theme?.extend || {};
},
get tokens() {
return this._tokens;
},
getPConfig() {
return this._pConfig;
},
setPConfig(newValue) {
this._pConfig = newValue;
},
getTokenValue(tokenPath) {
return ThemeUtils.getTokenValue(this.tokens, tokenPath, this.defaults);
},
setTheme(newValue) {
this._theme = newValue;
this._tokens = ThemeUtils.createTokens(newValue, this.defaults);
},
getCurrentColorScheme() {
return this._currentColorScheme;

View File

@ -2,20 +2,20 @@ import Theme, { SharedUtils } from 'primevue/themes';
const VARIABLE = Theme.defaults.variable;
export const $dt = (tokenPath) => {
export const $dt = (tokenPath, type) => {
const config = Theme.getPConfig();
return dt(config?.theme, tokenPath);
return dt(config?.theme, tokenPath, type);
};
export const dt = (theme = {}, tokenPath) => {
export const dt = (theme = {}, tokenPath, type) => {
if (tokenPath) {
const { prefix, transform } = theme?.options || {};
const regex = /{([^}]*)}/g;
const token = SharedUtils.object.test(regex, tokenPath) ? tokenPath : `{${tokenPath}}`;
const isStrictTransform = transform === 'strict'; // @todo - TRANSFORM: strict | lenient
const isStrictTransform = type === 'value' || transform === 'strict'; // @todo - TRANSFORM: strict | lenient(default)
return isStrictTransform ? SharedUtils.object.getComputedValue(theme?.preset, token, [VARIABLE.excludedKeyRegex]) : SharedUtils.object.getVariableValue(token, undefined, prefix, [VARIABLE.excludedKeyRegex]);
return isStrictTransform ? Theme.getTokenValue(tokenPath) : SharedUtils.object.getVariableValue(token, undefined, prefix, [VARIABLE.excludedKeyRegex]);
}
return '';

View File

@ -34,6 +34,9 @@ export default {
.toLowerCase()
: str;
},
toTokenKey(str) {
return this.isString(str) ? str.replace(/[A-Z]/g, (c, i) => (i === 0 ? c : '.' + c.toLowerCase())).toLowerCase() : str;
},
merge(value1, value2) {
if (this.isArray(value1)) {
value1.push(...(value2 || []));

View File

@ -30,7 +30,7 @@ export default {
)}`;
}
global_css = SharedUtils.object.getItemValue(base?.components?.global?.css, { ...params, dt: (tokenPath) => dt(theme, tokenPath) });
global_css = SharedUtils.object.getItemValue(base?.components?.global?.css, { ...params, dt: (tokenPath, type) => dt(theme, tokenPath, type) });
return {
primitive: primitive_css,
@ -53,7 +53,7 @@ export default {
getBaseC({ name = '', theme = {}, params, set, defaults }) {
const { base, options } = theme;
const { css } = base?.components?.[name] || {};
const computed_css = SharedUtils.object.getItemValue(css, { ...params, dt: (tokenPath) => dt(theme, tokenPath) });
const computed_css = SharedUtils.object.getItemValue(css, { ...params, dt: (tokenPath, type) => dt(theme, tokenPath, type) });
return this._transformCSS(name, computed_css, undefined, 'style', options, set, defaults);
},
@ -72,7 +72,7 @@ export default {
getBaseD({ name = '', theme = {}, params, set, defaults }) {
const { base, options } = theme;
const { css } = base?.directives?.[name] || {};
const computed_css = SharedUtils.object.getItemValue(css, { ...params, dt: (tokenPath) => dt(theme, tokenPath) });
const computed_css = SharedUtils.object.getItemValue(css, { ...params, dt: (tokenPath, type) => dt(theme, tokenPath, type) });
return this._transformCSS(name, computed_css, undefined, 'style', options, set, defaults);
},
@ -190,5 +190,62 @@ export default {
}
return '';
},
createTokens(obj = {}, currentColorScheme, defaults, parentKey = '', parentPath = '', tokens = {}) {
Object.entries(obj).forEach(([key, value]) => {
const currentKey = SharedUtils.object.test(defaults.variable.excludedKeyRegex, key) ? parentKey : parentKey ? `${parentKey}.${SharedUtils.object.toTokenKey(key)}` : SharedUtils.object.toTokenKey(key);
const currentPath = parentPath ? `${parentPath}.${key}` : key;
if (SharedUtils.object.isObject(value)) {
this.createTokens(value, currentColorScheme, defaults, currentKey, currentPath, tokens);
} else {
tokens[currentKey] ||= {
paths: [],
computed(colorScheme) {
const scheme = colorScheme || currentColorScheme;
return this.paths.find((p) => p.scheme === scheme || p.scheme === 'none')?.computed();
}
};
tokens[currentKey].paths.push({
path: currentPath,
value,
scheme: currentPath.includes('colorScheme.light') ? 'light' : currentPath.includes('colorScheme.dark') ? 'dark' : 'none',
computed(colorScheme) {
const regex = /{([^}]*)}/g;
if (SharedUtils.object.test(regex, value)) {
const val = value.trim();
const _val = val.replaceAll(regex, (v) => {
const path = v.replace(/{|}/g, '');
return tokens[path]?.computed(colorScheme);
});
const calculationRegex = /(\d+\w*\s+[\+\-\*\/]\s+\d+\w*)/g;
const cleanedVarRegex = /var\([^)]+\)/g;
return SharedUtils.object.test(calculationRegex, _val.replace(cleanedVarRegex, '0')) ? `calc(${_val})` : _val;
}
return value;
}
});
}
});
return tokens;
},
getTokenValue(tokens, path, defaults) {
const normalizePath = (str) => {
const strArr = str.split('.');
return strArr.filter((s) => !SharedUtils.object.test(defaults.variable.excludedKeyRegex, s.toLowerCase())).join('.');
};
const token = normalizePath(path);
const colorScheme = path.includes('colorScheme.light') ? 'light' : path.includes('colorScheme.dark') ? 'dark' : undefined;
return tokens[token]?.computed(colorScheme);
}
};