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: { variable: {
prefix: '', prefix: '',
selector: ':root', 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: { colorScheme: {
light: { light: {
@ -29,11 +29,13 @@ export default {
_initialized: false, _initialized: false,
_currentColorScheme: 'light', _currentColorScheme: 'light',
_layerNames: new Set(), _layerNames: new Set(),
_tokens: {},
init() { init() {
if (!this._initialized) { if (!this._initialized) {
this.applyColorScheme(); this.applyColorScheme();
} }
this._tokens = ThemeUtils.createTokens(this.preset, this.getCurrentColorScheme(), this.defaults);
this._initialized = true; this._initialized = true;
}, },
get theme() { get theme() {
@ -51,14 +53,21 @@ export default {
get extend() { get extend() {
return this.theme?.extend || {}; return this.theme?.extend || {};
}, },
get tokens() {
return this._tokens;
},
getPConfig() { getPConfig() {
return this._pConfig; return this._pConfig;
}, },
setPConfig(newValue) { setPConfig(newValue) {
this._pConfig = newValue; this._pConfig = newValue;
}, },
getTokenValue(tokenPath) {
return ThemeUtils.getTokenValue(this.tokens, tokenPath, this.defaults);
},
setTheme(newValue) { setTheme(newValue) {
this._theme = newValue; this._theme = newValue;
this._tokens = ThemeUtils.createTokens(newValue, this.defaults);
}, },
getCurrentColorScheme() { getCurrentColorScheme() {
return this._currentColorScheme; return this._currentColorScheme;

View File

@ -2,20 +2,20 @@ import Theme, { SharedUtils } from 'primevue/themes';
const VARIABLE = Theme.defaults.variable; const VARIABLE = Theme.defaults.variable;
export const $dt = (tokenPath) => { export const $dt = (tokenPath, type) => {
const config = Theme.getPConfig(); 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) { if (tokenPath) {
const { prefix, transform } = theme?.options || {}; const { prefix, transform } = theme?.options || {};
const regex = /{([^}]*)}/g; const regex = /{([^}]*)}/g;
const token = SharedUtils.object.test(regex, tokenPath) ? tokenPath : `{${tokenPath}}`; 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 ''; return '';

View File

@ -34,6 +34,9 @@ export default {
.toLowerCase() .toLowerCase()
: str; : str;
}, },
toTokenKey(str) {
return this.isString(str) ? str.replace(/[A-Z]/g, (c, i) => (i === 0 ? c : '.' + c.toLowerCase())).toLowerCase() : str;
},
merge(value1, value2) { merge(value1, value2) {
if (this.isArray(value1)) { if (this.isArray(value1)) {
value1.push(...(value2 || [])); 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 { return {
primitive: primitive_css, primitive: primitive_css,
@ -53,7 +53,7 @@ export default {
getBaseC({ name = '', theme = {}, params, set, defaults }) { getBaseC({ name = '', theme = {}, params, set, defaults }) {
const { base, options } = theme; const { base, options } = theme;
const { css } = base?.components?.[name] || {}; 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); return this._transformCSS(name, computed_css, undefined, 'style', options, set, defaults);
}, },
@ -72,7 +72,7 @@ export default {
getBaseD({ name = '', theme = {}, params, set, defaults }) { getBaseD({ name = '', theme = {}, params, set, defaults }) {
const { base, options } = theme; const { base, options } = theme;
const { css } = base?.directives?.[name] || {}; 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); return this._transformCSS(name, computed_css, undefined, 'style', options, set, defaults);
}, },
@ -190,5 +190,62 @@ export default {
} }
return ''; 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);
} }
}; };