mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-15 04:29:37 +01:00
184 lines
4.7 KiB
TypeScript
184 lines
4.7 KiB
TypeScript
import { fileURLToPath } from 'url'
|
|
import { resolve } from 'pathe'
|
|
import { defineNuxtModule, installModule, addComponentsDir, addTemplate, addPlugin, resolveModule } from '@nuxt/kit'
|
|
import { defu, defuArrayFn } from 'defu'
|
|
import type { TailwindConfig } from 'tailwindcss/tailwind-config'
|
|
import colors from 'tailwindcss/colors.js'
|
|
import { name, version } from '../package.json'
|
|
import { safeColorsAsRegex } from './runtime/utils/colors'
|
|
|
|
interface ColorsOptions {
|
|
/**
|
|
* @default 'indigo'
|
|
*/
|
|
primary?: string
|
|
|
|
/**
|
|
* @default 'zinc'
|
|
*/
|
|
gray?: string
|
|
}
|
|
|
|
export interface ModuleOptions {
|
|
/**
|
|
* @default 'tailwindui'
|
|
*/
|
|
preset?: string | object
|
|
|
|
/**
|
|
* @default 'u'
|
|
*/
|
|
prefix?: string
|
|
|
|
colors?: ColorsOptions
|
|
|
|
tailwindcss?: TailwindConfig
|
|
}
|
|
|
|
const defaults = {
|
|
preset: 'default',
|
|
prefix: 'u',
|
|
colors: {
|
|
primary: 'indigo',
|
|
gray: 'zinc'
|
|
},
|
|
tailwindcss: {
|
|
theme: {}
|
|
}
|
|
}
|
|
|
|
export default defineNuxtModule<ModuleOptions>({
|
|
meta: {
|
|
name,
|
|
version,
|
|
configKey: 'ui',
|
|
compatibility: {
|
|
nuxt: '^3.0.0',
|
|
bridge: true
|
|
}
|
|
},
|
|
defaults,
|
|
async setup (options, nuxt) {
|
|
const { preset, prefix, colors: { primary = 'indigo', gray = 'zinc' } = {}, tailwindcss: { theme = {} } = {} } = options
|
|
|
|
// Transpile runtime
|
|
const runtimeDir = fileURLToPath(new URL('./runtime', import.meta.url))
|
|
nuxt.options.build.transpile.push(runtimeDir)
|
|
nuxt.options.build.transpile.push('@popperjs/core', '@headlessui/vue', '@iconify/vue')
|
|
|
|
await installModule('@nuxtjs/color-mode', { classSuffix: '' })
|
|
await installModule('@nuxtjs/tailwindcss', {
|
|
viewer: false,
|
|
config: {
|
|
darkMode: 'class',
|
|
theme: defuArrayFn({
|
|
extend: {
|
|
colors: {
|
|
// @ts-ignore
|
|
gray: typeof gray === 'object' ? gray : (colors && colors[gray]),
|
|
// @ts-ignore
|
|
primary: typeof primary === 'object' ? primary : (colors && colors[primary])
|
|
}
|
|
}
|
|
}, theme),
|
|
plugins: [
|
|
require('@tailwindcss/forms'),
|
|
require('@tailwindcss/line-clamp'),
|
|
require('@tailwindcss/aspect-ratio')
|
|
],
|
|
content: [
|
|
resolve(runtimeDir, 'components/**/*.{vue,js,ts}'),
|
|
resolve(runtimeDir, 'presets/*.{mjs,js,ts}')
|
|
],
|
|
// Safelist dynamic colors used in preset
|
|
safelist: [
|
|
'dark',
|
|
{
|
|
pattern: new RegExp(`bg-(${safeColorsAsRegex})-400`)
|
|
},
|
|
{
|
|
pattern: new RegExp(`bg-(${safeColorsAsRegex})-(100|600|700)`),
|
|
variants: ['hover', 'disabled', 'dark']
|
|
},
|
|
{
|
|
pattern: new RegExp(`text-(${safeColorsAsRegex})-(100|800)`),
|
|
variants: ['dark']
|
|
},
|
|
{
|
|
pattern: new RegExp(`ring-(${safeColorsAsRegex})-(500)`),
|
|
variants: ['focus']
|
|
},
|
|
{
|
|
pattern: /rounded-(sm|md|lg|xl|2xl|3xl)/,
|
|
variants: ['sm']
|
|
},
|
|
{
|
|
pattern: /max-w-(xs|sm|md|lg|xl|2xl|3xl|4xl|5xl|6xl|7xl)/,
|
|
variants: ['sm']
|
|
}
|
|
]
|
|
},
|
|
cssPath: resolve(runtimeDir, 'tailwind.css')
|
|
})
|
|
|
|
const presetsDir = resolve(runtimeDir, './presets')
|
|
|
|
let ui: object = (await import(resolveModule(`./${defaults.preset}`, { paths: presetsDir }))).default
|
|
try {
|
|
if (typeof preset === 'object') {
|
|
ui = defu(preset, ui)
|
|
} else {
|
|
// @ts-ignore
|
|
ui = (await import(resolveModule(`./${preset}`, { paths: presetsDir }))).default
|
|
}
|
|
} catch (e) {
|
|
// eslint-disable-next-line no-console
|
|
console.warn('Could not load preset file.')
|
|
}
|
|
|
|
addTemplate({
|
|
filename: 'ui.mjs',
|
|
getContents: () => `export default ${JSON.stringify(ui)}`
|
|
})
|
|
|
|
addPlugin(resolve(runtimeDir, 'plugins', 'toast.client'))
|
|
addPlugin(resolve(runtimeDir, 'plugins', 'clipboard.client'))
|
|
|
|
addComponentsDir({
|
|
path: resolve(runtimeDir, 'components', 'elements'),
|
|
prefix,
|
|
watch: false
|
|
})
|
|
addComponentsDir({
|
|
path: resolve(runtimeDir, 'components', 'feedback'),
|
|
prefix,
|
|
watch: false
|
|
})
|
|
addComponentsDir({
|
|
path: resolve(runtimeDir, 'components', 'forms'),
|
|
prefix,
|
|
watch: false
|
|
})
|
|
addComponentsDir({
|
|
path: resolve(runtimeDir, 'components', 'layout'),
|
|
prefix,
|
|
watch: false
|
|
})
|
|
addComponentsDir({
|
|
path: resolve(runtimeDir, 'components', 'navigation'),
|
|
prefix,
|
|
watch: false
|
|
})
|
|
addComponentsDir({
|
|
path: resolve(runtimeDir, 'components', 'overlays'),
|
|
prefix,
|
|
watch: false
|
|
})
|
|
|
|
// Add composables
|
|
nuxt.hook('autoImports:dirs', (dirs) => {
|
|
dirs.push(resolve(runtimeDir, 'composables'))
|
|
})
|
|
}
|
|
})
|