From 0d1f8528c8e1ef0400098493d7fef86cb048473c Mon Sep 17 00:00:00 2001 From: Benjamin Canac Date: Wed, 6 Mar 2024 20:08:58 +0100 Subject: [PATCH] chore(module): dynamic colors --- src/module.ts | 31 +++++++++++++++++++++++---- src/runtime/main.css | 1 - src/runtime/plugins/index.ts | 41 ++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 5 deletions(-) delete mode 100644 src/runtime/main.css create mode 100644 src/runtime/plugins/index.ts diff --git a/src/module.ts b/src/module.ts index 3d7c2132..1d05d02c 100644 --- a/src/module.ts +++ b/src/module.ts @@ -1,5 +1,5 @@ import { defu } from 'defu' -import { createResolver, defineNuxtModule, addComponentsDir, addImportsDir, addVitePlugin, installModule } from '@nuxt/kit' +import { createResolver, defineNuxtModule, addComponentsDir, addImportsDir, addVitePlugin, addPlugin, addTemplate, installModule } from '@nuxt/kit' import tailwindcss from '@tailwindcss/vite' import type { DeepPartial } from './runtime/types' import * as theme from './runtime/theme' @@ -34,13 +34,15 @@ export default defineNuxtModule({ nuxt.options.alias['#ui'] = resolver.resolve('./runtime') - nuxt.options.css.push(resolver.resolve('./runtime/main.css')) - nuxt.options.appConfig.ui = defu(nuxt.options.appConfig.ui || {}, { primary: 'green', gray: 'cool', icons: { - loading: 'i-heroicons-arrow-path-20-solid' + search: 'i-heroicons-magnifying-glass-20-solid', + close: 'i-heroicons-x-mark-20-solid', + check: 'i-heroicons-check-20-solid', + loading: 'i-heroicons-arrow-path-20-solid', + empty: 'i-heroicons-circle-stack-20-solid' } }) @@ -48,6 +50,27 @@ export default defineNuxtModule({ addVitePlugin(tailwindcss) + addPlugin({ + src: resolver.resolve('./runtime/plugins/index') + }) + + const shades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950] + + const template = addTemplate({ + filename: 'main.css', + write: true, + getContents: () => ` + @import "tailwindcss"; + + @theme { + ${shades.map(shade => `--color-primary-${shade}: var(--color-primary-${shade});`).join('\n')} + ${shades.map(shade => `--color-gray-${shade}: var(--color-gray-${shade});`).join('\n')} + } + ` + }) + + nuxt.options.css.push(template.dst) + addComponentsDir({ path: resolver.resolve('./runtime/components'), prefix: 'U', diff --git a/src/runtime/main.css b/src/runtime/main.css deleted file mode 100644 index f1d8c73c..00000000 --- a/src/runtime/main.css +++ /dev/null @@ -1 +0,0 @@ -@import "tailwindcss"; diff --git a/src/runtime/plugins/index.ts b/src/runtime/plugins/index.ts new file mode 100644 index 00000000..57bf8a27 --- /dev/null +++ b/src/runtime/plugins/index.ts @@ -0,0 +1,41 @@ +import { computed } from 'vue' +import { defineNuxtPlugin, useAppConfig, useNuxtApp, useHead } from '#imports' + +export default defineNuxtPlugin(() => { + const appConfig = useAppConfig() + const nuxtApp = useNuxtApp() + + const shades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950] + + const root = computed(() => { + return `:root { +${shades.map(shade => `--color-primary-${shade}: var(--color-${appConfig.ui.primary}-${shade});`).join('\n')} +${shades.map(shade => `--color-gray-${shade}: var(--color-${appConfig.ui.gray}-${shade});`).join('\n')} +} +` + }) + + // Head + const headData: any = { + style: [{ + innerHTML: () => root.value, + tagPriority: -2, + id: 'nuxt-ui-colors' + }] + } + + // SPA mode + if (process.client && nuxtApp.isHydrating && !nuxtApp.payload.serverRendered) { + const style = document.createElement('style') + + style.innerHTML = root.value + style.setAttribute('data-nuxt-ui-colors', '') + document.head.appendChild(style) + + headData.script = [{ + innerHTML: 'document.head.removeChild(document.querySelector(\'[data-nuxt-ui-colors]\'))' + }] + } + + useHead(headData) +})