tailwindcss 3.4.6 → 3.4.8
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 +17 -1
- package/README.md +3 -3
- package/lib/cli/build/plugin.js +3 -1
- package/lib/corePlugins.js +6 -6
- package/lib/lib/content.js +56 -0
- package/lib/lib/defaultExtractor.js +2 -0
- package/lib/util/dataTypes.js +22 -0
- package/package.json +2 -2
- package/peers/index.js +3896 -2545
- package/src/cli/build/plugin.js +6 -2
- package/src/corePlugins.js +15 -11
- package/src/lib/content.js +74 -0
- package/src/lib/defaultExtractor.js +3 -0
- package/src/util/dataTypes.js +28 -0
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
- Nothing yet!
|
|
11
11
|
|
|
12
|
+
## [3.4.8] - 2024-08-07
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- Fix minification when using nested CSS ([#14105](https://github.com/tailwindlabs/tailwindcss/pull/14105))
|
|
17
|
+
- Warn when broad glob patterns are used in the content configuration ([#14140](https://github.com/tailwindlabs/tailwindcss/pull/14140))
|
|
18
|
+
|
|
19
|
+
## [3.4.7] - 2024-07-25
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Fix class detection in Slim templates with attached attributes and ID ([#14019](https://github.com/tailwindlabs/tailwindcss/pull/14019))
|
|
24
|
+
- Ensure attribute values in `data-*` and `aria-*` modifiers are always quoted in the generated CSS ([#14037](https://github.com/tailwindlabs/tailwindcss/pull/14037))
|
|
25
|
+
|
|
12
26
|
## [3.4.6] - 2024-07-16
|
|
13
27
|
|
|
14
28
|
### Fixed
|
|
@@ -2405,7 +2419,9 @@ No release notes
|
|
|
2405
2419
|
|
|
2406
2420
|
- Everything!
|
|
2407
2421
|
|
|
2408
|
-
[unreleased]: https://github.com/tailwindlabs/tailwindcss/compare/v3.4.
|
|
2422
|
+
[unreleased]: https://github.com/tailwindlabs/tailwindcss/compare/v3.4.8...HEAD
|
|
2423
|
+
[3.4.8]: https://github.com/tailwindlabs/tailwindcss/compare/v3.4.7...v3.4.8
|
|
2424
|
+
[3.4.7]: https://github.com/tailwindlabs/tailwindcss/compare/v3.4.6...v3.4.7
|
|
2409
2425
|
[3.4.6]: https://github.com/tailwindlabs/tailwindcss/compare/v3.4.5...v3.4.6
|
|
2410
2426
|
[3.4.5]: https://github.com/tailwindlabs/tailwindcss/compare/v3.4.4...v3.4.5
|
|
2411
2427
|
[3.4.4]: https://github.com/tailwindlabs/tailwindcss/compare/v3.4.3...v3.4.4
|
package/README.md
CHANGED
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
</p>
|
|
14
14
|
|
|
15
15
|
<p align="center">
|
|
16
|
-
<a href="https://github.com/tailwindlabs/tailwindcss/actions"><img src="https://img.shields.io/github/actions/workflow/status/tailwindlabs/tailwindcss/ci.yml?branch=
|
|
16
|
+
<a href="https://github.com/tailwindlabs/tailwindcss/actions"><img src="https://img.shields.io/github/actions/workflow/status/tailwindlabs/tailwindcss/ci.yml?branch=main" alt="Build Status"></a>
|
|
17
17
|
<a href="https://www.npmjs.com/package/tailwindcss"><img src="https://img.shields.io/npm/dt/tailwindcss.svg" alt="Total Downloads"></a>
|
|
18
18
|
<a href="https://github.com/tailwindcss/tailwindcss/releases"><img src="https://img.shields.io/npm/v/tailwindcss.svg" alt="Latest Release"></a>
|
|
19
|
-
<a href="https://github.com/tailwindcss/tailwindcss/blob/
|
|
19
|
+
<a href="https://github.com/tailwindcss/tailwindcss/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/tailwindcss.svg" alt="License"></a>
|
|
20
20
|
</p>
|
|
21
21
|
|
|
22
22
|
---
|
|
@@ -37,4 +37,4 @@ For casual chit-chat with others using the framework:
|
|
|
37
37
|
|
|
38
38
|
## Contributing
|
|
39
39
|
|
|
40
|
-
If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindcss/tailwindcss/blob/
|
|
40
|
+
If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindcss/tailwindcss/blob/main/.github/CONTRIBUTING.md) **before submitting a pull request**.
|
package/lib/cli/build/plugin.js
CHANGED
|
@@ -166,7 +166,9 @@ let state = {
|
|
|
166
166
|
// Resolve globs from the content config
|
|
167
167
|
// TODO: When we make the postcss plugin async-capable this can become async
|
|
168
168
|
let files = _fastglob.default.sync(this.contentPatterns.all);
|
|
169
|
+
let checkBroadPattern = (0, _content.createBroadPatternCheck)(this.contentPatterns.all);
|
|
169
170
|
for (let file of files){
|
|
171
|
+
checkBroadPattern(file);
|
|
170
172
|
content.push({
|
|
171
173
|
content: _fs.default.readFileSync(_path.default.resolve(file), "utf8"),
|
|
172
174
|
extension: _path.default.extname(file).slice(1)
|
|
@@ -277,7 +279,7 @@ async function createProcessor(args, cliConfigPath) {
|
|
|
277
279
|
if (input) {
|
|
278
280
|
return _fs.default.promises.readFile(_path.default.resolve(input), "utf8");
|
|
279
281
|
}
|
|
280
|
-
// No input file provided, fallback to default
|
|
282
|
+
// No input file provided, fallback to default at-rules
|
|
281
283
|
return "@tailwind base; @tailwind components; @tailwind utilities";
|
|
282
284
|
}
|
|
283
285
|
async function build() {
|
package/lib/corePlugins.js
CHANGED
|
@@ -482,29 +482,29 @@ let variantPlugins = {
|
|
|
482
482
|
},
|
|
483
483
|
ariaVariants: ({ matchVariant , theme })=>{
|
|
484
484
|
var _theme;
|
|
485
|
-
matchVariant("aria", (value)=>`&[aria-${(0, _dataTypes.normalize)(value)}]`, {
|
|
485
|
+
matchVariant("aria", (value)=>`&[aria-${(0, _dataTypes.normalizeAttributeSelectors)((0, _dataTypes.normalize)(value))}]`, {
|
|
486
486
|
values: (_theme = theme("aria")) !== null && _theme !== void 0 ? _theme : {}
|
|
487
487
|
});
|
|
488
488
|
var _theme1;
|
|
489
|
-
matchVariant("group-aria", (value, { modifier })=>modifier ? `:merge(.group\\/${modifier})[aria-${(0, _dataTypes.normalize)(value)}] &` : `:merge(.group)[aria-${(0, _dataTypes.normalize)(value)}] &`, {
|
|
489
|
+
matchVariant("group-aria", (value, { modifier })=>modifier ? `:merge(.group\\/${modifier})[aria-${(0, _dataTypes.normalizeAttributeSelectors)((0, _dataTypes.normalize)(value))}] &` : `:merge(.group)[aria-${(0, _dataTypes.normalizeAttributeSelectors)((0, _dataTypes.normalize)(value))}] &`, {
|
|
490
490
|
values: (_theme1 = theme("aria")) !== null && _theme1 !== void 0 ? _theme1 : {}
|
|
491
491
|
});
|
|
492
492
|
var _theme2;
|
|
493
|
-
matchVariant("peer-aria", (value, { modifier })=>modifier ? `:merge(.peer\\/${modifier})[aria-${(0, _dataTypes.normalize)(value)}] ~ &` : `:merge(.peer)[aria-${(0, _dataTypes.normalize)(value)}] ~ &`, {
|
|
493
|
+
matchVariant("peer-aria", (value, { modifier })=>modifier ? `:merge(.peer\\/${modifier})[aria-${(0, _dataTypes.normalizeAttributeSelectors)((0, _dataTypes.normalize)(value))}] ~ &` : `:merge(.peer)[aria-${(0, _dataTypes.normalizeAttributeSelectors)((0, _dataTypes.normalize)(value))}] ~ &`, {
|
|
494
494
|
values: (_theme2 = theme("aria")) !== null && _theme2 !== void 0 ? _theme2 : {}
|
|
495
495
|
});
|
|
496
496
|
},
|
|
497
497
|
dataVariants: ({ matchVariant , theme })=>{
|
|
498
498
|
var _theme;
|
|
499
|
-
matchVariant("data", (value)=>`&[data-${(0, _dataTypes.normalize)(value)}]`, {
|
|
499
|
+
matchVariant("data", (value)=>`&[data-${(0, _dataTypes.normalizeAttributeSelectors)((0, _dataTypes.normalize)(value))}]`, {
|
|
500
500
|
values: (_theme = theme("data")) !== null && _theme !== void 0 ? _theme : {}
|
|
501
501
|
});
|
|
502
502
|
var _theme1;
|
|
503
|
-
matchVariant("group-data", (value, { modifier })=>modifier ? `:merge(.group\\/${modifier})[data-${(0, _dataTypes.normalize)(value)}] &` : `:merge(.group)[data-${(0, _dataTypes.normalize)(value)}] &`, {
|
|
503
|
+
matchVariant("group-data", (value, { modifier })=>modifier ? `:merge(.group\\/${modifier})[data-${(0, _dataTypes.normalizeAttributeSelectors)((0, _dataTypes.normalize)(value))}] &` : `:merge(.group)[data-${(0, _dataTypes.normalizeAttributeSelectors)((0, _dataTypes.normalize)(value))}] &`, {
|
|
504
504
|
values: (_theme1 = theme("data")) !== null && _theme1 !== void 0 ? _theme1 : {}
|
|
505
505
|
});
|
|
506
506
|
var _theme2;
|
|
507
|
-
matchVariant("peer-data", (value, { modifier })=>modifier ? `:merge(.peer\\/${modifier})[data-${(0, _dataTypes.normalize)(value)}] ~ &` : `:merge(.peer)[data-${(0, _dataTypes.normalize)(value)}] ~ &`, {
|
|
507
|
+
matchVariant("peer-data", (value, { modifier })=>modifier ? `:merge(.peer\\/${modifier})[data-${(0, _dataTypes.normalizeAttributeSelectors)((0, _dataTypes.normalize)(value))}] ~ &` : `:merge(.peer)[data-${(0, _dataTypes.normalizeAttributeSelectors)((0, _dataTypes.normalize)(value))}] ~ &`, {
|
|
508
508
|
values: (_theme2 = theme("data")) !== null && _theme2 !== void 0 ? _theme2 : {}
|
|
509
509
|
});
|
|
510
510
|
},
|
package/lib/lib/content.js
CHANGED
|
@@ -15,6 +15,9 @@ _export(exports, {
|
|
|
15
15
|
},
|
|
16
16
|
resolvedChangedContent: function() {
|
|
17
17
|
return resolvedChangedContent;
|
|
18
|
+
},
|
|
19
|
+
createBroadPatternCheck: function() {
|
|
20
|
+
return createBroadPatternCheck;
|
|
18
21
|
}
|
|
19
22
|
});
|
|
20
23
|
const _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
|
|
@@ -24,6 +27,8 @@ const _fastglob = /*#__PURE__*/ _interop_require_default(require("fast-glob"));
|
|
|
24
27
|
const _normalizepath = /*#__PURE__*/ _interop_require_default(require("normalize-path"));
|
|
25
28
|
const _parseGlob = require("../util/parseGlob");
|
|
26
29
|
const _sharedState = require("./sharedState");
|
|
30
|
+
const _log = /*#__PURE__*/ _interop_require_default(require("../util/log"));
|
|
31
|
+
const _micromatch = /*#__PURE__*/ _interop_require_default(require("micromatch"));
|
|
27
32
|
function _interop_require_default(obj) {
|
|
28
33
|
return obj && obj.__esModule ? obj : {
|
|
29
34
|
default: obj
|
|
@@ -152,6 +157,55 @@ function resolvedChangedContent(context, candidateFiles, fileModifiedMap) {
|
|
|
152
157
|
mTimesToCommit
|
|
153
158
|
];
|
|
154
159
|
}
|
|
160
|
+
const LARGE_DIRECTORIES = [
|
|
161
|
+
"node_modules",
|
|
162
|
+
"vendor"
|
|
163
|
+
];
|
|
164
|
+
// Ensures that `node_modules` has to match as-is, otherwise `mynode_modules`
|
|
165
|
+
// would match as well, but that is not a known large directory.
|
|
166
|
+
const LARGE_DIRECTORIES_REGEX = new RegExp(`(${LARGE_DIRECTORIES.map((dir)=>String.raw`\b${dir}\b`).join("|")})`);
|
|
167
|
+
function createBroadPatternCheck(paths) {
|
|
168
|
+
// Detect whether a glob pattern might be too broad. This means that it:
|
|
169
|
+
// - Includes `**`
|
|
170
|
+
// - Does not include any of the known large directories (e.g.: node_modules)
|
|
171
|
+
let maybeBroadPattern = paths.some((path)=>path.includes("**") && !LARGE_DIRECTORIES_REGEX.test(path));
|
|
172
|
+
// Didn't detect any potentially broad patterns, so we can skip further
|
|
173
|
+
// checks.
|
|
174
|
+
if (!maybeBroadPattern) {
|
|
175
|
+
return ()=>{};
|
|
176
|
+
}
|
|
177
|
+
// All globs that explicitly contain any of the known large directories (e.g.:
|
|
178
|
+
// node_modules).
|
|
179
|
+
let explicitGlobs = paths.filter((path)=>LARGE_DIRECTORIES_REGEX.test(path));
|
|
180
|
+
// Keep track of whether we already warned about the broad pattern issue or
|
|
181
|
+
// not. The `log.warn` function already does something similar where we only
|
|
182
|
+
// output the log once. However, with this we can also skip the other checks
|
|
183
|
+
// when we already warned about the broad pattern.
|
|
184
|
+
let warned = false;
|
|
185
|
+
/**
|
|
186
|
+
* @param {string} file
|
|
187
|
+
*/ return (file)=>{
|
|
188
|
+
if (warned) return; // Already warned about the broad pattern
|
|
189
|
+
if (_micromatch.default.isMatch(file, explicitGlobs)) return; // Explicitly included, so we can skip further checks
|
|
190
|
+
// When a broad pattern is used, we have to double check that the file was
|
|
191
|
+
// not explicitly included in the globs.
|
|
192
|
+
let matchingGlob = paths.find((path)=>_micromatch.default.isMatch(file, path));
|
|
193
|
+
if (!matchingGlob) return; // This should never happen
|
|
194
|
+
// Create relative paths to make the output a bit more readable.
|
|
195
|
+
let relativeMatchingGlob = _path.default.relative(process.cwd(), matchingGlob);
|
|
196
|
+
if (relativeMatchingGlob[0] !== ".") relativeMatchingGlob = `./${relativeMatchingGlob}`;
|
|
197
|
+
let largeDirectory = LARGE_DIRECTORIES.find((directory)=>file.includes(directory));
|
|
198
|
+
if (largeDirectory) {
|
|
199
|
+
warned = true;
|
|
200
|
+
_log.default.warn("broad-content-glob-pattern", [
|
|
201
|
+
`Your \`content\` configuration includes a pattern which looks like it's accidentally matching all of \`${largeDirectory}\` and can cause serious performance issues.`,
|
|
202
|
+
`Pattern: \`${relativeMatchingGlob}\``,
|
|
203
|
+
`See our documentation for recommendations:`,
|
|
204
|
+
"https://tailwindcss.com/docs/content-configuration#pattern-recommendations"
|
|
205
|
+
]);
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
}
|
|
155
209
|
/**
|
|
156
210
|
*
|
|
157
211
|
* @param {ContentPath[]} candidateFiles
|
|
@@ -160,12 +214,14 @@ function resolvedChangedContent(context, candidateFiles, fileModifiedMap) {
|
|
|
160
214
|
*/ function resolveChangedFiles(candidateFiles, fileModifiedMap) {
|
|
161
215
|
let paths = candidateFiles.map((contentPath)=>contentPath.pattern);
|
|
162
216
|
let mTimesToCommit = new Map();
|
|
217
|
+
let checkBroadPattern = createBroadPatternCheck(paths);
|
|
163
218
|
let changedFiles = new Set();
|
|
164
219
|
_sharedState.env.DEBUG && console.time("Finding changed files");
|
|
165
220
|
let files = _fastglob.default.sync(paths, {
|
|
166
221
|
absolute: true
|
|
167
222
|
});
|
|
168
223
|
for (let file of files){
|
|
224
|
+
checkBroadPattern(file);
|
|
169
225
|
let prevModified = fileModifiedMap.get(file) || -Infinity;
|
|
170
226
|
let modified = _fs.default.statSync(file).mtimeMs;
|
|
171
227
|
if (modified > prevModified) {
|
|
@@ -191,6 +191,8 @@ function* buildRegExps(context) {
|
|
|
191
191
|
utility
|
|
192
192
|
]);
|
|
193
193
|
}
|
|
194
|
+
// 5. Inner matches
|
|
195
|
+
yield /[^<>"'`\s.(){}[\]#=%$][^<>"'`\s(){}[\]#=%$]*[^<>"'`\s.(){}[\]#=%:$]/g;
|
|
194
196
|
}
|
|
195
197
|
// We want to capture any "special" characters
|
|
196
198
|
// AND the characters immediately following them (if there is one)
|
package/lib/util/dataTypes.js
CHANGED
|
@@ -12,6 +12,9 @@ _export(exports, {
|
|
|
12
12
|
normalize: function() {
|
|
13
13
|
return normalize;
|
|
14
14
|
},
|
|
15
|
+
normalizeAttributeSelectors: function() {
|
|
16
|
+
return normalizeAttributeSelectors;
|
|
17
|
+
},
|
|
15
18
|
url: function() {
|
|
16
19
|
return url;
|
|
17
20
|
},
|
|
@@ -118,6 +121,25 @@ function normalize(value, context = null, isRoot = true) {
|
|
|
118
121
|
value = normalizeMathOperatorSpacing(value);
|
|
119
122
|
return value;
|
|
120
123
|
}
|
|
124
|
+
function normalizeAttributeSelectors(value) {
|
|
125
|
+
// Wrap values in attribute selectors with quotes
|
|
126
|
+
if (value.includes("=")) {
|
|
127
|
+
value = value.replace(/(=.*)/g, (_fullMatch, match)=>{
|
|
128
|
+
if (match[1] === "'" || match[1] === '"') {
|
|
129
|
+
return match;
|
|
130
|
+
}
|
|
131
|
+
// Handle regex flags on unescaped values
|
|
132
|
+
if (match.length > 2) {
|
|
133
|
+
let trailingCharacter = match[match.length - 1];
|
|
134
|
+
if (match[match.length - 2] === " " && (trailingCharacter === "i" || trailingCharacter === "I" || trailingCharacter === "s" || trailingCharacter === "S")) {
|
|
135
|
+
return `="${match.slice(1, -2)}" ${match[match.length - 1]}`;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return `="${match.slice(1)}"`;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
return value;
|
|
142
|
+
}
|
|
121
143
|
/**
|
|
122
144
|
* Add spaces around operators inside math functions
|
|
123
145
|
* like calc() that do not follow an operator, '(', or `,`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tailwindcss",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.8",
|
|
4
4
|
"description": "A utility-first CSS framework for rapidly building custom user interfaces.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"autoprefixer": "^10.4.14",
|
|
51
51
|
"browserslist": "^4.21.5",
|
|
52
52
|
"concurrently": "^8.0.1",
|
|
53
|
-
"cssnano": "^6.
|
|
53
|
+
"cssnano": "^6.1.2",
|
|
54
54
|
"esbuild": "^0.20.2",
|
|
55
55
|
"eslint": "^8.39.0",
|
|
56
56
|
"eslint-config-prettier": "^8.8.0",
|