mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-19 06:21:46 +01:00
feat: rewrite to use app config and rework docs (#143)
Co-authored-by: Daniel Roe <daniel@roe.dev> Co-authored-by: Sébastien Chopin <seb@nuxt.com>
This commit is contained in:
201
src/module.ts
201
src/module.ts
@@ -1,11 +1,10 @@
|
||||
import { defineNuxtModule, installModule, addComponentsDir, addImportsDir, addTemplate, createResolver } from '@nuxt/kit'
|
||||
import { defu } from 'defu'
|
||||
import { defineNuxtModule, installModule, addComponentsDir, addImportsDir, createResolver, addPlugin } from '@nuxt/kit'
|
||||
import colors from 'tailwindcss/colors.js'
|
||||
import type { Config } from 'tailwindcss'
|
||||
import { iconsPlugin, getIconCollections } from '@egoist/tailwindcss-icons'
|
||||
import { name, version } from '../package.json'
|
||||
import { colorsAsRegex, excludeColors } from './runtime/utils/colors'
|
||||
import defaultPreset from './runtime/presets/default'
|
||||
import preset from './runtime/app.config'
|
||||
import type { DeepPartial } from './runtime/types'
|
||||
|
||||
// @ts-ignore
|
||||
delete colors.lightBlue
|
||||
@@ -18,44 +17,28 @@ delete colors.coolGray
|
||||
// @ts-ignore
|
||||
delete colors.blueGray
|
||||
|
||||
interface ColorsOptions {
|
||||
/**
|
||||
* @default 'indigo'
|
||||
*/
|
||||
primary?: string
|
||||
|
||||
/**
|
||||
* @default 'gray'
|
||||
*/
|
||||
gray?: string
|
||||
declare module 'nuxt/schema' {
|
||||
interface AppConfigInput {
|
||||
ui?: {
|
||||
primary?: string
|
||||
gray?: string
|
||||
colors?: string[]
|
||||
} & DeepPartial<typeof preset.ui>
|
||||
}
|
||||
}
|
||||
|
||||
export interface ModuleOptions {
|
||||
preset?: object
|
||||
|
||||
/**
|
||||
* @default 'u'
|
||||
*/
|
||||
prefix?: string
|
||||
|
||||
colors?: ColorsOptions
|
||||
/**
|
||||
* @default false
|
||||
*/
|
||||
global?: boolean
|
||||
|
||||
icons: string[]
|
||||
|
||||
tailwindcss?: Partial<Config>
|
||||
}
|
||||
|
||||
const defaults = {
|
||||
preset: {},
|
||||
prefix: 'u',
|
||||
colors: {
|
||||
primary: 'indigo',
|
||||
gray: 'gray'
|
||||
},
|
||||
icons: ['heroicons'],
|
||||
tailwindcss: {
|
||||
theme: {}
|
||||
}
|
||||
}
|
||||
|
||||
export default defineNuxtModule<ModuleOptions>({
|
||||
@@ -67,10 +50,11 @@ export default defineNuxtModule<ModuleOptions>({
|
||||
nuxt: '^3.0.0-rc.8'
|
||||
}
|
||||
},
|
||||
defaults,
|
||||
defaults: {
|
||||
prefix: 'u',
|
||||
icons: ['heroicons']
|
||||
},
|
||||
async setup (options, nuxt) {
|
||||
const { preset = {}, prefix, colors: { primary = 'indigo', gray = 'gray' } = {}, tailwindcss: { theme = {} } = {} } = options
|
||||
|
||||
const { resolve } = createResolver(import.meta.url)
|
||||
|
||||
// Transpile runtime
|
||||
@@ -78,6 +62,12 @@ export default defineNuxtModule<ModuleOptions>({
|
||||
nuxt.options.build.transpile.push(runtimeDir)
|
||||
nuxt.options.build.transpile.push('@popperjs/core', '@headlessui/vue')
|
||||
|
||||
nuxt.options.css.push(resolve(runtimeDir, 'ui.css'))
|
||||
|
||||
nuxt.hook('app:resolve', (app) => {
|
||||
app.configs.push(resolve(runtimeDir, 'app.config.ts'))
|
||||
})
|
||||
|
||||
// @ts-ignore
|
||||
nuxt.hook('tailwindcss:config', function (tailwindConfig: TailwindConfig) {
|
||||
const globalColors = {
|
||||
@@ -85,55 +75,100 @@ export default defineNuxtModule<ModuleOptions>({
|
||||
...tailwindConfig.theme.extend?.colors
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
tailwindConfig.theme.extend.colors = tailwindConfig.theme.extend.colors || {}
|
||||
// @ts-ignore
|
||||
globalColors.primary = tailwindConfig.theme.extend.colors.primary = globalColors[primary] || colors[primary]
|
||||
// @ts-ignore
|
||||
globalColors.gray = tailwindConfig.theme.extend.colors.gray = globalColors[gray] || colors[gray]
|
||||
globalColors.primary = tailwindConfig.theme.extend.colors.primary = {
|
||||
50: 'rgb(var(--color-primary-50) / <alpha-value>)',
|
||||
100: 'rgb(var(--color-primary-100) / <alpha-value>)',
|
||||
200: 'rgb(var(--color-primary-200) / <alpha-value>)',
|
||||
300: 'rgb(var(--color-primary-300) / <alpha-value>)',
|
||||
400: 'rgb(var(--color-primary-400) / <alpha-value>)',
|
||||
500: 'rgb(var(--color-primary-500) / <alpha-value>)',
|
||||
600: 'rgb(var(--color-primary-600) / <alpha-value>)',
|
||||
700: 'rgb(var(--color-primary-700) / <alpha-value>)',
|
||||
800: 'rgb(var(--color-primary-800) / <alpha-value>)',
|
||||
900: 'rgb(var(--color-primary-900) / <alpha-value>)',
|
||||
950: 'rgb(var(--color-primary-950) / <alpha-value>)'
|
||||
}
|
||||
|
||||
if (globalColors.gray) {
|
||||
globalColors.cool = tailwindConfig.theme.extend.colors.cool = colors.gray
|
||||
}
|
||||
|
||||
globalColors.gray = tailwindConfig.theme.extend.colors.gray = {
|
||||
50: 'rgb(var(--color-gray-50) / <alpha-value>)',
|
||||
100: 'rgb(var(--color-gray-100) / <alpha-value>)',
|
||||
200: 'rgb(var(--color-gray-200) / <alpha-value>)',
|
||||
300: 'rgb(var(--color-gray-300) / <alpha-value>)',
|
||||
400: 'rgb(var(--color-gray-400) / <alpha-value>)',
|
||||
500: 'rgb(var(--color-gray-500) / <alpha-value>)',
|
||||
600: 'rgb(var(--color-gray-600) / <alpha-value>)',
|
||||
700: 'rgb(var(--color-gray-700) / <alpha-value>)',
|
||||
800: 'rgb(var(--color-gray-800) / <alpha-value>)',
|
||||
900: 'rgb(var(--color-gray-900) / <alpha-value>)',
|
||||
950: 'rgb(var(--color-gray-950) / <alpha-value>)'
|
||||
}
|
||||
|
||||
const variantColors = excludeColors(globalColors)
|
||||
const safeColorsAsRegex = colorsAsRegex(variantColors)
|
||||
|
||||
nuxt.options.appConfig.ui = {
|
||||
...nuxt.options.appConfig.ui,
|
||||
primary: 'sky',
|
||||
gray: 'cool',
|
||||
colors: variantColors
|
||||
}
|
||||
|
||||
tailwindConfig.safelist = tailwindConfig.safelist || []
|
||||
tailwindConfig.safelist.push(...[{
|
||||
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)`),
|
||||
pattern: new RegExp(`bg-(${safeColorsAsRegex})-(50|400|500)`)
|
||||
}, {
|
||||
pattern: new RegExp(`bg-(${safeColorsAsRegex})-500`),
|
||||
variants: ['disabled']
|
||||
}, {
|
||||
pattern: new RegExp(`bg-(${safeColorsAsRegex})-(400|950)`),
|
||||
variants: ['dark']
|
||||
},
|
||||
{
|
||||
pattern: new RegExp(`ring-(${safeColorsAsRegex})-(500)`),
|
||||
variants: ['focus']
|
||||
}, {
|
||||
pattern: new RegExp(`bg-(${safeColorsAsRegex})-(500|900|950)`),
|
||||
variants: ['dark:hover']
|
||||
}, {
|
||||
pattern: new RegExp(`bg-(${safeColorsAsRegex})-400`),
|
||||
variants: ['dark:disabled']
|
||||
}, {
|
||||
pattern: new RegExp(`bg-(${safeColorsAsRegex})-(50|100|600)`),
|
||||
variants: ['hover']
|
||||
}, {
|
||||
pattern: new RegExp(`outline-(${safeColorsAsRegex})-500`),
|
||||
variants: ['focus-visible']
|
||||
}, {
|
||||
pattern: new RegExp(`outline-(${safeColorsAsRegex})-400`),
|
||||
variants: ['dark:focus-visible']
|
||||
}, {
|
||||
pattern: new RegExp(`ring-(${safeColorsAsRegex})-500`),
|
||||
variants: ['focus-visible']
|
||||
}, {
|
||||
pattern: new RegExp(`ring-(${safeColorsAsRegex})-400`),
|
||||
variants: ['dark', 'dark:focus-visible']
|
||||
}, {
|
||||
pattern: new RegExp(`text-(${safeColorsAsRegex})-400`),
|
||||
variants: ['dark']
|
||||
}, {
|
||||
pattern: new RegExp(`text-(${safeColorsAsRegex})-600`),
|
||||
variants: ['hover']
|
||||
}, {
|
||||
pattern: new RegExp(`text-(${safeColorsAsRegex})-500`),
|
||||
variants: ['dark:hover']
|
||||
}])
|
||||
|
||||
tailwindConfig.plugins = tailwindConfig.plugins || []
|
||||
tailwindConfig.plugins.push(iconsPlugin({ collections: getIconCollections(options.icons as any[]) }))
|
||||
|
||||
const ui: object = defu(preset, defaultPreset(variantColors))
|
||||
|
||||
addTemplate({
|
||||
filename: 'ui.mjs',
|
||||
getContents: () => `export default ${JSON.stringify(ui)}`
|
||||
})
|
||||
addTemplate({
|
||||
filename: 'ui.d.ts',
|
||||
write: true,
|
||||
getContents: () => 'declare const d: any; export default d;'
|
||||
})
|
||||
})
|
||||
|
||||
await installModule('@nuxtjs/color-mode', { classSuffix: '' })
|
||||
await installModule('@nuxtjs/tailwindcss', {
|
||||
viewer: false,
|
||||
exposeConfig: true,
|
||||
config: {
|
||||
darkMode: 'class',
|
||||
theme,
|
||||
plugins: [
|
||||
require('@tailwindcss/forms'),
|
||||
require('@tailwindcss/aspect-ratio'),
|
||||
@@ -141,47 +176,43 @@ export default defineNuxtModule<ModuleOptions>({
|
||||
],
|
||||
content: [
|
||||
resolve(runtimeDir, 'components/**/*.{vue,js,ts}'),
|
||||
resolve(runtimeDir, 'presets/*.{mjs,js,ts}')
|
||||
],
|
||||
safelist: [
|
||||
'dark',
|
||||
{
|
||||
pattern: /rounded-(sm|md|lg|xl|2xl|3xl)/,
|
||||
variants: ['sm']
|
||||
}
|
||||
resolve(runtimeDir, '*.{mjs,js,ts}')
|
||||
]
|
||||
},
|
||||
cssPath: resolve(runtimeDir, 'tailwind.css')
|
||||
}
|
||||
})
|
||||
|
||||
addPlugin({
|
||||
src: resolve(runtimeDir, 'plugins', 'colors')
|
||||
})
|
||||
|
||||
addComponentsDir({
|
||||
path: resolve(runtimeDir, 'components', 'elements'),
|
||||
prefix,
|
||||
watch: false
|
||||
})
|
||||
addComponentsDir({
|
||||
path: resolve(runtimeDir, 'components', 'feedback'),
|
||||
prefix,
|
||||
prefix: options.prefix,
|
||||
global: options.global,
|
||||
watch: false
|
||||
})
|
||||
addComponentsDir({
|
||||
path: resolve(runtimeDir, 'components', 'forms'),
|
||||
prefix,
|
||||
prefix: options.prefix,
|
||||
global: options.global,
|
||||
watch: false
|
||||
})
|
||||
addComponentsDir({
|
||||
path: resolve(runtimeDir, 'components', 'layout'),
|
||||
prefix,
|
||||
prefix: options.prefix,
|
||||
global: options.global,
|
||||
watch: false
|
||||
})
|
||||
addComponentsDir({
|
||||
path: resolve(runtimeDir, 'components', 'navigation'),
|
||||
prefix,
|
||||
prefix: options.prefix,
|
||||
global: options.global,
|
||||
watch: false
|
||||
})
|
||||
addComponentsDir({
|
||||
path: resolve(runtimeDir, 'components', 'overlays'),
|
||||
prefix,
|
||||
prefix: options.prefix,
|
||||
global: options.global,
|
||||
watch: false
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user