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 = {}) { loadTheme(options = {}) {
return this.load(this.theme, options, (computedStyle) => Theme.transformCSS(options.name || this.name, computedStyle)); return this.load(this.theme, options, (computedStyle) => Theme.transformCSS(options.name || this.name, computedStyle));
}, },
getCommonThemeCSS(params) { getCommonTheme(params) {
return Theme.getCommonCSS(this.name, params); return Theme.getCommon(this.name, params);
}, },
getComponentThemeCSS(params) { getComponentTheme(params) {
return Theme.getComponentCSS(this.name, params); return Theme.getComponent(this.name, params);
}, },
getDirectiveThemeCSS(params) { getDirectiveTheme(params) {
return Theme.getDirectiveCSS(this.name, params); return Theme.getDirective(this.name, params);
}, },
getPresetThemeCSS(preset, selector, params) { getPresetTheme(preset, selector, params) {
return Theme.getPresetCSS(this.name, preset, selector, params); return Theme.getCustomPreset(this.name, preset, selector, params);
}, },
getLayerOrderThemeCSS() { getLayerOrderThemeCSS() {
return Theme.getLayerOrderCSS(this.name); return Theme.getLayerOrderCSS(this.name);

View File

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

View File

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

View File

@ -97,29 +97,23 @@ export default {
getTokenValue(tokenPath) { getTokenValue(tokenPath) {
return ThemeUtils.getTokenValue(this.tokens, tokenPath, this.defaults); 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) } }); 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) } }; const options = { name, theme: this.theme, params, defaults: this.defaults, set: { layerNames: this.setLayerNames.bind(this) } };
return { return ThemeUtils.getPresetC(options);
variables: 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) } }; const options = { name, theme: this.theme, params, defaults: this.defaults, set: { layerNames: this.setLayerNames.bind(this) } };
return { return ThemeUtils.getPresetD(options);
variables: 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) } }; const options = { name, preset, options: this.options, selector, params, defaults: this.defaults, set: { layerNames: this.setLayerNames.bind(this) } };
return { return ThemeUtils.getPreset(options);
variables: ThemeUtils.getPreset(options)
};
}, },
getLayerOrderCSS(name = '') { getLayerOrderCSS(name = '') {
return ThemeUtils.getLayerOrder(name, this.options, { names: this.getLayerNames() }, this.defaults); 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 { prefix = VARIABLE.prefix, selector = VARIABLE.selector, excludedKeyRegex = VARIABLE.excludedKeyRegex } = options;
const _toVariables = (_theme, _prefix = '') => { const _toVariables = (_theme, _prefix = '') => {
return Object.entries(_theme).reduce((acc, [key, value]) => { return Object.entries(_theme).reduce(
const px = SharedUtils.object.test(excludedKeyRegex, key) ? SharedUtils.object.toNormalizeVariable(_prefix) : SharedUtils.object.toNormalizeVariable(_prefix, SharedUtils.object.toKebabCase(key)); (acc, [key, value]) => {
const v = SharedUtils.object.toValue(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)) { if (SharedUtils.object.isObject(v)) {
const variables = _toVariables(v, px); const { variables, tokens } = _toVariables(v, px);
SharedUtils.object.merge(acc, variables); SharedUtils.object.merge(acc['tokens'], tokens);
} else { SharedUtils.object.merge(acc['variables'], variables);
SharedUtils.object.setProperty(acc, SharedUtils.object.getVariableName(px), SharedUtils.object.getVariableValue(v, px, prefix, [excludedKeyRegex])); } 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 { return {
value, value: variables,
declarations: value.join(''), tokens,
css: SharedUtils.object.getRule(selector, value.join('')) declarations: variables.join(''),
css: SharedUtils.object.getRule(selector, variables.join(''))
}; };
} }

View File

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

View File

@ -15,7 +15,6 @@ export default defineNuxtModule({
layerOrder: 'tailwind-base, primevue, tailwind-utilities', layerOrder: 'tailwind-base, primevue, tailwind-utilities',
importPT: undefined, importPT: undefined,
importTheme: undefined, importTheme: undefined,
unstyled: undefined,
options: {}, options: {},
components: { components: {
prefix: '', prefix: '',
@ -40,8 +39,8 @@ export default defineNuxtModule({
setup(moduleOptions, nuxt) { setup(moduleOptions, nuxt) {
const resolver = createResolver(import.meta.url); const resolver = createResolver(import.meta.url);
const registered = register(moduleOptions); const registered = register(moduleOptions);
const { importPT, importTheme, options, unstyled } = moduleOptions; const { importPT, importTheme, options } = moduleOptions;
const hasTheme = importTheme && unstyled !== true && !options.unstyled; const hasTheme = importTheme && !options.unstyled;
nuxt.options.runtimeConfig.public.primevue = { nuxt.options.runtimeConfig.public.primevue = {
...moduleOptions, ...moduleOptions,
@ -103,7 +102,7 @@ export default defineNuxtPlugin(({ vueApp }) => {
const pt = ${importPT ? `{ pt: ${importPT.as} }` : `{}`}; const pt = ${importPT ? `{ pt: ${importPT.as} }` : `{}`};
const theme = ${hasTheme ? `{ theme: ${importTheme.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.services.map((service) => `vueApp.use(${service.as});`).join('\n')}
${registered.directives.map((directive) => `vueApp.directive('${directive.name}', ${directive.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) { function registerConfig(resolvePath, moduleOptions) {
const configs = []; const configs = [];
if (moduleOptions.unstyled === true) { configs.push({ name: 'PrimeVue', as: 'PrimeVue', from: resolvePath({ name: 'PrimeVue', as: 'PrimeVue', from: `primevue/config`, type: 'config' }) });
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' }) });
}
return configs; return configs;
} }
@ -115,7 +101,7 @@ function registerStyles(resolvePath, registered, moduleOptions) {
} }
]; ];
if (!moduleOptions.unstyled) { if (!moduleOptions?.options?.unstyled) {
if (Utils.object.isNotEmpty(registered?.components)) { if (Utils.object.isNotEmpty(registered?.components)) {
styles.push({ styles.push({
name: 'BaseComponentStyle', name: 'BaseComponentStyle',