tailwindcss 0.0.0-insiders.2cd6fad → 0.0.0-insiders.2d40d0b

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 (68) hide show
  1. package/CHANGELOG.md +68 -1
  2. package/README.md +1 -1
  3. package/lib/cli/build/index.js +5 -1
  4. package/lib/cli/build/plugin.js +23 -12
  5. package/lib/cli/build/watching.js +77 -12
  6. package/lib/cli/init/index.js +2 -2
  7. package/lib/cli.js +21 -11
  8. package/lib/corePlugins.js +34 -27
  9. package/lib/css/preflight.css +2 -0
  10. package/lib/featureFlags.js +8 -8
  11. package/lib/index.js +2 -2
  12. package/lib/lib/collapseAdjacentRules.js +2 -2
  13. package/lib/lib/collapseDuplicateDeclarations.js +2 -2
  14. package/lib/lib/content.js +14 -6
  15. package/lib/lib/defaultExtractor.js +10 -5
  16. package/lib/lib/detectNesting.js +7 -1
  17. package/lib/lib/evaluateTailwindFunctions.js +4 -4
  18. package/lib/lib/expandApplyAtRules.js +36 -17
  19. package/lib/lib/expandTailwindAtRules.js +5 -5
  20. package/lib/lib/findAtConfigPath.js +3 -3
  21. package/lib/lib/generateRules.js +93 -44
  22. package/lib/lib/offsets.js +83 -1
  23. package/lib/lib/remap-bitfield.js +87 -0
  24. package/lib/lib/resolveDefaultsAtRules.js +4 -4
  25. package/lib/lib/setupContextUtils.js +114 -79
  26. package/lib/lib/setupTrackingContext.js +25 -4
  27. package/lib/postcss-plugins/nesting/plugin.js +2 -2
  28. package/lib/util/cloneNodes.js +2 -2
  29. package/lib/util/color.js +4 -4
  30. package/lib/util/createUtilityPlugin.js +2 -2
  31. package/lib/util/dataTypes.js +29 -2
  32. package/lib/util/defaults.js +4 -4
  33. package/lib/util/escapeClassName.js +3 -3
  34. package/lib/util/formatVariantSelector.js +174 -106
  35. package/lib/util/getAllConfigs.js +2 -2
  36. package/lib/util/{isValidArbitraryValue.js → isSyntacticallyValidPropertyValue.js} +2 -2
  37. package/lib/util/normalizeConfig.js +36 -22
  38. package/lib/util/pluginUtils.js +60 -42
  39. package/lib/util/prefixSelector.js +22 -8
  40. package/lib/util/resolveConfig.js +11 -16
  41. package/package.json +17 -17
  42. package/peers/index.js +685 -605
  43. package/resolveConfig.d.ts +11 -2
  44. package/src/cli/build/index.js +6 -2
  45. package/src/cli/build/plugin.js +21 -4
  46. package/src/cli/build/watching.js +105 -12
  47. package/src/cli.js +24 -13
  48. package/src/corePlugins.js +16 -3
  49. package/src/css/preflight.css +2 -0
  50. package/src/lib/content.js +10 -7
  51. package/src/lib/defaultExtractor.js +9 -3
  52. package/src/lib/detectNesting.js +9 -1
  53. package/src/lib/expandApplyAtRules.js +35 -15
  54. package/src/lib/generateRules.js +87 -30
  55. package/src/lib/offsets.js +98 -1
  56. package/src/lib/remap-bitfield.js +82 -0
  57. package/src/lib/setupContextUtils.js +100 -58
  58. package/src/lib/setupTrackingContext.js +31 -6
  59. package/src/util/dataTypes.js +33 -4
  60. package/src/util/formatVariantSelector.js +216 -123
  61. package/src/util/{isValidArbitraryValue.js → isSyntacticallyValidPropertyValue.js} +1 -1
  62. package/src/util/normalizeConfig.js +18 -0
  63. package/src/util/pluginUtils.js +49 -21
  64. package/src/util/prefixSelector.js +28 -10
  65. package/src/util/resolveConfig.js +3 -9
  66. package/stubs/defaultConfig.stub.js +148 -163
  67. package/types/config.d.ts +7 -2
  68. package/types/generated/default-theme.d.ts +82 -79
package/CHANGELOG.md CHANGED
@@ -7,10 +7,74 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Added
11
+
12
+ - Add `line-height` modifier support to `font-size` utilities ([#9875](https://github.com/tailwindlabs/tailwindcss/pull/9875))
13
+ - Support using variables as arbitrary values without `var(...)` ([#9880](https://github.com/tailwindlabs/tailwindcss/pull/9880), [#9962](https://github.com/tailwindlabs/tailwindcss/pull/9962))
14
+ - Add `--watch=always` option to prevent exit when stdin closes ([#9966](https://github.com/tailwindlabs/tailwindcss/pull/9966))
15
+ - Add standalone CLI build for 64-bit Windows on ARM (`node16-win-arm64`) ([#10001](https://github.com/tailwindlabs/tailwindcss/pull/10001))
16
+ - Add `delay-0` and `duration-0` by default ([#10294](https://github.com/tailwindlabs/tailwindcss/pull/10294))
17
+
18
+ ### Fixed
19
+
20
+ - Cleanup unused `variantOrder` ([#9829](https://github.com/tailwindlabs/tailwindcss/pull/9829))
21
+ - Fix `foo-[abc]/[def]` not being handled correctly ([#9866](https://github.com/tailwindlabs/tailwindcss/pull/9866))
22
+ - Add container queries plugin to standalone CLI ([#9865](https://github.com/tailwindlabs/tailwindcss/pull/9865))
23
+ - Support renaming of output files by `PostCSS` plugin. ([#9944](https://github.com/tailwindlabs/tailwindcss/pull/9944))
24
+ - Improve return value of `resolveConfig`, unwrap `ResolvableTo` ([#9972](https://github.com/tailwindlabs/tailwindcss/pull/9972))
25
+ - Clip unbalanced brackets in arbitrary values ([#9973](https://github.com/tailwindlabs/tailwindcss/pull/9973))
26
+ - Don’t reorder webkit scrollbar pseudo elements ([#9991](https://github.com/tailwindlabs/tailwindcss/pull/9991))
27
+ - Deterministic sorting of arbitrary variants ([#10016](https://github.com/tailwindlabs/tailwindcss/pull/10016))
28
+ - Add `data` key to theme types ([#10023](https://github.com/tailwindlabs/tailwindcss/pull/10023))
29
+ - Prevent invalid arbitrary variant selectors from failing the build ([#10059](https://github.com/tailwindlabs/tailwindcss/pull/10059))
30
+ - Properly handle subtraction followed by a variable ([#10074](https://github.com/tailwindlabs/tailwindcss/pull/10074))
31
+ - Fix missing `string[]` in the `theme.dropShadow` types ([#10072](https://github.com/tailwindlabs/tailwindcss/pull/10072))
32
+ - Update list of length units ([#10100](https://github.com/tailwindlabs/tailwindcss/pull/10100))
33
+ - Fix not matching arbitrary properties when closely followed by square brackets ([#10212](https://github.com/tailwindlabs/tailwindcss/pull/10212))
34
+ - Allow direct nesting in `root` or `@layer` nodes ([#10229](https://github.com/tailwindlabs/tailwindcss/pull/10229))
35
+ - Don't prefix classes in arbitrary variants ([#10214](https://github.com/tailwindlabs/tailwindcss/pull/10214))
36
+ - Fix perf regression when checking for changed content ([#10234](https://github.com/tailwindlabs/tailwindcss/pull/10234))
37
+ - Fix missing `blocklist` member in the `Config` type ([#10239](https://github.com/tailwindlabs/tailwindcss/pull/10239))
38
+ - Escape group names in selectors ([#10276](https://github.com/tailwindlabs/tailwindcss/pull/10276))
39
+ - Consider earlier variants before sorting functions ([#10288](https://github.com/tailwindlabs/tailwindcss/pull/10288))
40
+
41
+ ### Changed
42
+
43
+ - Alphabetize `theme` keys in default config ([#9953](https://github.com/tailwindlabs/tailwindcss/pull/9953))
44
+ - Update esbuild to v16 ([#10178](https://github.com/tailwindlabs/tailwindcss/pull/10178))
45
+
46
+ ## [3.2.4] - 2022-11-11
47
+
48
+ ### Added
49
+
50
+ - Add `blocklist` option to prevent generating unwanted CSS ([#9812](https://github.com/tailwindlabs/tailwindcss/pull/9812))
51
+
52
+ ### Fixed
53
+
54
+ - Fix watching of files on Linux when renames are involved ([#9796](https://github.com/tailwindlabs/tailwindcss/pull/9796))
55
+ - Make sure errors are always displayed when watching for changes ([#9810](https://github.com/tailwindlabs/tailwindcss/pull/9810))
56
+
57
+ ## [3.2.3] - 2022-11-09
58
+
59
+ ### Fixed
60
+
61
+ - Fixed use of `raw` content in the CLI ([#9773](https://github.com/tailwindlabs/tailwindcss/pull/9773))
62
+ - Pick up changes from files that are both context and content deps ([#9787](https://github.com/tailwindlabs/tailwindcss/pull/9787))
63
+ - Sort pseudo-elements ONLY after classes when using variants and `@apply` ([#9765](https://github.com/tailwindlabs/tailwindcss/pull/9765))
64
+ - Support important utilities in the safelist (pattern must include a `!`) ([#9791](https://github.com/tailwindlabs/tailwindcss/pull/9791))
65
+
66
+ ## [3.2.2] - 2022-11-04
67
+
10
68
  ### Fixed
11
69
 
12
70
  - Escape special characters in resolved content base paths ([#9650](https://github.com/tailwindlabs/tailwindcss/pull/9650))
13
71
  - Don't reuse container for array returning variant functions ([#9644](https://github.com/tailwindlabs/tailwindcss/pull/9644))
72
+ - Exclude non-relevant selectors when generating rules with the important modifier ([#9677](https://github.com/tailwindlabs/tailwindcss/issues/9677))
73
+ - Fix merging of arrays during config resolution ([#9706](https://github.com/tailwindlabs/tailwindcss/issues/9706))
74
+ - Ensure configured `font-feature-settings` are included in Preflight ([#9707](https://github.com/tailwindlabs/tailwindcss/pull/9707))
75
+ - Fix fractional values not being parsed properly inside arbitrary properties ([#9705](https://github.com/tailwindlabs/tailwindcss/pull/9705))
76
+ - Fix incorrect selectors when using `@apply` in selectors with combinators and pseudos ([#9722](https://github.com/tailwindlabs/tailwindcss/pull/9722))
77
+ - Fix cannot read properties of undefined (reading 'modifier') ([#9656](https://github.com/tailwindlabs/tailwindcss/pull/9656), [aa979d6](https://github.com/tailwindlabs/tailwindcss/commit/aa979d645f8bf4108c5fc938d7c0ba085b654c31))
14
78
 
15
79
  ## [3.2.1] - 2022-10-21
16
80
 
@@ -2091,7 +2155,10 @@ No release notes
2091
2155
 
2092
2156
  - Everything!
2093
2157
 
2094
- [unreleased]: https://github.com/tailwindlabs/tailwindcss/compare/v3.2.1...HEAD
2158
+ [unreleased]: https://github.com/tailwindlabs/tailwindcss/compare/v3.2.4...HEAD
2159
+ [3.2.4]: https://github.com/tailwindlabs/tailwindcss/compare/v3.2.3...v3.2.4
2160
+ [3.2.3]: https://github.com/tailwindlabs/tailwindcss/compare/v3.2.2...v3.2.3
2161
+ [3.2.2]: https://github.com/tailwindlabs/tailwindcss/compare/v3.2.1...v3.2.2
2095
2162
  [3.2.1]: https://github.com/tailwindlabs/tailwindcss/compare/v3.2.0...v3.2.1
2096
2163
  [3.2.0]: https://github.com/tailwindlabs/tailwindcss/compare/v3.1.8...v3.2.0
2097
2164
  [3.1.8]: https://github.com/tailwindlabs/tailwindcss/compare/v3.1.7...v3.1.8
package/README.md CHANGED
@@ -14,7 +14,7 @@
14
14
 
15
15
 
16
16
  <p align="center">
17
- <a href="https://github.com/tailwindlabs/tailwindcss/actions"><img src="https://img.shields.io/github/workflow/status/tailwindlabs/tailwindcss/Node.js%20CI" alt="Build Status"></a>
17
+ <a href="https://github.com/tailwindlabs/tailwindcss/actions"><img src="https://img.shields.io/github/actions/workflow/status/tailwindlabs/tailwindcss/nodejs.yml?branch=master" alt="Build Status"></a>
18
18
  <a href="https://www.npmjs.com/package/tailwindcss"><img src="https://img.shields.io/npm/dt/tailwindcss.svg" alt="Total Downloads"></a>
19
19
  <a href="https://github.com/tailwindcss/tailwindcss/releases"><img src="https://img.shields.io/npm/v/tailwindcss.svg" alt="Latest Release"></a>
20
20
  <a href="https://github.com/tailwindcss/tailwindcss/blob/master/LICENSE"><img src="https://img.shields.io/npm/l/tailwindcss.svg" alt="License"></a>
@@ -35,7 +35,11 @@ async function build(args, configs) {
35
35
  let configPath = args["--config"] ? args["--config"] : ((defaultPath)=>_fs.default.existsSync(defaultPath) ? defaultPath : null)(_path.default.resolve(`./${configs.tailwind}`));
36
36
  let processor = await (0, _pluginJs.createProcessor)(args, configPath);
37
37
  if (shouldWatch) {
38
- /* Abort the watcher if stdin is closed to avoid zombie processes */ process.stdin.on("end", ()=>process.exit(0));
38
+ // Abort the watcher if stdin is closed to avoid zombie processes
39
+ // You can disable this behavior with --watch=always
40
+ if (args["--watch"] !== "always") {
41
+ process.stdin.on("end", ()=>process.exit(0));
42
+ }
39
43
  process.stdin.resume();
40
44
  await processor.watch();
41
45
  } else {
@@ -113,8 +113,8 @@ let state = {
113
113
  contextDependencies: new Set(),
114
114
  /** @type {import('../../lib/content.js').ContentPath[]} */ contentPaths: [],
115
115
  refreshContentPaths () {
116
- var ref;
117
- this.contentPaths = (0, _contentJs.parseCandidateFiles)(this.context, (ref = this.context) === null || ref === void 0 ? void 0 : ref.tailwindConfig);
116
+ var _this_context;
117
+ this.contentPaths = (0, _contentJs.parseCandidateFiles)(this.context, (_this_context = this.context) === null || _this_context === void 0 ? void 0 : _this_context.tailwindConfig);
118
118
  },
119
119
  get config () {
120
120
  return this.context.tailwindConfig;
@@ -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
  }
@@ -184,8 +184,8 @@ let state = {
184
184
  return this.context;
185
185
  }
186
186
  _shared.env.DEBUG && console.time("Searching for config");
187
- var ref;
188
- let configPath = (ref = (0, _findAtConfigPathJs.findAtConfigPath)(root, result)) !== null && ref !== void 0 ? ref : cliConfigPath;
187
+ var _findAtConfigPath;
188
+ let configPath = (_findAtConfigPath = (0, _findAtConfigPathJs.findAtConfigPath)(root, result)) !== null && _findAtConfigPath !== void 0 ? _findAtConfigPath : cliConfigPath;
189
189
  _shared.env.DEBUG && console.timeEnd("Searching for config");
190
190
  _shared.env.DEBUG && console.time("Loading config");
191
191
  let config = this.loadConfig(configPath, content);
@@ -213,7 +213,7 @@ let state = {
213
213
  }
214
214
  };
215
215
  async function createProcessor(args, cliConfigPath) {
216
- var ref;
216
+ var _args_content;
217
217
  let postcss = (0, _deps.loadPostcss)();
218
218
  let input = args["--input"];
219
219
  let output = args["--output"];
@@ -229,8 +229,8 @@ async function createProcessor(args, cliConfigPath) {
229
229
  args["--content"] = args["--purge"];
230
230
  }
231
231
  }
232
- var ref1;
233
- let content = (ref1 = (ref = args["--content"]) === null || ref === void 0 ? void 0 : ref.split(/(?<!{[^}]+),/)) !== null && ref1 !== void 0 ? ref1 : [];
232
+ var _args_content_split;
233
+ let content = (_args_content_split = (_args_content = args["--content"]) === null || _args_content === void 0 ? void 0 : _args_content.split(/(?<!{[^}]+),/)) !== null && _args_content_split !== void 0 ? _args_content_split : [];
234
234
  let tailwindPlugin = ()=>{
235
235
  return {
236
236
  postcssPlugin: "tailwindcss",
@@ -304,13 +304,24 @@ async function createProcessor(args, cliConfigPath) {
304
304
  return;
305
305
  }
306
306
  return Promise.all([
307
- (0, _utils.outputFile)(output, result.css),
308
- result.map && (0, _utils.outputFile)(output + ".map", result.map.toString())
307
+ (0, _utils.outputFile)(result.opts.to, result.css),
308
+ result.map && (0, _utils.outputFile)(result.opts.to + ".map", result.map.toString())
309
309
  ]);
310
310
  }).then(()=>{
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 {
@@ -16,8 +16,8 @@ function _interopRequireDefault(obj) {
16
16
  }
17
17
  function init(args, configs) {
18
18
  let messages = [];
19
- var ref;
20
- let tailwindConfigLocation = _path.default.resolve((ref = args["_"][1]) !== null && ref !== void 0 ? ref : `./${configs.tailwind}`);
19
+ var _args___;
20
+ let tailwindConfigLocation = _path.default.resolve((_args___ = args["_"][1]) !== null && _args___ !== void 0 ? _args___ : `./${configs.tailwind}`);
21
21
  if (_fs.default.existsSync(tailwindConfigLocation)) {
22
22
  messages.push(`${_path.default.basename(tailwindConfigLocation)} already exists.`);
23
23
  } else {
package/lib/cli.js CHANGED
@@ -72,7 +72,7 @@ let commands = {
72
72
  description: "Output file"
73
73
  },
74
74
  "--watch": {
75
- type: Boolean,
75
+ type: oneOf(String, Boolean),
76
76
  description: "Watch for changes and rebuild as needed"
77
77
  },
78
78
  "--poll": {
@@ -159,8 +159,8 @@ let args = (()=>{
159
159
  ...flags,
160
160
  ...sharedFlags
161
161
  }).filter(([_key, value])=>{
162
- var ref;
163
- return !(value === null || value === void 0 ? void 0 : (ref = value.type) === null || ref === void 0 ? void 0 : ref.manualParsing);
162
+ var _value_type;
163
+ return !(value === null || value === void 0 ? void 0 : (_value_type = value.type) === null || _value_type === void 0 ? void 0 : _value_type.manualParsing);
164
164
  }).map(([key, value])=>[
165
165
  key,
166
166
  typeof value === "object" ? value.type : value
@@ -171,8 +171,8 @@ let args = (()=>{
171
171
  for(let i = result["_"].length - 1; i >= 0; --i){
172
172
  let flag = result["_"][i];
173
173
  if (!flag.startsWith("-")) continue;
174
- let flagName = flag;
175
- let handler = flags[flag];
174
+ let [flagName, flagValue] = flag.split("=");
175
+ let handler = flags[flagName];
176
176
  // Resolve flagName & handler
177
177
  while(typeof handler === "string"){
178
178
  flagName = handler;
@@ -181,14 +181,24 @@ let args = (()=>{
181
181
  if (!handler) continue;
182
182
  let args = [];
183
183
  let offset = i + 1;
184
- // Parse args for current flag
185
- while(result["_"][offset] && !result["_"][offset].startsWith("-")){
186
- args.push(result["_"][offset++]);
184
+ // --flag value syntax was used so we need to pull `value` from `args`
185
+ if (flagValue === undefined) {
186
+ // Parse args for current flag
187
+ while(result["_"][offset] && !result["_"][offset].startsWith("-")){
188
+ args.push(result["_"][offset++]);
189
+ }
190
+ // Cleanup manually parsed flags + args
191
+ result["_"].splice(i, 1 + args.length);
192
+ // No args were provided, use default value defined in handler
193
+ // One arg was provided, use that directly
194
+ // Multiple args were provided so pass them all in an array
195
+ flagValue = args.length === 0 ? undefined : args.length === 1 ? args[0] : args;
196
+ } else {
197
+ // Remove the whole flag from the args array
198
+ result["_"].splice(i, 1);
187
199
  }
188
- // Cleanup manually parsed flags + args
189
- result["_"].splice(i, 1 + args.length);
190
200
  // Set the resolved value in the `result` object
191
- result[flagName] = handler.type(args.length === 0 ? undefined : args.length === 1 ? args[0] : args, flagName);
201
+ result[flagName] = handler.type(flagValue, flagName);
192
202
  }
193
203
  // Ensure that the `command` is always the first argument in the `args`.
194
204
  // This is important so that we don't have to check if a default command
@@ -212,14 +212,14 @@ let variantPlugins = {
212
212
  }
213
213
  let variants = {
214
214
  group: (_, { modifier })=>modifier ? [
215
- `:merge(.group\\/${modifier})`,
215
+ `:merge(.group\\/${(0, _escapeClassName.default)(modifier)})`,
216
216
  " &"
217
217
  ] : [
218
218
  `:merge(.group)`,
219
219
  " &"
220
220
  ],
221
221
  peer: (_, { modifier })=>modifier ? [
222
- `:merge(.peer\\/${modifier})`,
222
+ `:merge(.peer\\/${(0, _escapeClassName.default)(modifier)})`,
223
223
  " ~ &"
224
224
  ] : [
225
225
  `:merge(.peer)`,
@@ -277,15 +277,15 @@ let variantPlugins = {
277
277
  addVariant("print", "@media print");
278
278
  },
279
279
  screenVariants: ({ theme , addVariant , matchVariant })=>{
280
- var ref;
281
- let rawScreens = (ref = theme("screens")) !== null && ref !== void 0 ? ref : {};
280
+ var _theme;
281
+ let rawScreens = (_theme = theme("screens")) !== null && _theme !== void 0 ? _theme : {};
282
282
  let areSimpleScreens = Object.values(rawScreens).every((v)=>typeof v === "string");
283
283
  let screens = (0, _normalizeScreens.normalizeScreens)(theme("screens"));
284
284
  /** @type {Set<string>} */ let unitCache = new Set([]);
285
285
  /** @param {string} value */ function units(value) {
286
- var ref;
287
- var ref1;
288
- return (ref1 = (ref = value.match(/(\D+)$/)) === null || ref === void 0 ? void 0 : ref[1]) !== null && ref1 !== void 0 ? ref1 : "(none)";
286
+ var _value_match;
287
+ var _value_match_;
288
+ return (_value_match_ = (_value_match = value.match(/(\D+)$/)) === null || _value_match === void 0 ? void 0 : _value_match[1]) !== null && _value_match_ !== void 0 ? _value_match_ : "(none)";
289
289
  }
290
290
  /** @param {string} value */ function recordUnits(value) {
291
291
  if (value !== undefined) {
@@ -384,7 +384,7 @@ let variantPlugins = {
384
384
  });
385
385
  },
386
386
  supportsVariants: ({ matchVariant , theme })=>{
387
- var ref;
387
+ var _theme;
388
388
  matchVariant("supports", (value = "")=>{
389
389
  let check = (0, _dataTypes.normalize)(value);
390
390
  let isRaw = /^\w*\s*\(/.test(check);
@@ -402,35 +402,35 @@ let variantPlugins = {
402
402
  }
403
403
  return `@supports ${check}`;
404
404
  }, {
405
- values: (ref = theme("supports")) !== null && ref !== void 0 ? ref : {}
405
+ values: (_theme = theme("supports")) !== null && _theme !== void 0 ? _theme : {}
406
406
  });
407
407
  },
408
408
  ariaVariants: ({ matchVariant , theme })=>{
409
- var ref;
409
+ var _theme;
410
410
  matchVariant("aria", (value)=>`&[aria-${(0, _dataTypes.normalize)(value)}]`, {
411
- values: (ref = theme("aria")) !== null && ref !== void 0 ? ref : {}
411
+ values: (_theme = theme("aria")) !== null && _theme !== void 0 ? _theme : {}
412
412
  });
413
- var ref1;
413
+ var _theme1;
414
414
  matchVariant("group-aria", (value, { modifier })=>modifier ? `:merge(.group\\/${modifier})[aria-${(0, _dataTypes.normalize)(value)}] &` : `:merge(.group)[aria-${(0, _dataTypes.normalize)(value)}] &`, {
415
- values: (ref1 = theme("aria")) !== null && ref1 !== void 0 ? ref1 : {}
415
+ values: (_theme1 = theme("aria")) !== null && _theme1 !== void 0 ? _theme1 : {}
416
416
  });
417
- var ref2;
417
+ var _theme2;
418
418
  matchVariant("peer-aria", (value, { modifier })=>modifier ? `:merge(.peer\\/${modifier})[aria-${(0, _dataTypes.normalize)(value)}] ~ &` : `:merge(.peer)[aria-${(0, _dataTypes.normalize)(value)}] ~ &`, {
419
- values: (ref2 = theme("aria")) !== null && ref2 !== void 0 ? ref2 : {}
419
+ values: (_theme2 = theme("aria")) !== null && _theme2 !== void 0 ? _theme2 : {}
420
420
  });
421
421
  },
422
422
  dataVariants: ({ matchVariant , theme })=>{
423
- var ref;
423
+ var _theme;
424
424
  matchVariant("data", (value)=>`&[data-${(0, _dataTypes.normalize)(value)}]`, {
425
- values: (ref = theme("data")) !== null && ref !== void 0 ? ref : {}
425
+ values: (_theme = theme("data")) !== null && _theme !== void 0 ? _theme : {}
426
426
  });
427
- var ref1;
427
+ var _theme1;
428
428
  matchVariant("group-data", (value, { modifier })=>modifier ? `:merge(.group\\/${modifier})[data-${(0, _dataTypes.normalize)(value)}] &` : `:merge(.group)[data-${(0, _dataTypes.normalize)(value)}] &`, {
429
- values: (ref1 = theme("data")) !== null && ref1 !== void 0 ? ref1 : {}
429
+ values: (_theme1 = theme("data")) !== null && _theme1 !== void 0 ? _theme1 : {}
430
430
  });
431
- var ref2;
431
+ var _theme2;
432
432
  matchVariant("peer-data", (value, { modifier })=>modifier ? `:merge(.peer\\/${modifier})[data-${(0, _dataTypes.normalize)(value)}] ~ &` : `:merge(.peer)[data-${(0, _dataTypes.normalize)(value)}] ~ &`, {
433
- values: (ref2 = theme("data")) !== null && ref2 !== void 0 ? ref2 : {}
433
+ values: (_theme2 = theme("data")) !== null && _theme2 !== void 0 ? _theme2 : {}
434
434
  });
435
435
  },
436
436
  orientationVariants: ({ addVariant })=>{
@@ -1223,8 +1223,8 @@ let corePlugins = {
1223
1223
  },
1224
1224
  animation: ({ matchUtilities , theme , config })=>{
1225
1225
  let prefixName = (name)=>`${config("prefix")}${(0, _escapeClassName.default)(name)}`;
1226
- var ref;
1227
- let keyframes = Object.fromEntries(Object.entries((ref = theme("keyframes")) !== null && ref !== void 0 ? ref : {}).map(([key, value])=>{
1226
+ var _theme;
1227
+ let keyframes = Object.fromEntries(Object.entries((_theme = theme("keyframes")) !== null && _theme !== void 0 ? _theme : {}).map(([key, value])=>{
1228
1228
  return [
1229
1229
  key,
1230
1230
  {
@@ -2872,10 +2872,16 @@ let corePlugins = {
2872
2872
  },
2873
2873
  fontSize: ({ matchUtilities , theme })=>{
2874
2874
  matchUtilities({
2875
- text: (value)=>{
2875
+ text: (value, { modifier })=>{
2876
2876
  let [fontSize, options] = Array.isArray(value) ? value : [
2877
2877
  value
2878
2878
  ];
2879
+ if (modifier) {
2880
+ return {
2881
+ "font-size": fontSize,
2882
+ "line-height": modifier
2883
+ };
2884
+ }
2879
2885
  let { lineHeight , letterSpacing , fontWeight } = (0, _isPlainObject.default)(options) ? options : {
2880
2886
  lineHeight: options
2881
2887
  };
@@ -2894,6 +2900,7 @@ let corePlugins = {
2894
2900
  }
2895
2901
  }, {
2896
2902
  values: theme("fontSize"),
2903
+ modifiers: theme("lineHeight"),
2897
2904
  type: [
2898
2905
  "absolute-size",
2899
2906
  "relative-size",
@@ -3441,15 +3448,15 @@ let corePlugins = {
3441
3448
  },
3442
3449
  ringWidth: ({ matchUtilities , addDefaults , addUtilities , theme , config })=>{
3443
3450
  let ringColorDefault = (()=>{
3444
- var ref, ref1;
3451
+ var _theme, _theme1;
3445
3452
  if ((0, _featureFlags.flagEnabled)(config(), "respectDefaultRingColorOpacity")) {
3446
3453
  return theme("ringColor.DEFAULT");
3447
3454
  }
3448
3455
  let ringOpacityDefault = theme("ringOpacity.DEFAULT", "0.5");
3449
- if (!((ref = theme("ringColor")) === null || ref === void 0 ? void 0 : ref.DEFAULT)) {
3456
+ if (!((_theme = theme("ringColor")) === null || _theme === void 0 ? void 0 : _theme.DEFAULT)) {
3450
3457
  return `rgb(147 197 253 / ${ringOpacityDefault})`;
3451
3458
  }
3452
- return (0, _withAlphaVariable.withAlphaValue)((ref1 = theme("ringColor")) === null || ref1 === void 0 ? void 0 : ref1.DEFAULT, ringOpacityDefault, `rgb(147 197 253 / ${ringOpacityDefault})`);
3459
+ return (0, _withAlphaVariable.withAlphaValue)((_theme1 = theme("ringColor")) === null || _theme1 === void 0 ? void 0 : _theme1.DEFAULT, ringOpacityDefault, `rgb(147 197 253 / ${ringOpacityDefault})`);
3453
3460
  })();
3454
3461
  addDefaults("ring-width", {
3455
3462
  "--tw-ring-inset": " ",
@@ -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
  /*
@@ -38,14 +38,14 @@ let featureFlags = {
38
38
  };
39
39
  function flagEnabled(config, flag) {
40
40
  if (featureFlags.future.includes(flag)) {
41
- var ref;
42
- var ref1, ref2;
43
- return config.future === "all" || ((ref2 = (ref1 = config === null || config === void 0 ? void 0 : (ref = config.future) === null || ref === void 0 ? void 0 : ref[flag]) !== null && ref1 !== void 0 ? ref1 : defaults[flag]) !== null && ref2 !== void 0 ? ref2 : false);
41
+ var _config_future;
42
+ var _config_future_flag, _ref;
43
+ return config.future === "all" || ((_ref = (_config_future_flag = config === null || config === void 0 ? void 0 : (_config_future = config.future) === null || _config_future === void 0 ? void 0 : _config_future[flag]) !== null && _config_future_flag !== void 0 ? _config_future_flag : defaults[flag]) !== null && _ref !== void 0 ? _ref : false);
44
44
  }
45
45
  if (featureFlags.experimental.includes(flag)) {
46
- var ref3;
47
- var ref4, ref5;
48
- return config.experimental === "all" || ((ref5 = (ref4 = config === null || config === void 0 ? void 0 : (ref3 = config.experimental) === null || ref3 === void 0 ? void 0 : ref3[flag]) !== null && ref4 !== void 0 ? ref4 : defaults[flag]) !== null && ref5 !== void 0 ? ref5 : false);
46
+ var _config_experimental;
47
+ var _config_experimental_flag, _ref1;
48
+ return config.experimental === "all" || ((_ref1 = (_config_experimental_flag = config === null || config === void 0 ? void 0 : (_config_experimental = config.experimental) === null || _config_experimental === void 0 ? void 0 : _config_experimental[flag]) !== null && _config_experimental_flag !== void 0 ? _config_experimental_flag : defaults[flag]) !== null && _ref1 !== void 0 ? _ref1 : false);
49
49
  }
50
50
  return false;
51
51
  }
@@ -53,8 +53,8 @@ function experimentalFlagsEnabled(config) {
53
53
  if (config.experimental === "all") {
54
54
  return featureFlags.experimental;
55
55
  }
56
- var ref;
57
- return Object.keys((ref = config === null || config === void 0 ? void 0 : config.experimental) !== null && ref !== void 0 ? ref : {}).filter((flag)=>featureFlags.experimental.includes(flag) && config.experimental[flag]);
56
+ var _config_experimental;
57
+ return Object.keys((_config_experimental = config === null || config === void 0 ? void 0 : config.experimental) !== null && _config_experimental !== void 0 ? _config_experimental : {}).filter((flag)=>featureFlags.experimental.includes(flag) && config.experimental[flag]);
58
58
  }
59
59
  function issueFlagNotices(config) {
60
60
  if (process.env.JEST_WORKER_ID !== undefined) {
package/lib/index.js CHANGED
@@ -21,10 +21,10 @@ module.exports = function tailwindcss(configOrPath) {
21
21
  return root;
22
22
  },
23
23
  function(root, result) {
24
- var ref;
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
27
- configOrPath = (ref = (0, _findAtConfigPath.findAtConfigPath)(root, result)) !== null && ref !== void 0 ? ref : configOrPath;
27
+ configOrPath = (_findAtConfigPath1 = (0, _findAtConfigPath.findAtConfigPath)(root, result)) !== null && _findAtConfigPath1 !== void 0 ? _findAtConfigPath1 : configOrPath;
28
28
  let context = (0, _setupTrackingContext.default)(configOrPath);
29
29
  if (root.type === "document") {
30
30
  let roots = root.nodes.filter((node)=>node.type === "root");
@@ -29,10 +29,10 @@ function collapseAdjacentRules() {
29
29
  return;
30
30
  }
31
31
  let properties = comparisonMap[node.type];
32
- var _property, _property1;
32
+ var _node_property, _currentRule_property;
33
33
  if (node.type === "atrule" && node.name === "font-face") {
34
34
  currentRule = node;
35
- } else if (properties.every((property)=>((_property = node[property]) !== null && _property !== void 0 ? _property : "").replace(/\s+/g, " ") === ((_property1 = currentRule[property]) !== null && _property1 !== void 0 ? _property1 : "").replace(/\s+/g, " "))) {
35
+ } else if (properties.every((property)=>((_node_property = node[property]) !== null && _node_property !== void 0 ? _node_property : "").replace(/\s+/g, " ") === ((_currentRule_property = currentRule[property]) !== null && _currentRule_property !== void 0 ? _currentRule_property : "").replace(/\s+/g, " "))) {
36
36
  // An AtRule may not have children (for example if we encounter duplicate @import url(…) rules)
37
37
  if (node.nodes) {
38
38
  currentRule.append(node.nodes);
@@ -76,8 +76,8 @@ let UNITLESS_NUMBER = Symbol("unitless-number");
76
76
  function resolveUnit(input) {
77
77
  let result = /^-?\d*.?\d+([\w%]+)?$/g.exec(input);
78
78
  if (result) {
79
- var ref;
80
- return (ref = result[1]) !== null && ref !== void 0 ? ref : UNITLESS_NUMBER;
79
+ var _result_;
80
+ return (_result_ = result[1]) !== null && _result_ !== void 0 ? _result_ : UNITLESS_NUMBER;
81
81
  }
82
82
  return null;
83
83
  }