tailwindcss 3.0.23 → 3.1.1

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.
Files changed (119) hide show
  1. package/CHANGELOG.md +92 -2
  2. package/colors.d.ts +3 -0
  3. package/defaultConfig.d.ts +3 -0
  4. package/defaultTheme.d.ts +3 -0
  5. package/lib/cli-peer-dependencies.js +10 -5
  6. package/lib/cli.js +266 -203
  7. package/lib/constants.js +8 -8
  8. package/lib/corePluginList.js +1 -0
  9. package/lib/corePlugins.js +1640 -1562
  10. package/lib/css/preflight.css +1 -8
  11. package/lib/featureFlags.js +14 -12
  12. package/lib/index.js +16 -6
  13. package/lib/lib/cacheInvalidation.js +87 -0
  14. package/lib/lib/collapseAdjacentRules.js +30 -15
  15. package/lib/lib/collapseDuplicateDeclarations.js +1 -1
  16. package/lib/lib/defaultExtractor.js +191 -32
  17. package/lib/lib/detectNesting.js +9 -9
  18. package/lib/lib/evaluateTailwindFunctions.js +37 -28
  19. package/lib/lib/expandApplyAtRules.js +379 -189
  20. package/lib/lib/expandTailwindAtRules.js +168 -144
  21. package/lib/lib/generateRules.js +177 -95
  22. package/lib/lib/getModuleDependencies.js +14 -14
  23. package/lib/lib/normalizeTailwindDirectives.js +35 -35
  24. package/lib/lib/partitionApplyAtRules.js +7 -7
  25. package/lib/lib/regex.js +52 -0
  26. package/lib/lib/resolveDefaultsAtRules.js +96 -81
  27. package/lib/lib/setupContextUtils.js +202 -159
  28. package/lib/lib/setupTrackingContext.js +61 -63
  29. package/lib/lib/sharedState.js +10 -9
  30. package/lib/lib/substituteScreenAtRules.js +3 -4
  31. package/lib/postcss-plugins/nesting/README.md +2 -2
  32. package/lib/postcss-plugins/nesting/index.js +1 -1
  33. package/lib/postcss-plugins/nesting/plugin.js +40 -9
  34. package/lib/processTailwindFeatures.js +7 -7
  35. package/lib/public/colors.js +241 -241
  36. package/lib/public/resolve-config.js +5 -5
  37. package/lib/util/buildMediaQuery.js +2 -3
  38. package/lib/util/cloneDeep.js +3 -5
  39. package/lib/util/cloneNodes.js +12 -1
  40. package/lib/util/color.js +42 -51
  41. package/lib/util/createPlugin.js +1 -2
  42. package/lib/util/createUtilityPlugin.js +6 -7
  43. package/lib/util/dataTypes.js +85 -81
  44. package/lib/util/escapeClassName.js +5 -5
  45. package/lib/util/escapeCommas.js +1 -1
  46. package/lib/util/flattenColorPalette.js +4 -7
  47. package/lib/util/formatVariantSelector.js +82 -75
  48. package/lib/util/getAllConfigs.js +15 -10
  49. package/lib/util/hashConfig.js +5 -5
  50. package/lib/util/isKeyframeRule.js +1 -1
  51. package/lib/util/isPlainObject.js +1 -1
  52. package/lib/util/isValidArbitraryValue.js +26 -27
  53. package/lib/util/log.js +9 -10
  54. package/lib/util/nameClass.js +7 -7
  55. package/lib/util/negateValue.js +4 -5
  56. package/lib/util/normalizeConfig.js +68 -58
  57. package/lib/util/normalizeScreens.js +5 -6
  58. package/lib/util/parseAnimationValue.js +56 -57
  59. package/lib/util/parseBoxShadowValue.js +19 -20
  60. package/lib/util/parseDependency.js +32 -32
  61. package/lib/util/parseObjectStyles.js +6 -6
  62. package/lib/util/pluginUtils.js +20 -12
  63. package/lib/util/prefixSelector.js +1 -1
  64. package/lib/util/resolveConfig.js +81 -58
  65. package/lib/util/resolveConfigPath.js +16 -16
  66. package/lib/util/responsive.js +6 -6
  67. package/lib/util/splitAtTopLevelOnly.js +90 -0
  68. package/lib/util/toColorValue.js +1 -1
  69. package/lib/util/toPath.js +2 -2
  70. package/lib/util/transformThemeValue.js +30 -28
  71. package/lib/util/validateConfig.js +21 -0
  72. package/lib/util/withAlphaVariable.js +23 -23
  73. package/package.json +33 -27
  74. package/peers/index.js +7702 -5822
  75. package/plugin.d.ts +11 -0
  76. package/scripts/generate-types.js +52 -0
  77. package/src/cli-peer-dependencies.js +7 -1
  78. package/src/cli.js +118 -24
  79. package/src/corePluginList.js +1 -1
  80. package/src/corePlugins.js +109 -30
  81. package/src/css/preflight.css +1 -8
  82. package/src/featureFlags.js +4 -4
  83. package/src/index.js +15 -1
  84. package/src/lib/cacheInvalidation.js +52 -0
  85. package/src/lib/collapseAdjacentRules.js +21 -2
  86. package/src/lib/defaultExtractor.js +177 -35
  87. package/src/lib/evaluateTailwindFunctions.js +20 -4
  88. package/src/lib/expandApplyAtRules.js +418 -186
  89. package/src/lib/expandTailwindAtRules.js +29 -9
  90. package/src/lib/generateRules.js +137 -51
  91. package/src/lib/regex.js +74 -0
  92. package/src/lib/resolveDefaultsAtRules.js +53 -32
  93. package/src/lib/setupContextUtils.js +128 -65
  94. package/src/lib/setupTrackingContext.js +7 -3
  95. package/src/lib/sharedState.js +1 -0
  96. package/src/postcss-plugins/nesting/README.md +2 -2
  97. package/src/postcss-plugins/nesting/plugin.js +36 -0
  98. package/src/util/cloneNodes.js +14 -1
  99. package/src/util/color.js +25 -21
  100. package/src/util/dataTypes.js +14 -6
  101. package/src/util/formatVariantSelector.js +79 -62
  102. package/src/util/getAllConfigs.js +7 -0
  103. package/src/util/log.js +8 -8
  104. package/src/util/normalizeConfig.js +0 -8
  105. package/src/util/parseBoxShadowValue.js +3 -2
  106. package/src/util/pluginUtils.js +13 -1
  107. package/src/util/resolveConfig.js +66 -22
  108. package/src/util/splitAtTopLevelOnly.js +71 -0
  109. package/src/util/toPath.js +1 -1
  110. package/src/util/transformThemeValue.js +4 -2
  111. package/src/util/validateConfig.js +13 -0
  112. package/src/util/withAlphaVariable.js +1 -1
  113. package/stubs/defaultConfig.stub.js +5 -1
  114. package/stubs/simpleConfig.stub.js +1 -0
  115. package/types/config.d.ts +325 -0
  116. package/types/generated/.gitkeep +0 -0
  117. package/types/generated/colors.d.ts +276 -0
  118. package/types/generated/corePluginList.d.ts +1 -0
  119. package/types/index.d.ts +7 -0
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
+ exports.isValidVariantFormatString = isValidVariantFormatString;
6
+ exports.parseVariant = parseVariant;
5
7
  exports.getFileModifiedMap = getFileModifiedMap;
6
8
  exports.createContext = createContext;
7
9
  exports.getContext = getContext;
@@ -10,6 +12,7 @@ var _url = _interopRequireDefault(require("url"));
10
12
  var _postcss = _interopRequireDefault(require("postcss"));
11
13
  var _dlv = _interopRequireDefault(require("dlv"));
12
14
  var _postcssSelectorParser = _interopRequireDefault(require("postcss-selector-parser"));
15
+ var _featureFlagsJs = require("../featureFlags.js");
13
16
  var _transformThemeValue = _interopRequireDefault(require("../util/transformThemeValue"));
14
17
  var _parseObjectStyles = _interopRequireDefault(require("../util/parseObjectStyles"));
15
18
  var _prefixSelector = _interopRequireDefault(require("../util/prefixSelector"));
@@ -25,41 +28,60 @@ var _log = _interopRequireDefault(require("../util/log"));
25
28
  var _negateValue = _interopRequireDefault(require("../util/negateValue"));
26
29
  var _isValidArbitraryValue = _interopRequireDefault(require("../util/isValidArbitraryValue"));
27
30
  var _generateRules = require("./generateRules");
31
+ var _cacheInvalidationJs = require("./cacheInvalidation.js");
28
32
  function _interopRequireDefault(obj) {
29
33
  return obj && obj.__esModule ? obj : {
30
34
  default: obj
31
35
  };
32
36
  }
37
+ function _getRequireWildcardCache() {
38
+ if (typeof WeakMap !== "function") return null;
39
+ var cache = new WeakMap();
40
+ _getRequireWildcardCache = function() {
41
+ return cache;
42
+ };
43
+ return cache;
44
+ }
33
45
  function _interopRequireWildcard(obj) {
34
46
  if (obj && obj.__esModule) {
35
47
  return obj;
36
- } else {
37
- var newObj = {};
38
- if (obj != null) {
39
- for(var key in obj){
40
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
41
- var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {};
42
- if (desc.get || desc.set) {
43
- Object.defineProperty(newObj, key, desc);
44
- } else {
45
- newObj[key] = obj[key];
46
- }
47
- }
48
+ }
49
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
50
+ return {
51
+ default: obj
52
+ };
53
+ }
54
+ var cache = _getRequireWildcardCache();
55
+ if (cache && cache.has(obj)) {
56
+ return cache.get(obj);
57
+ }
58
+ var newObj = {};
59
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
60
+ for(var key in obj){
61
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
62
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
63
+ if (desc && (desc.get || desc.set)) {
64
+ Object.defineProperty(newObj, key, desc);
65
+ } else {
66
+ newObj[key] = obj[key];
48
67
  }
49
68
  }
50
- newObj.default = obj;
51
- return newObj;
52
69
  }
70
+ newObj.default = obj;
71
+ if (cache) {
72
+ cache.set(obj, newObj);
73
+ }
74
+ return newObj;
53
75
  }
76
+ let MATCH_VARIANT = Symbol();
54
77
  function prefix(context, selector) {
55
78
  let prefix1 = context.tailwindConfig.prefix;
56
- return typeof prefix1 === 'function' ? prefix1(selector) : prefix1 + selector;
79
+ return typeof prefix1 === "function" ? prefix1(selector) : prefix1 + selector;
57
80
  }
58
81
  function parseVariantFormatString(input) {
59
- if (input.includes('{')) {
82
+ if (input.includes("{")) {
60
83
  if (!isBalanced(input)) throw new Error(`Your { and } are unbalanced.`);
61
- return input.split(/{(.*)}/gim).flatMap((line)=>parseVariantFormatString(line)
62
- ).filter(Boolean);
84
+ return input.split(/{(.*)}/gim).flatMap((line)=>parseVariantFormatString(line)).filter(Boolean);
63
85
  }
64
86
  return [
65
87
  input.trim()
@@ -68,9 +90,9 @@ function parseVariantFormatString(input) {
68
90
  function isBalanced(input) {
69
91
  let count = 0;
70
92
  for (let char of input){
71
- if (char === '{') {
93
+ if (char === "{") {
72
94
  count++;
73
- } else if (char === '}') {
95
+ } else if (char === "}") {
74
96
  if (--count < 0) {
75
97
  return false // unbalanced
76
98
  ;
@@ -104,9 +126,12 @@ function parseStyles(styles) {
104
126
  return isNode ? style : (0, _parseObjectStyles).default(style);
105
127
  });
106
128
  }
107
- function getClasses(selector) {
129
+ function getClasses(selector, mutate) {
108
130
  let parser = (0, _postcssSelectorParser).default((selectors)=>{
109
131
  let allClasses = [];
132
+ if (mutate) {
133
+ mutate(selectors);
134
+ }
110
135
  selectors.walkClasses((classNode)=>{
111
136
  allClasses.push(classNode.value);
112
137
  });
@@ -119,9 +144,20 @@ function extractCandidates(node, state = {
119
144
  }, depth = 0) {
120
145
  let classes = [];
121
146
  // Handle normal rules
122
- if (node.type === 'rule') {
147
+ if (node.type === "rule") {
148
+ // Ignore everything inside a :not(...). This allows you to write code like
149
+ // `div:not(.foo)`. If `.foo` is never found in your code, then we used to
150
+ // not generated it. But now we will ignore everything inside a `:not`, so
151
+ // that it still gets generated.
152
+ function ignoreNot(selectors) {
153
+ selectors.walkPseudos((pseudo)=>{
154
+ if (pseudo.value === ":not") {
155
+ pseudo.remove();
156
+ }
157
+ });
158
+ }
123
159
  for (let selector of node.selectors){
124
- let classCandidates = getClasses(selector);
160
+ let classCandidates = getClasses(selector, ignoreNot);
125
161
  // At least one of the selectors contains non-"on-demandable" candidates.
126
162
  if (classCandidates.length === 0) {
127
163
  state.containsNonOnDemandable = true;
@@ -130,10 +166,9 @@ function extractCandidates(node, state = {
130
166
  classes.push(classCandidate);
131
167
  }
132
168
  }
133
- } else if (node.type === 'atrule') {
169
+ } else if (node.type === "atrule") {
134
170
  node.walkRules((rule)=>{
135
- for (let classCandidate of rule.selectors.flatMap((selector)=>getClasses(selector, state, depth + 1)
136
- )){
171
+ for (let classCandidate of rule.selectors.flatMap((selector)=>getClasses(selector))){
137
172
  classes.push(classCandidate);
138
173
  }
139
174
  });
@@ -168,6 +203,27 @@ function withIdentifiers(styles) {
168
203
  });
169
204
  });
170
205
  }
206
+ function isValidVariantFormatString(format) {
207
+ return format.startsWith("@") || format.includes("&");
208
+ }
209
+ function parseVariant(variant) {
210
+ variant = variant.replace(/\n+/g, "").replace(/\s{1,}/g, " ").trim();
211
+ let fns = parseVariantFormatString(variant).map((str)=>{
212
+ if (!str.startsWith("@")) {
213
+ return ({ format })=>format(str);
214
+ }
215
+ let [, name, params] = /@(.*?)( .+|[({].*)/g.exec(str);
216
+ return ({ wrap })=>wrap(_postcss.default.atRule({
217
+ name,
218
+ params: params.trim()
219
+ }));
220
+ }).reverse();
221
+ return (api)=>{
222
+ for (let fn of fns){
223
+ fn(api);
224
+ }
225
+ };
226
+ }
171
227
  function buildPluginApi(tailwindConfig, context, { variantList , variantMap , offsets , classList }) {
172
228
  function getConfigValue(path, defaultValue) {
173
229
  return path ? (0, _dlv).default(tailwindConfig, path, defaultValue) : tailwindConfig;
@@ -184,60 +240,32 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
184
240
  }
185
241
  return context.tailwindConfig.prefix + identifier;
186
242
  }
187
- return {
188
- addVariant (variantName, variantFunctions, options = {}) {
189
- variantFunctions = [].concat(variantFunctions).map((variantFunction)=>{
190
- if (typeof variantFunction !== 'string') {
191
- // Safelist public API functions
192
- return ({ modifySelectors , container , separator })=>{
193
- return variantFunction({
194
- modifySelectors,
195
- container,
196
- separator
197
- });
198
- };
199
- }
200
- variantFunction = variantFunction.replace(/\n+/g, '').replace(/\s{1,}/g, ' ').trim();
201
- let fns = parseVariantFormatString(variantFunction).map((str)=>{
202
- if (!str.startsWith('@')) {
203
- return ({ format })=>format(str)
204
- ;
205
- }
206
- let [, name, params] = /@(.*?) (.*)/g.exec(str);
207
- return ({ wrap })=>wrap(_postcss.default.atRule({
208
- name,
209
- params
210
- }))
211
- ;
212
- }).reverse();
213
- return (api)=>{
214
- for (let fn of fns){
215
- fn(api);
216
- }
217
- };
218
- });
219
- insertInto(variantList, variantName, options);
220
- variantMap.set(variantName, variantFunctions);
221
- },
243
+ function resolveThemeValue(path, defaultValue, opts = {}) {
244
+ const [pathRoot, ...subPaths] = (0, _toPath).toPath(path);
245
+ const value = getConfigValue([
246
+ "theme",
247
+ pathRoot,
248
+ ...subPaths
249
+ ], defaultValue);
250
+ return (0, _transformThemeValue).default(pathRoot)(value, opts);
251
+ }
252
+ const theme = Object.assign((path, defaultValue = undefined)=>resolveThemeValue(path, defaultValue), {
253
+ withAlpha: (path, opacityValue)=>resolveThemeValue(path, undefined, {
254
+ opacityValue
255
+ })
256
+ });
257
+ let api1 = {
222
258
  postcss: _postcss.default,
223
259
  prefix: applyConfiguredPrefix,
224
260
  e: _escapeClassName.default,
225
261
  config: getConfigValue,
226
- theme (path, defaultValue) {
227
- const [pathRoot, ...subPaths] = (0, _toPath).toPath(path);
228
- const value = getConfigValue([
229
- 'theme',
230
- pathRoot,
231
- ...subPaths
232
- ], defaultValue);
233
- return (0, _transformThemeValue).default(pathRoot)(value);
234
- },
262
+ theme,
235
263
  corePlugins: (path)=>{
236
264
  if (Array.isArray(tailwindConfig.corePlugins)) {
237
265
  return tailwindConfig.corePlugins.includes(path);
238
266
  }
239
267
  return getConfigValue([
240
- 'corePlugins',
268
+ "corePlugins",
241
269
  path
242
270
  ], true);
243
271
  },
@@ -245,21 +273,6 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
245
273
  // Preserved for backwards compatibility but not used in v3.0+
246
274
  return [];
247
275
  },
248
- addUserCss (userCss) {
249
- for (let [identifier, rule] of withIdentifiers(userCss)){
250
- let offset = offsets.user++;
251
- if (!context.candidateRuleMap.has(identifier)) {
252
- context.candidateRuleMap.set(identifier, []);
253
- }
254
- context.candidateRuleMap.get(identifier).push([
255
- {
256
- sort: offset,
257
- layer: 'user'
258
- },
259
- rule
260
- ]);
261
- }
262
- },
263
276
  addBase (base) {
264
277
  for (let [identifier, rule] of withIdentifiers(base)){
265
278
  let prefixedIdentifier = prefixIdentifier(identifier, {});
@@ -270,7 +283,7 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
270
283
  context.candidateRuleMap.get(prefixedIdentifier).push([
271
284
  {
272
285
  sort: offset,
273
- layer: 'base'
286
+ layer: "base"
274
287
  },
275
288
  rule
276
289
  ]);
@@ -291,7 +304,7 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
291
304
  context.candidateRuleMap.get(prefixedIdentifier).push([
292
305
  {
293
306
  sort: offsets.base++,
294
- layer: 'defaults'
307
+ layer: "defaults"
295
308
  },
296
309
  rule
297
310
  ]);
@@ -312,7 +325,7 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
312
325
  context.candidateRuleMap.get(prefixedIdentifier).push([
313
326
  {
314
327
  sort: offsets.components++,
315
- layer: 'components',
328
+ layer: "components",
316
329
  options
317
330
  },
318
331
  rule
@@ -334,7 +347,7 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
334
347
  context.candidateRuleMap.get(prefixedIdentifier).push([
335
348
  {
336
349
  sort: offsets.utilities++,
337
- layer: 'utilities',
350
+ layer: "utilities",
338
351
  options
339
352
  },
340
353
  rule
@@ -359,7 +372,7 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
359
372
  options
360
373
  ]);
361
374
  function wrapped(modifier, { isOnlyPlugin }) {
362
- let { type ='any' } = options;
375
+ let { type ="any" } = options;
363
376
  type = [].concat(type);
364
377
  let [value, coercedType] = (0, _pluginUtils).coerceValue(type, modifier, options, tailwindConfig);
365
378
  if (value === undefined) {
@@ -373,14 +386,13 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
373
386
  }
374
387
  let ruleSets = [].concat(rule(value)).filter(Boolean).map((declaration)=>({
375
388
  [(0, _nameClass).default(identifier, modifier)]: declaration
376
- })
377
- );
389
+ }));
378
390
  return ruleSets;
379
391
  }
380
392
  let withOffsets = [
381
393
  {
382
394
  sort: offset,
383
- layer: 'utilities',
395
+ layer: "utilities",
384
396
  options
385
397
  },
386
398
  wrapped
@@ -409,7 +421,7 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
409
421
  options
410
422
  ]);
411
423
  function wrapped(modifier, { isOnlyPlugin }) {
412
- let { type ='any' } = options;
424
+ let { type ="any" } = options;
413
425
  type = [].concat(type);
414
426
  let [value, coercedType] = (0, _pluginUtils).coerceValue(type, modifier, options, tailwindConfig);
415
427
  if (value === undefined) {
@@ -419,7 +431,7 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
419
431
  if (isOnlyPlugin) {
420
432
  _log.default.warn([
421
433
  `Unnecessary typehint \`${coercedType}\` in \`${identifier}-${modifier}\`.`,
422
- `You can safely update it to \`${identifier}-${modifier.replace(coercedType + ':', '')}\`.`,
434
+ `You can safely update it to \`${identifier}-${modifier.replace(coercedType + ":", "")}\`.`,
423
435
  ]);
424
436
  } else {
425
437
  return [];
@@ -430,14 +442,13 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
430
442
  }
431
443
  let ruleSets = [].concat(rule(value)).filter(Boolean).map((declaration)=>({
432
444
  [(0, _nameClass).default(identifier, modifier)]: declaration
433
- })
434
- );
445
+ }));
435
446
  return ruleSets;
436
447
  }
437
448
  let withOffsets = [
438
449
  {
439
450
  sort: offset,
440
- layer: 'components',
451
+ layer: "components",
441
452
  options
442
453
  },
443
454
  wrapped
@@ -447,8 +458,55 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
447
458
  }
448
459
  context.candidateRuleMap.get(prefixedIdentifier).push(withOffsets);
449
460
  }
461
+ },
462
+ addVariant (variantName, variantFunctions, options = {}) {
463
+ variantFunctions = [].concat(variantFunctions).map((variantFunction)=>{
464
+ if (typeof variantFunction !== "string") {
465
+ // Safelist public API functions
466
+ return (api)=>{
467
+ let { args , modifySelectors , container , separator , wrap , format } = api;
468
+ let result = variantFunction(Object.assign({
469
+ modifySelectors,
470
+ container,
471
+ separator
472
+ }, variantFunction[MATCH_VARIANT] && {
473
+ args,
474
+ wrap,
475
+ format
476
+ }));
477
+ if (typeof result === "string" && !isValidVariantFormatString(result)) {
478
+ throw new Error(`Your custom variant \`${variantName}\` has an invalid format string. Make sure it's an at-rule or contains a \`&\` placeholder.`);
479
+ }
480
+ if (Array.isArray(result)) {
481
+ return result.map((variant)=>parseVariant(variant));
482
+ }
483
+ // result may be undefined with legacy variants that use APIs like `modifySelectors`
484
+ return result && parseVariant(result)(api);
485
+ };
486
+ }
487
+ if (!isValidVariantFormatString(variantFunction)) {
488
+ throw new Error(`Your custom variant \`${variantName}\` has an invalid format string. Make sure it's an at-rule or contains a \`&\` placeholder.`);
489
+ }
490
+ return parseVariant(variantFunction);
491
+ });
492
+ insertInto(variantList, variantName, options);
493
+ variantMap.set(variantName, variantFunctions);
450
494
  }
451
495
  };
496
+ if ((0, _featureFlagsJs).flagEnabled(tailwindConfig, "matchVariant")) {
497
+ api1.matchVariant = function(variants, options) {
498
+ for(let variant in variants){
499
+ var ref;
500
+ for (let [k, v] of Object.entries((ref = options === null || options === void 0 ? void 0 : options.values) !== null && ref !== void 0 ? ref : {})){
501
+ api1.addVariant(`${variant}-${k}`, variants[variant](v));
502
+ }
503
+ api1.addVariant(variant, Object.assign(({ args })=>variants[variant](args), {
504
+ [MATCH_VARIANT]: true
505
+ }), options);
506
+ }
507
+ };
508
+ }
509
+ return api1;
452
510
  }
453
511
  let fileModifiedMapCache = new WeakMap();
454
512
  function getFileModifiedMap(context) {
@@ -463,8 +521,8 @@ function trackModified(files, fileModifiedMap) {
463
521
  var ref;
464
522
  if (!file) continue;
465
523
  let parsed = _url.default.parse(file);
466
- let pathname = parsed.hash ? parsed.href.replace(parsed.hash, '') : parsed.href;
467
- pathname = parsed.search ? pathname.replace(parsed.search, '') : pathname;
524
+ let pathname = parsed.hash ? parsed.href.replace(parsed.hash, "") : parsed.href;
525
+ pathname = parsed.search ? pathname.replace(parsed.search, "") : pathname;
468
526
  let newModified = (ref = _fs.default.statSync(decodeURIComponent(pathname), {
469
527
  throwIfNoEntry: false
470
528
  })) === null || ref === void 0 ? void 0 : ref.mtimeMs;
@@ -481,8 +539,8 @@ function trackModified(files, fileModifiedMap) {
481
539
  function extractVariantAtRules(node) {
482
540
  node.walkAtRules((atRule)=>{
483
541
  if ([
484
- 'responsive',
485
- 'variants'
542
+ "responsive",
543
+ "variants"
486
544
  ].includes(atRule.name)) {
487
545
  extractVariantAtRules(atRule);
488
546
  atRule.before(atRule.nodes);
@@ -493,18 +551,18 @@ function extractVariantAtRules(node) {
493
551
  function collectLayerPlugins(root) {
494
552
  let layerPlugins = [];
495
553
  root.each((node)=>{
496
- if (node.type === 'atrule' && [
497
- 'responsive',
498
- 'variants'
554
+ if (node.type === "atrule" && [
555
+ "responsive",
556
+ "variants"
499
557
  ].includes(node.name)) {
500
- node.name = 'layer';
501
- node.params = 'utilities';
558
+ node.name = "layer";
559
+ node.params = "utilities";
502
560
  }
503
561
  });
504
562
  // Walk @layer rules and treat them like plugins
505
- root.walkAtRules('layer', (layerRule)=>{
563
+ root.walkAtRules("layer", (layerRule)=>{
506
564
  extractVariantAtRules(layerRule);
507
- if (layerRule.params === 'base') {
565
+ if (layerRule.params === "base") {
508
566
  for (let node of layerRule.nodes){
509
567
  layerPlugins.push(function({ addBase }) {
510
568
  addBase(node, {
@@ -513,7 +571,7 @@ function collectLayerPlugins(root) {
513
571
  });
514
572
  }
515
573
  layerRule.remove();
516
- } else if (layerRule.params === 'components') {
574
+ } else if (layerRule.params === "components") {
517
575
  for (let node of layerRule.nodes){
518
576
  layerPlugins.push(function({ addComponents }) {
519
577
  addComponents(node, {
@@ -522,7 +580,7 @@ function collectLayerPlugins(root) {
522
580
  });
523
581
  }
524
582
  layerRule.remove();
525
- } else if (layerRule.params === 'utilities') {
583
+ } else if (layerRule.params === "utilities") {
526
584
  for (let node of layerRule.nodes){
527
585
  layerPlugins.push(function({ addUtilities }) {
528
586
  addUtilities(node, {
@@ -533,16 +591,6 @@ function collectLayerPlugins(root) {
533
591
  layerRule.remove();
534
592
  }
535
593
  });
536
- root.walkRules((rule)=>{
537
- // At this point it is safe to include all the left-over css from the
538
- // user's css file. This is because the `@tailwind` and `@layer` directives
539
- // will already be handled and will be removed from the css tree.
540
- layerPlugins.push(function({ addUserCss }) {
541
- addUserCss(rule, {
542
- respectPrefix: false
543
- });
544
- });
545
- });
546
594
  return layerPlugins;
547
595
  }
548
596
  function resolvePlugins(context, root) {
@@ -559,22 +607,23 @@ function resolvePlugins(context, root) {
559
607
  if (plugin.__isOptionsFunction) {
560
608
  plugin = plugin();
561
609
  }
562
- return typeof plugin === 'function' ? plugin : plugin.handler;
610
+ return typeof plugin === "function" ? plugin : plugin.handler;
563
611
  });
564
612
  let layerPlugins = collectLayerPlugins(root);
565
613
  // TODO: This is a workaround for backwards compatibility, since custom variants
566
614
  // were historically sorted before screen/stackable variants.
567
615
  let beforeVariants = [
568
- _corePlugins.variantPlugins['pseudoElementVariants'],
569
- _corePlugins.variantPlugins['pseudoClassVariants'],
616
+ _corePlugins.variantPlugins["pseudoElementVariants"],
617
+ _corePlugins.variantPlugins["pseudoClassVariants"],
570
618
  ];
571
619
  let afterVariants = [
572
- _corePlugins.variantPlugins['directionVariants'],
573
- _corePlugins.variantPlugins['reducedMotionVariants'],
574
- _corePlugins.variantPlugins['darkVariants'],
575
- _corePlugins.variantPlugins['printVariant'],
576
- _corePlugins.variantPlugins['screenVariants'],
577
- _corePlugins.variantPlugins['orientationVariants'],
620
+ _corePlugins.variantPlugins["directionVariants"],
621
+ _corePlugins.variantPlugins["reducedMotionVariants"],
622
+ _corePlugins.variantPlugins["prefersContrastVariants"],
623
+ _corePlugins.variantPlugins["darkVariants"],
624
+ _corePlugins.variantPlugins["printVariant"],
625
+ _corePlugins.variantPlugins["screenVariants"],
626
+ _corePlugins.variantPlugins["orientationVariants"],
578
627
  ];
579
628
  return [
580
629
  ...corePluginList,
@@ -610,9 +659,7 @@ function registerPlugins(plugins, context) {
610
659
  plugin === null || plugin === void 0 ? void 0 : plugin(pluginApi);
611
660
  }
612
661
  }
613
- let highestOffset = ((args)=>args.reduce((m, e)=>e > m ? e : m
614
- )
615
- )([
662
+ let highestOffset = ((args)=>args.reduce((m, e)=>e > m ? e : m))([
616
663
  offsets.base,
617
664
  offsets.defaults,
618
665
  offsets.components,
@@ -640,8 +687,7 @@ function registerPlugins(plugins, context) {
640
687
  variant,
641
688
  bits
642
689
  ];
643
- }).sort(([, a], [, z])=>(0, _bigSign).default(a - z)
644
- ));
690
+ }).sort(([, a], [, z])=>(0, _bigSign).default(a - z)));
645
691
  context.minimumScreen = [
646
692
  ...context.variantOrder.values()
647
693
  ].shift();
@@ -651,26 +697,25 @@ function registerPlugins(plugins, context) {
651
697
  context.variantMap.set(variantName, variantFunctions1.map((variantFunction, idx)=>[
652
698
  sort << BigInt(idx),
653
699
  variantFunction
654
- ]
655
- ));
700
+ ]));
656
701
  }
657
702
  var _safelist;
658
703
  let safelist = ((_safelist = context.tailwindConfig.safelist) !== null && _safelist !== void 0 ? _safelist : []).filter(Boolean);
659
704
  if (safelist.length > 0) {
660
705
  let checks = [];
661
706
  for (let value1 of safelist){
662
- if (typeof value1 === 'string') {
707
+ if (typeof value1 === "string") {
663
708
  context.changedContent.push({
664
709
  content: value1,
665
- extension: 'html'
710
+ extension: "html"
666
711
  });
667
712
  continue;
668
713
  }
669
714
  if (value1 instanceof RegExp) {
670
- _log.default.warn('root-regex', [
671
- 'Regular expressions in `safelist` work differently in Tailwind CSS v3.0.',
672
- 'Update your `safelist` configuration to eliminate this warning.',
673
- 'https://tailwindcss.com/docs/content-configuration#safelisting-classes',
715
+ _log.default.warn("root-regex", [
716
+ "Regular expressions in `safelist` work differently in Tailwind CSS v3.0.",
717
+ "Update your `safelist` configuration to eliminate this warning.",
718
+ "https://tailwindcss.com/docs/content-configuration#safelisting-classes",
674
719
  ]);
675
720
  continue;
676
721
  }
@@ -684,15 +729,13 @@ function registerPlugins(plugins, context) {
684
729
  let [utilName, options] = util;
685
730
  var ref;
686
731
  let values = Object.keys((ref = options === null || options === void 0 ? void 0 : options.values) !== null && ref !== void 0 ? ref : {});
687
- let classes = values.map((value)=>(0, _nameClass).formatClass(utilName, value)
688
- );
732
+ let classes = values.map((value)=>(0, _nameClass).formatClass(utilName, value));
689
733
  if (options === null || options === void 0 ? void 0 : options.supportsNegativeValues) {
690
734
  // This is the normal negated version
691
735
  // e.g. `-inset-1` or `-tw-inset-1`
692
736
  classes = [
693
737
  ...classes,
694
- ...classes.map((cls)=>'-' + cls
695
- )
738
+ ...classes.map((cls)=>"-" + cls)
696
739
  ];
697
740
  // This is the negated version *after* the prefix
698
741
  // e.g. `tw--inset-1`
@@ -700,8 +743,7 @@ function registerPlugins(plugins, context) {
700
743
  // So we add the negative after the prefix
701
744
  classes = [
702
745
  ...classes,
703
- ...classes.map((cls)=>cls.slice(0, prefixLength) + '-' + cls.slice(prefixLength)
704
- ),
746
+ ...classes.map((cls)=>cls.slice(0, prefixLength) + "-" + cls.slice(prefixLength)),
705
747
  ];
706
748
  }
707
749
  return classes;
@@ -720,12 +762,12 @@ function registerPlugins(plugins, context) {
720
762
  patternMatchingCount.set(pattern, patternMatchingCount.get(pattern) + 1);
721
763
  context.changedContent.push({
722
764
  content: util1,
723
- extension: 'html'
765
+ extension: "html"
724
766
  });
725
767
  for (let variant of variants){
726
768
  context.changedContent.push({
727
769
  content: variant + context.tailwindConfig.separator + util1,
728
- extension: 'html'
770
+ extension: "html"
729
771
  });
730
772
  }
731
773
  }
@@ -735,8 +777,8 @@ function registerPlugins(plugins, context) {
735
777
  if (count !== 0) continue;
736
778
  _log.default.warn([
737
779
  `The safelist pattern \`${regex}\` doesn't match any Tailwind CSS classes.`,
738
- 'Fix this pattern or remove it from your `safelist` configuration.',
739
- 'https://tailwindcss.com/docs/content-configuration#safelisting-classes',
780
+ "Fix this pattern or remove it from your `safelist` configuration.",
781
+ "https://tailwindcss.com/docs/content-configuration#safelisting-classes",
740
782
  ]);
741
783
  }
742
784
  }
@@ -746,8 +788,8 @@ function registerPlugins(plugins, context) {
746
788
  // sorting could be weird since you still require them in order to make the
747
789
  // host utitlies work properly. (Thanks Biology)
748
790
  let parasiteUtilities = new Set([
749
- prefix(context, 'group'),
750
- prefix(context, 'peer')
791
+ prefix(context, "group"),
792
+ prefix(context, "peer")
751
793
  ]);
752
794
  context.getClassOrder = function getClassOrder(classes) {
753
795
  let sortedClassNames = new Map();
@@ -817,7 +859,7 @@ let contextSourcesMap = sharedState.contextSourcesMap;
817
859
  function getContext(root, result, tailwindConfig, userConfigPath, tailwindConfigHash, contextDependencies) {
818
860
  let sourcePath = result.opts.from;
819
861
  let isConfigFile = userConfigPath !== null;
820
- sharedState.env.DEBUG && console.log('Source path:', sourcePath);
862
+ sharedState.env.DEBUG && console.log("Source path:", sourcePath);
821
863
  let existingContext;
822
864
  if (isConfigFile && contextMap.has(sourcePath)) {
823
865
  existingContext = contextMap.get(sourcePath);
@@ -827,13 +869,14 @@ function getContext(root, result, tailwindConfig, userConfigPath, tailwindConfig
827
869
  contextMap.set(sourcePath, context);
828
870
  existingContext = context;
829
871
  }
872
+ let cssDidChange = (0, _cacheInvalidationJs).hasContentChanged(sourcePath, root);
830
873
  // If there's already a context in the cache and we don't need to
831
874
  // reset the context, return the cached context.
832
875
  if (existingContext) {
833
876
  let contextDependenciesChanged = trackModified([
834
877
  ...contextDependencies
835
878
  ], getFileModifiedMap(existingContext));
836
- if (!contextDependenciesChanged) {
879
+ if (!contextDependenciesChanged && !cssDidChange) {
837
880
  return [
838
881
  existingContext,
839
882
  false
@@ -862,7 +905,7 @@ function getContext(root, result, tailwindConfig, userConfigPath, tailwindConfig
862
905
  }
863
906
  }
864
907
  }
865
- sharedState.env.DEBUG && console.log('Setting up new context...');
908
+ sharedState.env.DEBUG && console.log("Setting up new context...");
866
909
  let context = createContext(tailwindConfig, [], root);
867
910
  trackModified([
868
911
  ...contextDependencies