Skip to content

Commit d4d5da2

Browse files
committed
chore: fix test and provide tw util
1 parent 575f26f commit d4d5da2

File tree

5 files changed

+53
-19
lines changed

5 files changed

+53
-19
lines changed

src/module.ts

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import {
55
addTemplate,
66
resolvePath,
77
useNuxt,
8+
createResolver,
9+
addImports,
810
} from '@nuxt/kit'
911
import { join } from 'pathe'
1012
import { name, version, configKey, compatibility } from '../package.json'
@@ -44,19 +46,46 @@ async function resolveInjectPosition(css: string[], position: InjectPosition = '
4446
throw new Error(`\`injectPosition\` specifies a relative location \`${minIndex}\` that cannot be resolved (i.e., \`after\` orders \`before\` may be reversed): ` + JSON.stringify(position))
4547
}
4648

47-
return minIndex
49+
return 'after' in position ? minIndex : maxIndex
4850
}
4951

5052
throw new Error('invalid `injectPosition`: ' + JSON.stringify(position))
5153
}
5254

55+
type EditorSupportConfig = Partial<{
56+
/**
57+
* Enable utility to write Tailwind CSS classes inside strings.
58+
*
59+
* You will need to update `.vscode/settings.json` based on this value. This works only for Nuxt 3 or Nuxt 2 with Bridge.
60+
*
61+
* ```json
62+
* {
63+
* "tailwindCSS.experimental.classRegex": ["tw`(.*?)`", "tw\\('(.*?)'\\)"]
64+
* }
65+
* ```
66+
*
67+
* Read https://tailwindcss.nuxtjs.org/tailwind/editor-support#string-classes-autocomplete.
68+
*
69+
* @default false // if true, { as: 'tw' }
70+
*/
71+
autocompleteUtil: false | true | Pick<Exclude<Parameters<typeof addImports>[0], any[]>, 'as'>
72+
}>
73+
5374
export interface ModuleOptions {
5475
/**
5576
* The path of the Tailwind CSS file. If the file does not exist, the module's default CSS file will be imported instead.
5677
*
5778
* The default is `<assets>/css/tailwind.css` if found, else we generate a CSS file with `@import "tailwindcss"` in the buildDir.
5879
*/
59-
cssPath: string | false | [string, { injectPosition: InjectPosition }]
80+
cssFile: string | false | [string, { position: InjectPosition }]
81+
/**
82+
* Enable some utilities for better editor support and DX.
83+
*
84+
* Read https://tailwindcss.nuxtjs.org/tailwind/editor-support.
85+
*
86+
* @default false // if true, { autocompleteUtil: true }
87+
*/
88+
editorSupport: false | true | EditorSupportConfig
6089
}
6190

6291
export default defineNuxtModule<ModuleOptions>({
@@ -67,10 +96,10 @@ export default defineNuxtModule<ModuleOptions>({
6796
compatibility
6897
},
6998
defaults: (nuxt = useNuxt()) => ({
70-
cssPath: join(nuxt.options.dir.assets, 'css/tailwind.css'),
99+
cssFile: join(nuxt.options.dir.assets, 'css/tailwind.css'),
71100
}),
72101
async setup(moduleOptions, nuxt) {
73-
// const resolver = createResolver(import.meta.url)
102+
const resolver = createResolver(import.meta.url)
74103

75104
// add plugin
76105
if (nuxt.options.builder === '@nuxt/vite-builder') {
@@ -79,9 +108,22 @@ export default defineNuxtModule<ModuleOptions>({
79108
nuxt.options.postcss.plugins['@tailwindcss/postcss'] = {}
80109
}
81110

111+
if (moduleOptions.editorSupport) {
112+
const { autocompleteUtil = true } = (typeof moduleOptions.editorSupport === 'object' ? typeof moduleOptions.editorSupport : {}) as EditorSupportConfig
113+
114+
if (autocompleteUtil) {
115+
addImports({
116+
name: 'autocompleteUtil',
117+
from: resolver.resolve('./runtime/utils'),
118+
as: 'tw',
119+
...(typeof autocompleteUtil === 'object' ? autocompleteUtil : {}),
120+
})
121+
}
122+
}
123+
82124
nuxt.hook('modules:done', async () => {
83125
// resolve CSS
84-
const [cssPath, cssPathConfig] = Array.isArray(moduleOptions.cssPath) ? moduleOptions.cssPath : [moduleOptions.cssPath]
126+
const [cssPath, cssPathConfig] = Array.isArray(moduleOptions.cssFile) ? moduleOptions.cssFile : [moduleOptions.cssFile]
85127
if (!cssPath) return
86128

87129
const resolvedCss = await resolveCSSPath(cssPath)
@@ -90,7 +132,7 @@ export default defineNuxtModule<ModuleOptions>({
90132

91133
// inject only if this file isn't listed already by user
92134
if (!resolvedNuxtCss.includes(resolvedCss)) {
93-
const injectPosition = await resolveInjectPosition(resolvedNuxtCss, cssPathConfig?.injectPosition)
135+
const injectPosition = await resolveInjectPosition(resolvedNuxtCss, cssPathConfig?.position)
94136
nuxt.options.css.splice(injectPosition, 0, resolvedCss)
95137
}
96138
})

src/runtime/utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const autocompleteUtil = <T extends TemplateStringsArray | string>(tailwindClasses: T) => tailwindClasses

test/.snapshot/styles.css

Lines changed: 2 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/basic.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ describe('module', async () => {
1212
it('ssr styles', async () => {
1313
const html = await $fetch<string>('/')
1414
const cssContents = await getCSSContents(html)
15-
expect(cssContents).includes('https://tailwindcss.com')
15+
expect(cssContents).includes('tailwindcss')
1616
expect(cssContents).toMatchFileSnapshot('.snapshot/styles.css')
1717
})
1818

test/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ import { $fetch } from '@nuxt/test-utils/e2e'
22

33
export const getCSSContents = async (html: string) => {
44
const cssImport = html.match(/<link rel="stylesheet" href="([^"]+)"[^>]*>/)
5-
return cssImport ? $fetch<string>(cssImport[1]) : html.match(/<style type="text\/css"[^>]*>([\s\S]*?)<\/style>/gi)?.[1] ?? html
5+
return cssImport ? $fetch<string>(cssImport[1]) : html.match(/<style(?: type="text\/css")?[^>]*>([\s\S]*?)<\/style>/)?.[1] ?? html
66
}

0 commit comments

Comments
 (0)