diff --git a/components/lib/badgedirective/BadgeDirective.js b/components/lib/badgedirective/BadgeDirective.js index 3a8930cb6..1c325cf9c 100644 --- a/components/lib/badgedirective/BadgeDirective.js +++ b/components/lib/badgedirective/BadgeDirective.js @@ -8,6 +8,7 @@ const BadgeDirective = BaseBadgeDirective.extend('badge', { const badge = DomHandler.createElement('span', { id, class: !this.isUnstyled() && this.cx('root'), + [this.$attrSelector]: '', 'p-bind': this.ptm('root', { context: { ...binding.modifiers, diff --git a/components/lib/basedirective/BaseDirective.js b/components/lib/basedirective/BaseDirective.js index 2de2d7a1f..bb8165bc7 100644 --- a/components/lib/basedirective/BaseDirective.js +++ b/components/lib/basedirective/BaseDirective.js @@ -1,6 +1,6 @@ import BaseStyle from 'primevue/base/style'; import Theme, { ThemeService } from 'primevue/themes'; -import { ObjectUtils } from 'primevue/utils'; +import { ObjectUtils, UniqueComponentId } from 'primevue/utils'; import { mergeProps } from 'vue'; const BaseDirective = { @@ -82,6 +82,8 @@ const BaseDirective = { BaseDirective._loadThemeStyles(el.$instance, { nonce: config?.csp?.nonce }); ThemeService.on('theme:change', () => BaseDirective._loadThemeStyles(el.$instance, { nonce: config?.csp?.nonce })); + + BaseDirective._loadScopedThemeStyles(el.$instance, { nonce: config?.csp?.nonce }); }, _loadThemeStyles: (instance = {}, useStyleOptions) => { if (instance?.isUnstyled()) return; @@ -116,6 +118,16 @@ const BaseDirective = { Theme.setLoadedStyleName('layer-order'); } }, + _loadScopedThemeStyles(instance = {}, useStyleOptions) { + const preset = instance.preset(); + + if (preset && instance.$attrSelector) { + const variables = instance.$style?.getPresetThemeCSS?.(preset, `[${instance.$attrSelector}]`) || {}; + const scopedStyle = instance.$style?.loadTheme(variables, { name: `${instance.$attrSelector}-${instance.$style.name}`, ...useStyleOptions }); + + instance.scopedStyleEl = scopedStyle.el; + } + }, _hook: (directiveName, hookName, el, binding, vnode, prevVnode) => { const name = `on${ObjectUtils.toCapitalCase(hookName)}`; const config = BaseDirective._getConfig(binding, vnode); @@ -149,10 +161,12 @@ const BaseDirective = { $el: $prevInstance['$el'] || el || undefined, $style: { classes: undefined, inlineStyles: undefined, loadStyle: () => {}, loadTheme: () => {}, ...options?.style }, $config: config, + $attrSelector: el.$attrSelector, /* computed instance variables */ defaultPT: () => BaseDirective._getPT(config?.pt, undefined, (value) => value?.directives?.[name]), isUnstyled: () => (el.$instance?.$binding?.value?.unstyled !== undefined ? el.$instance?.$binding?.value?.unstyled : config?.unstyled), theme: () => el.$instance?.$config?.theme, + preset: () => el.$instance?.$binding?.value?.dt, /* instance's methods */ ptm: (key = '', params = {}) => BaseDirective._getPTValue(el.$instance, el.$instance?.$binding?.value?.pt, key, { ...params }), ptmo: (obj = {}, key = '', params = {}) => BaseDirective._getPTValue(el.$instance, obj, key, params, false), @@ -172,6 +186,7 @@ const BaseDirective = { handleHook('created', el, binding, vnode, prevVnode); }, beforeMount: (el, binding, vnode, prevVnode) => { + el.$attrSelector = UniqueComponentId('pd'); BaseDirective._loadStyles(el, binding, vnode); handleHook('beforeMount', el, binding, vnode, prevVnode); }, @@ -190,6 +205,7 @@ const BaseDirective = { handleHook('beforeUnmount', el, binding, vnode, prevVnode); }, unmounted: (el, binding, vnode, prevVnode) => { + el.$instance?.scopedStyleEl?.value?.remove(); handleHook('unmounted', el, binding, vnode, prevVnode); } }; diff --git a/components/lib/ripple/Ripple.js b/components/lib/ripple/Ripple.js index f44816648..5a8b94396 100644 --- a/components/lib/ripple/Ripple.js +++ b/components/lib/ripple/Ripple.js @@ -31,6 +31,7 @@ const Ripple = BaseRipple.extend('ripple', { 'data-p-ink-active': false, class: !this.isUnstyled() && this.cx('root'), onAnimationEnd: this.onAnimationEnd.bind(this), + [this.$attrSelector]: '', 'p-bind': this.ptm('root') }); diff --git a/components/lib/themes/utils/themeUtils.js b/components/lib/themes/utils/themeUtils.js index a380437ab..cf83ffb5b 100644 --- a/components/lib/themes/utils/themeUtils.js +++ b/components/lib/themes/utils/themeUtils.js @@ -72,14 +72,15 @@ export default { }; }, 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_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 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 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}`; }, diff --git a/components/lib/tooltip/Tooltip.js b/components/lib/tooltip/Tooltip.js index fda785019..68ac710ae 100755 --- a/components/lib/tooltip/Tooltip.js +++ b/components/lib/tooltip/Tooltip.js @@ -279,6 +279,7 @@ const Tooltip = BaseTooltip.extend('tooltip', { pointerEvents: !this.isUnstyled() && el.$_ptooltipAutoHide && 'none' }, class: [!this.isUnstyled() && this.cx('root'), el.$_ptooltipClass], + [this.$attrSelector]: '', 'p-bind': this.ptm('root', { context: modifiers })