tailwindcss 3.4.17 → 3.4.19

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.
@@ -52,10 +52,13 @@ function _interop_require_default(obj) {
52
52
  if (!config.plugins) {
53
53
  config.plugins = [];
54
54
  }
55
+ // We have to await these because in v5 and v6 of postcss-load-config
56
+ // these functions return promises while they don't in v4. Awaiting a
57
+ // non-promise is basically a no-op so this is safe to do.
55
58
  return {
56
59
  file,
57
- plugins: (0, _plugins.default)(config, file),
58
- options: (0, _options.default)(config, file)
60
+ plugins: await (0, _plugins.default)(config, file),
61
+ options: await (0, _options.default)(config, file)
59
62
  };
60
63
  })() : await (0, _postcssloadconfig.default)();
61
64
  let configPlugins = config.plugins;
@@ -441,8 +441,8 @@ let variantPlugins = {
441
441
  supportsVariants: ({ matchVariant , theme })=>{
442
442
  var _theme;
443
443
  matchVariant("supports", (value = "")=>{
444
- let check = (0, _dataTypes.normalize)(value);
445
- let isRaw = /^\w*\s*\(/.test(check);
444
+ let check = value.startsWith("--") ? value : (0, _dataTypes.normalize)(value);
445
+ let isRaw = /^[\w-]*\s*\(/.test(check);
446
446
  // Chrome has a bug where `(condition1)or(condition2)` is not valid
447
447
  // But `(condition1) or (condition2)` is supported.
448
448
  check = isRaw ? check.replace(/\b(and|or|not)\b/g, " $1 ") : check;
@@ -182,7 +182,12 @@ function applyImportant(matches, classCandidate) {
182
182
  ast.each((sel)=>(0, _formatVariantSelector.eliminateIrrelevantSelectors)(sel, classCandidate));
183
183
  // Update all instances of the base candidate to include the important marker
184
184
  (0, _pluginUtils.updateAllClasses)(ast, (className)=>className === classCandidate ? `!${className}` : className);
185
- r.selector = ast.toString();
185
+ let newSelector = ast.toString();
186
+ if (newSelector.trim() === "") {
187
+ r.remove();
188
+ return;
189
+ }
190
+ r.selector = newSelector;
186
191
  r.walkDecls((d)=>d.important = true);
187
192
  });
188
193
  result.push([
@@ -47,15 +47,8 @@ function lazyJiti() {
47
47
  function loadConfig(path) {
48
48
  let config = function() {
49
49
  if (!path) return {};
50
- // Always use jiti for now. There is a a bug that occurs in Node v22.12+
51
- // where imported files return invalid results
52
- return lazyJiti()(path);
53
- // Always use jiti for ESM or TS files
54
- if (path && (path.endsWith(".mjs") || path.endsWith(".ts") || path.endsWith(".cts") || path.endsWith(".mts"))) {
55
- return lazyJiti()(path);
56
- }
57
50
  try {
58
- return path ? require(path) : {};
51
+ return require(path);
59
52
  } catch {
60
53
  return lazyJiti()(path);
61
54
  }
@@ -66,6 +66,9 @@ function getTailwindConfig(configOrPath) {
66
66
  }
67
67
  // It has changed (based on timestamps), or first run
68
68
  for (let file of newDeps){
69
+ // When loaded transitively through a TypeScript file `require.cache`
70
+ // may be undefined. Happens in Node 22.18+.
71
+ if (!require.cache) continue;
69
72
  delete require.cache[file];
70
73
  }
71
74
  let newConfig = (0, _validateConfig.validateConfig)((0, _resolveconfig.default)((0, _loadconfig.loadConfig)(userConfigPath)));
@@ -59,6 +59,7 @@ _export(exports, {
59
59
  }
60
60
  });
61
61
  const _color = require("./color");
62
+ const _mathoperators = require("./math-operators");
62
63
  const _parseBoxShadowValue = require("./parseBoxShadowValue");
63
64
  const _splitAtTopLevelOnly = require("./splitAtTopLevelOnly");
64
65
  let cssFunctions = [
@@ -118,7 +119,7 @@ function normalize(value, context = null, isRoot = true) {
118
119
  if (isRoot) {
119
120
  value = value.trim();
120
121
  }
121
- value = normalizeMathOperatorSpacing(value);
122
+ value = (0, _mathoperators.addWhitespaceAroundMathOperators)(value);
122
123
  return value;
123
124
  }
124
125
  function normalizeAttributeSelectors(value) {
@@ -140,113 +141,6 @@ function normalizeAttributeSelectors(value) {
140
141
  }
141
142
  return value;
142
143
  }
143
- /**
144
- * Add spaces around operators inside math functions
145
- * like calc() that do not follow an operator, '(', or `,`.
146
- *
147
- * @param {string} value
148
- * @returns {string}
149
- */ function normalizeMathOperatorSpacing(value) {
150
- let preventFormattingInFunctions = [
151
- "theme"
152
- ];
153
- let preventFormattingKeywords = [
154
- "min-content",
155
- "max-content",
156
- "fit-content",
157
- // Env
158
- "safe-area-inset-top",
159
- "safe-area-inset-right",
160
- "safe-area-inset-bottom",
161
- "safe-area-inset-left",
162
- "titlebar-area-x",
163
- "titlebar-area-y",
164
- "titlebar-area-width",
165
- "titlebar-area-height",
166
- "keyboard-inset-top",
167
- "keyboard-inset-right",
168
- "keyboard-inset-bottom",
169
- "keyboard-inset-left",
170
- "keyboard-inset-width",
171
- "keyboard-inset-height",
172
- "radial-gradient",
173
- "linear-gradient",
174
- "conic-gradient",
175
- "repeating-radial-gradient",
176
- "repeating-linear-gradient",
177
- "repeating-conic-gradient",
178
- "anchor-size"
179
- ];
180
- return value.replace(/(calc|min|max|clamp)\(.+\)/g, (match)=>{
181
- let result = "";
182
- function lastChar() {
183
- let char = result.trimEnd();
184
- return char[char.length - 1];
185
- }
186
- for(let i = 0; i < match.length; i++){
187
- function peek(word) {
188
- return word.split("").every((char, j)=>match[i + j] === char);
189
- }
190
- function consumeUntil(chars) {
191
- let minIndex = Infinity;
192
- for (let char of chars){
193
- let index = match.indexOf(char, i);
194
- if (index !== -1 && index < minIndex) {
195
- minIndex = index;
196
- }
197
- }
198
- let result = match.slice(i, minIndex);
199
- i += result.length - 1;
200
- return result;
201
- }
202
- let char = match[i];
203
- // Handle `var(--variable)`
204
- if (peek("var")) {
205
- // When we consume until `)`, then we are dealing with this scenario:
206
- // `var(--example)`
207
- //
208
- // When we consume until `,`, then we are dealing with this scenario:
209
- // `var(--example, 1rem)`
210
- //
211
- // In this case we do want to "format", the default value as well
212
- result += consumeUntil([
213
- ")",
214
- ","
215
- ]);
216
- } else if (preventFormattingKeywords.some((keyword)=>peek(keyword))) {
217
- let keyword = preventFormattingKeywords.find((keyword)=>peek(keyword));
218
- result += keyword;
219
- i += keyword.length - 1;
220
- } else if (preventFormattingInFunctions.some((fn)=>peek(fn))) {
221
- result += consumeUntil([
222
- ")"
223
- ]);
224
- } else if (peek("[")) {
225
- result += consumeUntil([
226
- "]"
227
- ]);
228
- } else if ([
229
- "+",
230
- "-",
231
- "*",
232
- "/"
233
- ].includes(char) && ![
234
- "(",
235
- "+",
236
- "-",
237
- "*",
238
- "/",
239
- ","
240
- ].includes(lastChar())) {
241
- result += ` ${char} `;
242
- } else {
243
- result += char;
244
- }
245
- }
246
- // Simplify multiple spaces
247
- return result.replace(/\s+/g, " ");
248
- });
249
- }
250
144
  function url(value) {
251
145
  return value.startsWith("url(");
252
146
  }
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
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
+ hasMathFn: function() {
13
+ return hasMathFn;
14
+ },
15
+ addWhitespaceAroundMathOperators: function() {
16
+ return addWhitespaceAroundMathOperators;
17
+ }
18
+ });
19
+ const LOWER_A = 0x61;
20
+ const LOWER_Z = 0x7a;
21
+ const UPPER_A = 0x41;
22
+ const UPPER_Z = 0x5a;
23
+ const LOWER_E = 0x65;
24
+ const UPPER_E = 0x45;
25
+ const ZERO = 0x30;
26
+ const NINE = 0x39;
27
+ const ADD = 0x2b;
28
+ const SUB = 0x2d;
29
+ const MUL = 0x2a;
30
+ const DIV = 0x2f;
31
+ const OPEN_PAREN = 0x28;
32
+ const CLOSE_PAREN = 0x29;
33
+ const COMMA = 0x2c;
34
+ const SPACE = 0x20;
35
+ const PERCENT = 0x25;
36
+ const MATH_FUNCTIONS = [
37
+ "calc",
38
+ "min",
39
+ "max",
40
+ "clamp",
41
+ "mod",
42
+ "rem",
43
+ "sin",
44
+ "cos",
45
+ "tan",
46
+ "asin",
47
+ "acos",
48
+ "atan",
49
+ "atan2",
50
+ "pow",
51
+ "sqrt",
52
+ "hypot",
53
+ "log",
54
+ "exp",
55
+ "round"
56
+ ];
57
+ function hasMathFn(input) {
58
+ return input.indexOf("(") !== -1 && MATH_FUNCTIONS.some((fn)=>input.includes(`${fn}(`));
59
+ }
60
+ function addWhitespaceAroundMathOperators(input) {
61
+ // Bail early if there are no math functions in the input
62
+ if (!MATH_FUNCTIONS.some((fn)=>input.includes(fn))) {
63
+ return input;
64
+ }
65
+ let result = "";
66
+ let formattable = [];
67
+ let valuePos = null;
68
+ let lastValuePos = null;
69
+ for(let i = 0; i < input.length; i++){
70
+ let char = input.charCodeAt(i);
71
+ // Track if we see a number followed by a unit, then we know for sure that
72
+ // this is not a function call.
73
+ if (char >= ZERO && char <= NINE) {
74
+ valuePos = i;
75
+ } else if (valuePos !== null && (char === PERCENT || char >= LOWER_A && char <= LOWER_Z || char >= UPPER_A && char <= UPPER_Z)) {
76
+ valuePos = i;
77
+ } else {
78
+ lastValuePos = valuePos;
79
+ valuePos = null;
80
+ }
81
+ // Determine if we're inside a math function
82
+ if (char === OPEN_PAREN) {
83
+ result += input[i];
84
+ // Scan backwards to determine the function name. This assumes math
85
+ // functions are named with lowercase alphanumeric characters.
86
+ let start = i;
87
+ for(let j = i - 1; j >= 0; j--){
88
+ let inner = input.charCodeAt(j);
89
+ if (inner >= ZERO && inner <= NINE) {
90
+ start = j // 0-9
91
+ ;
92
+ } else if (inner >= LOWER_A && inner <= LOWER_Z) {
93
+ start = j // a-z
94
+ ;
95
+ } else {
96
+ break;
97
+ }
98
+ }
99
+ let fn = input.slice(start, i);
100
+ // This is a known math function so start formatting
101
+ if (MATH_FUNCTIONS.includes(fn)) {
102
+ formattable.unshift(true);
103
+ continue;
104
+ } else if (formattable[0] && fn === "") {
105
+ formattable.unshift(true);
106
+ continue;
107
+ }
108
+ // This is not a known math function so don't format it
109
+ formattable.unshift(false);
110
+ continue;
111
+ } else if (char === CLOSE_PAREN) {
112
+ result += input[i];
113
+ formattable.shift();
114
+ } else if (char === COMMA && formattable[0]) {
115
+ result += `, `;
116
+ continue;
117
+ } else if (char === SPACE && formattable[0] && result.charCodeAt(result.length - 1) === SPACE) {
118
+ continue;
119
+ } else if ((char === ADD || char === MUL || char === DIV || char === SUB) && formattable[0]) {
120
+ let trimmed = result.trimEnd();
121
+ let prev = trimmed.charCodeAt(trimmed.length - 1);
122
+ let prevPrev = trimmed.charCodeAt(trimmed.length - 2);
123
+ let next = input.charCodeAt(i + 1);
124
+ // Do not add spaces for scientific notation, e.g.: `-3.4e-2`
125
+ if ((prev === LOWER_E || prev === UPPER_E) && prevPrev >= ZERO && prevPrev <= NINE) {
126
+ result += input[i];
127
+ continue;
128
+ } else if (prev === ADD || prev === MUL || prev === DIV || prev === SUB) {
129
+ result += input[i];
130
+ continue;
131
+ } else if (prev === OPEN_PAREN || prev === COMMA) {
132
+ result += input[i];
133
+ continue;
134
+ } else if (input.charCodeAt(i - 1) === SPACE) {
135
+ result += `${input[i]} `;
136
+ } else if (// Previous is a digit
137
+ prev >= ZERO && prev <= NINE || // Next is a digit
138
+ next >= ZERO && next <= NINE || // Previous is end of a function call (or parenthesized expression)
139
+ prev === CLOSE_PAREN || // Next is start of a parenthesized expression
140
+ next === OPEN_PAREN || // Next is an operator
141
+ next === ADD || next === MUL || next === DIV || next === SUB || // Previous position was a value (+ unit)
142
+ lastValuePos !== null && lastValuePos === i - 1) {
143
+ result += ` ${input[i]} `;
144
+ } else {
145
+ result += input[i];
146
+ }
147
+ } else {
148
+ result += input[i];
149
+ }
150
+ }
151
+ return result;
152
+ }
package/package.json CHANGED
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "tailwindcss",
3
- "version": "3.4.17",
3
+ "version": "3.4.19",
4
4
  "description": "A utility-first CSS framework for rapidly building custom user interfaces.",
5
5
  "license": "MIT",
6
6
  "main": "lib/index.js",
7
7
  "types": "types/index.d.ts",
8
- "repository": "https://github.com/tailwindlabs/tailwindcss.git",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/tailwindlabs/tailwindcss.git#v3"
11
+ },
9
12
  "bugs": "https://github.com/tailwindlabs/tailwindcss/issues",
10
13
  "homepage": "https://tailwindcss.com",
11
14
  "bin": {
@@ -29,6 +32,9 @@
29
32
  "release-notes": "node ./scripts/release-notes.js",
30
33
  "prepublishOnly": "npm install --force && npm run build"
31
34
  },
35
+ "publishConfig": {
36
+ "provenance": true
37
+ },
32
38
  "files": [
33
39
  "src/*",
34
40
  "cli/*",
@@ -72,7 +78,7 @@
72
78
  "fast-glob": "^3.3.2",
73
79
  "glob-parent": "^6.0.2",
74
80
  "is-glob": "^4.0.3",
75
- "jiti": "^1.21.6",
81
+ "jiti": "^1.21.7",
76
82
  "lilconfig": "^3.1.3",
77
83
  "micromatch": "^4.0.8",
78
84
  "normalize-path": "^3.0.0",
@@ -81,7 +87,7 @@
81
87
  "postcss": "^8.4.47",
82
88
  "postcss-import": "^15.1.0",
83
89
  "postcss-js": "^4.0.1",
84
- "postcss-load-config": "^4.0.2",
90
+ "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0",
85
91
  "postcss-nested": "^6.2.0",
86
92
  "postcss-selector-parser": "^6.1.2",
87
93
  "resolve": "^1.22.8",