Files
ui/src/templates.ts
2024-03-22 12:46:52 +01:00

100 lines
2.8 KiB
TypeScript

import { addTemplate, addTypeTemplate } from '@nuxt/kit'
import type { Nuxt } from '@nuxt/schema'
import type { ModuleOptions } from './module'
import * as theme from './theme'
export default function createTemplates (options: ModuleOptions, nuxt: Nuxt) {
const shades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950]
const template = addTemplate({
filename: 'tailwind.css',
write: true,
getContents: () => `@import "tailwindcss";
@layer base {
:root {
color-scheme: light dark;
}
}
@theme {
--color-gray-*: initial;
--color-cool-50: #f9fafb;
--color-cool-100: #f3f4f6;
--color-cool-200: #e5e7eb;
--color-cool-300: #d1d5db;
--color-cool-400: #9ca3af;
--color-cool-500: #6b7280;
--color-cool-600: #4b5563;
--color-cool-700: #374151;
--color-cool-800: #1f2937;
--color-cool-900: #111827;
--color-cool-950: #030712;
${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)
for (const component in theme) {
addTemplate({
filename: `ui/${component}.ts`,
write: true,
getContents: async () => {
const template = (theme as any)[component]
const result = typeof template === 'function' ? template({ colors: options.colors }) : template
const variants = Object.keys(result.variants || {})
let json = JSON.stringify(result, null, 2)
for (const variant of variants) {
json = json.replaceAll(new RegExp(`("${variant}": "[0-9a-z-]+")`, 'g'), '$1 as const')
}
return `export default ${json}`
}
})
}
addTemplate({
filename: 'ui/index.ts',
write: true,
getContents: () => Object.keys(theme).map(component => `export { default as ${component} } from './${component}'`).join('\n')
})
// FIXME: `typeof colors[number]` should include all colors from the theme
addTypeTemplate({
filename: 'types/ui.d.ts',
getContents: () => `import * as ui from '#build/ui'
type DeepPartial<T> = Partial<{
[P in keyof T]: DeepPartial<T[P]> | { [key: string]: string | object }
}>
const colors = ${JSON.stringify(options.colors)} as const;
type UI = {
primary?: typeof colors[number]
gray?: 'slate' | 'cool' | 'zinc' | 'neutral' | 'stone'
[key: string]: any
} & DeepPartial<typeof ui>
declare module 'nuxt/schema' {
interface AppConfigInput {
ui?: UI
}
}
declare module '@nuxt/schema' {
interface AppConfigInput {
ui?: UI
}
}
export {}
`
})
}