tailwindcss 3.0.13 → 3.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/cli.js CHANGED
@@ -437,7 +437,6 @@ async function build() {
437
437
 
438
438
  function resolveConfig() {
439
439
  let config = configPath ? require(configPath) : {}
440
- let resolvedConfig = resolveConfigInternal(config)
441
440
 
442
441
  if (args['--purge']) {
443
442
  log.warn('purge-flag-deprecated', [
@@ -450,10 +449,13 @@ async function build() {
450
449
  }
451
450
 
452
451
  if (args['--content']) {
453
- resolvedConfig.content.files = args['--content'].split(/(?<!{[^}]+),/)
452
+ let files = args['--content'].split(/(?<!{[^}]+),/)
453
+ let resolvedConfig = resolveConfigInternal(config, { content: { files } })
454
+ resolvedConfig.content.files = files
455
+ return resolvedConfig
454
456
  }
455
457
 
456
- return resolvedConfig
458
+ return resolveConfigInternal(config)
457
459
  }
458
460
 
459
461
  function extractFileGlobs(config) {
@@ -144,6 +144,7 @@ export let variantPlugins = {
144
144
  log.warn('darkmode-false', [
145
145
  'The `darkMode` option in your Tailwind CSS configuration is set to `false`, which now behaves the same as `media`.',
146
146
  'Change `darkMode` to `media` or remove it entirely.',
147
+ 'https://tailwindcss.com/docs/upgrade-guide#remove-dark-mode-configuration',
147
148
  ])
148
149
  }
149
150
 
@@ -2,6 +2,7 @@ import LRU from 'quick-lru'
2
2
  import * as sharedState from './sharedState'
3
3
  import { generateRules } from './generateRules'
4
4
  import bigSign from '../util/bigSign'
5
+ import log from '../util/log'
5
6
  import cloneNodes from '../util/cloneNodes'
6
7
  import { defaultExtractor } from './defaultExtractor'
7
8
 
@@ -204,9 +205,6 @@ export default function expandTailwindAtRules(context) {
204
205
 
205
206
  if (layerNodes.base) {
206
207
  layerNodes.base.before(cloneNodes([...baseNodes, ...defaultNodes], layerNodes.base.source))
207
- }
208
-
209
- if (layerNodes.base) {
210
208
  layerNodes.base.remove()
211
209
  }
212
210
 
@@ -220,11 +218,38 @@ export default function expandTailwindAtRules(context) {
220
218
  layerNodes.utilities.remove()
221
219
  }
222
220
 
221
+ // We do post-filtering to not alter the emitted order of the variants
222
+ const variantNodes = Array.from(screenNodes).filter((node) => {
223
+ const parentLayer = node.raws.tailwind?.parentLayer
224
+
225
+ if (parentLayer === 'components') {
226
+ return layerNodes.components !== null
227
+ }
228
+
229
+ if (parentLayer === 'utilities') {
230
+ return layerNodes.utilities !== null
231
+ }
232
+
233
+ return true
234
+ })
235
+
223
236
  if (layerNodes.variants) {
224
- layerNodes.variants.before(cloneNodes([...screenNodes], layerNodes.variants.source))
237
+ layerNodes.variants.before(cloneNodes(variantNodes, layerNodes.variants.source))
225
238
  layerNodes.variants.remove()
226
- } else {
227
- root.append(cloneNodes([...screenNodes], root.source))
239
+ } else if (variantNodes.length > 0) {
240
+ root.append(cloneNodes(variantNodes, root.source))
241
+ }
242
+
243
+ // If we've got a utility layer and no utilities are generated there's likely something wrong
244
+ const hasUtilityVariants = variantNodes.some(
245
+ (node) => node.raws.tailwind?.parentLayer === 'utilities'
246
+ )
247
+
248
+ if (layerNodes.utilities && utilityNodes.size === 0 && !hasUtilityVariants) {
249
+ log.warn('content-problems', [
250
+ 'No utility classes were detected in your source files. If this is unexpected, double-check the `content` option in your Tailwind CSS configuration.',
251
+ 'https://tailwindcss.com/docs/content-configuration',
252
+ ])
228
253
  }
229
254
 
230
255
  // ---
@@ -216,6 +216,12 @@ function applyVariant(variant, matches, context) {
216
216
  })
217
217
  }
218
218
 
219
+ // This tracks the originating layer for the variant
220
+ // For example:
221
+ // .sm:underline {} is a variant of something in the utilities layer
222
+ // .sm:container {} is a variant of the container component
223
+ clone.nodes[0].raws.tailwind = { parentLayer: meta.layer }
224
+
219
225
  let withOffset = [
220
226
  {
221
227
  ...meta,
@@ -49,6 +49,7 @@ export default function normalizeTailwindDirectives(root) {
49
49
  log.warn(`${atRule.name}-at-rule-deprecated`, [
50
50
  `The \`@${atRule.name}\` directive has been deprecated in Tailwind CSS v3.0.`,
51
51
  `Use \`@layer utilities\` or \`@layer components\` instead.`,
52
+ 'https://tailwindcss.com/docs/upgrade-guide#replace-variants-with-layer',
52
53
  ])
53
54
  }
54
55
  layerDirectives.add(atRule)
@@ -656,7 +656,7 @@ function registerPlugins(plugins, context) {
656
656
  log.warn('root-regex', [
657
657
  'Regular expressions in `safelist` work differently in Tailwind CSS v3.0.',
658
658
  'Update your `safelist` configuration to eliminate this warning.',
659
- // TODO: Add https://tw.wtf/regex-safelist
659
+ 'https://tailwindcss.com/docs/content-configuration#safelisting-classes',
660
660
  ])
661
661
  continue
662
662
  }
@@ -714,6 +714,7 @@ function registerPlugins(plugins, context) {
714
714
  log.warn([
715
715
  `The safelist pattern \`${regex}\` doesn't match any Tailwind CSS classes.`,
716
716
  'Fix this pattern or remove it from your `safelist` configuration.',
717
+ 'https://tailwindcss.com/docs/content-configuration#safelisting-classes',
717
718
  ])
718
719
  }
719
720
  }
@@ -0,0 +1,42 @@
1
+ # tailwindcss/nesting
2
+
3
+ This is a PostCSS plugin that wraps [postcss-nested](https://github.com/postcss/postcss-nested) or [postcss-nesting](https://github.com/jonathantneal/postcss-nesting) and acts as a compatibility layer to make sure your nesting plugin of choice properly understands Tailwind's custom syntax like `@apply` and `@screen`.
4
+
5
+ Add it to your PostCSS configuration, somewhere before Tailwind itself:
6
+
7
+ ```js
8
+ // postcss.config.js
9
+ module.exports = {
10
+ plugins: [
11
+ require('postcss-import'),
12
+ require('tailwindcss/nesting'),
13
+ require('tailwindcss'),
14
+ require('autoprefixer'),
15
+ ]
16
+ }
17
+ ```
18
+
19
+ By default, it uses the [postcss-nested](https://github.com/postcss/postcss-nested) plugin under the hood, which uses a Sass-like syntax and is the plugin that powers nesting support in the [Tailwind CSS plugin API](https://tailwindcss.com/docs/plugins#css-in-js-syntax).
20
+
21
+ If you'd rather use [postcss-nesting](https://github.com/jonathantneal/postcss-nesting) (which is based on the work-in-progress [CSS Nesting](https://drafts.csswg.org/css-nesting-1/) specification), first install the plugin alongside:
22
+
23
+ ```shell
24
+ npm install postcss-nesting
25
+ ```
26
+
27
+ Then pass the plugin itself as an argument to `tailwindcss/nesting` in your PostCSS configuration:
28
+
29
+ ```js
30
+ // postcss.config.js
31
+ module.exports = {
32
+ plugins: [
33
+ require('postcss-import'),
34
+ require('tailwindcss/nesting')(require('postcss-nesting')),
35
+ require('tailwindcss'),
36
+ require('autoprefixer'),
37
+ ]
38
+ }
39
+ ```
40
+
41
+ This can also be helpful if for whatever reason you need to use a very specific version of `postcss-nested` and want to override the version we bundle with `tailwindcss/nesting` itself.
42
+
@@ -0,0 +1,13 @@
1
+ import { nesting } from './plugin'
2
+
3
+ export default Object.assign(
4
+ function (opts) {
5
+ return {
6
+ postcssPlugin: 'tailwindcss/nesting',
7
+ Once(root, { result }) {
8
+ return nesting(opts)(root, result)
9
+ },
10
+ }
11
+ },
12
+ { postcss: true }
13
+ )
@@ -1,7 +1,7 @@
1
- let postcss = require('postcss')
2
- let postcssNested = require('postcss-nested')
1
+ import postcss from 'postcss'
2
+ import postcssNested from 'postcss-nested'
3
3
 
4
- module.exports = function nesting(opts = postcssNested) {
4
+ export function nesting(opts = postcssNested) {
5
5
  return (root, result) => {
6
6
  root.walkAtRules('screen', (rule) => {
7
7
  rule.name = 'media'
@@ -14,7 +14,10 @@ module.exports = function nesting(opts = postcssNested) {
14
14
  })
15
15
 
16
16
  let plugin = (() => {
17
- if (typeof opts === 'function') {
17
+ if (
18
+ typeof opts === 'function' ||
19
+ (typeof opts === 'object' && opts?.hasOwnProperty?.('postcssPlugin'))
20
+ ) {
18
21
  return opts
19
22
  }
20
23
 
@@ -124,7 +124,7 @@ export function normalizeConfig(config) {
124
124
  log.warn('purge-deprecation', [
125
125
  'The `purge`/`content` options have changed in Tailwind CSS v3.0.',
126
126
  'Update your configuration file to eliminate this warning.',
127
- // TODO: Add https://tw.wtf/purge-deprecation
127
+ 'https://tailwindcss.com/docs/upgrade-guide#configure-content-sources',
128
128
  ])
129
129
  }
130
130
 
@@ -145,7 +145,7 @@ export function normalizeConfig(config) {
145
145
  log.warn('prefix-function', [
146
146
  'As of Tailwind CSS v3.0, `prefix` cannot be a function.',
147
147
  'Update `prefix` in your configuration to be a string to eliminate this warning.',
148
- // TODO: Add https://tw.wtf/prefix-function
148
+ 'https://tailwindcss.com/docs/upgrade-guide#prefix-cannot-be-a-function',
149
149
  ])
150
150
  config.prefix = ''
151
151
  } else {
@@ -250,13 +250,21 @@ export function normalizeConfig(config) {
250
250
  for (let file of config.content.files) {
251
251
  if (typeof file === 'string' && /{([^,]*?)}/g.test(file)) {
252
252
  log.warn('invalid-glob-braces', [
253
- `The glob pattern ${dim(file)} in your config is invalid.`,
254
- ` Update it to ${dim(file.replace(/{([^,]*?)}/g, '$1'))} to silence this warning.`,
253
+ `The glob pattern ${dim(file)} in your Tailwind CSS configuration is invalid.`,
254
+ `Update it to ${dim(file.replace(/{([^,]*?)}/g, '$1'))} to silence this warning.`,
255
255
  // TODO: Add https://tw.wtf/invalid-glob-braces
256
256
  ])
257
257
  break
258
258
  }
259
259
  }
260
260
 
261
+ if (config.content.files.length === 0) {
262
+ log.warn('content-problems', [
263
+ 'The `content` option in your Tailwind CSS configuration is missing or empty.',
264
+ 'Configure your content sources or your generated CSS will be missing styles.',
265
+ 'https://tailwindcss.com/docs/content-configuration',
266
+ ])
267
+ }
268
+
261
269
  return config
262
270
  }