diff --git a/components/lib/base/style/BaseStyle.js b/components/lib/base/style/BaseStyle.js index bbe464b06..9cf0b907e 100644 --- a/components/lib/base/style/BaseStyle.js +++ b/components/lib/base/style/BaseStyle.js @@ -40,7 +40,9 @@ export default { return css ? useStyle(ObjectUtils.minifyCSS(css), { name: this.name, ...options }) : {}; }, loadTheme(theme, options = {}) { - return theme ? useStyle(ObjectUtils.minifyCSS(theme), { name: this.name, ...options }) : {}; + const callbacks = { onMounted: (name) => Theme.onStyleMounted(name), onUpdated: (name) => Theme.onStyleUpdated(name), onLoad: (event, options) => Theme.onStyleLoaded(event, options) }; + + return theme ? useStyle(ObjectUtils.minifyCSS(theme), { name: this.name, ...options, ...callbacks }) : {}; }, getCommonThemeCSS(params) { return Theme.getCommonCSS(this.name, params); diff --git a/components/lib/themes/config/index.js b/components/lib/themes/config/index.js index cdc57919f..d888e3ca9 100644 --- a/components/lib/themes/config/index.js +++ b/components/lib/themes/config/index.js @@ -16,6 +16,7 @@ export default { _theme: undefined, _layerNames: new Set(), _loadedStyleNames: new Set(), + _loadingStyles: new Set(), _tokens: {}, update(newValues = {}) { const { theme } = newValues; @@ -121,5 +122,19 @@ export default { }, getStyleSheet(name, params, props = {}) { return ThemeUtils.getStyleSheet({ name, theme: this.theme, params, props, defaults: this.defaults, set: { layerNames: this.setLayerNames.bind(this) } }); + }, + onStyleMounted(name) { + this._loadingStyles.add(name); + }, + onStyleUpdated(name) { + this._loadingStyles.add(name); + }, + onStyleLoaded(event, { name }) { + if (this._loadingStyles.size) { + this._loadingStyles.delete(name); + + ThemeService.emit(`theme:${name}:load`, event); // Exp: ThemeService.emit('theme:panel-style:load', event) + !this._loadingStyles.size && ThemeService.emit('theme:load'); + } } }; diff --git a/components/lib/usestyle/UseStyle.js b/components/lib/usestyle/UseStyle.js index 625a0ae7d..6907be85c 100644 --- a/components/lib/usestyle/UseStyle.js +++ b/components/lib/usestyle/UseStyle.js @@ -19,7 +19,20 @@ export function useStyle(css, options = {}) { const styleRef = ref(null); const defaultDocument = DomHandler.isClient() ? window.document : undefined; - const { document = defaultDocument, immediate = true, manual = false, name = `style_${++_id}`, id = undefined, media = undefined, nonce = undefined, first = false, onLoad = undefined, props = {} } = options; + const { + document = defaultDocument, + immediate = true, + manual = false, + name = `style_${++_id}`, + id = undefined, + media = undefined, + nonce = undefined, + first = false, + onMounted: onStyleMounted = undefined, + onUpdated: onStyleUpdated = undefined, + onLoad: onStyleLoaded = undefined, + props = {} + } = options; let stop = () => {}; @@ -42,9 +55,10 @@ export function useStyle(css, options = {}) { nonce: _nonce }); first ? document.head.prepend(styleRef.value) : document.head.appendChild(styleRef.value); - DomHandler.setAttribute(styleRef.value, 'data-primevue-style-id', name); + DomHandler.setAttribute(styleRef.value, 'data-primevue-style-id', _name); DomHandler.setAttributes(styleRef.value, _styleProps); - styleRef.value.onload = onLoad; + styleRef.value.onload = (event) => onStyleLoaded?.(event, { name: _name }); + onStyleMounted?.(_name); } if (isLoaded.value) return; @@ -53,6 +67,7 @@ export function useStyle(css, options = {}) { cssRef, (value) => { styleRef.value.textContent = value; + onStyleUpdated?.(_name); }, { immediate: true } );