tailwindcss 3.1.2 → 3.1.3
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 +15 -1
- package/lib/corePlugins.js +16 -16
- package/lib/lib/defaultExtractor.js +6 -3
- package/lib/lib/evaluateTailwindFunctions.js +4 -1
- package/lib/lib/generateRules.js +18 -10
- package/lib/lib/setupContextUtils.js +3 -2
- package/lib/util/dataTypes.js +2 -2
- package/lib/util/removeAlphaVariables.js +18 -0
- package/package.json +4 -4
- package/src/corePlugins.js +19 -16
- package/src/lib/defaultExtractor.js +3 -3
- package/src/lib/evaluateTailwindFunctions.js +5 -3
- package/src/lib/generateRules.js +18 -10
- package/src/lib/setupContextUtils.js +5 -2
- package/src/util/dataTypes.js +2 -2
- package/src/util/removeAlphaVariables.js +24 -0
- package/types/config.d.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
- Nothing yet!
|
|
11
11
|
|
|
12
|
+
## [3.1.3] - 2022-06-14
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- Fix extraction of multi-word utilities with arbitrary values and quotes ([#8604](https://github.com/tailwindlabs/tailwindcss/pull/8604))
|
|
17
|
+
- Fix casing of import of `corePluginList` type definition ([#8587](https://github.com/tailwindlabs/tailwindcss/pull/8587))
|
|
18
|
+
- Ignore PostCSS nodes returned by `addVariant` ([#8608](https://github.com/tailwindlabs/tailwindcss/pull/8608))
|
|
19
|
+
- Fix missing spaces around arithmetic operators ([#8615](https://github.com/tailwindlabs/tailwindcss/pull/8615))
|
|
20
|
+
- Detect alpha value in CSS `theme()` function when using quotes ([#8625](https://github.com/tailwindlabs/tailwindcss/pull/8625))
|
|
21
|
+
- Fix "Maximum call stack size exceeded" bug ([#8636](https://github.com/tailwindlabs/tailwindcss/pull/8636))
|
|
22
|
+
- Allow functions returning parallel variants to mutate the container ([#8622](https://github.com/tailwindlabs/tailwindcss/pull/8622))
|
|
23
|
+
- Remove text opacity CSS variables from `::marker` ([#8622](https://github.com/tailwindlabs/tailwindcss/pull/8622))
|
|
24
|
+
|
|
12
25
|
## [3.1.2] - 2022-06-10
|
|
13
26
|
|
|
14
27
|
### Fixed
|
|
@@ -1968,7 +1981,8 @@ No release notes
|
|
|
1968
1981
|
|
|
1969
1982
|
- Everything!
|
|
1970
1983
|
|
|
1971
|
-
[unreleased]: https://github.com/tailwindlabs/tailwindcss/compare/v3.1.
|
|
1984
|
+
[unreleased]: https://github.com/tailwindlabs/tailwindcss/compare/v3.1.3...HEAD
|
|
1985
|
+
[3.1.3]: https://github.com/tailwindlabs/tailwindcss/compare/v3.1.2...v3.1.3
|
|
1972
1986
|
[3.1.2]: https://github.com/tailwindlabs/tailwindcss/compare/v3.1.1...v3.1.2
|
|
1973
1987
|
[3.1.1]: https://github.com/tailwindlabs/tailwindcss/compare/v3.1.0...v3.1.1
|
|
1974
1988
|
[3.1.0]: https://github.com/tailwindlabs/tailwindcss/compare/v3.0.24...v3.1.0
|
package/lib/corePlugins.js
CHANGED
|
@@ -19,6 +19,7 @@ var _packageJson = require("../package.json");
|
|
|
19
19
|
var _log = _interopRequireDefault(require("./util/log"));
|
|
20
20
|
var _normalizeScreens = require("./util/normalizeScreens");
|
|
21
21
|
var _parseBoxShadowValue = require("./util/parseBoxShadowValue");
|
|
22
|
+
var _removeAlphaVariables = require("./util/removeAlphaVariables");
|
|
22
23
|
var _featureFlags = require("./featureFlags");
|
|
23
24
|
function _interopRequireDefault(obj) {
|
|
24
25
|
return obj && obj.__esModule ? obj : {
|
|
@@ -69,8 +70,18 @@ let variantPlugins = {
|
|
|
69
70
|
addVariant("first-letter", "&::first-letter");
|
|
70
71
|
addVariant("first-line", "&::first-line");
|
|
71
72
|
addVariant("marker", [
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
({ container })=>{
|
|
74
|
+
(0, _removeAlphaVariables).removeAlphaVariables(container, [
|
|
75
|
+
"--tw-text-opacity"
|
|
76
|
+
]);
|
|
77
|
+
return "& *::marker";
|
|
78
|
+
},
|
|
79
|
+
({ container })=>{
|
|
80
|
+
(0, _removeAlphaVariables).removeAlphaVariables(container, [
|
|
81
|
+
"--tw-text-opacity"
|
|
82
|
+
]);
|
|
83
|
+
return "&::marker";
|
|
84
|
+
},
|
|
74
85
|
]);
|
|
75
86
|
addVariant("selection", [
|
|
76
87
|
"& *::selection",
|
|
@@ -140,22 +151,11 @@ let variantPlugins = {
|
|
|
140
151
|
[
|
|
141
152
|
"visited",
|
|
142
153
|
({ container })=>{
|
|
143
|
-
|
|
154
|
+
(0, _removeAlphaVariables).removeAlphaVariables(container, [
|
|
144
155
|
"--tw-text-opacity",
|
|
145
156
|
"--tw-border-opacity",
|
|
146
|
-
"--tw-bg-opacity"
|
|
147
|
-
];
|
|
148
|
-
container.walkDecls((decl)=>{
|
|
149
|
-
if (toRemove.includes(decl.prop)) {
|
|
150
|
-
decl.remove();
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
for (const varName of toRemove){
|
|
154
|
-
if (decl.value.includes(`/ var(${varName})`)) {
|
|
155
|
-
decl.value = decl.value.replace(`/ var(${varName})`, "");
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
});
|
|
157
|
+
"--tw-bg-opacity",
|
|
158
|
+
]);
|
|
159
159
|
return "&:visited";
|
|
160
160
|
},
|
|
161
161
|
],
|
|
@@ -52,7 +52,10 @@ function defaultExtractor(context) {
|
|
|
52
52
|
/** @type {(string|string)[]} */ let results = [];
|
|
53
53
|
for (let pattern of patterns){
|
|
54
54
|
var ref;
|
|
55
|
-
results
|
|
55
|
+
results = [
|
|
56
|
+
...results,
|
|
57
|
+
...(ref = content.match(pattern)) !== null && ref !== void 0 ? ref : []
|
|
58
|
+
];
|
|
56
59
|
}
|
|
57
60
|
return results.filter((v)=>v !== undefined).map(clipAtBalancedParens);
|
|
58
61
|
};
|
|
@@ -71,7 +74,7 @@ function* buildRegExps(context) {
|
|
|
71
74
|
regex.optional(regex.any([
|
|
72
75
|
regex.pattern([
|
|
73
76
|
// Arbitrary values
|
|
74
|
-
|
|
77
|
+
/-(?:\w+-)*\[[^\s:]+\]/,
|
|
75
78
|
// Not immediately followed by an `{[(`
|
|
76
79
|
/(?![{([]])/,
|
|
77
80
|
// optionally followed by an opacity modifier
|
|
@@ -79,7 +82,7 @@ function* buildRegExps(context) {
|
|
|
79
82
|
]),
|
|
80
83
|
regex.pattern([
|
|
81
84
|
// Arbitrary values
|
|
82
|
-
|
|
85
|
+
/-(?:\w+-)*\[[^\s]+\]/,
|
|
83
86
|
// Not immediately followed by an `{[(`
|
|
84
87
|
/(?![{([]])/,
|
|
85
88
|
// optionally followed by an opacity modifier
|
|
@@ -42,7 +42,7 @@ function listKeys(obj) {
|
|
|
42
42
|
return list(Object.keys(obj));
|
|
43
43
|
}
|
|
44
44
|
function validatePath(config, path, defaultValue, themeOpts = {}) {
|
|
45
|
-
const pathString = Array.isArray(path) ? pathToString(path) : path.replace(/^['"]
|
|
45
|
+
const pathString = Array.isArray(path) ? pathToString(path) : path.replace(/^['"]+|['"]+$/g, "");
|
|
46
46
|
const pathSegments = Array.isArray(path) ? path : (0, _toPath).toPath(pathString);
|
|
47
47
|
const value = (0, _dlv).default(config.theme, pathSegments, defaultValue);
|
|
48
48
|
if (value === undefined) {
|
|
@@ -140,6 +140,9 @@ let nodeTypePropertyMap = {
|
|
|
140
140
|
function _default({ tailwindConfig: config }) {
|
|
141
141
|
let functions = {
|
|
142
142
|
theme: (node, path, ...defaultValue)=>{
|
|
143
|
+
// Strip quotes from beginning and end of string
|
|
144
|
+
// This allows the alpha value to be present inside of quotes
|
|
145
|
+
path = path.replace(/^['"]+|['"]+$/g, "");
|
|
143
146
|
let matches = path.match(/^([^\s]+)(?![^\[]*\])(?:\s*\/\s*([^\/\s]+))$/);
|
|
144
147
|
let alpha = undefined;
|
|
145
148
|
if (matches) {
|
package/lib/lib/generateRules.js
CHANGED
|
@@ -205,13 +205,16 @@ function applyVariant(variant, matches, context) {
|
|
|
205
205
|
rule1.clone()
|
|
206
206
|
]
|
|
207
207
|
});
|
|
208
|
-
for (let [variantSort, variantFunction] of variantFunctionTuples){
|
|
209
|
-
let clone = container.clone();
|
|
208
|
+
for (let [variantSort, variantFunction, containerFromArray] of variantFunctionTuples){
|
|
209
|
+
let clone = containerFromArray !== null && containerFromArray !== void 0 ? containerFromArray : container.clone();
|
|
210
210
|
let collectedFormats = [];
|
|
211
|
-
let originals = new Map();
|
|
212
211
|
function prepareBackup() {
|
|
213
|
-
|
|
214
|
-
clone.
|
|
212
|
+
// Already prepared, chicken out
|
|
213
|
+
if (clone.raws.neededBackup) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
clone.raws.neededBackup = true;
|
|
217
|
+
clone.walkRules((rule)=>rule.raws.originalSelector = rule.selector);
|
|
215
218
|
}
|
|
216
219
|
function modifySelectors(modifierFunction) {
|
|
217
220
|
prepareBackup();
|
|
@@ -264,7 +267,10 @@ function applyVariant(variant, matches, context) {
|
|
|
264
267
|
// then this might be the place too look at. One potential solution to this problem is
|
|
265
268
|
// reserving additional X places for these 'unknown' variants in between.
|
|
266
269
|
variantSort | BigInt(idx << ruleWithVariant.length),
|
|
267
|
-
variantFunction,
|
|
270
|
+
variantFunction,
|
|
271
|
+
// If the clone has been modified we have to pass that back
|
|
272
|
+
// though so each rule can use the modified container
|
|
273
|
+
clone.clone(),
|
|
268
274
|
]);
|
|
269
275
|
}
|
|
270
276
|
continue;
|
|
@@ -275,13 +281,15 @@ function applyVariant(variant, matches, context) {
|
|
|
275
281
|
if (ruleWithVariant === null) {
|
|
276
282
|
continue;
|
|
277
283
|
}
|
|
278
|
-
// We
|
|
284
|
+
// We had to backup selectors, therefore we assume that somebody touched
|
|
279
285
|
// `container` or `modifySelectors`. Let's see if they did, so that we
|
|
280
286
|
// can restore the selectors, and collect the format strings.
|
|
281
|
-
if (
|
|
287
|
+
if (clone.raws.neededBackup) {
|
|
288
|
+
delete clone.raws.neededBackup;
|
|
282
289
|
clone.walkRules((rule)=>{
|
|
283
|
-
|
|
284
|
-
|
|
290
|
+
let before = rule.raws.originalSelector;
|
|
291
|
+
if (!before) return;
|
|
292
|
+
delete rule.raws.originalSelector;
|
|
285
293
|
if (before === rule.selector) return; // No mutation happened
|
|
286
294
|
let modified = rule.selector;
|
|
287
295
|
// Rebuild the base selector, this is what plugin authors would do
|
|
@@ -478,10 +478,11 @@ function buildPluginApi(tailwindConfig, context, { variantList , variantMap , of
|
|
|
478
478
|
throw new Error(`Your custom variant \`${variantName}\` has an invalid format string. Make sure it's an at-rule or contains a \`&\` placeholder.`);
|
|
479
479
|
}
|
|
480
480
|
if (Array.isArray(result)) {
|
|
481
|
-
return result.map((variant)=>parseVariant(variant));
|
|
481
|
+
return result.filter((variant)=>typeof variant === "string").map((variant)=>parseVariant(variant));
|
|
482
482
|
}
|
|
483
483
|
// result may be undefined with legacy variants that use APIs like `modifySelectors`
|
|
484
|
-
|
|
484
|
+
// result may also be a postcss node if someone was returning the result from `modifySelectors`
|
|
485
|
+
return result && typeof result === "string" && parseVariant(result)(api);
|
|
485
486
|
};
|
|
486
487
|
}
|
|
487
488
|
if (!isValidVariantFormatString(variantFunction)) {
|
package/lib/util/dataTypes.js
CHANGED
|
@@ -46,9 +46,9 @@ function normalize(value, isRoot = true) {
|
|
|
46
46
|
if (isRoot) {
|
|
47
47
|
value = value.trim();
|
|
48
48
|
}
|
|
49
|
-
// Add spaces around operators inside calc() that do not follow an operator
|
|
49
|
+
// Add spaces around operators inside math functions like calc() that do not follow an operator
|
|
50
50
|
// or '('.
|
|
51
|
-
value = value.replace(/calc\(.+\)/g, (match)=>{
|
|
51
|
+
value = value.replace(/(calc|min|max|clamp)\(.+\)/g, (match)=>{
|
|
52
52
|
return match.replace(/(-?\d*\.?\d(?!\b-.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g, "$1 $2 ");
|
|
53
53
|
});
|
|
54
54
|
// Add spaces around some operators not inside calc() that do not follow an operator
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
exports.removeAlphaVariables = removeAlphaVariables;
|
|
6
|
+
function removeAlphaVariables(container, toRemove) {
|
|
7
|
+
container.walkDecls((decl)=>{
|
|
8
|
+
if (toRemove.includes(decl.prop)) {
|
|
9
|
+
decl.remove();
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
for (let varName of toRemove){
|
|
13
|
+
if (decl.value.includes(`/ var(${varName})`)) {
|
|
14
|
+
decl.value = decl.value.replace(`/ var(${varName})`, "");
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tailwindcss",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.3",
|
|
4
4
|
"description": "A utility-first CSS framework for rapidly building custom user interfaces.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
"eslint": "^8.16.0",
|
|
53
53
|
"eslint-config-prettier": "^8.5.0",
|
|
54
54
|
"eslint-plugin-prettier": "^4.0.0",
|
|
55
|
-
"jest": "^28.1.
|
|
56
|
-
"jest-diff": "^28.1.
|
|
55
|
+
"jest": "^28.1.1",
|
|
56
|
+
"jest-diff": "^28.1.1",
|
|
57
57
|
"prettier": "^2.6.2",
|
|
58
58
|
"prettier-plugin-tailwindcss": "^0.1.11",
|
|
59
59
|
"rimraf": "^3.0.0",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"postcss": "^8.0.9"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
-
"arg": "^5.0.
|
|
66
|
+
"arg": "^5.0.2",
|
|
67
67
|
"chokidar": "^3.5.3",
|
|
68
68
|
"color-name": "^1.1.4",
|
|
69
69
|
"detective": "^5.2.1",
|
package/src/corePlugins.js
CHANGED
|
@@ -14,6 +14,7 @@ import { version as tailwindVersion } from '../package.json'
|
|
|
14
14
|
import log from './util/log'
|
|
15
15
|
import { normalizeScreens } from './util/normalizeScreens'
|
|
16
16
|
import { formatBoxShadowValue, parseBoxShadowValue } from './util/parseBoxShadowValue'
|
|
17
|
+
import { removeAlphaVariables } from './util/removeAlphaVariables'
|
|
17
18
|
import { flagEnabled } from './featureFlags'
|
|
18
19
|
|
|
19
20
|
export let variantPlugins = {
|
|
@@ -21,7 +22,19 @@ export let variantPlugins = {
|
|
|
21
22
|
addVariant('first-letter', '&::first-letter')
|
|
22
23
|
addVariant('first-line', '&::first-line')
|
|
23
24
|
|
|
24
|
-
addVariant('marker', [
|
|
25
|
+
addVariant('marker', [
|
|
26
|
+
({ container }) => {
|
|
27
|
+
removeAlphaVariables(container, ['--tw-text-opacity'])
|
|
28
|
+
|
|
29
|
+
return '& *::marker'
|
|
30
|
+
},
|
|
31
|
+
({ container }) => {
|
|
32
|
+
removeAlphaVariables(container, ['--tw-text-opacity'])
|
|
33
|
+
|
|
34
|
+
return '&::marker'
|
|
35
|
+
},
|
|
36
|
+
])
|
|
37
|
+
|
|
25
38
|
addVariant('selection', ['& *::selection', '&::selection'])
|
|
26
39
|
|
|
27
40
|
addVariant('file', '&::file-selector-button')
|
|
@@ -77,21 +90,11 @@ export let variantPlugins = {
|
|
|
77
90
|
[
|
|
78
91
|
'visited',
|
|
79
92
|
({ container }) => {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
for (const varName of toRemove) {
|
|
90
|
-
if (decl.value.includes(`/ var(${varName})`)) {
|
|
91
|
-
decl.value = decl.value.replace(`/ var(${varName})`, '')
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
})
|
|
93
|
+
removeAlphaVariables(container, [
|
|
94
|
+
'--tw-text-opacity',
|
|
95
|
+
'--tw-border-opacity',
|
|
96
|
+
'--tw-bg-opacity',
|
|
97
|
+
])
|
|
95
98
|
|
|
96
99
|
return '&:visited'
|
|
97
100
|
},
|
|
@@ -12,7 +12,7 @@ export function defaultExtractor(context) {
|
|
|
12
12
|
let results = []
|
|
13
13
|
|
|
14
14
|
for (let pattern of patterns) {
|
|
15
|
-
results
|
|
15
|
+
results = [...results, ...(content.match(pattern) ?? [])]
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
return results.filter((v) => v !== undefined).map(clipAtBalancedParens)
|
|
@@ -37,7 +37,7 @@ function* buildRegExps(context) {
|
|
|
37
37
|
regex.any([
|
|
38
38
|
regex.pattern([
|
|
39
39
|
// Arbitrary values
|
|
40
|
-
|
|
40
|
+
/-(?:\w+-)*\[[^\s:]+\]/,
|
|
41
41
|
|
|
42
42
|
// Not immediately followed by an `{[(`
|
|
43
43
|
/(?![{([]])/,
|
|
@@ -48,7 +48,7 @@ function* buildRegExps(context) {
|
|
|
48
48
|
|
|
49
49
|
regex.pattern([
|
|
50
50
|
// Arbitrary values
|
|
51
|
-
|
|
51
|
+
/-(?:\w+-)*\[[^\s]+\]/,
|
|
52
52
|
|
|
53
53
|
// Not immediately followed by an `{[(`
|
|
54
54
|
/(?![{([]])/,
|
|
@@ -40,9 +40,7 @@ function listKeys(obj) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
function validatePath(config, path, defaultValue, themeOpts = {}) {
|
|
43
|
-
const pathString = Array.isArray(path)
|
|
44
|
-
? pathToString(path)
|
|
45
|
-
: path.replace(/^['"]+/g, '').replace(/['"]+$/g, '')
|
|
43
|
+
const pathString = Array.isArray(path) ? pathToString(path) : path.replace(/^['"]+|['"]+$/g, '')
|
|
46
44
|
const pathSegments = Array.isArray(path) ? path : toPath(pathString)
|
|
47
45
|
const value = dlv(config.theme, pathSegments, defaultValue)
|
|
48
46
|
|
|
@@ -162,6 +160,10 @@ let nodeTypePropertyMap = {
|
|
|
162
160
|
export default function ({ tailwindConfig: config }) {
|
|
163
161
|
let functions = {
|
|
164
162
|
theme: (node, path, ...defaultValue) => {
|
|
163
|
+
// Strip quotes from beginning and end of string
|
|
164
|
+
// This allows the alpha value to be present inside of quotes
|
|
165
|
+
path = path.replace(/^['"]+|['"]+$/g, '')
|
|
166
|
+
|
|
165
167
|
let matches = path.match(/^([^\s]+)(?![^\[]*\])(?:\s*\/\s*([^\/\s]+))$/)
|
|
166
168
|
let alpha = undefined
|
|
167
169
|
|
package/src/lib/generateRules.js
CHANGED
|
@@ -163,15 +163,17 @@ function applyVariant(variant, matches, context) {
|
|
|
163
163
|
|
|
164
164
|
let container = postcss.root({ nodes: [rule.clone()] })
|
|
165
165
|
|
|
166
|
-
for (let [variantSort, variantFunction] of variantFunctionTuples) {
|
|
167
|
-
let clone = container.clone()
|
|
166
|
+
for (let [variantSort, variantFunction, containerFromArray] of variantFunctionTuples) {
|
|
167
|
+
let clone = containerFromArray ?? container.clone()
|
|
168
168
|
let collectedFormats = []
|
|
169
169
|
|
|
170
|
-
let originals = new Map()
|
|
171
|
-
|
|
172
170
|
function prepareBackup() {
|
|
173
|
-
|
|
174
|
-
clone.
|
|
171
|
+
// Already prepared, chicken out
|
|
172
|
+
if (clone.raws.neededBackup) {
|
|
173
|
+
return
|
|
174
|
+
}
|
|
175
|
+
clone.raws.neededBackup = true
|
|
176
|
+
clone.walkRules((rule) => (rule.raws.originalSelector = rule.selector))
|
|
175
177
|
}
|
|
176
178
|
|
|
177
179
|
function modifySelectors(modifierFunction) {
|
|
@@ -231,6 +233,10 @@ function applyVariant(variant, matches, context) {
|
|
|
231
233
|
// reserving additional X places for these 'unknown' variants in between.
|
|
232
234
|
variantSort | BigInt(idx << ruleWithVariant.length),
|
|
233
235
|
variantFunction,
|
|
236
|
+
|
|
237
|
+
// If the clone has been modified we have to pass that back
|
|
238
|
+
// though so each rule can use the modified container
|
|
239
|
+
clone.clone(),
|
|
234
240
|
])
|
|
235
241
|
}
|
|
236
242
|
continue
|
|
@@ -244,13 +250,15 @@ function applyVariant(variant, matches, context) {
|
|
|
244
250
|
continue
|
|
245
251
|
}
|
|
246
252
|
|
|
247
|
-
// We
|
|
253
|
+
// We had to backup selectors, therefore we assume that somebody touched
|
|
248
254
|
// `container` or `modifySelectors`. Let's see if they did, so that we
|
|
249
255
|
// can restore the selectors, and collect the format strings.
|
|
250
|
-
if (
|
|
256
|
+
if (clone.raws.neededBackup) {
|
|
257
|
+
delete clone.raws.neededBackup
|
|
251
258
|
clone.walkRules((rule) => {
|
|
252
|
-
|
|
253
|
-
|
|
259
|
+
let before = rule.raws.originalSelector
|
|
260
|
+
if (!before) return
|
|
261
|
+
delete rule.raws.originalSelector
|
|
254
262
|
if (before === rule.selector) return // No mutation happened
|
|
255
263
|
|
|
256
264
|
let modified = rule.selector
|
|
@@ -465,11 +465,14 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|
|
465
465
|
}
|
|
466
466
|
|
|
467
467
|
if (Array.isArray(result)) {
|
|
468
|
-
return result
|
|
468
|
+
return result
|
|
469
|
+
.filter((variant) => typeof variant === 'string')
|
|
470
|
+
.map((variant) => parseVariant(variant))
|
|
469
471
|
}
|
|
470
472
|
|
|
471
473
|
// result may be undefined with legacy variants that use APIs like `modifySelectors`
|
|
472
|
-
|
|
474
|
+
// result may also be a postcss node if someone was returning the result from `modifySelectors`
|
|
475
|
+
return result && typeof result === 'string' && parseVariant(result)(api)
|
|
473
476
|
}
|
|
474
477
|
}
|
|
475
478
|
|
package/src/util/dataTypes.js
CHANGED
|
@@ -40,9 +40,9 @@ export function normalize(value, isRoot = true) {
|
|
|
40
40
|
value = value.trim()
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
// Add spaces around operators inside calc() that do not follow an operator
|
|
43
|
+
// Add spaces around operators inside math functions like calc() that do not follow an operator
|
|
44
44
|
// or '('.
|
|
45
|
-
value = value.replace(/calc\(.+\)/g, (match) => {
|
|
45
|
+
value = value.replace(/(calc|min|max|clamp)\(.+\)/g, (match) => {
|
|
46
46
|
return match.replace(
|
|
47
47
|
/(-?\d*\.?\d(?!\b-.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g,
|
|
48
48
|
'$1 $2 '
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This function removes any uses of CSS variables used as an alpha channel
|
|
3
|
+
*
|
|
4
|
+
* This is required for selectors like `:visited` which do not allow
|
|
5
|
+
* changes in opacity or external control using CSS variables.
|
|
6
|
+
*
|
|
7
|
+
* @param {import('postcss').Container} container
|
|
8
|
+
* @param {string[]} toRemove
|
|
9
|
+
*/
|
|
10
|
+
export function removeAlphaVariables(container, toRemove) {
|
|
11
|
+
container.walkDecls((decl) => {
|
|
12
|
+
if (toRemove.includes(decl.prop)) {
|
|
13
|
+
decl.remove()
|
|
14
|
+
|
|
15
|
+
return
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
for (let varName of toRemove) {
|
|
19
|
+
if (decl.value.includes(`/ var(${varName})`)) {
|
|
20
|
+
decl.value = decl.value.replace(`/ var(${varName})`, '')
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
})
|
|
24
|
+
}
|
package/types/config.d.ts
CHANGED