tailwindcss 0.0.0-insiders.e63c111 → 0.0.0-insiders.e66110e

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/CHANGELOG.md CHANGED
@@ -9,7 +9,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ### Fixed
11
11
 
12
+ - Cleanup unused `variantOrder` ([#9829](https://github.com/tailwindlabs/tailwindcss/pull/9829))
13
+ - Fix `foo-[abc]/[def]` not being handled correctly ([#9866](https://github.com/tailwindlabs/tailwindcss/pull/9866))
14
+
15
+ ### Added
16
+
17
+ - Add container queries plugin to standalone CLI ([#9865](https://github.com/tailwindlabs/tailwindcss/pull/9865))
18
+
19
+ ## [3.2.4] - 2022-11-11
20
+
21
+ ### Added
22
+
23
+ - Add `blocklist` option to prevent generating unwanted CSS ([#9812](https://github.com/tailwindlabs/tailwindcss/pull/9812))
24
+
25
+ ### Fixed
26
+
27
+ - Fix watching of files on Linux when renames are involved ([#9796](https://github.com/tailwindlabs/tailwindcss/pull/9796))
28
+ - Make sure errors are always displayed when watching for changes ([#9810](https://github.com/tailwindlabs/tailwindcss/pull/9810))
29
+
30
+ ## [3.2.3] - 2022-11-09
31
+
32
+ ### Fixed
33
+
34
+ - Fixed use of `raw` content in the CLI ([#9773](https://github.com/tailwindlabs/tailwindcss/pull/9773))
35
+ - Pick up changes from files that are both context and content deps ([#9787](https://github.com/tailwindlabs/tailwindcss/pull/9787))
36
+ - Sort pseudo-elements ONLY after classes when using variants and `@apply` ([#9765](https://github.com/tailwindlabs/tailwindcss/pull/9765))
37
+ - Support important utilities in the safelist (pattern must include a `!`) ([#9791](https://github.com/tailwindlabs/tailwindcss/pull/9791))
38
+
39
+ ## [3.2.2] - 2022-11-04
40
+
41
+ ### Fixed
42
+
12
43
  - Escape special characters in resolved content base paths ([#9650](https://github.com/tailwindlabs/tailwindcss/pull/9650))
44
+ - Don't reuse container for array returning variant functions ([#9644](https://github.com/tailwindlabs/tailwindcss/pull/9644))
45
+ - Exclude non-relevant selectors when generating rules with the important modifier ([#9677](https://github.com/tailwindlabs/tailwindcss/issues/9677))
46
+ - Fix merging of arrays during config resolution ([#9706](https://github.com/tailwindlabs/tailwindcss/issues/9706))
47
+ - Ensure configured `font-feature-settings` are included in Preflight ([#9707](https://github.com/tailwindlabs/tailwindcss/pull/9707))
48
+ - Fix fractional values not being parsed properly inside arbitrary properties ([#9705](https://github.com/tailwindlabs/tailwindcss/pull/9705))
49
+ - Fix incorrect selectors when using `@apply` in selectors with combinators and pseudos ([#9722](https://github.com/tailwindlabs/tailwindcss/pull/9722))
50
+ - Fix cannot read properties of undefined (reading 'modifier') ([#9656](https://github.com/tailwindlabs/tailwindcss/pull/9656), [aa979d6](https://github.com/tailwindlabs/tailwindcss/commit/aa979d645f8bf4108c5fc938d7c0ba085b654c31))
13
51
 
14
52
  ## [3.2.1] - 2022-10-21
15
53
 
@@ -2090,7 +2128,10 @@ No release notes
2090
2128
 
2091
2129
  - Everything!
2092
2130
 
2093
- [unreleased]: https://github.com/tailwindlabs/tailwindcss/compare/v3.2.1...HEAD
2131
+ [unreleased]: https://github.com/tailwindlabs/tailwindcss/compare/v3.2.4...HEAD
2132
+ [3.2.4]: https://github.com/tailwindlabs/tailwindcss/compare/v3.2.3...v3.2.4
2133
+ [3.2.3]: https://github.com/tailwindlabs/tailwindcss/compare/v3.2.2...v3.2.3
2134
+ [3.2.2]: https://github.com/tailwindlabs/tailwindcss/compare/v3.2.1...v3.2.2
2094
2135
  [3.2.1]: https://github.com/tailwindlabs/tailwindcss/compare/v3.2.0...v3.2.1
2095
2136
  [3.2.0]: https://github.com/tailwindlabs/tailwindcss/compare/v3.1.8...v3.2.0
2096
2137
  [3.1.8]: https://github.com/tailwindlabs/tailwindcss/compare/v3.1.7...v3.1.8
@@ -170,9 +170,9 @@ let state = {
170
170
  let rawContent = this.config.content.files.filter((file)=>{
171
171
  return file !== null && typeof file === "object";
172
172
  });
173
- for (let { raw: content1 , extension ="html" } of rawContent){
174
- content1.push({
175
- content: content1,
173
+ for (let { raw: htmlContent , extension ="html" } of rawContent){
174
+ content.push({
175
+ content: htmlContent,
176
176
  extension
177
177
  });
178
178
  }
@@ -311,6 +311,17 @@ async function createProcessor(args, cliConfigPath) {
311
311
  let end = process.hrtime.bigint();
312
312
  console.error();
313
313
  console.error("Done in", (end - start) / BigInt(1e6) + "ms.");
314
+ }).then(()=>{}, (err)=>{
315
+ // TODO: If an initial build fails we can't easily pick up any PostCSS dependencies
316
+ // that were collected before the error occurred
317
+ // The result is not stored on the error so we have to store it externally
318
+ // and pull the messages off of it here somehow
319
+ // This results in a less than ideal DX because the watcher will not pick up
320
+ // changes to imported CSS if one of them caused an error during the initial build
321
+ // If you fix it and then save the main CSS file so there's no error
322
+ // The watcher will start watching the imported CSS files and will be
323
+ // resilient to future errors.
324
+ console.error(err);
314
325
  });
315
326
  }
316
327
  /**
@@ -37,22 +37,70 @@ function createWatcher(args, { state , rebuild }) {
37
37
  pollInterval: pollInterval
38
38
  } : false
39
39
  });
40
+ // A queue of rebuilds, file reads, etc… to run
40
41
  let chain = Promise.resolve();
41
- let pendingRebuilds = new Set();
42
- let changedContent = [];
42
+ /**
43
+ * A list of files that have been changed since the last rebuild
44
+ *
45
+ * @type {{file: string, content: () => Promise<string>, extension: string}[]}
46
+ */ let changedContent = [];
47
+ /**
48
+ * A list of files for which a rebuild has already been queued.
49
+ * This is used to prevent duplicate rebuilds when multiple events are fired for the same file.
50
+ * The rebuilt file is cleared from this list when it's associated rebuild has _started_
51
+ * This is because if the file is changed during a rebuild it won't trigger a new rebuild which it should
52
+ **/ let pendingRebuilds = new Set();
53
+ let _timer;
54
+ let _reject;
55
+ /**
56
+ * Rebuilds the changed files and resolves when the rebuild is
57
+ * complete regardless of whether it was successful or not
58
+ */ async function rebuildAndContinue() {
59
+ let changes = changedContent.splice(0);
60
+ // There are no changes to rebuild so we can just do nothing
61
+ if (changes.length === 0) {
62
+ return Promise.resolve();
63
+ }
64
+ // Clear all pending rebuilds for the about-to-be-built files
65
+ changes.forEach((change)=>pendingRebuilds.delete(change.file));
66
+ // Resolve the promise even when the rebuild fails
67
+ return rebuild(changes).then(()=>{}, ()=>{});
68
+ }
43
69
  /**
44
70
  *
45
71
  * @param {*} file
46
72
  * @param {(() => Promise<string>) | null} content
47
- */ function recordChangedFile(file, content = null) {
73
+ * @param {boolean} skipPendingCheck
74
+ * @returns {Promise<void>}
75
+ */ function recordChangedFile(file, content = null, skipPendingCheck = false) {
48
76
  file = _path.default.resolve(file);
49
- content = content !== null && content !== void 0 ? content : async ()=>await _fs.default.promises.readFile(file, "utf8");
77
+ // Applications like Vim/Neovim fire both rename and change events in succession for atomic writes
78
+ // In that case rebuild has already been queued by rename, so can be skipped in change
79
+ if (pendingRebuilds.has(file) && !skipPendingCheck) {
80
+ return Promise.resolve();
81
+ }
82
+ // Mark that a rebuild of this file is going to happen
83
+ // It MUST happen synchronously before the rebuild is queued for this to be effective
84
+ pendingRebuilds.add(file);
50
85
  changedContent.push({
51
86
  file,
52
- content,
87
+ content: content !== null && content !== void 0 ? content : ()=>_fs.default.promises.readFile(file, "utf8"),
53
88
  extension: _path.default.extname(file).slice(1)
54
89
  });
55
- chain = chain.then(()=>rebuild(changedContent.splice(0)));
90
+ if (_timer) {
91
+ clearTimeout(_timer);
92
+ _reject();
93
+ }
94
+ // If a rebuild is already in progress we don't want to start another one until the 10ms timer has expired
95
+ chain = chain.then(()=>new Promise((resolve, reject)=>{
96
+ _timer = setTimeout(resolve, 10);
97
+ _reject = reject;
98
+ }));
99
+ // Resolves once this file has been rebuilt (or the rebuild for this file has failed)
100
+ // This queues as many rebuilds as there are changed files
101
+ // But those rebuilds happen after some delay
102
+ // And will immediately resolve if there are no changes
103
+ chain = chain.then(rebuildAndContinue, rebuildAndContinue);
56
104
  return chain;
57
105
  }
58
106
  watcher.on("change", (file)=>recordChangedFile(file));
@@ -91,15 +139,32 @@ function createWatcher(args, { state , rebuild }) {
91
139
  if (pendingRebuilds.has(filePath)) {
92
140
  return;
93
141
  }
142
+ // We'll go ahead and add the file to the pending rebuilds list here
143
+ // It'll be removed when the rebuild starts unless the read fails
144
+ // which will be taken care of as well
94
145
  pendingRebuilds.add(filePath);
95
- chain = chain.then(async ()=>{
96
- let content;
146
+ async function enqueue() {
97
147
  try {
98
- content = await (0, _utilsJs.readFileWithRetries)(_path.default.resolve(filePath));
99
- } finally{
100
- pendingRebuilds.delete(filePath);
148
+ // We need to read the file as early as possible outside of the chain
149
+ // because it may be gone by the time we get to it. doing the read
150
+ // immediately increases the chance that the file is still there
151
+ let content = await (0, _utilsJs.readFileWithRetries)(_path.default.resolve(filePath));
152
+ if (content === undefined) {
153
+ return;
154
+ }
155
+ // This will push the rebuild onto the chain
156
+ // We MUST skip the rebuild check here otherwise the rebuild will never happen on Linux
157
+ // This is because the order of events and timing is different on Linux
158
+ // @ts-ignore: TypeScript isn't picking up that content is a string here
159
+ await recordChangedFile(filePath, ()=>content, true);
160
+ } catch {
161
+ // If reading the file fails, it's was probably a deleted temporary file
162
+ // So we can ignore it and no rebuild is needed
101
163
  }
102
- return recordChangedFile(filePath, ()=>content);
164
+ }
165
+ enqueue().then(()=>{
166
+ // If the file read fails we still need to make sure the file isn't stuck in the pending rebuilds list
167
+ pendingRebuilds.delete(filePath);
103
168
  });
104
169
  });
105
170
  return {
@@ -22,6 +22,7 @@
22
22
  2. Prevent adjustments of font size after orientation changes in iOS.
23
23
  3. Use a more readable tab size.
24
24
  4. Use the user's configured `sans` font-family by default.
25
+ 5. Use the user's configured `sans` font-feature-settings by default.
25
26
  */
26
27
 
27
28
  html {
@@ -30,6 +31,7 @@ html {
30
31
  -moz-tab-size: 4; /* 3 */
31
32
  tab-size: 4; /* 3 */
32
33
  font-family: theme('fontFamily.sans', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"); /* 4 */
34
+ font-feature-settings: theme('fontFamily.sans[1].fontFeatureSettings', normal); /* 5 */
33
35
  }
34
36
 
35
37
  /*
@@ -160,7 +160,14 @@ function resolvedChangedContent(context, candidateFiles, fileModifiedMap) {
160
160
  for (let file of files){
161
161
  let prevModified = fileModifiedMap.has(file) ? fileModifiedMap.get(file) : -Infinity;
162
162
  let modified = _fs.default.statSync(file).mtimeMs;
163
- if (modified > prevModified) {
163
+ // This check is intentionally >= because we track the last modified time of context dependencies
164
+ // earier in the process and we want to make sure we don't miss any changes that happen
165
+ // when a context dependency is also a content dependency
166
+ // Ideally, we'd do all this tracking at one time but that is a larger refactor
167
+ // than we want to commit to right now, so this is a decent compromise.
168
+ // This should be sufficient because file modification times will be off by at least
169
+ // 1ms (the precision of fstat in Node) in most cases if they exist and were changed.
170
+ if (modified >= prevModified) {
164
171
  changedFiles.add(file);
165
172
  fileModifiedMap.set(file, modified);
166
173
  }
@@ -72,7 +72,7 @@ function* buildRegExps(context) {
72
72
  ])) : "";
73
73
  let utility = _regex.any([
74
74
  // Arbitrary properties
75
- /\[[^\s:'"`]+:[^\s\]]+\]/,
75
+ /\[[^\s:'"`]+:[^\s]+\]/,
76
76
  // Utilities
77
77
  _regex.pattern([
78
78
  // Utility Name / Group Name
@@ -306,21 +306,40 @@ function processApply(root, context, localCache) {
306
306
  hasReplaced = true;
307
307
  });
308
308
  });
309
- // Sort tag names before class names
309
+ // Sort tag names before class names (but only sort each group (separated by a combinator)
310
+ // separately and not in total)
310
311
  // This happens when replacing `.bar` in `.foo.bar` with a tag like `section`
311
- for (const sel1 of replaced){
312
- sel1.sort((a, b)=>{
313
- if (a.type === "tag" && b.type === "class") {
314
- return -1;
315
- } else if (a.type === "class" && b.type === "tag") {
316
- return 1;
317
- } else if (a.type === "class" && b.type === "pseudo") {
318
- return -1;
319
- } else if (a.type === "pseudo" && b.type === "class") {
320
- return 1;
312
+ for (let sel1 of replaced){
313
+ let groups = [
314
+ []
315
+ ];
316
+ for (let node of sel1.nodes){
317
+ if (node.type === "combinator") {
318
+ groups.push(node);
319
+ groups.push([]);
320
+ } else {
321
+ let last = groups[groups.length - 1];
322
+ last.push(node);
321
323
  }
322
- return sel1.index(a) - sel1.index(b);
323
- });
324
+ }
325
+ sel1.nodes = [];
326
+ for (let group of groups){
327
+ if (Array.isArray(group)) {
328
+ group.sort((a, b)=>{
329
+ if (a.type === "tag" && b.type === "class") {
330
+ return -1;
331
+ } else if (a.type === "class" && b.type === "tag") {
332
+ return 1;
333
+ } else if (a.type === "class" && b.type === "pseudo" && b.value.startsWith("::")) {
334
+ return -1;
335
+ } else if (a.type === "pseudo" && a.value.startsWith("::") && b.type === "class") {
336
+ return 1;
337
+ }
338
+ return 0;
339
+ });
340
+ }
341
+ sel1.nodes = sel1.nodes.concat(group);
342
+ }
324
343
  }
325
344
  sel.replaceWith(...replaced);
326
345
  });
@@ -340,7 +359,7 @@ function processApply(root, context, localCache) {
340
359
  let [applyCandidates1, important] = extractApplyCandidates(apply.params);
341
360
  if (apply.parent.type === "atrule") {
342
361
  if (apply.parent.name === "screen") {
343
- const screenType = apply.parent.params;
362
+ let screenType = apply.parent.params;
344
363
  throw apply.error(`@apply is not supported within nested at-rules like @screen. We suggest you write this as @apply ${applyCandidates1.map((c)=>`${screenType}:${c}`).join(" ")} instead.`);
345
364
  }
346
365
  throw apply.error(`@apply is not supported within nested at-rules like @${apply.parent.name}. You can fix this by un-nesting @${apply.parent.name}.`);
@@ -364,7 +383,7 @@ function processApply(root, context, localCache) {
364
383
  ]);
365
384
  }
366
385
  }
367
- for (const [parent, [candidates1, atApplySource]] of perParentApplies){
386
+ for (let [parent, [candidates1, atApplySource]] of perParentApplies){
368
387
  let siblings = [];
369
388
  for (let [applyCandidate1, important1, rules1] of candidates1){
370
389
  let potentialApplyCandidates = [
@@ -169,7 +169,7 @@ function expandTailwindAtRules(context) {
169
169
  ], context);
170
170
  }
171
171
  env.DEBUG && console.timeEnd("Build stylesheet");
172
- let { defaults: defaultNodes , base: baseNodes , components: componentNodes , utilities: utilityNodes , variants: screenNodes , } = context.stylesheetCache;
172
+ let { defaults: defaultNodes , base: baseNodes , components: componentNodes , utilities: utilityNodes , variants: screenNodes } = context.stylesheetCache;
173
173
  // ---
174
174
  // Replace any Tailwind directives with generated CSS
175
175
  if (layerNodes.base) {
@@ -162,7 +162,7 @@ function applyImportant(matches, classCandidate) {
162
162
  ]
163
163
  });
164
164
  container.walkRules((r)=>{
165
- r.selector = (0, _pluginUtils.updateAllClasses)(r.selector, (className)=>{
165
+ r.selector = (0, _pluginUtils.updateAllClasses)((0, _pluginUtils.filterSelectorsForClass)(r.selector, classCandidate), (className)=>{
166
166
  if (className === classCandidate) {
167
167
  return `!${className}`;
168
168
  }
@@ -256,7 +256,7 @@ function applyVariant(variant, matches, context) {
256
256
  ]
257
257
  });
258
258
  for (let [variantSort, variantFunction, containerFromArray] of variantFunctionTuples){
259
- let clone = containerFromArray !== null && containerFromArray !== void 0 ? containerFromArray : container.clone();
259
+ let clone = (containerFromArray !== null && containerFromArray !== void 0 ? containerFromArray : container).clone();
260
260
  let collectedFormats = [];
261
261
  function prepareBackup() {
262
262
  // Already prepared, chicken out
@@ -533,7 +533,7 @@ function parseVariant(variant) {
533
533
  variantFunctions = [].concat(variantFunctions).map((variantFunction)=>{
534
534
  if (typeof variantFunction !== "string") {
535
535
  // Safelist public API functions
536
- return (api)=>{
536
+ return (api = {})=>{
537
537
  let { args , modifySelectors , container , separator , wrap , format } = api;
538
538
  let result = variantFunction(Object.assign({
539
539
  modifySelectors,
@@ -574,12 +574,14 @@ function parseVariant(variant) {
574
574
  var ref1;
575
575
  for (let [key, value] of Object.entries((ref1 = options === null || options === void 0 ? void 0 : options.values) !== null && ref1 !== void 0 ? ref1 : {})){
576
576
  if (key === "DEFAULT") continue;
577
- api.addVariant(isSpecial ? `${variant}${key}` : `${variant}-${key}`, ({ args , container })=>variantFn(value, modifiersEnabled ? {
578
- modifier: args.modifier,
577
+ api.addVariant(isSpecial ? `${variant}${key}` : `${variant}-${key}`, ({ args , container })=>{
578
+ return variantFn(value, modifiersEnabled ? {
579
+ modifier: args === null || args === void 0 ? void 0 : args.modifier,
579
580
  container
580
581
  } : {
581
582
  container
582
- }), {
583
+ });
584
+ }, {
583
585
  ...options,
584
586
  value,
585
587
  id,
@@ -590,11 +592,13 @@ function parseVariant(variant) {
590
592
  var ref2;
591
593
  let hasDefault = "DEFAULT" in ((ref2 = options === null || options === void 0 ? void 0 : options.values) !== null && ref2 !== void 0 ? ref2 : {});
592
594
  api.addVariant(variant, ({ args , container })=>{
593
- if (args.value === _sharedState.NONE && !hasDefault) {
595
+ if ((args === null || args === void 0 ? void 0 : args.value) === _sharedState.NONE && !hasDefault) {
594
596
  return null;
595
597
  }
596
- return variantFn(args.value === _sharedState.NONE ? options.values.DEFAULT : args.value, modifiersEnabled ? {
597
- modifier: args.modifier,
598
+ var // (JetBrains) plugins.
599
+ ref;
600
+ return variantFn((args === null || args === void 0 ? void 0 : args.value) === _sharedState.NONE ? options.values.DEFAULT : (ref = args === null || args === void 0 ? void 0 : args.value) !== null && ref !== void 0 ? ref : typeof args === "string" ? args : "", modifiersEnabled ? {
601
+ modifier: args === null || args === void 0 ? void 0 : args.modifier,
598
602
  container
599
603
  } : {
600
604
  container
@@ -795,6 +799,7 @@ function registerPlugins(plugins, context) {
795
799
  if (checks.length > 0) {
796
800
  let patternMatchingCount = new Map();
797
801
  let prefixLength = context.tailwindConfig.prefix.length;
802
+ let checkImportantUtils = checks.some((check)=>check.pattern.source.includes("!"));
798
803
  for (let util of classList){
799
804
  let utils = Array.isArray(util) ? (()=>{
800
805
  let [utilName, options] = util;
@@ -823,6 +828,12 @@ function registerPlugins(plugins, context) {
823
828
  ...classes.flatMap((cls)=>Object.keys(context.tailwindConfig.theme.opacity).map((opacity)=>`${cls}/${opacity}`))
824
829
  ];
825
830
  }
831
+ if (checkImportantUtils && (options === null || options === void 0 ? void 0 : options.respectImportant)) {
832
+ classes = [
833
+ ...classes,
834
+ ...classes.map((cls)=>"!" + cls)
835
+ ];
836
+ }
826
837
  return classes;
827
838
  })() : [
828
839
  util
@@ -1087,13 +1098,15 @@ function registerPlugins(plugins, context) {
1087
1098
  markInvalidUtilityCandidate(context, candidate);
1088
1099
  }
1089
1100
  function createContext(tailwindConfig, changedContent = [], root = _postcss.default.root()) {
1101
+ var _blocklist;
1090
1102
  let context = {
1091
1103
  disposables: [],
1092
1104
  ruleCache: new Set(),
1093
1105
  candidateRuleCache: new Map(),
1094
1106
  classCache: new Map(),
1095
1107
  applyClassCache: new Map(),
1096
- notClassCache: new Set(),
1108
+ // Seed the not class cache with the blocklist (which is only strings)
1109
+ notClassCache: new Set((_blocklist = tailwindConfig.blocklist) !== null && _blocklist !== void 0 ? _blocklist : []),
1097
1110
  postCssNodeCache: new Map(),
1098
1111
  candidateRuleMap: new Map(),
1099
1112
  tailwindConfig,
@@ -78,9 +78,9 @@ function formatVariantSelector(current, ...others) {
78
78
  return -1;
79
79
  } else if (a.type === "class" && b.type === "tag") {
80
80
  return 1;
81
- } else if (a.type === "class" && b.type === "pseudo" && b.value !== ":merge") {
81
+ } else if (a.type === "class" && b.type === "pseudo" && b.value.startsWith("::")) {
82
82
  return -1;
83
- } else if (a.type === "pseudo" && a.value !== ":merge" && b.type === "class") {
83
+ } else if (a.type === "pseudo" && a.value.startsWith("::") && b.type === "class") {
84
84
  return 1;
85
85
  }
86
86
  return sel.index(a) - sel.index(b);
@@ -114,7 +114,7 @@ function finalizeSelector(format, { selector , candidate , context , isArbitrary
114
114
  // │ │ │ ╰── We will not split here
115
115
  // ╰──┴─────┴─────────────── We will split here
116
116
  //
117
- base =candidate.split(new RegExp(`\\${(ref1 = context === null || context === void 0 ? void 0 : (ref = context.tailwindConfig) === null || ref === void 0 ? void 0 : ref.separator) !== null && ref1 !== void 0 ? ref1 : ":"}(?![^[]*\\])`)).pop() , }) {
117
+ base =candidate.split(new RegExp(`\\${(ref1 = context === null || context === void 0 ? void 0 : (ref = context.tailwindConfig) === null || ref === void 0 ? void 0 : ref.separator) !== null && ref1 !== void 0 ? ref1 : ":"}(?![^[]*\\])`)).pop() }) {
118
118
  var ref2;
119
119
  let ast = (0, _postcssSelectorParser.default)().astSync(selector);
120
120
  // We explicitly DO NOT prefix classes in arbitrary variants
@@ -162,6 +162,20 @@ function normalizeConfig(config) {
162
162
  if (Array.isArray(purge === null || purge === void 0 ? void 0 : (ref = purge.options) === null || ref === void 0 ? void 0 : ref.safelist)) return purge.options.safelist;
163
163
  return [];
164
164
  })();
165
+ // Normalize the `blocklist`
166
+ config.blocklist = (()=>{
167
+ let { blocklist } = config;
168
+ if (Array.isArray(blocklist)) {
169
+ if (blocklist.every((item)=>typeof item === "string")) {
170
+ return blocklist;
171
+ }
172
+ _log.default.warn("blocklist-invalid", [
173
+ "The `blocklist` option must be an array of strings.",
174
+ "https://tailwindcss.com/docs/content-configuration#discarding-classes"
175
+ ]);
176
+ }
177
+ return [];
178
+ })();
165
179
  // Normalize prefix option
166
180
  if (typeof config.prefix === "function") {
167
181
  _log.default.warn("prefix-function", [
@@ -10,6 +10,7 @@ function _export(target, all) {
10
10
  }
11
11
  _export(exports, {
12
12
  updateAllClasses: ()=>updateAllClasses,
13
+ filterSelectorsForClass: ()=>filterSelectorsForClass,
13
14
  asValue: ()=>asValue,
14
15
  parseColorFormat: ()=>parseColorFormat,
15
16
  asColor: ()=>asColor,
@@ -43,6 +44,18 @@ function updateAllClasses(selectors, updateClass) {
43
44
  let result = parser.processSync(selectors);
44
45
  return result;
45
46
  }
47
+ function filterSelectorsForClass(selectors, classCandidate) {
48
+ let parser = (0, _postcssSelectorParser.default)((selectors)=>{
49
+ selectors.each((sel)=>{
50
+ const containsClass = sel.nodes.some((node)=>node.type === "class" && node.value === classCandidate);
51
+ if (!containsClass) {
52
+ sel.remove();
53
+ }
54
+ });
55
+ });
56
+ let result = parser.processSync(selectors);
57
+ return result;
58
+ }
46
59
  function resolveArbitraryValue(modifier, validate) {
47
60
  if (!isArbitraryValue(modifier)) {
48
61
  return undefined;
@@ -110,15 +123,15 @@ function parseColorFormat(value) {
110
123
  }
111
124
  return value;
112
125
  }
113
- function asColor(_, options = {}, { tailwindConfig ={} , utilityModifier , rawModifier } = {}) {
126
+ function asColor(modifier, options = {}, { tailwindConfig ={} } = {}) {
114
127
  var ref;
115
- if (((ref = options.values) === null || ref === void 0 ? void 0 : ref[rawModifier]) !== undefined) {
128
+ if (((ref = options.values) === null || ref === void 0 ? void 0 : ref[modifier]) !== undefined) {
116
129
  var ref1;
117
- return parseColorFormat((ref1 = options.values) === null || ref1 === void 0 ? void 0 : ref1[rawModifier]);
130
+ return parseColorFormat((ref1 = options.values) === null || ref1 === void 0 ? void 0 : ref1[modifier]);
118
131
  }
119
132
  // TODO: Hoist this up to getMatchingTypes or something
120
133
  // We do this here because we need the alpha value (if any)
121
- let [color, alpha] = splitUtilityModifier(rawModifier);
134
+ let [color, alpha] = splitUtilityModifier(modifier);
122
135
  if (alpha !== undefined) {
123
136
  var ref2, ref3, ref4;
124
137
  var ref5;
@@ -135,9 +148,7 @@ function asColor(_, options = {}, { tailwindConfig ={} , utilityModifier , rawMo
135
148
  }
136
149
  return (0, _withAlphaVariable.withAlphaValue)(normalizedColor, tailwindConfig.theme.opacity[alpha]);
137
150
  }
138
- return asValue(rawModifier, options, {
139
- rawModifier,
140
- utilityModifier,
151
+ return asValue(modifier, options, {
141
152
  validate: _dataTypes.color
142
153
  });
143
154
  }
@@ -146,9 +157,8 @@ function asLookupValue(modifier, options = {}) {
146
157
  return (ref = options.values) === null || ref === void 0 ? void 0 : ref[modifier];
147
158
  }
148
159
  function guess(validate) {
149
- return (modifier, options, extras)=>{
160
+ return (modifier, options)=>{
150
161
  return asValue(modifier, options, {
151
- ...extras,
152
162
  validate
153
163
  });
154
164
  };
@@ -184,6 +194,21 @@ function splitAtFirst(input, delim) {
184
194
  ];
185
195
  }
186
196
  function coerceValue(types, modifier, options, tailwindConfig) {
197
+ if (options.values && modifier in options.values) {
198
+ for (let { type } of types !== null && types !== void 0 ? types : []){
199
+ let result = typeMap[type](modifier, options, {
200
+ tailwindConfig
201
+ });
202
+ if (result === undefined) {
203
+ continue;
204
+ }
205
+ return [
206
+ result,
207
+ type,
208
+ null
209
+ ];
210
+ }
211
+ }
187
212
  if (isArbitraryValue(modifier)) {
188
213
  let arbitraryValue = modifier.slice(1, -1);
189
214
  let [explicitType, value] = splitAtFirst(arbitraryValue, ":");
@@ -234,30 +259,16 @@ function* getMatchingTypes(types, rawModifier, options, tailwindConfig) {
234
259
  utilityModifier = utilityModifier.slice(1, -1);
235
260
  }
236
261
  }
237
- let result = asValue(rawModifier, options, {
238
- rawModifier,
239
- utilityModifier,
240
- tailwindConfig
241
- });
242
- if (result !== undefined) {
243
- yield [
244
- result,
245
- "any",
246
- null
247
- ];
248
- }
249
262
  }
250
- for (const { type } of types !== null && types !== void 0 ? types : []){
251
- let result1 = typeMap[type](modifier, options, {
252
- rawModifier,
253
- utilityModifier,
263
+ for (let { type } of types !== null && types !== void 0 ? types : []){
264
+ let result = typeMap[type](modifier, options, {
254
265
  tailwindConfig
255
266
  });
256
- if (result1 === undefined) {
267
+ if (result === undefined) {
257
268
  continue;
258
269
  }
259
270
  yield [
260
- result1,
271
+ result,
261
272
  type,
262
273
  utilityModifier !== null && utilityModifier !== void 0 ? utilityModifier : null
263
274
  ];
@@ -9,7 +9,6 @@ Object.defineProperty(exports, "default", {
9
9
  const _negateValue = /*#__PURE__*/ _interopRequireDefault(require("./negateValue"));
10
10
  const _corePluginList = /*#__PURE__*/ _interopRequireDefault(require("../corePluginList"));
11
11
  const _configurePlugins = /*#__PURE__*/ _interopRequireDefault(require("./configurePlugins"));
12
- const _defaultConfigStub = /*#__PURE__*/ _interopRequireDefault(require("../../stubs/defaultConfig.stub"));
13
12
  const _colors = /*#__PURE__*/ _interopRequireDefault(require("../public/colors"));
14
13
  const _defaults = require("./defaults");
15
14
  const _toPath = require("./toPath");
@@ -27,16 +26,13 @@ function _interopRequireDefault(obj) {
27
26
  function isFunction(input) {
28
27
  return typeof input === "function";
29
28
  }
30
- function isObject(input) {
31
- return typeof input === "object" && input !== null;
32
- }
33
29
  function mergeWith(target, ...sources) {
34
30
  let customizer = sources.pop();
35
31
  for (let source of sources){
36
32
  for(let k in source){
37
33
  let merged = customizer(target[k], source[k]);
38
34
  if (merged === undefined) {
39
- if (isObject(target[k]) && isObject(source[k])) {
35
+ if ((0, _isPlainObject.default)(target[k]) && (0, _isPlainObject.default)(source[k])) {
40
36
  target[k] = mergeWith({}, target[k], source[k], customizer);
41
37
  } else {
42
38
  target[k] = source[k];
@@ -101,11 +97,11 @@ function mergeThemes(themes) {
101
97
  }
102
98
  function mergeExtensionCustomizer(merged, value) {
103
99
  // When we have an array of objects, we do want to merge it
104
- if (Array.isArray(merged) && isObject(merged[0])) {
100
+ if (Array.isArray(merged) && (0, _isPlainObject.default)(merged[0])) {
105
101
  return merged.concat(value);
106
102
  }
107
103
  // When the incoming value is an array, and the existing config is an object, prepend the existing object
108
- if (Array.isArray(value) && isObject(value[0]) && isObject(merged)) {
104
+ if (Array.isArray(value) && (0, _isPlainObject.default)(value[0]) && (0, _isPlainObject.default)(merged)) {
109
105
  return [
110
106
  merged,
111
107
  ...value
@@ -242,8 +238,7 @@ function resolveConfig(configs) {
242
238
  {
243
239
  prefix: "",
244
240
  important: false,
245
- separator: ":",
246
- variantOrder: _defaultConfigStub.default.variantOrder
241
+ separator: ":"
247
242
  }
248
243
  ];
249
244
  var ref, ref1;