Files
ui/src/runtime/plugins/colors.ts
Benjamin Canac 24b54f6d9a chore(deps): update @nuxt/module-builder (#3799)
Co-authored-by: Daniel Roe <daniel@roe.dev>
2025-04-05 10:42:16 +02:00

66 lines
2.0 KiB
TypeScript

import { computed } from 'vue'
import colors from 'tailwindcss/colors'
import type { UseHeadInput } from '@unhead/vue/types'
import { defineNuxtPlugin, useAppConfig, useNuxtApp, useHead } from '#imports'
const shades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950] as const
function getColor(color: keyof typeof colors, shade: typeof shades[number]): string {
if (color in colors && typeof colors[color] === 'object' && shade in colors[color]) {
return colors[color][shade] as string
}
return ''
}
function generateShades(key: string, value: string) {
return `${shades.map(shade => `--ui-color-${key}-${shade}: var(--color-${value === 'neutral' ? 'old-neutral' : value}-${shade}, ${getColor(value as keyof typeof colors, shade)});`).join('\n ')}`
}
function generateColor(key: string, shade: number) {
return `--ui-${key}: var(--ui-color-${key}-${shade});`
}
export default defineNuxtPlugin(() => {
const appConfig = useAppConfig()
const nuxtApp = useNuxtApp()
const root = computed(() => {
const { neutral, ...colors } = appConfig.ui.colors
return `@layer base {
:root {
${Object.entries(appConfig.ui.colors).map(([key, value]: [string, string]) => generateShades(key, value)).join('\n ')}
}
:root, .light {
${Object.keys(colors).map(key => generateColor(key, 500)).join('\n ')}
}
.dark {
${Object.keys(colors).map(key => generateColor(key, 400)).join('\n ')}
}
}`
})
// Head
const headData: UseHeadInput = {
style: [{
innerHTML: () => root.value,
tagPriority: -2,
id: 'nuxt-ui-colors'
}]
}
// SPA mode
if (import.meta.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)
})