Theming API: Refactor on methods

pull/5756/head
Mert Sincan 2024-05-14 09:35:40 +01:00
parent ed0c36da66
commit 6273826b41
8 changed files with 100 additions and 85 deletions

View File

@ -168,17 +168,17 @@ export default {
loadTheme(options = {}) {
return this.load(this.theme, options, (computedStyle) => Theme.transformCSS(options.name || this.name, computedStyle));
},
getCommonThemeCSS(params) {
return Theme.getCommonCSS(this.name, params);
getCommonTheme(params) {
return Theme.getCommon(this.name, params);
},
getComponentThemeCSS(params) {
return Theme.getComponentCSS(this.name, params);
getComponentTheme(params) {
return Theme.getComponent(this.name, params);
},
getDirectiveThemeCSS(params) {
return Theme.getDirectiveCSS(this.name, params);
getDirectiveTheme(params) {
return Theme.getDirective(this.name, params);
},
getPresetThemeCSS(preset, selector, params) {
return Theme.getPresetCSS(this.name, preset, selector, params);
getPresetTheme(preset, selector, params) {
return Theme.getCustomPreset(this.name, preset, selector, params);
},
getLayerOrderThemeCSS() {
return Theme.getLayerOrderCSS(this.name);

View File

@ -54,6 +54,7 @@ export default {
}
},
scopedStyleEl: undefined,
rootEl: undefined,
beforeCreate() {
const _usept = this.pt?.['_usept'];
const originalValue = _usept ? this.pt?.originalValue?.[this.$.type.name] : undefined;
@ -76,9 +77,13 @@ export default {
},
mounted() {
// @todo - improve performance
const rootElement = DomHandler.findSingle(this.$el, `[data-pc-name="${ObjectUtils.toFlatCase(this.$.type.name)}"]`);
this.rootEl = DomHandler.findSingle(this.$el, `[data-pc-name="${ObjectUtils.toFlatCase(this.$.type.name)}"]`);
if (this.rootEl) {
this.rootEl.setAttribute(this.$attrSelector, '');
this.rootEl.$pc = { name: this.$.type.name, ...this.$params };
}
rootElement?.setAttribute(this.$attrSelector, '');
this._hook('onMounted');
},
beforeUpdate() {
@ -151,10 +156,10 @@ export default {
// common
if (!Theme.isStyleNameLoaded('common')) {
const { primitive, semantic } = this.$style?.getCommonThemeCSS?.() || {};
const { primitive, semantic } = this.$style?.getCommonTheme?.() || {};
BaseStyle.load(primitive, { name: 'primitive-variables', ...this.$styleOptions });
BaseStyle.load(semantic, { name: 'semantic-variables', ...this.$styleOptions });
BaseStyle.load(primitive?.css, { name: 'primitive-variables', ...this.$styleOptions });
BaseStyle.load(semantic?.css, { name: 'semantic-variables', ...this.$styleOptions });
BaseStyle.loadTheme({ name: 'global-style', ...this.$styleOptions });
Theme.setLoadedStyleName('common');
@ -162,9 +167,9 @@ export default {
// component
if (!Theme.isStyleNameLoaded(this.$style?.name) && this.$style?.name) {
const { variables } = this.$style?.getComponentThemeCSS?.() || {};
const { css } = this.$style?.getComponentTheme?.() || {};
this.$style?.load(variables, { name: `${this.$style.name}-variables`, ...this.$styleOptions });
this.$style?.load(css, { name: `${this.$style.name}-variables`, ...this.$styleOptions });
this.$style?.loadTheme({ name: `${this.$style.name}-style`, ...this.$styleOptions });
Theme.setLoadedStyleName(this.$style.name);
@ -180,8 +185,8 @@ export default {
}
},
_loadScopedThemeStyles(preset) {
const { variables } = this.$style?.getPresetThemeCSS?.(preset, `[${this.$attrSelector}]`) || {};
const scopedStyle = this.$style?.load(variables, { name: `${this.$attrSelector}-${this.$style.name}`, ...this.$styleOptions });
const { css } = this.$style?.getPresetTheme?.(preset, `[${this.$attrSelector}]`) || {};
const scopedStyle = this.$style?.load(css, { name: `${this.$attrSelector}-${this.$style.name}`, ...this.$styleOptions });
this.scopedStyleEl = scopedStyle.el;
},

View File

@ -99,10 +99,10 @@ const BaseDirective = {
// common
if (!Theme.isStyleNameLoaded('common')) {
const { primitive, semantic } = instance.$style?.getCommonThemeCSS?.() || {};
const { primitive, semantic } = instance.$style?.getCommonTheme?.() || {};
BaseStyle.load(primitive, { name: 'primitive-variables', ...useStyleOptions });
BaseStyle.load(semantic, { name: 'semantic-variables', ...useStyleOptions });
BaseStyle.load(primitive?.css, { name: 'primitive-variables', ...useStyleOptions });
BaseStyle.load(semantic?.css, { name: 'semantic-variables', ...useStyleOptions });
BaseStyle.loadTheme({ name: 'global-style', ...useStyleOptions });
Theme.setLoadedStyleName('common');
@ -110,9 +110,9 @@ const BaseDirective = {
// directive
if (!Theme.isStyleNameLoaded(instance.$style?.name) && instance.$style?.name) {
const { variables } = instance.$style?.getDirectiveThemeCSS?.() || {};
const { css } = instance.$style?.getDirectiveTheme?.() || {};
instance.$style?.load(variables, { name: `${instance.$style.name}-variables`, ...useStyleOptions });
instance.$style?.load(css, { name: `${instance.$style.name}-variables`, ...useStyleOptions });
instance.$style?.loadTheme({ name: `${instance.$style.name}-style`, ...useStyleOptions });
Theme.setLoadedStyleName(instance.$style.name);
@ -131,8 +131,8 @@ const BaseDirective = {
const preset = instance.preset();
if (preset && instance.$attrSelector) {
const { variables } = instance.$style?.getPresetThemeCSS?.(preset, `[${instance.$attrSelector}]`) || {};
const scopedStyle = instance.$style?.load(variables, { name: `${instance.$attrSelector}-${instance.$style.name}`, ...useStyleOptions });
const { css } = instance.$style?.getPresetTheme?.(preset, `[${instance.$attrSelector}]`) || {};
const scopedStyle = instance.$style?.load(css, { name: `${instance.$attrSelector}-${instance.$style.name}`, ...useStyleOptions });
instance.scopedStyleEl = scopedStyle.el;
}
@ -192,6 +192,9 @@ const BaseDirective = {
el.$instance[hook]?.(el, binding, vnode, prevVnode); // handle hook in directive implementation
el[`$${name}`] = el.$instance; // expose all options with $<directive_name>
BaseDirective._hook(name, hook, el, binding, vnode, prevVnode); // handle hooks during directive uses (global and self-definition)
el.$pd ||= {};
el.$pd[name] = { ...el.$pd?.[name], name, instance: el.$instance };
};
const handleWatch = (el) => {

View File

@ -97,29 +97,23 @@ export default {
getTokenValue(tokenPath) {
return ThemeUtils.getTokenValue(this.tokens, tokenPath, this.defaults);
},
getCommonCSS(name = '', params) {
getCommon(name = '', params) {
return ThemeUtils.getCommon({ name, theme: this.theme, params, defaults: this.defaults, set: { layerNames: this.setLayerNames.bind(this) } });
},
getComponentCSS(name = '', params) {
getComponent(name = '', params) {
const options = { name, theme: this.theme, params, defaults: this.defaults, set: { layerNames: this.setLayerNames.bind(this) } };
return {
variables: ThemeUtils.getPresetC(options)
};
return ThemeUtils.getPresetC(options);
},
getDirectiveCSS(name = '', params) {
getDirective(name = '', params) {
const options = { name, theme: this.theme, params, defaults: this.defaults, set: { layerNames: this.setLayerNames.bind(this) } };
return {
variables: ThemeUtils.getPresetD(options)
};
return ThemeUtils.getPresetD(options);
},
getPresetCSS(name = '', preset, selector, params) {
getCustomPreset(name = '', preset, selector, params) {
const options = { name, preset, options: this.options, selector, params, defaults: this.defaults, set: { layerNames: this.setLayerNames.bind(this) } };
return {
variables: ThemeUtils.getPreset(options)
};
return ThemeUtils.getPreset(options);
},
getLayerOrderCSS(name = '') {
return ThemeUtils.getLayerOrder(name, this.options, { names: this.getLayerNames() }, this.defaults);

View File

@ -5,27 +5,33 @@ export default function (theme, options = {}) {
const { prefix = VARIABLE.prefix, selector = VARIABLE.selector, excludedKeyRegex = VARIABLE.excludedKeyRegex } = options;
const _toVariables = (_theme, _prefix = '') => {
return Object.entries(_theme).reduce((acc, [key, value]) => {
const px = SharedUtils.object.test(excludedKeyRegex, key) ? SharedUtils.object.toNormalizeVariable(_prefix) : SharedUtils.object.toNormalizeVariable(_prefix, SharedUtils.object.toKebabCase(key));
const v = SharedUtils.object.toValue(value);
return Object.entries(_theme).reduce(
(acc, [key, value]) => {
const px = SharedUtils.object.test(excludedKeyRegex, key) ? SharedUtils.object.toNormalizeVariable(_prefix) : SharedUtils.object.toNormalizeVariable(_prefix, SharedUtils.object.toKebabCase(key));
const v = SharedUtils.object.toValue(value);
if (SharedUtils.object.isObject(v)) {
const variables = _toVariables(v, px);
if (SharedUtils.object.isObject(v)) {
const { variables, tokens } = _toVariables(v, px);
SharedUtils.object.merge(acc, variables);
} else {
SharedUtils.object.setProperty(acc, SharedUtils.object.getVariableName(px), SharedUtils.object.getVariableValue(v, px, prefix, [excludedKeyRegex]));
}
SharedUtils.object.merge(acc['tokens'], tokens);
SharedUtils.object.merge(acc['variables'], variables);
} else {
acc['tokens'].push((prefix ? px.replace(`${prefix}-`, '') : px).replaceAll('-', '.'));
SharedUtils.object.setProperty(acc['variables'], SharedUtils.object.getVariableName(px), SharedUtils.object.getVariableValue(v, px, prefix, [excludedKeyRegex]));
}
return acc;
}, []);
return acc;
},
{ variables: [], tokens: [] }
);
};
const value = _toVariables(theme, prefix);
const { variables, tokens } = _toVariables(theme, prefix);
return {
value,
declarations: value.join(''),
css: SharedUtils.object.getRule(selector, value.join(''))
value: variables,
tokens,
declarations: variables.join(''),
css: SharedUtils.object.getRule(selector, variables.join(''))
};
}

View File

@ -46,42 +46,63 @@ export default {
},
getCommon({ name = '', theme = {}, params, set, defaults }) {
const { preset, options } = theme;
let primitive_css, semantic_css;
let primitive_css, primitive_tokens, semantic_css, semantic_tokens;
if (SharedUtils.object.isNotEmpty(preset)) {
const { primitive, semantic } = preset;
const { colorScheme, ...sRest } = semantic || {};
const { dark, ...csRest } = colorScheme || {};
const prim_css = SharedUtils.object.isNotEmpty(primitive) ? this._toVariables({ primitive }, options).declarations : '';
const sRest_css = SharedUtils.object.isNotEmpty(sRest) ? this._toVariables({ semantic: sRest }, options).declarations : '';
const csRest_css = SharedUtils.object.isNotEmpty(csRest) ? this._toVariables({ light: csRest }, options).declarations : '';
const dark_css = SharedUtils.object.isNotEmpty(dark) ? this._toVariables({ dark }, options).declarations : '';
const prim_var = SharedUtils.object.isNotEmpty(primitive) ? this._toVariables({ primitive }, options) : {};
const sRest_var = SharedUtils.object.isNotEmpty(sRest) ? this._toVariables({ semantic: sRest }, options) : {};
const csRest_var = SharedUtils.object.isNotEmpty(csRest) ? this._toVariables({ light: csRest }, options) : {};
const dark_var = SharedUtils.object.isNotEmpty(dark) ? this._toVariables({ dark }, options) : {};
const [prim_css, prim_tokens] = [prim_var.declarations ?? '', prim_var.tokens];
const [sRest_css, sRest_tokens] = [sRest_var.declarations ?? '', sRest_var.tokens || []];
const [csRest_css, csRest_tokens] = [csRest_var.declarations ?? '', csRest_var.tokens || []];
const [dark_css, dark_tokens] = [dark_var.declarations ?? '', dark_var.tokens || []];
primitive_css = this.transformCSS(name, prim_css, 'light', 'variable', options, set, defaults);
primitive_tokens = prim_tokens;
const semantic_light_css = this.transformCSS(name, `${sRest_css}${csRest_css}color-scheme:light`, 'light', 'variable', options, set, defaults);
const semantic_dark_css = this.transformCSS(name, `${dark_css}color-scheme:dark`, 'dark', 'variable', options, set, defaults);
semantic_css = `${semantic_light_css}${semantic_dark_css}`;
semantic_tokens = [...new Set([...sRest_tokens, ...csRest_tokens, ...dark_tokens])];
}
return {
primitive: primitive_css,
semantic: semantic_css
primitive: {
css: primitive_css,
tokens: primitive_tokens
},
semantic: {
css: semantic_css,
tokens: semantic_tokens
}
};
},
getPreset({ name = '', preset = {}, options, params, set, defaults, selector }) {
const _name = name.replace('-directive', '');
const { colorScheme, ...vRest } = preset;
const { dark, ...csRest } = colorScheme || {};
const vRest_css = SharedUtils.object.isNotEmpty(vRest) ? this._toVariables({ [_name]: vRest }, options).declarations : '';
const csRest_css = SharedUtils.object.isNotEmpty(csRest) ? this._toVariables({ [_name]: csRest }, options).declarations : '';
const dark_css = SharedUtils.object.isNotEmpty(dark) ? this._toVariables({ [_name]: dark }, options).declarations : '';
const vRest_var = SharedUtils.object.isNotEmpty(vRest) ? this._toVariables({ [_name]: vRest }, options) : {};
const csRest_var = SharedUtils.object.isNotEmpty(csRest) ? this._toVariables({ [_name]: csRest }, options) : {};
const dark_var = SharedUtils.object.isNotEmpty(dark) ? this._toVariables({ [_name]: dark }, options) : {};
const [vRest_css, vRest_tokens] = [vRest_var.declarations ?? '', vRest_var.tokens || []];
const [csRest_css, csRest_tokens] = [csRest_var.declarations ?? '', csRest_var.tokens || []];
const [dark_css, dark_tokens] = [dark_var.declarations ?? '', dark_var.tokens || []];
const tokens = [...new Set([...vRest_tokens, ...csRest_tokens, ...dark_tokens])];
const light_variable_css = this.transformCSS(_name, `${vRest_css}${csRest_css}`, 'light', 'variable', options, set, defaults, selector);
const dark_variable_css = this.transformCSS(_name, dark_css, 'dark', 'variable', options, set, defaults, selector);
return `${light_variable_css}${dark_variable_css}`;
return {
css: `${light_variable_css}${dark_variable_css}`,
tokens
};
},
getPresetC({ name = '', theme = {}, params, set, defaults }) {
const { preset, options } = theme;
@ -111,7 +132,8 @@ export default {
return '';
},
getCommonStyleSheet({ name = '', theme = {}, params, props = {}, set, defaults }) {
const common_css = this.getCommon({ name, theme, params, set, defaults });
const { primitive, semantic } = this.getCommon({ name, theme, params, set, defaults });
const common_css = `${primitive.css}${semantic.css}`;
const _props = Object.entries(props)
.reduce((acc, [k, v]) => acc.push(`${k}="${v}"`) && acc, [])
.join(' ');
@ -130,7 +152,7 @@ export default {
.join('');
},
getStyleSheet({ name = '', theme = {}, params, props = {}, set, defaults }) {
const presetC_css = this.getPresetC({ name, theme, params, set, defaults });
const presetC_css = this.getPresetC({ name, theme, params, set, defaults })?.css;
const _props = Object.entries(props)
.reduce((acc, [k, v]) => acc.push(`${k}="${v}"`) && acc, [])
.join(' ');

View File

@ -15,7 +15,6 @@ export default defineNuxtModule({
layerOrder: 'tailwind-base, primevue, tailwind-utilities',
importPT: undefined,
importTheme: undefined,
unstyled: undefined,
options: {},
components: {
prefix: '',
@ -40,8 +39,8 @@ export default defineNuxtModule({
setup(moduleOptions, nuxt) {
const resolver = createResolver(import.meta.url);
const registered = register(moduleOptions);
const { importPT, importTheme, options, unstyled } = moduleOptions;
const hasTheme = importTheme && unstyled !== true && !options.unstyled;
const { importPT, importTheme, options } = moduleOptions;
const hasTheme = importTheme && !options.unstyled;
nuxt.options.runtimeConfig.public.primevue = {
...moduleOptions,
@ -103,7 +102,7 @@ export default defineNuxtPlugin(({ vueApp }) => {
const pt = ${importPT ? `{ pt: ${importPT.as} }` : `{}`};
const theme = ${hasTheme ? `{ theme: ${importTheme.as} }` : `{}`};
usePrimeVue && vueApp.use(${unstyled === true ? 'PrimeVueUnstyled' : unstyled === false ? 'PrimeVueStyled' : 'PrimeVue'}, { ...options, ...pt, ...theme });
usePrimeVue && vueApp.use(PrimeVue, { ...options, ...pt, ...theme });
${registered.services.map((service) => `vueApp.use(${service.as});`).join('\n')}
${registered.directives.map((directive) => `vueApp.directive('${directive.name}', ${directive.as});`).join('\n')}
});

View File

@ -20,21 +20,7 @@ function registerItems(items = [], options = {}, params) {
function registerConfig(resolvePath, moduleOptions) {
const configs = [];
if (moduleOptions.unstyled === true) {
configs.push({
name: 'PrimeVueUnstyled',
as: 'PrimeVueUnstyled',
from: resolvePath({ name: 'PrimeVueUnstyled', as: 'PrimeVueUnstyled', from: `primevue/unstyled`, type: 'config' })
});
} else if (moduleOptions.unstyled === false) {
configs.push({
name: 'PrimeVueStyled',
as: 'PrimeVueStyled',
from: resolvePath({ name: 'PrimeVueStyled', as: 'PrimeVueStyled', from: `primevue/styled`, type: 'config' })
});
} else {
configs.push({ name: 'PrimeVue', as: 'PrimeVue', from: resolvePath({ name: 'PrimeVue', as: 'PrimeVue', from: `primevue/config`, type: 'config' }) });
}
configs.push({ name: 'PrimeVue', as: 'PrimeVue', from: resolvePath({ name: 'PrimeVue', as: 'PrimeVue', from: `primevue/config`, type: 'config' }) });
return configs;
}
@ -115,7 +101,7 @@ function registerStyles(resolvePath, registered, moduleOptions) {
}
];
if (!moduleOptions.unstyled) {
if (!moduleOptions?.options?.unstyled) {
if (Utils.object.isNotEmpty(registered?.components)) {
styles.push({
name: 'BaseComponentStyle',