Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: nuxt-modules/tailwindcss
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v6.2.0
Choose a base ref
...
head repository: nuxt-modules/tailwindcss
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v6.3.0
Choose a head ref
  • 13 commits
  • 15 files changed
  • 4 contributors

Commits on Dec 19, 2022

  1. chore: fix build

    atinux committed Dec 19, 2022
    Copy the full SHA
    96adbbd View commit details

Commits on Dec 22, 2022

  1. docs: update bages

    atinux authored Dec 22, 2022
    Copy the full SHA
    c32cadb View commit details

Commits on Jan 25, 2023

  1. chore: add pathe as dependency

    Resolves #595
    atinux committed Jan 25, 2023
    Copy the full SHA
    3508f7d View commit details
  2. chore(deps): update dependency postcss-nesting to v11 (#600)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    renovate[bot] authored Jan 25, 2023
    Copy the full SHA
    3f8a30b View commit details
  3. chore: add tw typo

    atinux committed Jan 25, 2023
    Copy the full SHA
    9a72aab View commit details
  4. fix: css intellisense not working (#596)

    * fix: css intellisense not working (#593)
    
    * chore: add comment
    
    Co-authored-by: Sébastien Chopin <seb@nuxtjs.com>
    nazar1ua and atinux authored Jan 25, 2023
    Copy the full SHA
    de81e7d View commit details
  5. chore(deps): update devdependency jsdom to v21 (#588)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    renovate[bot] authored Jan 25, 2023
    Copy the full SHA
    cc9e081 View commit details
  6. chore(deps): update dependency ufo to v1 (#564)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    renovate[bot] authored Jan 25, 2023
    Copy the full SHA
    ac9ab96 View commit details
  7. fix: considered content as function (#592)

    * fix: considered content as function
    
    * fix: passing content function to defu
    
    * docs: fixed braces.. not sure howd that disappear
    
    * chore: using non-typed test config instead
    
    * chore: update
    
    Co-authored-by: Sébastien Chopin <seb@nuxtjs.com>
    ineshbose and atinux authored Jan 25, 2023
    Copy the full SHA
    cf67d89 View commit details
  8. chore(deps): update dependency postcss-custom-properties to v13 (#599)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    Co-authored-by: Sébastien Chopin <seb@nuxtjs.com>
    renovate[bot] and atinux authored Jan 25, 2023
    Copy the full SHA
    8effba9 View commit details
  9. chore: update deps

    atinux committed Jan 25, 2023
    Copy the full SHA
    7da555c View commit details
  10. feat(exposeConfig): nested properties (#583)

    * refactor(expose-config): recursively iterating over config
    
    * chore: type definitions and a bugfix
    
    * bugfix: escaping quotes and special characters
    
    * refactor: using templates now
    
    * feat: exports depending on exposeLevel
    
    * chore: set start level to 1
    
    * chore: updated docs and added test
    
    * chore: more docs, and reverting d.ts file
    
    * fix: passing write prop to test setup
    
    Co-authored-by: Sébastien Chopin <seb@nuxtjs.com>
    ineshbose and atinux authored Jan 25, 2023
    Copy the full SHA
    e88c23a View commit details
  11. chore(release): 6.3.0

    atinux committed Jan 25, 2023
    Copy the full SHA
    7a5289e View commit details
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -2,6 +2,19 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

## [6.3.0](https://github.com/nuxt-community/tailwindcss-module/compare/v6.2.0...v6.3.0) (2023-01-25)


### Features

* **exposeConfig:** nested properties ([#583](https://github.com/nuxt-community/tailwindcss-module/issues/583)) ([e88c23a](https://github.com/nuxt-community/tailwindcss-module/commit/e88c23ab6237d69450617773bd75e8fdd3402bfd))


### Bug Fixes

* considered content as function ([#592](https://github.com/nuxt-community/tailwindcss-module/issues/592)) ([cf67d89](https://github.com/nuxt-community/tailwindcss-module/commit/cf67d892914ff6b38c7740aaa585d4ad93f6fba6))
* css intellisense not working ([#596](https://github.com/nuxt-community/tailwindcss-module/issues/596)) ([de81e7d](https://github.com/nuxt-community/tailwindcss-module/commit/de81e7d7bca9a70eabca1e23c23c6302334fe758)), closes [#593](https://github.com/nuxt-community/tailwindcss-module/issues/593)

## [6.2.0](https://github.com/nuxt-community/tailwindcss-module/compare/v6.1.3...v6.2.0) (2022-12-19)


7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@
[![npm version][npm-version-src]][npm-version-href]
[![npm downloads][npm-downloads-src]][npm-downloads-href]
[![License][license-src]][license-href]
<a href="https://volta.net/nuxt-modules/tailwindcss?utm_source=nuxt_tailwind_readme"><img src="https://user-images.githubusercontent.com/904724/209143798-32345f6c-3cf8-4e06-9659-f4ace4a6acde.svg" alt="Volta board"></a>

> [Tailwind CSS](https://tailwindcss.com) module for [Nuxt](https://nuxtjs.org) with [modern css](https://tailwindcss.com/docs/using-with-preprocessors#future-css-features) ⚡️
@@ -69,11 +70,11 @@ Or locally:
Copyright (c) Nuxt Community

<!-- Badges -->
[npm-version-src]: https://img.shields.io/npm/v/@nuxtjs/tailwindcss/latest.svg?style=flat&colorA=002438&colorB=28CF8D
[npm-version-src]: https://img.shields.io/npm/v/@nuxtjs/tailwindcss/latest.svg?style=flat&colorA=18181B&colorB=28CF8D
[npm-version-href]: https://npmjs.com/package/@nuxtjs/tailwindcss

[npm-downloads-src]: https://img.shields.io/npm/dm/@nuxtjs/tailwindcss.svg?style=flat&colorA=002438&colorB=28CF8D
[npm-downloads-src]: https://img.shields.io/npm/dm/@nuxtjs/tailwindcss.svg?style=flat&colorA=18181B&colorB=28CF8D
[npm-downloads-href]: https://npmjs.com/package/@nuxtjs/tailwindcss

[license-src]: https://img.shields.io/npm/l/@nuxtjs/tailwindcss.svg?style=flat&colorA=002438&colorB=28CF8D
[license-src]: https://img.shields.io/npm/l/@nuxtjs/tailwindcss.svg?style=flat&colorA=18181B&colorB=28CF8D
[license-href]: https://npmjs.com/package/@nuxtjs/tailwindcss
3 changes: 2 additions & 1 deletion build.config.ts
Original file line number Diff line number Diff line change
@@ -4,5 +4,6 @@ export default defineBuildConfig({
externals: [
'pathe',
'minimatch'
]
],
failOnWarn: false
})
29 changes: 29 additions & 0 deletions docs/content/1.getting-started/2.options.md
Original file line number Diff line number Diff line change
@@ -90,6 +90,35 @@ export default {

Learn more about it in the [Referencing in the application](/tailwind/config#referencing-in-the-application) section.

## `exposeLevel`

- Default: `2`

If you want to only import *really* specific parts of your tailwind config, you can enable imports for each property in the config:

```ts [nuxt.config]
export default {
tailwindcss: {
exposeConfig: true,
exposeLevel: 3
}
}
```

This is only relevant when [`exposeConfig`](/getting-started/options#exposeconfig) is `true`. Using `exposeLevel` to be ≤ 0 will only expose root properties.

::alert{type="warning"}

It is unlikely for `exposeLevel` to ever be over 4 - the usual depth of a Tailwind config. A higher value is also likely to increase boot-time and disk space in dev.

::

::alert{type="info"}

Named exports for properties below [root options](https://tailwindcss.com/docs/configuration#configuration-options) are prefixed with `_` (`_colors`, `_900`, `_2xl`) to ensure safe variable names. You can use default imports to provide any identifier or rename named imports using `as`. Properties with unsafe variable names (`spacing['1.5']`, `height['1/2']`, `keyframes.ping['75%, 100%']`) do not get exported individually.

::

## `injectPosition`

- Default: `'first'`
18 changes: 12 additions & 6 deletions docs/content/2.tailwind/1.config.md
Original file line number Diff line number Diff line change
@@ -188,7 +188,7 @@ If you want to fully overwrite its value, you can use a `function` that receives
```js{}[tailwind.config.js]
export default {
content (contentDefaults) {
return tailwindContent
return [...contentDefaults.filter((c) => c.endsWith('*.vue')), './my-components/**/*.vue', `${srcDir}/themes/**/*.js`]
}
}
```
@@ -199,15 +199,15 @@ This merging strategy of with a function only applies to `plugins` and `content`

::

### Whitelisting classes
### Safelisting classes

If you need to whitelist classes and avoid the content purge system, you need to specify the `safelist` option:
If you need to safelist classes and avoid the content purge system, you need to specify the `safelist` option:

```js{}[tailwind.config.js]
module.exports = {
// Whitelisting some classes to avoid content purge
// Safelisting some classes to avoid content purge
safelist: [
'whitelisted',
'safelisted',
{
pattern: /bg-(red|green|blue)-(100|200|300)/,
},
@@ -224,7 +224,8 @@ If you need resolved Tailwind config at runtime, you can enable the [exposeConfi
```js{}[nuxt.config]
export default {
tailwindcss: {
exposeConfig: true
exposeConfig: true,
// exposeLevel: 1, // determines tree-shaking (optional)
}
}
```
@@ -237,6 +238,11 @@ import tailwindConfig from '#tailwind-config'

// Import only part which is required to allow tree-shaking
import { theme } from '#tailwind-config'

// Import within properties for further tree-shaking (based on exposeLevel)
import screens from '#tailwind-config/theme/screens' // default import
import { _neutral } from '#tailwind-config/theme/colors' // named (with _ prefix)
import { _800 as slate800 } from '#tailwind-config/theme/colors/slate' // alias
```

::alert{type="warning"}
32 changes: 17 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nuxtjs/tailwindcss",
"version": "6.2.0",
"version": "6.3.0",
"description": "TailwindCSS module for Nuxt",
"repository": "nuxt-community/tailwindcss-module",
"license": "MIT",
@@ -26,31 +26,33 @@
"test": "vitest"
},
"dependencies": {
"@nuxt/kit": "^3.0.0",
"@nuxt/kit": "^3.1.1",
"@nuxt/postcss8": "^1.1.3",
"autoprefixer": "^10.4.13",
"chalk": "^5.1.2",
"chalk": "^5.2.0",
"clear-module": "^4.1.2",
"consola": "^2.15.3",
"defu": "^6.1.0",
"postcss": "^8.4.18",
"postcss-custom-properties": "^12.1.10",
"postcss-nesting": "^10.2.0",
"defu": "^6.1.2",
"pathe": "^1.1.0",
"postcss": "^8.4.21",
"postcss-custom-properties": "^13.1.0",
"postcss-nesting": "^11.0.0",
"tailwind-config-viewer": "^1.7.2",
"tailwindcss": "^3.2.1",
"ufo": "^0.8.6"
"tailwindcss": "^3.2.4",
"ufo": "^1.0.1"
},
"devDependencies": {
"@fontsource/inter": "^4.5.14",
"@nuxt/content": "^2.2.1",
"@fontsource/inter": "^4.5.15",
"@nuxt/content": "^2.4.0",
"@nuxt/module-builder": "latest",
"@nuxt/test-utils": "^3.0.0",
"@nuxt/test-utils": "^3.1.1",
"@nuxtjs/eslint-config-typescript": "latest",
"@tailwindcss/typography": "^0.5.9",
"codecov": "latest",
"eslint": "latest",
"jsdom": "^20.0.2",
"nuxt": "^3.0.0",
"jsdom": "^21.1.0",
"nuxt": "^3.1.1",
"standard-version": "latest",
"vitest": "^0.24.5"
"vitest": "^0.28.2"
}
}
6 changes: 6 additions & 0 deletions playground/content/content.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
---
layout: prose
---

# Hello

::div{.my-4}
[@nuxt/content support]{.px-4 .text-xl .font-bold}
::
5 changes: 5 additions & 0 deletions playground/layouts/prose.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<template>
<div class="prose">
<slot />
</div>
</template>
7 changes: 6 additions & 1 deletion playground/tailwind.config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import typography from '@tailwindcss/typography'

export default {
theme: {
extend: {
fontFamily: {
sans: 'Inter, ui-sans-serif, system-ui, -apple-system, Arial, Roboto, sans-serif'
}
}
}
},
plugins: [
typography()
]
}
70 changes: 55 additions & 15 deletions src/module.ts
Original file line number Diff line number Diff line change
@@ -47,6 +47,7 @@ export interface ModuleOptions {
config: Config;
viewer: boolean;
exposeConfig: boolean;
exposeLevel: number;
injectPosition: InjectPosition;
disableHmrHotfix: boolean;
}
@@ -63,6 +64,7 @@ export default defineNuxtModule<ModuleOptions>({
config: defaultTailwindConfig(),
viewer: true,
exposeConfig: false,
exposeLevel: 2,
injectPosition: 'first',
disableHmrHotfix: false
}),
@@ -71,7 +73,7 @@ export default defineNuxtModule<ModuleOptions>({
* Config file handling
*/

const configPaths = []
const configPaths: string[] = []
const contentPaths = []

/**
@@ -109,12 +111,15 @@ export default defineNuxtModule<ModuleOptions>({

// Watch the Tailwind config file to restart the server
if (nuxt.options.dev) {
// @ts-ignore
nuxt.options.watch = nuxt.options.watch || []
// @ts-ignore
configPaths.forEach(path => nuxt.options.watch.push(path))
}

// Default tailwind config
let tailwindConfig: any = defuArrayFn(moduleOptions.config, { content: contentPaths })
// Recursively resolve each config and merge tailwind configs together.
let tailwindConfig: any = {}
for (const configPath of configPaths) {
let _tailwindConfig
try {
@@ -124,21 +129,19 @@ export default defineNuxtModule<ModuleOptions>({
}

// Transform purge option from Array to object with { content }
if (_tailwindConfig && Array.isArray(_tailwindConfig.purge)) {
if (_tailwindConfig && Array.isArray(_tailwindConfig.purge) && !_tailwindConfig.content) {
_tailwindConfig.content = _tailwindConfig.purge
}

tailwindConfig = defu(_tailwindConfig || {}, tailwindConfig)
if (_tailwindConfig) {
tailwindConfig = defuArrayFn(_tailwindConfig, tailwindConfig)
}
}

tailwindConfig.content = [...(tailwindConfig.content || []), ...contentPaths]

// Merge with our default purgecss default
tailwindConfig = defuArrayFn(tailwindConfig, moduleOptions.config)

// Write cjs version of config to support vscode extension
const resolveConfig: any = await import('tailwindcss/resolveConfig.js').then(r => r.default || r)
const resolvedConfig = resolveConfig(tailwindConfig)
// Avoid creating null plugins for intelisense
resolvedConfig.plugins = []
addTemplate({
filename: 'tailwind.config.cjs',
getContents: () => `module.exports = ${JSON.stringify(resolvedConfig, null, 2)}`,
@@ -148,14 +151,49 @@ export default defineNuxtModule<ModuleOptions>({
// Expose resolved tailwind config as an alias
// https://tailwindcss.com/docs/configuration/#referencing-in-javascript
if (moduleOptions.exposeConfig) {
/**
* Creates MJS exports for properties of the config
*
* @param obj config
* @param path parent properties trace
* @param level level of object depth
* @param maxLevel maximum level of depth
*/
const populateMap = (obj: any, path: string[] = [], level = 1, maxLevel = moduleOptions.exposeLevel) => {
Object.entries(obj).forEach(([key, value = {}]) => {
if (
level >= maxLevel || // if recursive call is more than desired
typeof value !== 'object' || // if its not an object, no more recursion required
Array.isArray(value) || // arrays are objects in JS, but we can't break it down
Object.keys(value).find(k => !k.match(/^[0-9a-z]+$/i)) // object has non-alphanumeric property (unsafe var name)
) {
addTemplate({
filename: `tailwind.config/${path.concat(key).join('/')}.mjs`,
getContents: () => `export default ${JSON.stringify(value, null, 2)}`
})
} else {
// recurse through nested objects
populateMap(value, path.concat(key), level + 1, maxLevel)

const values = Object.keys(value)
addTemplate({
filename: `tailwind.config/${path.concat(key).join('/')}.mjs`,
getContents: () => `${Object.keys(value).map(v => `import _${v} from "./${key}/${v}.mjs"`).join('\n')}\nconst config = { ${values.map(k => `"${k}": _${k}`).join(', ')} }\nexport { config as default${values.length > 0 ? ', _' : ''}${values.join(', _')} }`
})
}
})
}

populateMap(resolvedConfig)

const configOptions = Object.keys(resolvedConfig)
const template = addTemplate({
filename: 'tailwind.config.mjs',
getContents: () => `${Object.entries(resolvedConfig).map(([k, v]) => `export const ${k} = ${JSON.stringify(v, null, 2)}`).join('\n')}\nexport default { ${configOptions.join(', ')} }`
getContents: () => `${configOptions.map(v => `import ${v} from "./tailwind.config/${v}.mjs"`).join('\n')}\nconst config = { ${configOptions.join(', ')} }\nexport { config as default, ${configOptions.join(', ')} }`
})
addTemplate({
filename: 'tailwind.config.d.ts',
getContents: () => `type tailwindcssConfig = import("tailwindcss").Config\ndeclare const config: tailwindcssConfig\n${configOptions.map((o) => `declare const ${o}: tailwindcssConfig["${o}"]`).join('\n')}\nexport { config as default, ${configOptions.join(', ')} }`,
getContents: () => `type tailwindcssConfig = import("tailwindcss").Config\ndeclare const config: tailwindcssConfig\n${configOptions.map(o => `declare const ${o}: tailwindcssConfig["${o}"]`).join('\n')}\nexport { config as default, ${configOptions.join(', ')} }`,
write: true
})
nuxt.options.alias['#tailwind-config'] = template.dst
@@ -198,7 +236,7 @@ export default defineNuxtModule<ModuleOptions>({
let injectPosition: number
try {
injectPosition = resolveInjectPosition(nuxt.options.css, moduleOptions.injectPosition)
} catch (e) {
} catch (e: any) {
throw new Error('failed to resolve Tailwind CSS injection position: ' + e.message)
}

@@ -212,8 +250,8 @@ export default defineNuxtModule<ModuleOptions>({
// Setup postcss plugins
// https://tailwindcss.com/docs/using-with-preprocessors#future-css-features
const postcssOptions =
nuxt.options.postcss || /* nuxt 3 */
nuxt.options.build.postcss.postcssOptions || /* older nuxt3 */
nuxt.options.postcss || /* nuxt 3 */ /* @ts-ignore */
nuxt.options.build.postcss.postcssOptions || /* older nuxt3 */ /* @ts-ignore */
nuxt.options.build.postcss as any
postcssOptions.plugins = postcssOptions.plugins || {}
postcssOptions.plugins['tailwindcss/nesting'] = postcssOptions.plugins['tailwindcss/nesting'] ?? {}
@@ -241,6 +279,7 @@ export default defineNuxtModule<ModuleOptions>({
// TODO: Fix `addServerHandler` on Nuxt 2 w/o Bridge
if (nuxt.options.dev && moduleOptions.viewer) {
const route = '/_tailwind'
// @ts-ignore
const createServer = await import('tailwind-config-viewer/server/index.js').then(r => r.default || r) as any
const { withTrailingSlash, withoutTrailingSlash } = await import('ufo')
const routerPrefix = isNuxt3() ? route : undefined
@@ -252,6 +291,7 @@ export default defineNuxtModule<ModuleOptions>({
_viewerDevMiddleware(event.req, event.res)
})
if (isNuxt3()) { addDevServerHandler({ route, handler: viewerDevMiddleware }) }
// @ts-ignore
if (isNuxt2()) { nuxt.options.serverMiddleware.push({ route, handler: viewerDevMiddleware }) }
nuxt.hook('listen', (_, listener) => {
const viewerUrl = `${withoutTrailingSlash(listener.url)}${route}`
Loading