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.
- package/lib/cli/build/plugin.js +5 -2
- package/lib/corePlugins.js +2 -2
- package/lib/lib/generateRules.js +6 -1
- package/lib/lib/load-config.js +1 -8
- package/lib/lib/setupTrackingContext.js +3 -0
- package/lib/util/dataTypes.js +2 -108
- package/lib/util/math-operators.js +152 -0
- package/package.json +10 -4
- package/peers/index.js +166 -287
- package/src/cli/build/plugin.js +5 -2
- package/src/corePlugins.js +2 -2
- package/src/lib/generateRules.js +8 -1
- package/src/lib/load-config.ts +1 -16
- package/src/lib/setupTrackingContext.js +3 -0
- package/src/util/dataTypes.js +2 -117
- package/src/util/math-operators.ts +205 -0
- package/CHANGELOG.md +0 -2713
package/lib/cli/build/plugin.js
CHANGED
|
@@ -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;
|
package/lib/corePlugins.js
CHANGED
|
@@ -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 =
|
|
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;
|
package/lib/lib/generateRules.js
CHANGED
|
@@ -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
|
-
|
|
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([
|
package/lib/lib/load-config.js
CHANGED
|
@@ -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
|
|
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)));
|
package/lib/util/dataTypes.js
CHANGED
|
@@ -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 =
|
|
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.
|
|
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":
|
|
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.
|
|
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",
|