From 9911c8f60119c1d8477897493665cdf277f90ab0 Mon Sep 17 00:00:00 2001 From: mertsincan Date: Tue, 16 May 2023 11:30:26 +0100 Subject: [PATCH] Refactor #3965 - Add useStyle hook for dynamic styling --- components/lib/usestyle/UseStyle.js | 70 ++++++++++++++++++++++++++++ components/lib/usestyle/package.json | 6 +++ rollup.config.js | 1 + vite.config.js | 1 + 4 files changed, 78 insertions(+) create mode 100644 components/lib/usestyle/UseStyle.js create mode 100644 components/lib/usestyle/package.json diff --git a/components/lib/usestyle/UseStyle.js b/components/lib/usestyle/UseStyle.js new file mode 100644 index 000000000..9d61bb758 --- /dev/null +++ b/components/lib/usestyle/UseStyle.js @@ -0,0 +1,70 @@ +/* + * Ported from useStyleTag in @vueuse/core + * https://github.com/vueuse + */ +import { DomHandler } from 'primevue/utils'; +import { getCurrentInstance, nextTick, onMounted, readonly, ref, watch } from 'vue'; + +function tryOnMounted(fn, sync = true) { + if (getCurrentInstance()) onMounted(fn); + else if (sync) fn(); + else nextTick(fn); +} + +let _id = 0; + +export function useStyle(css, options = {}) { + const isLoaded = ref(false); + + const defaultDocument = DomHandler.isClient() ? window.document : undefined; + const { document = defaultDocument, immediate = true, manual = false, id = `primevue_style_${++_id}` } = options; + + const cssRef = ref(css); + + let stop = () => {}; + + const load = () => { + if (!document) return; + + const el = document.getElementById(id) || document.createElement('style'); + + if (!el.isConnected) { + el.type = 'text/css'; + el.id = id; + if (options.media) el.media = options.media; + document.head.appendChild(el); + } + + if (isLoaded.value) return; + + stop = watch( + cssRef, + (value) => { + el.textContent = value; + }, + { immediate: true } + ); + + isLoaded.value = true; + }; + + const unload = () => { + if (!document || !isLoaded.value) return; + stop(); + document.head.removeChild(document.getElementById(id)); + isLoaded.value = false; + }; + + if (immediate && !manual) tryOnMounted(load); + + /*if (!manual) + tryOnScopeDispose(unload)*/ + + return { + id, + css: cssRef, + unload, + load, + isLoaded: readonly(isLoaded) + }; +} diff --git a/components/lib/usestyle/package.json b/components/lib/usestyle/package.json new file mode 100644 index 000000000..ab7eb70ca --- /dev/null +++ b/components/lib/usestyle/package.json @@ -0,0 +1,6 @@ +{ + "main": "./usestyle.cjs.js", + "module": "./usestyle.esm.js", + "unpkg": "./usestyle.min.js", + "types": "./UseStyle.d.ts" +} \ No newline at end of file diff --git a/rollup.config.js b/rollup.config.js index e69c5a824..1a110952d 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -77,6 +77,7 @@ let coreDependencies = { 'primevue/useconfirm': 'primevue.useconfirm', 'primevue/usetoast': 'primevue.usetoast', 'primevue/usedialog': 'primevue.usedialog', + 'primevue/usestyle': 'primevue.usestyle', 'primevue/button': 'primevue.button', 'primevue/inputtext': 'primevue.inputtext', 'primevue/inputnumber': 'primevue.inputnumber', diff --git a/vite.config.js b/vite.config.js index 1f804586d..49063aecd 100644 --- a/vite.config.js +++ b/vite.config.js @@ -10,6 +10,7 @@ export default { 'primevue/usetoast': path.resolve(__dirname, './components/lib/usetoast/UseToast.js'), 'primevue/usedialog': path.resolve(__dirname, './components/lib/usedialog/UseDialog.js'), 'primevue/utils': path.resolve(__dirname, './components/lib/utils/Utils.js'), + 'primevue/usestyle': path.resolve(__dirname, './components/lib/usestyle/UseStyle.js'), 'primevue/api': path.resolve(__dirname, './components/lib/api/Api.js'), 'primevue/portal': path.resolve(__dirname, './components/lib/portal/Portal.vue'), 'primevue/basecomponent': path.resolve(__dirname, './components/lib/basecomponent/BaseComponent.vue'),