tailwindcss 0.0.0-insiders.ddec022 → 0.0.0-insiders.de00a62

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 (81) hide show
  1. package/lib/cli/build/plugin.js +6 -6
  2. package/lib/cli/build/watching.js +1 -1
  3. package/lib/corePluginList.js +5 -1
  4. package/lib/corePlugins.js +170 -13
  5. package/lib/css/preflight.css +24 -8
  6. package/lib/lib/content.js +36 -3
  7. package/lib/lib/defaultExtractor.js +33 -25
  8. package/lib/lib/evaluateTailwindFunctions.js +5 -3
  9. package/lib/lib/expandApplyAtRules.js +6 -0
  10. package/lib/lib/expandTailwindAtRules.js +23 -6
  11. package/lib/lib/generateRules.js +47 -25
  12. package/lib/lib/load-config.js +14 -3
  13. package/lib/lib/offsets.js +51 -2
  14. package/lib/lib/resolveDefaultsAtRules.js +3 -1
  15. package/lib/lib/setupContextUtils.js +76 -37
  16. package/lib/lib/setupTrackingContext.js +2 -1
  17. package/lib/oxide/cli/build/plugin.js +6 -6
  18. package/lib/plugin.js +3 -3
  19. package/lib/processTailwindFeatures.js +2 -2
  20. package/lib/util/cloneNodes.js +33 -13
  21. package/lib/util/color.js +1 -1
  22. package/lib/util/dataTypes.js +135 -16
  23. package/lib/util/formatVariantSelector.js +10 -3
  24. package/lib/util/isPlainObject.js +1 -1
  25. package/lib/util/pluginUtils.js +13 -0
  26. package/lib/util/prefixSelector.js +1 -1
  27. package/lib/util/pseudoElements.js +21 -34
  28. package/lib/value-parser/LICENSE +22 -0
  29. package/lib/value-parser/README.md +3 -0
  30. package/lib/value-parser/index.d.js +2 -0
  31. package/lib/value-parser/index.js +22 -0
  32. package/lib/value-parser/parse.js +259 -0
  33. package/lib/value-parser/stringify.js +38 -0
  34. package/lib/value-parser/unit.js +86 -0
  35. package/lib/value-parser/walk.js +16 -0
  36. package/nesting/index.d.ts +4 -0
  37. package/package.json +5 -6
  38. package/peers/index.js +701 -617
  39. package/resolveConfig.d.ts +22 -3
  40. package/scripts/generate-types.js +1 -2
  41. package/src/cli/build/plugin.js +6 -6
  42. package/src/cli/build/watching.js +1 -1
  43. package/src/corePluginList.js +1 -1
  44. package/src/corePlugins.js +149 -12
  45. package/src/css/preflight.css +24 -8
  46. package/src/featureFlags.js +1 -5
  47. package/src/lib/content.js +42 -1
  48. package/src/lib/defaultExtractor.js +30 -17
  49. package/src/lib/evaluateTailwindFunctions.js +4 -1
  50. package/src/lib/expandApplyAtRules.js +7 -0
  51. package/src/lib/expandTailwindAtRules.js +23 -6
  52. package/src/lib/generateRules.js +50 -26
  53. package/src/lib/load-config.ts +8 -0
  54. package/src/lib/offsets.js +61 -2
  55. package/src/lib/resolveDefaultsAtRules.js +5 -1
  56. package/src/lib/setupContextUtils.js +77 -38
  57. package/src/lib/setupTrackingContext.js +1 -3
  58. package/src/oxide/cli/build/plugin.ts +6 -6
  59. package/src/plugin.js +3 -3
  60. package/src/processTailwindFeatures.js +3 -2
  61. package/src/util/cloneNodes.js +35 -14
  62. package/src/util/color.js +1 -1
  63. package/src/util/dataTypes.js +143 -18
  64. package/src/util/formatVariantSelector.js +11 -3
  65. package/src/util/isPlainObject.js +1 -1
  66. package/src/util/pluginUtils.js +16 -0
  67. package/src/util/prefixSelector.js +1 -0
  68. package/src/util/pseudoElements.js +18 -17
  69. package/src/value-parser/LICENSE +22 -0
  70. package/src/value-parser/README.md +3 -0
  71. package/src/value-parser/index.d.ts +177 -0
  72. package/src/value-parser/index.js +28 -0
  73. package/src/value-parser/parse.js +303 -0
  74. package/src/value-parser/stringify.js +41 -0
  75. package/src/value-parser/unit.js +118 -0
  76. package/src/value-parser/walk.js +18 -0
  77. package/stubs/config.full.js +86 -14
  78. package/types/config.d.ts +17 -9
  79. package/types/generated/corePluginList.d.ts +1 -1
  80. package/types/generated/default-theme.d.ts +35 -9
  81. package/types/index.d.ts +7 -3
@@ -482,6 +482,12 @@ function processApply(root, context, localCache) {
482
482
  // We do *not* want to do this for user CSS that happens to be structured the same
483
483
  let isGenerated = parent.raws.tailwind !== undefined;
484
484
  let parentSelector = isGenerated && importantSelector && parent.selector.indexOf(importantSelector) === 0 ? parent.selector.slice(importantSelector.length) : parent.selector;
485
+ // If the selector becomes empty after replacing the important selector
486
+ // This means that it's the same as the parent selector and we don't want to replace it
487
+ // Otherwise we'll crash
488
+ if (parentSelector === "") {
489
+ parentSelector = parent.selector;
490
+ }
485
491
  rule.selector = replaceSelector(parentSelector, rule.selector, applyCandidate);
486
492
  // And then re-add it if it was removed
487
493
  if (importantSelector && parentSelector !== parent.selector) {
@@ -124,7 +124,7 @@ function getClassCandidates(content, extractor, candidates, seen) {
124
124
  return returnValue;
125
125
  }
126
126
  function expandTailwindAtRules(context) {
127
- return (root)=>{
127
+ return async (root)=>{
128
128
  let layerNodes = {
129
129
  base: null,
130
130
  components: null,
@@ -165,11 +165,25 @@ function expandTailwindAtRules(context) {
165
165
  // getClassCandidatesOxide(file, transformer(content), extractor, candidates, seen)
166
166
  // }
167
167
  } else {
168
- for (let { file , content , extension } of context.changedContent){
169
- let transformer = getTransformer(context.tailwindConfig, extension);
170
- let extractor = getExtractor(context, extension);
171
- content = file ? _fs.default.readFileSync(file, "utf8") : content;
172
- getClassCandidates(transformer(content), extractor, candidates, seen);
168
+ /** @type {[item: {file?: string, content?: string}, meta: {transformer: any, extractor: any}][]} */ let regexParserContent = [];
169
+ for (let item of context.changedContent){
170
+ let transformer = getTransformer(context.tailwindConfig, item.extension);
171
+ let extractor = getExtractor(context, item.extension);
172
+ regexParserContent.push([
173
+ item,
174
+ {
175
+ transformer,
176
+ extractor
177
+ }
178
+ ]);
179
+ }
180
+ const BATCH_SIZE = 500;
181
+ for(let i = 0; i < regexParserContent.length; i += BATCH_SIZE){
182
+ let batch = regexParserContent.slice(i, i + BATCH_SIZE);
183
+ await Promise.all(batch.map(async ([{ file , content }, { transformer , extractor }])=>{
184
+ content = file ? await _fs.default.promises.readFile(file, "utf8") : content;
185
+ getClassCandidates(transformer(content), extractor, candidates, seen);
186
+ }));
173
187
  }
174
188
  }
175
189
  env.DEBUG && console.timeEnd("Reading changed files");
@@ -246,6 +260,9 @@ function expandTailwindAtRules(context) {
246
260
  layer: "variants"
247
261
  }));
248
262
  }
263
+ var _root_source_end;
264
+ // TODO: Why is the root node having no source location for `end` possible?
265
+ root.source.end = (_root_source_end = root.source.end) !== null && _root_source_end !== void 0 ? _root_source_end : root.source.start;
249
266
  // If we've got a utility layer and no utilities are generated there's likely something wrong
250
267
  const hasUtilityVariants = variantNodes.some((node)=>{
251
268
  var _node_raws_tailwind;
@@ -162,6 +162,9 @@ function applyImportant(matches, classCandidate) {
162
162
  return matches;
163
163
  }
164
164
  let result = [];
165
+ function isInKeyframes(rule) {
166
+ return rule.parent && rule.parent.type === "atrule" && rule.parent.name === "keyframes";
167
+ }
165
168
  for (let [meta, rule] of matches){
166
169
  let container = _postcss.default.root({
167
170
  nodes: [
@@ -169,6 +172,11 @@ function applyImportant(matches, classCandidate) {
169
172
  ]
170
173
  });
171
174
  container.walkRules((r)=>{
175
+ // Declarations inside keyframes cannot be marked as important
176
+ // They will be ignored by the browser
177
+ if (isInKeyframes(r)) {
178
+ return;
179
+ }
172
180
  let ast = (0, _postcssselectorparser.default)().astSync(r.selector);
173
181
  // Remove extraneous selectors that do not include the base candidate
174
182
  ast.each((sel)=>(0, _formatVariantSelector.eliminateIrrelevantSelectors)(sel, classCandidate));
@@ -231,12 +239,12 @@ function applyVariant(variant, matches, context) {
231
239
  // group[:hover] (`-` is missing)
232
240
  let match = /(.)(-?)\[(.*)\]/g.exec(variant);
233
241
  if (match) {
234
- let [, char, seperator, value] = match;
242
+ let [, char, separator, value] = match;
235
243
  // @-[200px] case
236
- if (char === "@" && seperator === "-") return [];
244
+ if (char === "@" && separator === "-") return [];
237
245
  // group[:hover] case
238
- if (char !== "@" && seperator === "") return [];
239
- variant = variant.replace(`${seperator}[${value}]`, "");
246
+ if (char !== "@" && separator === "") return [];
247
+ variant = variant.replace(`${separator}[${value}]`, "");
240
248
  args.value = value;
241
249
  }
242
250
  }
@@ -259,9 +267,17 @@ function applyVariant(variant, matches, context) {
259
267
  context.variantMap.set(variant, records);
260
268
  }
261
269
  if (context.variantMap.has(variant)) {
270
+ var _context_variantOptions_get;
262
271
  let isArbitraryVariant = isArbitraryValue(variant);
272
+ var _context_variantOptions_get_INTERNAL_FEATURES;
273
+ let internalFeatures = (_context_variantOptions_get_INTERNAL_FEATURES = (_context_variantOptions_get = context.variantOptions.get(variant)) === null || _context_variantOptions_get === void 0 ? void 0 : _context_variantOptions_get[_setupContextUtils.INTERNAL_FEATURES]) !== null && _context_variantOptions_get_INTERNAL_FEATURES !== void 0 ? _context_variantOptions_get_INTERNAL_FEATURES : {};
263
274
  let variantFunctionTuples = context.variantMap.get(variant).slice();
264
275
  let result = [];
276
+ let respectPrefix = (()=>{
277
+ if (isArbitraryVariant) return false;
278
+ if (internalFeatures.respectPrefix === false) return false;
279
+ return true;
280
+ })();
265
281
  for (let [meta, rule] of matches){
266
282
  // Don't generate variants for user css
267
283
  if (meta.layer === "user") {
@@ -318,7 +334,7 @@ function applyVariant(variant, matches, context) {
318
334
  format (selectorFormat) {
319
335
  collectedFormats.push({
320
336
  format: selectorFormat,
321
- isArbitraryVariant
337
+ respectPrefix
322
338
  });
323
339
  },
324
340
  args
@@ -344,7 +360,7 @@ function applyVariant(variant, matches, context) {
344
360
  if (typeof ruleWithVariant === "string") {
345
361
  collectedFormats.push({
346
362
  format: ruleWithVariant,
347
- isArbitraryVariant
363
+ respectPrefix
348
364
  });
349
365
  }
350
366
  if (ruleWithVariant === null) {
@@ -383,7 +399,7 @@ function applyVariant(variant, matches, context) {
383
399
  // format: .foo &
384
400
  collectedFormats.push({
385
401
  format: modified.replace(rebuiltBase, "&"),
386
- isArbitraryVariant
402
+ respectPrefix
387
403
  });
388
404
  rule.selector = before;
389
405
  });
@@ -492,11 +508,13 @@ function extractArbitraryProperty(classCandidate, context) {
492
508
  if (!(0, _isSyntacticallyValidPropertyValue.default)(value)) {
493
509
  return null;
494
510
  }
495
- let normalized = (0, _dataTypes.normalize)(value);
511
+ let normalized = (0, _dataTypes.normalize)(value, {
512
+ property
513
+ });
496
514
  if (!isParsableCssValue(property, normalized)) {
497
515
  return null;
498
516
  }
499
- let sort = context.offsets.arbitraryProperty();
517
+ let sort = context.offsets.arbitraryProperty(classCandidate);
500
518
  return [
501
519
  [
502
520
  {
@@ -570,7 +588,7 @@ function* recordCandidates(matches, classCandidate) {
570
588
  yield match;
571
589
  }
572
590
  }
573
- function* resolveMatches(candidate, context, original = candidate) {
591
+ function* resolveMatches(candidate, context) {
574
592
  let separator = context.tailwindConfig.separator;
575
593
  let [classCandidate, ...variants] = splitWithSeparator(candidate, separator).reverse();
576
594
  let important = false;
@@ -578,14 +596,6 @@ function* resolveMatches(candidate, context, original = candidate) {
578
596
  important = true;
579
597
  classCandidate = classCandidate.slice(1);
580
598
  }
581
- if ((0, _featureFlags.flagEnabled)(context.tailwindConfig, "variantGrouping")) {
582
- if (classCandidate.startsWith("(") && classCandidate.endsWith(")")) {
583
- let base = variants.slice().reverse().join(separator);
584
- for (let part of (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(classCandidate.slice(1, -1), ",")){
585
- yield* resolveMatches(base + separator + part, context, original);
586
- }
587
- }
588
- }
589
599
  // TODO: Reintroduce this in ways that doesn't break on false positives
590
600
  // function sortAgainst(toSort, against) {
591
601
  // return toSort.slice().sort((a, z) => {
@@ -745,8 +755,7 @@ function* resolveMatches(candidate, context, original = candidate) {
745
755
  // Apply final format selector
746
756
  match = applyFinalFormat(match, {
747
757
  context,
748
- candidate,
749
- original
758
+ candidate
750
759
  });
751
760
  // Skip rules with invalid selectors
752
761
  // This will cause the candidate to be added to the "not class"
@@ -758,7 +767,7 @@ function* resolveMatches(candidate, context, original = candidate) {
758
767
  }
759
768
  }
760
769
  }
761
- function applyFinalFormat(match, { context , candidate , original }) {
770
+ function applyFinalFormat(match, { context , candidate }) {
762
771
  if (!match[0].collectedFormats) {
763
772
  return match;
764
773
  }
@@ -791,10 +800,17 @@ function applyFinalFormat(match, { context , candidate , original }) {
791
800
  return;
792
801
  }
793
802
  try {
794
- rule.selector = (0, _formatVariantSelector.finalizeSelector)(rule.selector, finalFormat, {
795
- candidate: original,
803
+ let selector = (0, _formatVariantSelector.finalizeSelector)(rule.selector, finalFormat, {
804
+ candidate,
796
805
  context
797
806
  });
807
+ // Finalize Selector determined that this candidate is irrelevant
808
+ // TODO: This elimination should happen earlier so this never happens
809
+ if (selector === null) {
810
+ rule.remove();
811
+ return;
812
+ }
813
+ rule.selector = selector;
798
814
  } catch {
799
815
  // If this selector is invalid we also want to skip it
800
816
  // But it's likely that being invalid here means there's a bug in a plugin rather than too loosely matching content
@@ -805,6 +821,10 @@ function applyFinalFormat(match, { context , candidate , original }) {
805
821
  if (!isValid) {
806
822
  return null;
807
823
  }
824
+ // If all rules have been eliminated we can skip this candidate entirely
825
+ if (container.nodes.length === 0) {
826
+ return null;
827
+ }
808
828
  match[1] = container.nodes[0];
809
829
  return match;
810
830
  }
@@ -835,7 +855,7 @@ function getImportantStrategy(important) {
835
855
  };
836
856
  }
837
857
  }
838
- function generateRules(candidates, context) {
858
+ function generateRules(candidates, context, isSorting = false) {
839
859
  let allRules = [];
840
860
  let strategy = getImportantStrategy(context.tailwindConfig.important);
841
861
  for (let candidate of candidates){
@@ -866,9 +886,11 @@ function generateRules(candidates, context) {
866
886
  container.walkRules(strategy);
867
887
  rule = container.nodes[0];
868
888
  }
889
+ // Note: We have to clone rules during sorting
890
+ // so we eliminate some shared mutable state
869
891
  let newEntry = [
870
892
  sort,
871
- rule
893
+ isSorting ? rule.clone() : rule
872
894
  ];
873
895
  rules.add(newEntry);
874
896
  context.ruleCache.add(newEntry);
@@ -2,9 +2,17 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- Object.defineProperty(exports, "loadConfig", {
6
- enumerable: true,
7
- get: function() {
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ useCustomJiti: function() {
13
+ return useCustomJiti;
14
+ },
15
+ loadConfig: function() {
8
16
  return loadConfig;
9
17
  }
10
18
  });
@@ -16,6 +24,9 @@ function _interop_require_default(obj) {
16
24
  };
17
25
  }
18
26
  let jiti = null;
27
+ function useCustomJiti(_jiti) {
28
+ jiti = _jiti();
29
+ }
19
30
  function lazyJiti() {
20
31
  return jiti !== null && jiti !== void 0 ? jiti : jiti = (0, _jiti.default)(__filename, {
21
32
  interopDefault: true,
@@ -66,15 +66,19 @@ class Offsets {
66
66
  variants: 0n,
67
67
  parallelIndex: 0n,
68
68
  index: this.offsets[layer]++,
69
+ propertyOffset: 0n,
70
+ property: "",
69
71
  options: []
70
72
  };
71
73
  }
72
74
  /**
75
+ * @param {string} name
73
76
  * @returns {RuleOffset}
74
- */ arbitraryProperty() {
77
+ */ arbitraryProperty(name) {
75
78
  return {
76
79
  ...this.create("utilities"),
77
- arbitrary: 1n
80
+ arbitrary: 1n,
81
+ property: name
78
82
  };
79
83
  }
80
84
  /**
@@ -214,6 +218,10 @@ class Offsets {
214
218
  if (a.arbitrary !== b.arbitrary) {
215
219
  return a.arbitrary - b.arbitrary;
216
220
  }
221
+ // Always sort arbitrary properties alphabetically
222
+ if (a.propertyOffset !== b.propertyOffset) {
223
+ return a.propertyOffset - b.propertyOffset;
224
+ }
217
225
  // Sort utilities, components, etc… in the order they were registered
218
226
  return a.index - b.index;
219
227
  }
@@ -267,8 +275,49 @@ class Offsets {
267
275
  * @template T
268
276
  * @param {[RuleOffset, T][]} list
269
277
  * @returns {[RuleOffset, T][]}
278
+ */ sortArbitraryProperties(list) {
279
+ // Collect all known arbitrary properties
280
+ let known = new Set();
281
+ for (let [offset] of list){
282
+ if (offset.arbitrary === 1n) {
283
+ known.add(offset.property);
284
+ }
285
+ }
286
+ // No arbitrary properties? Nothing to do.
287
+ if (known.size === 0) {
288
+ return list;
289
+ }
290
+ // Sort the properties alphabetically
291
+ let properties = Array.from(known).sort();
292
+ // Create a map from the property name to its offset
293
+ let offsets = new Map();
294
+ let offset = 1n;
295
+ for (let property of properties){
296
+ offsets.set(property, offset++);
297
+ }
298
+ // Apply the sorted offsets to the list
299
+ return list.map((item)=>{
300
+ let [offset, rule] = item;
301
+ var _offsets_get;
302
+ offset = {
303
+ ...offset,
304
+ propertyOffset: (_offsets_get = offsets.get(offset.property)) !== null && _offsets_get !== void 0 ? _offsets_get : 0n
305
+ };
306
+ return [
307
+ offset,
308
+ rule
309
+ ];
310
+ });
311
+ }
312
+ /**
313
+ * @template T
314
+ * @param {[RuleOffset, T][]} list
315
+ * @returns {[RuleOffset, T][]}
270
316
  */ sort(list) {
317
+ // Sort arbitrary variants so they're in alphabetical order
271
318
  list = this.remapArbitraryVariantOffsets(list);
319
+ // Sort arbitrary properties so they're in alphabetical order
320
+ list = this.sortArbitraryProperties(list);
272
321
  return list.sort(([a], [b])=>(0, _bigSign.default)(this.compare(a, b)));
273
322
  }
274
323
  }
@@ -111,7 +111,9 @@ function resolveDefaultsAtRules({ tailwindConfig }) {
111
111
  // we consider them separately because merging the declarations into
112
112
  // a single rule will cause browsers that do not understand the
113
113
  // vendor prefix to throw out the whole rule
114
- let selectorGroupName = selector.includes(":-") || selector.includes("::-") ? selector : "__DEFAULT__";
114
+ // Additionally if a selector contains `:has` we also consider
115
+ // it separately because FF only recently gained support for it
116
+ let selectorGroupName = selector.includes(":-") || selector.includes("::-") || selector.includes(":has") ? selector : "__DEFAULT__";
115
117
  var _selectorGroups_get;
116
118
  let selectors = (_selectorGroups_get = selectorGroups.get(selectorGroupName)) !== null && _selectorGroups_get !== void 0 ? _selectorGroups_get : new Set();
117
119
  selectorGroups.set(selectorGroupName, selectors);
@@ -9,6 +9,9 @@ function _export(target, all) {
9
9
  });
10
10
  }
11
11
  _export(exports, {
12
+ INTERNAL_FEATURES: function() {
13
+ return INTERNAL_FEATURES;
14
+ },
12
15
  isValidVariantFormatString: function() {
13
16
  return isValidVariantFormatString;
14
17
  },
@@ -92,6 +95,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
92
95
  }
93
96
  return newObj;
94
97
  }
98
+ const INTERNAL_FEATURES = Symbol();
95
99
  const VARIANT_TYPES = {
96
100
  AddVariant: Symbol.for("ADD_VARIANT"),
97
101
  MatchVariant: Symbol.for("MATCH_VARIANT")
@@ -197,39 +201,41 @@ function getClasses(selector, mutate) {
197
201
  });
198
202
  return parser.transformSync(selector);
199
203
  }
204
+ /**
205
+ * Ignore everything inside a :not(...). This allows you to write code like
206
+ * `div:not(.foo)`. If `.foo` is never found in your code, then we used to
207
+ * not generated it. But now we will ignore everything inside a `:not`, so
208
+ * that it still gets generated.
209
+ *
210
+ * @param {selectorParser.Root} selectors
211
+ */ function ignoreNot(selectors) {
212
+ selectors.walkPseudos((pseudo)=>{
213
+ if (pseudo.value === ":not") {
214
+ pseudo.remove();
215
+ }
216
+ });
217
+ }
200
218
  function extractCandidates(node, state = {
201
219
  containsNonOnDemandable: false
202
220
  }, depth = 0) {
203
221
  let classes = [];
204
- // Handle normal rules
222
+ let selectors = [];
205
223
  if (node.type === "rule") {
206
- // Ignore everything inside a :not(...). This allows you to write code like
207
- // `div:not(.foo)`. If `.foo` is never found in your code, then we used to
208
- // not generated it. But now we will ignore everything inside a `:not`, so
209
- // that it still gets generated.
210
- function ignoreNot(selectors) {
211
- selectors.walkPseudos((pseudo)=>{
212
- if (pseudo.value === ":not") {
213
- pseudo.remove();
214
- }
215
- });
224
+ // Handle normal rules
225
+ selectors.push(...node.selectors);
226
+ } else if (node.type === "atrule") {
227
+ // Handle at-rules (which contains nested rules)
228
+ node.walkRules((rule)=>selectors.push(...rule.selectors));
229
+ }
230
+ for (let selector of selectors){
231
+ let classCandidates = getClasses(selector, ignoreNot);
232
+ // At least one of the selectors contains non-"on-demandable" candidates.
233
+ if (classCandidates.length === 0) {
234
+ state.containsNonOnDemandable = true;
216
235
  }
217
- for (let selector of node.selectors){
218
- let classCandidates = getClasses(selector, ignoreNot);
219
- // At least one of the selectors contains non-"on-demandable" candidates.
220
- if (classCandidates.length === 0) {
221
- state.containsNonOnDemandable = true;
222
- }
223
- for (let classCandidate of classCandidates){
224
- classes.push(classCandidate);
225
- }
236
+ for (let classCandidate of classCandidates){
237
+ classes.push(classCandidate);
226
238
  }
227
- } else if (node.type === "atrule") {
228
- node.walkRules((rule)=>{
229
- for (let classCandidate of rule.selectors.flatMap((selector)=>getClasses(selector))){
230
- classes.push(classCandidate);
231
- }
232
- });
233
239
  }
234
240
  if (depth === 0) {
235
241
  return [
@@ -270,11 +276,14 @@ function parseVariant(variant) {
270
276
  if (!str.startsWith("@")) {
271
277
  return ({ format })=>format(str);
272
278
  }
273
- let [, name, params] = /@(.*?)( .+|[({].*)/g.exec(str);
274
- return ({ wrap })=>wrap(_postcss.default.atRule({
279
+ let [, name, params] = /@(\S*)( .+|[({].*)?/g.exec(str);
280
+ var _params_trim;
281
+ return ({ wrap })=>{
282
+ return wrap(_postcss.default.atRule({
275
283
  name,
276
- params: params.trim()
284
+ params: (_params_trim = params === null || params === void 0 ? void 0 : params.trim()) !== null && _params_trim !== void 0 ? _params_trim : ""
277
285
  }));
286
+ };
278
287
  }).reverse();
279
288
  return (api)=>{
280
289
  for (let fn of fns){
@@ -742,21 +751,40 @@ function resolvePlugins(context, root) {
742
751
  // TODO: This is a workaround for backwards compatibility, since custom variants
743
752
  // were historically sorted before screen/stackable variants.
744
753
  let beforeVariants = [
754
+ _corePlugins.variantPlugins["childVariant"],
745
755
  _corePlugins.variantPlugins["pseudoElementVariants"],
746
756
  _corePlugins.variantPlugins["pseudoClassVariants"],
757
+ _corePlugins.variantPlugins["hasVariants"],
747
758
  _corePlugins.variantPlugins["ariaVariants"],
748
759
  _corePlugins.variantPlugins["dataVariants"]
749
760
  ];
750
761
  let afterVariants = [
751
762
  _corePlugins.variantPlugins["supportsVariants"],
752
- _corePlugins.variantPlugins["directionVariants"],
753
763
  _corePlugins.variantPlugins["reducedMotionVariants"],
754
764
  _corePlugins.variantPlugins["prefersContrastVariants"],
755
- _corePlugins.variantPlugins["darkVariants"],
756
- _corePlugins.variantPlugins["printVariant"],
757
765
  _corePlugins.variantPlugins["screenVariants"],
758
- _corePlugins.variantPlugins["orientationVariants"]
766
+ _corePlugins.variantPlugins["orientationVariants"],
767
+ _corePlugins.variantPlugins["directionVariants"],
768
+ _corePlugins.variantPlugins["darkVariants"],
769
+ _corePlugins.variantPlugins["forcedColorsVariants"],
770
+ _corePlugins.variantPlugins["printVariant"]
759
771
  ];
772
+ // This is a compatibility fix for the pre 3.4 dark mode behavior
773
+ // `class` retains the old behavior, but `selector` keeps the new behavior
774
+ let isLegacyDarkMode = context.tailwindConfig.darkMode === "class" || Array.isArray(context.tailwindConfig.darkMode) && context.tailwindConfig.darkMode[0] === "class";
775
+ if (isLegacyDarkMode) {
776
+ afterVariants = [
777
+ _corePlugins.variantPlugins["supportsVariants"],
778
+ _corePlugins.variantPlugins["reducedMotionVariants"],
779
+ _corePlugins.variantPlugins["prefersContrastVariants"],
780
+ _corePlugins.variantPlugins["darkVariants"],
781
+ _corePlugins.variantPlugins["screenVariants"],
782
+ _corePlugins.variantPlugins["orientationVariants"],
783
+ _corePlugins.variantPlugins["directionVariants"],
784
+ _corePlugins.variantPlugins["forcedColorsVariants"],
785
+ _corePlugins.variantPlugins["printVariant"]
786
+ ];
787
+ }
760
788
  return [
761
789
  ...corePluginList,
762
790
  ...beforeVariants,
@@ -920,11 +948,15 @@ function registerPlugins(plugins, context) {
920
948
  ]));
921
949
  // Sort all classes in order
922
950
  // Non-tailwind classes won't be generated and will be left as `null`
923
- let rules = (0, _generateRules.generateRules)(new Set(sorted), context);
951
+ let rules = (0, _generateRules.generateRules)(new Set(sorted), context, true);
924
952
  rules = context.offsets.sort(rules);
925
953
  let idx = BigInt(parasiteUtilities.length);
926
954
  for (const [, rule] of rules){
927
- sortedClassNames.set(rule.raws.tailwind.candidate, idx++);
955
+ let candidate = rule.raws.tailwind.candidate;
956
+ var _sortedClassNames_get;
957
+ // When multiple rules match a candidate
958
+ // always take the position of the first one
959
+ sortedClassNames.set(candidate, (_sortedClassNames_get = sortedClassNames.get(candidate)) !== null && _sortedClassNames_get !== void 0 ? _sortedClassNames_get : idx++);
928
960
  }
929
961
  return classes.map((className)=>{
930
962
  var _sortedClassNames_get;
@@ -1095,13 +1127,20 @@ function registerPlugins(plugins, context) {
1095
1127
  }
1096
1128
  var _options_values1;
1097
1129
  let isArbitraryVariant = !(value in ((_options_values1 = options.values) !== null && _options_values1 !== void 0 ? _options_values1 : {}));
1130
+ var _options_INTERNAL_FEATURES;
1131
+ let internalFeatures = (_options_INTERNAL_FEATURES = options[INTERNAL_FEATURES]) !== null && _options_INTERNAL_FEATURES !== void 0 ? _options_INTERNAL_FEATURES : {};
1132
+ let respectPrefix = (()=>{
1133
+ if (isArbitraryVariant) return false;
1134
+ if (internalFeatures.respectPrefix === false) return false;
1135
+ return true;
1136
+ })();
1098
1137
  formatStrings = formatStrings.map((format)=>format.map((str)=>({
1099
1138
  format: str,
1100
- isArbitraryVariant
1139
+ respectPrefix
1101
1140
  })));
1102
1141
  manualFormatStrings = manualFormatStrings.map((format)=>({
1103
1142
  format,
1104
- isArbitraryVariant
1143
+ respectPrefix
1105
1144
  }));
1106
1145
  let opts = {
1107
1146
  candidate,
@@ -83,8 +83,9 @@ function getTailwindConfig(configOrPath) {
83
83
  newDeps
84
84
  ];
85
85
  }
86
+ var _configOrPath_config, _ref;
86
87
  // It's a plain object, not a path
87
- let newConfig = (0, _resolveconfig.default)(configOrPath.config === undefined ? configOrPath : configOrPath.config);
88
+ let newConfig = (0, _resolveconfig.default)((_ref = (_configOrPath_config = configOrPath === null || configOrPath === void 0 ? void 0 : configOrPath.config) !== null && _configOrPath_config !== void 0 ? _configOrPath_config : configOrPath) !== null && _ref !== void 0 ? _ref : {});
88
89
  newConfig = (0, _validateConfig.validateConfig)(newConfig);
89
90
  return [
90
91
  newConfig,
@@ -191,14 +191,14 @@ let state = {
191
191
  return content;
192
192
  },
193
193
  getContext ({ createContext , cliConfigPath , root , result , content }) {
194
- if (this.context) {
195
- this.context.changedContent = this.changedContent.splice(0);
196
- return this.context;
197
- }
198
194
  _sharedState.env.DEBUG && console.time("Searching for config");
199
195
  var _findAtConfigPath1;
200
196
  let configPath = (_findAtConfigPath1 = (0, _findAtConfigPath.findAtConfigPath)(root, result)) !== null && _findAtConfigPath1 !== void 0 ? _findAtConfigPath1 : cliConfigPath;
201
197
  _sharedState.env.DEBUG && console.timeEnd("Searching for config");
198
+ if (this.context) {
199
+ this.context.changedContent = this.changedContent.splice(0);
200
+ return this.context;
201
+ }
202
202
  _sharedState.env.DEBUG && console.time("Loading config");
203
203
  let config = this.loadConfig(configPath, content);
204
204
  _sharedState.env.DEBUG && console.timeEnd("Loading config");
@@ -244,9 +244,9 @@ async function createProcessor(args, cliConfigPath) {
244
244
  let tailwindPlugin = ()=>{
245
245
  return {
246
246
  postcssPlugin: "tailwindcss",
247
- Once (root, { result }) {
247
+ async Once (root, { result }) {
248
248
  _sharedState.env.DEBUG && console.time("Compiling CSS");
249
- (0, _processTailwindFeatures.default)(({ createContext })=>{
249
+ await (0, _processTailwindFeatures.default)(({ createContext })=>{
250
250
  console.error();
251
251
  console.error("Rebuilding...");
252
252
  return ()=>{
package/lib/plugin.js CHANGED
@@ -20,7 +20,7 @@ module.exports = function tailwindcss(configOrPath) {
20
20
  console.time("JIT TOTAL");
21
21
  return root;
22
22
  },
23
- function(root, result) {
23
+ async function(root, result) {
24
24
  var _findAtConfigPath1;
25
25
  // Use the path for the `@config` directive if it exists, otherwise use the
26
26
  // path for the file being processed
@@ -30,12 +30,12 @@ module.exports = function tailwindcss(configOrPath) {
30
30
  let roots = root.nodes.filter((node)=>node.type === "root");
31
31
  for (const root of roots){
32
32
  if (root.type === "root") {
33
- (0, _processTailwindFeatures.default)(context)(root, result);
33
+ await (0, _processTailwindFeatures.default)(context)(root, result);
34
34
  }
35
35
  }
36
36
  return;
37
37
  }
38
- (0, _processTailwindFeatures.default)(context)(root, result);
38
+ await (0, _processTailwindFeatures.default)(context)(root, result);
39
39
  },
40
40
  false && function lightningCssPlugin(_root, result) {
41
41
  let postcss = require("postcss");
@@ -26,7 +26,7 @@ function _interop_require_default(obj) {
26
26
  };
27
27
  }
28
28
  function processTailwindFeatures(setupContext) {
29
- return function(root, result) {
29
+ return async function(root, result) {
30
30
  let { tailwindDirectives , applyDirectives } = (0, _normalizeTailwindDirectives.default)(root);
31
31
  (0, _detectNesting.default)()(root, result);
32
32
  // Partition apply rules that are found in the css
@@ -50,7 +50,7 @@ function processTailwindFeatures(setupContext) {
50
50
  throw new Error("The '-' character cannot be used as a custom separator in JIT mode due to parsing ambiguity. Please use another character like '_' instead.");
51
51
  }
52
52
  (0, _featureFlags.issueFlagNotices)(context.tailwindConfig);
53
- (0, _expandTailwindAtRules.default)(context)(root, result);
53
+ await (0, _expandTailwindAtRules.default)(context)(root, result);
54
54
  // Partition apply rules that are generated by
55
55
  // addComponents, addUtilities and so on.
56
56
  (0, _partitionApplyAtRules.default)()(root, result);