tailwindcss 3.1.8 → 3.2.1
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 +64 -3
- package/README.md +6 -5
- package/lib/cli/build/deps.js +54 -0
- package/lib/cli/build/index.js +44 -0
- package/lib/cli/build/plugin.js +351 -0
- package/lib/cli/build/utils.js +78 -0
- package/lib/cli/build/watching.js +113 -0
- package/lib/cli/help/index.js +71 -0
- package/lib/cli/index.js +18 -0
- package/lib/cli/init/index.js +46 -0
- package/lib/cli/shared.js +12 -0
- package/lib/cli.js +11 -590
- package/lib/corePlugins.js +332 -108
- package/lib/css/preflight.css +5 -0
- package/lib/featureFlags.js +7 -4
- package/lib/index.js +6 -1
- package/lib/lib/content.js +167 -0
- package/lib/lib/defaultExtractor.js +15 -10
- package/lib/lib/detectNesting.js +2 -2
- package/lib/lib/evaluateTailwindFunctions.js +17 -1
- package/lib/lib/expandApplyAtRules.js +66 -37
- package/lib/lib/expandTailwindAtRules.js +10 -42
- package/lib/lib/findAtConfigPath.js +44 -0
- package/lib/lib/generateRules.js +180 -93
- package/lib/lib/normalizeTailwindDirectives.js +1 -1
- package/lib/lib/offsets.js +217 -0
- package/lib/lib/regex.js +1 -1
- package/lib/lib/setupContextUtils.js +339 -100
- package/lib/lib/setupTrackingContext.js +5 -39
- package/lib/lib/sharedState.js +2 -0
- package/lib/public/colors.js +1 -1
- package/lib/util/buildMediaQuery.js +6 -3
- package/lib/util/configurePlugins.js +1 -1
- package/lib/util/dataTypes.js +15 -19
- package/lib/util/formatVariantSelector.js +92 -8
- package/lib/util/getAllConfigs.js +14 -3
- package/lib/util/isValidArbitraryValue.js +1 -1
- package/lib/util/nameClass.js +3 -0
- package/lib/util/negateValue.js +15 -2
- package/lib/util/normalizeConfig.js +17 -3
- package/lib/util/normalizeScreens.js +100 -3
- package/lib/util/parseAnimationValue.js +1 -1
- package/lib/util/parseBoxShadowValue.js +1 -1
- package/lib/util/parseDependency.js +33 -54
- package/lib/util/parseGlob.js +34 -0
- package/lib/util/parseObjectStyles.js +1 -1
- package/lib/util/pluginUtils.js +87 -17
- package/lib/util/resolveConfig.js +2 -2
- package/lib/util/splitAtTopLevelOnly.js +31 -81
- package/lib/util/transformThemeValue.js +9 -2
- package/lib/util/validateConfig.js +1 -1
- package/lib/util/validateFormalSyntax.js +24 -0
- package/package.json +14 -13
- package/peers/index.js +3263 -1887
- package/plugin.d.ts +3 -3
- package/scripts/release-channel.js +18 -0
- package/scripts/release-notes.js +21 -0
- package/src/cli/build/deps.js +56 -0
- package/src/cli/build/index.js +45 -0
- package/src/cli/build/plugin.js +417 -0
- package/src/cli/build/utils.js +76 -0
- package/src/cli/build/watching.js +134 -0
- package/src/cli/help/index.js +70 -0
- package/src/cli/index.js +3 -0
- package/src/cli/init/index.js +50 -0
- package/src/cli/shared.js +5 -0
- package/src/cli.js +4 -696
- package/src/corePlugins.js +262 -39
- package/src/css/preflight.css +5 -0
- package/src/featureFlags.js +12 -2
- package/src/index.js +5 -0
- package/src/lib/content.js +205 -0
- package/src/lib/defaultExtractor.js +3 -0
- package/src/lib/evaluateTailwindFunctions.js +22 -1
- package/src/lib/expandApplyAtRules.js +70 -29
- package/src/lib/expandTailwindAtRules.js +8 -46
- package/src/lib/findAtConfigPath.js +48 -0
- package/src/lib/generateRules.js +223 -101
- package/src/lib/offsets.js +270 -0
- package/src/lib/setupContextUtils.js +376 -89
- package/src/lib/setupTrackingContext.js +4 -45
- package/src/lib/sharedState.js +2 -0
- package/src/util/buildMediaQuery.js +5 -3
- package/src/util/dataTypes.js +15 -17
- package/src/util/formatVariantSelector.js +113 -9
- package/src/util/getAllConfigs.js +14 -2
- package/src/util/nameClass.js +4 -0
- package/src/util/negateValue.js +10 -2
- package/src/util/normalizeConfig.js +22 -2
- package/src/util/normalizeScreens.js +99 -4
- package/src/util/parseBoxShadowValue.js +1 -1
- package/src/util/parseDependency.js +37 -42
- package/src/util/parseGlob.js +24 -0
- package/src/util/pluginUtils.js +96 -14
- package/src/util/resolveConfig.js +1 -1
- package/src/util/splitAtTopLevelOnly.js +23 -49
- package/src/util/transformThemeValue.js +9 -1
- package/src/util/validateFormalSyntax.js +34 -0
- package/stubs/defaultConfig.stub.js +20 -3
- package/types/config.d.ts +48 -13
- package/types/generated/default-theme.d.ts +11 -0
|
@@ -11,18 +11,15 @@ Object.defineProperty(exports, // DISABLE_TOUCH = TRUE
|
|
|
11
11
|
get: ()=>setupTrackingContext
|
|
12
12
|
});
|
|
13
13
|
const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs"));
|
|
14
|
-
const _path = /*#__PURE__*/ _interopRequireDefault(require("path"));
|
|
15
|
-
const _fastGlob = /*#__PURE__*/ _interopRequireDefault(require("fast-glob"));
|
|
16
14
|
const _quickLru = /*#__PURE__*/ _interopRequireDefault(require("quick-lru"));
|
|
17
|
-
const _normalizePath = /*#__PURE__*/ _interopRequireDefault(require("normalize-path"));
|
|
18
15
|
const _hashConfig = /*#__PURE__*/ _interopRequireDefault(require("../util/hashConfig"));
|
|
19
16
|
const _getModuleDependencies = /*#__PURE__*/ _interopRequireDefault(require("../lib/getModuleDependencies"));
|
|
20
17
|
const _resolveConfig = /*#__PURE__*/ _interopRequireDefault(require("../public/resolve-config"));
|
|
21
18
|
const _resolveConfigPath = /*#__PURE__*/ _interopRequireDefault(require("../util/resolveConfigPath"));
|
|
22
|
-
const _sharedState = require("./sharedState");
|
|
23
19
|
const _setupContextUtils = require("./setupContextUtils");
|
|
24
20
|
const _parseDependency = /*#__PURE__*/ _interopRequireDefault(require("../util/parseDependency"));
|
|
25
21
|
const _validateConfigJs = require("../util/validateConfig.js");
|
|
22
|
+
const _contentJs = require("./content.js");
|
|
26
23
|
function _interopRequireDefault(obj) {
|
|
27
24
|
return obj && obj.__esModule ? obj : {
|
|
28
25
|
default: obj
|
|
@@ -36,7 +33,7 @@ function getCandidateFiles(context, tailwindConfig) {
|
|
|
36
33
|
if (candidateFilesCache.has(context)) {
|
|
37
34
|
return candidateFilesCache.get(context);
|
|
38
35
|
}
|
|
39
|
-
let candidateFiles =
|
|
36
|
+
let candidateFiles = (0, _contentJs.parseCandidateFiles)(context, tailwindConfig);
|
|
40
37
|
return candidateFilesCache.set(context, candidateFiles).get(context);
|
|
41
38
|
}
|
|
42
39
|
// Get the config object based on a path
|
|
@@ -93,36 +90,6 @@ function getTailwindConfig(configOrPath) {
|
|
|
93
90
|
[]
|
|
94
91
|
];
|
|
95
92
|
}
|
|
96
|
-
function resolvedChangedContent(context, candidateFiles, fileModifiedMap) {
|
|
97
|
-
let changedContent = context.tailwindConfig.content.files.filter((item)=>typeof item.raw === "string").map(({ raw , extension ="html" })=>({
|
|
98
|
-
content: raw,
|
|
99
|
-
extension
|
|
100
|
-
}));
|
|
101
|
-
for (let changedFile of resolveChangedFiles(candidateFiles, fileModifiedMap)){
|
|
102
|
-
let content = _fs.default.readFileSync(changedFile, "utf8");
|
|
103
|
-
let extension = _path.default.extname(changedFile).slice(1);
|
|
104
|
-
changedContent.push({
|
|
105
|
-
content,
|
|
106
|
-
extension
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
return changedContent;
|
|
110
|
-
}
|
|
111
|
-
function resolveChangedFiles(candidateFiles, fileModifiedMap) {
|
|
112
|
-
let changedFiles = new Set();
|
|
113
|
-
_sharedState.env.DEBUG && console.time("Finding changed files");
|
|
114
|
-
let files = _fastGlob.default.sync(candidateFiles);
|
|
115
|
-
for (let file of files){
|
|
116
|
-
let prevModified = fileModifiedMap.has(file) ? fileModifiedMap.get(file) : -Infinity;
|
|
117
|
-
let modified = _fs.default.statSync(file).mtimeMs;
|
|
118
|
-
if (modified > prevModified) {
|
|
119
|
-
changedFiles.add(file);
|
|
120
|
-
fileModifiedMap.set(file, modified);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
_sharedState.env.DEBUG && console.timeEnd("Finding changed files");
|
|
124
|
-
return changedFiles;
|
|
125
|
-
}
|
|
126
93
|
function setupTrackingContext(configOrPath) {
|
|
127
94
|
return ({ tailwindDirectives , registerDependency })=>{
|
|
128
95
|
return (root, result)=>{
|
|
@@ -154,13 +121,12 @@ function setupTrackingContext(configOrPath) {
|
|
|
154
121
|
if (tailwindDirectives.size > 0) {
|
|
155
122
|
let fileModifiedMap = (0, _setupContextUtils.getFileModifiedMap)(context);
|
|
156
123
|
// Add template paths as postcss dependencies.
|
|
157
|
-
for (let
|
|
158
|
-
let dependency
|
|
159
|
-
if (dependency) {
|
|
124
|
+
for (let contentPath of candidateFiles){
|
|
125
|
+
for (let dependency of (0, _parseDependency.default)(contentPath)){
|
|
160
126
|
registerDependency(dependency);
|
|
161
127
|
}
|
|
162
128
|
}
|
|
163
|
-
for (let changedContent of resolvedChangedContent(context, candidateFiles, fileModifiedMap)){
|
|
129
|
+
for (let changedContent of (0, _contentJs.resolvedChangedContent)(context, candidateFiles, fileModifiedMap)){
|
|
164
130
|
context.changedContent.push(changedContent);
|
|
165
131
|
}
|
|
166
132
|
}
|
package/lib/lib/sharedState.js
CHANGED
|
@@ -15,6 +15,7 @@ _export(exports, {
|
|
|
15
15
|
contextSourcesMap: ()=>contextSourcesMap,
|
|
16
16
|
sourceHashMap: ()=>sourceHashMap,
|
|
17
17
|
NOT_ON_DEMAND: ()=>NOT_ON_DEMAND,
|
|
18
|
+
NONE: ()=>NONE,
|
|
18
19
|
resolveDebug: ()=>resolveDebug
|
|
19
20
|
});
|
|
20
21
|
const env = {
|
|
@@ -26,6 +27,7 @@ const configContextMap = new Map();
|
|
|
26
27
|
const contextSourcesMap = new Map();
|
|
27
28
|
const sourceHashMap = new Map();
|
|
28
29
|
const NOT_ON_DEMAND = new String("*");
|
|
30
|
+
const NONE = Symbol("__NONE__");
|
|
29
31
|
function resolveDebug(debug) {
|
|
30
32
|
if (debug === undefined) {
|
|
31
33
|
return false;
|
package/lib/public/colors.js
CHANGED
|
@@ -15,7 +15,7 @@ function _interopRequireDefault(obj) {
|
|
|
15
15
|
function warn({ version , from , to }) {
|
|
16
16
|
_log.default.warn(`${from}-color-renamed`, [
|
|
17
17
|
`As of Tailwind CSS ${version}, \`${from}\` has been renamed to \`${to}\`.`,
|
|
18
|
-
"Update your configuration file to silence this warning."
|
|
18
|
+
"Update your configuration file to silence this warning."
|
|
19
19
|
]);
|
|
20
20
|
}
|
|
21
21
|
const _default = {
|
|
@@ -10,13 +10,16 @@ function buildMediaQuery(screens) {
|
|
|
10
10
|
screens = Array.isArray(screens) ? screens : [
|
|
11
11
|
screens
|
|
12
12
|
];
|
|
13
|
-
return screens.map((screen)=>
|
|
13
|
+
return screens.map((screen)=>{
|
|
14
|
+
let values = screen.values.map((screen)=>{
|
|
14
15
|
if (screen.raw !== undefined) {
|
|
15
16
|
return screen.raw;
|
|
16
17
|
}
|
|
17
18
|
return [
|
|
18
19
|
screen.min && `(min-width: ${screen.min})`,
|
|
19
|
-
screen.max && `(max-width: ${screen.max})
|
|
20
|
+
screen.max && `(max-width: ${screen.max})`
|
|
20
21
|
].filter(Boolean).join(" and ");
|
|
21
|
-
})
|
|
22
|
+
});
|
|
23
|
+
return screen.not ? `not all and ${values}` : values;
|
|
24
|
+
}).join(", ");
|
|
22
25
|
}
|
|
@@ -15,7 +15,7 @@ function _default(pluginConfig, plugins) {
|
|
|
15
15
|
return pluginConfig !== false && pluginConfig[pluginName] !== false;
|
|
16
16
|
}).concat(Object.keys(pluginConfig).filter((pluginName)=>{
|
|
17
17
|
return pluginConfig[pluginName] !== false;
|
|
18
|
-
})))
|
|
18
|
+
})))
|
|
19
19
|
];
|
|
20
20
|
return pluginNames;
|
|
21
21
|
}
|
package/lib/util/dataTypes.js
CHANGED
|
@@ -27,6 +27,7 @@ _export(exports, {
|
|
|
27
27
|
});
|
|
28
28
|
const _color = require("./color");
|
|
29
29
|
const _parseBoxShadowValue = require("./parseBoxShadowValue");
|
|
30
|
+
const _splitAtTopLevelOnly = require("./splitAtTopLevelOnly");
|
|
30
31
|
let cssFunctions = [
|
|
31
32
|
"min",
|
|
32
33
|
"max",
|
|
@@ -34,10 +35,9 @@ let cssFunctions = [
|
|
|
34
35
|
"calc"
|
|
35
36
|
];
|
|
36
37
|
// Ref: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Types
|
|
37
|
-
|
|
38
|
-
;
|
|
39
|
-
|
|
40
|
-
;
|
|
38
|
+
function isCSSFunction(value) {
|
|
39
|
+
return cssFunctions.some((fn)=>new RegExp(`^${fn}\\(.*\\)`).test(value));
|
|
40
|
+
}
|
|
41
41
|
function normalize(value, isRoot = true) {
|
|
42
42
|
// Keep raw strings if it starts with `url(`
|
|
43
43
|
if (value.includes("url(")) {
|
|
@@ -65,12 +65,10 @@ function url(value) {
|
|
|
65
65
|
return value.startsWith("url(");
|
|
66
66
|
}
|
|
67
67
|
function number(value) {
|
|
68
|
-
return !isNaN(Number(value)) ||
|
|
68
|
+
return !isNaN(Number(value)) || isCSSFunction(value);
|
|
69
69
|
}
|
|
70
70
|
function percentage(value) {
|
|
71
|
-
return value.
|
|
72
|
-
return /%$/g.test(part) || cssFunctions.some((fn)=>new RegExp(`^${fn}\\(.+?%`).test(part));
|
|
73
|
-
});
|
|
71
|
+
return value.endsWith("%") && number(value.slice(0, -1)) || isCSSFunction(value);
|
|
74
72
|
}
|
|
75
73
|
let lengthUnits = [
|
|
76
74
|
"cm",
|
|
@@ -88,13 +86,11 @@ let lengthUnits = [
|
|
|
88
86
|
"vw",
|
|
89
87
|
"vh",
|
|
90
88
|
"vmin",
|
|
91
|
-
"vmax"
|
|
89
|
+
"vmax"
|
|
92
90
|
];
|
|
93
91
|
let lengthUnitsPattern = `(?:${lengthUnits.join("|")})`;
|
|
94
92
|
function length(value) {
|
|
95
|
-
return value
|
|
96
|
-
return part === "0" || new RegExp(`${lengthUnitsPattern}$`).test(part) || cssFunctions.some((fn)=>new RegExp(`^${fn}\\(.+?${lengthUnitsPattern}`).test(part));
|
|
97
|
-
});
|
|
93
|
+
return value === "0" || new RegExp(`^[+-]?[0-9]*\.?[0-9]+(?:[eE][+-]?[0-9]+)?${lengthUnitsPattern}$`).test(value) || isCSSFunction(value);
|
|
98
94
|
}
|
|
99
95
|
let lineWidths = new Set([
|
|
100
96
|
"thin",
|
|
@@ -115,7 +111,7 @@ function shadow(value) {
|
|
|
115
111
|
}
|
|
116
112
|
function color(value) {
|
|
117
113
|
let colors = 0;
|
|
118
|
-
let result =
|
|
114
|
+
let result = (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(value, "_").every((part)=>{
|
|
119
115
|
part = normalize(part);
|
|
120
116
|
if (part.startsWith("var(")) return true;
|
|
121
117
|
if ((0, _color.parseColor)(part, {
|
|
@@ -128,7 +124,7 @@ function color(value) {
|
|
|
128
124
|
}
|
|
129
125
|
function image(value) {
|
|
130
126
|
let images = 0;
|
|
131
|
-
let result =
|
|
127
|
+
let result = (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(value, ",").every((part)=>{
|
|
132
128
|
part = normalize(part);
|
|
133
129
|
if (part.startsWith("var(")) return true;
|
|
134
130
|
if (url(part) || gradient(part) || [
|
|
@@ -150,7 +146,7 @@ let gradientTypes = new Set([
|
|
|
150
146
|
"radial-gradient",
|
|
151
147
|
"repeating-linear-gradient",
|
|
152
148
|
"repeating-radial-gradient",
|
|
153
|
-
"conic-gradient"
|
|
149
|
+
"conic-gradient"
|
|
154
150
|
]);
|
|
155
151
|
function gradient(value) {
|
|
156
152
|
value = normalize(value);
|
|
@@ -170,7 +166,7 @@ let validPositions = new Set([
|
|
|
170
166
|
]);
|
|
171
167
|
function position(value) {
|
|
172
168
|
let positions = 0;
|
|
173
|
-
let result =
|
|
169
|
+
let result = (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(value, "_").every((part)=>{
|
|
174
170
|
part = normalize(part);
|
|
175
171
|
if (part.startsWith("var(")) return true;
|
|
176
172
|
if (validPositions.has(part) || length(part) || percentage(part)) {
|
|
@@ -184,7 +180,7 @@ function position(value) {
|
|
|
184
180
|
}
|
|
185
181
|
function familyName(value) {
|
|
186
182
|
let fonts = 0;
|
|
187
|
-
let result =
|
|
183
|
+
let result = (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(value, ",").every((part)=>{
|
|
188
184
|
part = normalize(part);
|
|
189
185
|
if (part.startsWith("var(")) return true;
|
|
190
186
|
// If it contains spaces, then it should be quoted
|
|
@@ -216,7 +212,7 @@ let genericNames = new Set([
|
|
|
216
212
|
"ui-rounded",
|
|
217
213
|
"math",
|
|
218
214
|
"emoji",
|
|
219
|
-
"fangsong"
|
|
215
|
+
"fangsong"
|
|
220
216
|
]);
|
|
221
217
|
function genericName(value) {
|
|
222
218
|
return genericNames.has(value);
|
|
@@ -229,7 +225,7 @@ let absoluteSizes = new Set([
|
|
|
229
225
|
"large",
|
|
230
226
|
"x-large",
|
|
231
227
|
"x-large",
|
|
232
|
-
"xxx-large"
|
|
228
|
+
"xxx-large"
|
|
233
229
|
]);
|
|
234
230
|
function absoluteSize(value) {
|
|
235
231
|
return absoluteSizes.has(value);
|
|
@@ -45,6 +45,67 @@ function formatVariantSelector(current, ...others) {
|
|
|
45
45
|
}
|
|
46
46
|
return current;
|
|
47
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Given any node in a selector this gets the "simple" selector it's a part of
|
|
50
|
+
* A simple selector is just a list of nodes without any combinators
|
|
51
|
+
* Technically :is(), :not(), :has(), etc… can have combinators but those are nested
|
|
52
|
+
* inside the relevant node and won't be picked up so they're fine to ignore
|
|
53
|
+
*
|
|
54
|
+
* @param {import('postcss-selector-parser').Node} node
|
|
55
|
+
* @returns {import('postcss-selector-parser').Node[]}
|
|
56
|
+
**/ function simpleSelectorForNode(node) {
|
|
57
|
+
/** @type {import('postcss-selector-parser').Node[]} */ let nodes = [];
|
|
58
|
+
// Walk backwards until we hit a combinator node (or the start)
|
|
59
|
+
while(node.prev() && node.prev().type !== "combinator"){
|
|
60
|
+
node = node.prev();
|
|
61
|
+
}
|
|
62
|
+
// Now record all non-combinator nodes until we hit one (or the end)
|
|
63
|
+
while(node && node.type !== "combinator"){
|
|
64
|
+
nodes.push(node);
|
|
65
|
+
node = node.next();
|
|
66
|
+
}
|
|
67
|
+
return nodes;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Resorts the nodes in a selector to ensure they're in the correct order
|
|
71
|
+
* Tags go before classes, and pseudo classes go after classes
|
|
72
|
+
*
|
|
73
|
+
* @param {import('postcss-selector-parser').Selector} sel
|
|
74
|
+
* @returns {import('postcss-selector-parser').Selector}
|
|
75
|
+
**/ function resortSelector(sel) {
|
|
76
|
+
sel.sort((a, b)=>{
|
|
77
|
+
if (a.type === "tag" && b.type === "class") {
|
|
78
|
+
return -1;
|
|
79
|
+
} else if (a.type === "class" && b.type === "tag") {
|
|
80
|
+
return 1;
|
|
81
|
+
} else if (a.type === "class" && b.type === "pseudo" && b.value !== ":merge") {
|
|
82
|
+
return -1;
|
|
83
|
+
} else if (a.type === "pseudo" && a.value !== ":merge" && b.type === "class") {
|
|
84
|
+
return 1;
|
|
85
|
+
}
|
|
86
|
+
return sel.index(a) - sel.index(b);
|
|
87
|
+
});
|
|
88
|
+
return sel;
|
|
89
|
+
}
|
|
90
|
+
function eliminateIrrelevantSelectors(sel, base) {
|
|
91
|
+
let hasClassesMatchingCandidate = false;
|
|
92
|
+
sel.walk((child)=>{
|
|
93
|
+
if (child.type === "class" && child.value === base) {
|
|
94
|
+
hasClassesMatchingCandidate = true;
|
|
95
|
+
return false // Stop walking
|
|
96
|
+
;
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
if (!hasClassesMatchingCandidate) {
|
|
100
|
+
sel.remove();
|
|
101
|
+
}
|
|
102
|
+
// We do NOT recursively eliminate sub selectors that don't have the base class
|
|
103
|
+
// as this is NOT a safe operation. For example, if we have:
|
|
104
|
+
// `.space-x-2 > :not([hidden]) ~ :not([hidden])`
|
|
105
|
+
// We cannot remove the [hidden] from the :not() because it would change the
|
|
106
|
+
// meaning of the selector.
|
|
107
|
+
// TODO: Can we do this for :matches, :is, and :where?
|
|
108
|
+
}
|
|
48
109
|
var ref1;
|
|
49
110
|
function finalizeSelector(format, { selector , candidate , context , isArbitraryVariant , // Split by the separator, but ignore the separator inside square brackets:
|
|
50
111
|
//
|
|
@@ -65,12 +126,7 @@ base =candidate.split(new RegExp(`\\${(ref1 = context === null || context === vo
|
|
|
65
126
|
// Remove extraneous selectors that do not include the base class/candidate being matched against
|
|
66
127
|
// For example if we have a utility defined `.a, .b { color: red}`
|
|
67
128
|
// And the formatted variant is sm:b then we want the final selector to be `.sm\:b` and not `.a, .sm\:b`
|
|
68
|
-
ast.each((
|
|
69
|
-
let hasClassesMatchingCandidate = node.some((n)=>n.type === "class" && n.value === base);
|
|
70
|
-
if (!hasClassesMatchingCandidate) {
|
|
71
|
-
node.remove();
|
|
72
|
-
}
|
|
73
|
-
});
|
|
129
|
+
ast.each((sel)=>eliminateIrrelevantSelectors(sel, base));
|
|
74
130
|
// Normalize escaped classes, e.g.:
|
|
75
131
|
//
|
|
76
132
|
// The idea would be to replace the escaped `base` in the selector with the
|
|
@@ -87,12 +143,40 @@ base =candidate.split(new RegExp(`\\${(ref1 = context === null || context === vo
|
|
|
87
143
|
node.raws.value = (0, _escapeClassName.default)((0, _unesc.default)(node.raws.value));
|
|
88
144
|
}
|
|
89
145
|
});
|
|
146
|
+
let simpleStart = _postcssSelectorParser.default.comment({
|
|
147
|
+
value: "/*__simple__*/"
|
|
148
|
+
});
|
|
149
|
+
let simpleEnd = _postcssSelectorParser.default.comment({
|
|
150
|
+
value: "/*__simple__*/"
|
|
151
|
+
});
|
|
90
152
|
// We can safely replace the escaped base now, since the `base` section is
|
|
91
153
|
// now in a normalized escaped value.
|
|
92
154
|
ast.walkClasses((node)=>{
|
|
93
|
-
if (node.value
|
|
94
|
-
|
|
155
|
+
if (node.value !== base) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
let parent = node.parent;
|
|
159
|
+
let formatNodes = formatAst.nodes[0].nodes;
|
|
160
|
+
// Perf optimization: if the parent is a single class we can just replace it and be done
|
|
161
|
+
if (parent.nodes.length === 1) {
|
|
162
|
+
node.replaceWith(...formatNodes);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
let simpleSelector = simpleSelectorForNode(node);
|
|
166
|
+
parent.insertBefore(simpleSelector[0], simpleStart);
|
|
167
|
+
parent.insertAfter(simpleSelector[simpleSelector.length - 1], simpleEnd);
|
|
168
|
+
for (let child of formatNodes){
|
|
169
|
+
parent.insertBefore(simpleSelector[0], child);
|
|
95
170
|
}
|
|
171
|
+
node.remove();
|
|
172
|
+
// Re-sort the simple selector to ensure it's in the correct order
|
|
173
|
+
simpleSelector = simpleSelectorForNode(simpleStart);
|
|
174
|
+
let firstNode = parent.index(simpleStart);
|
|
175
|
+
parent.nodes.splice(firstNode, simpleSelector.length, ...resortSelector(_postcssSelectorParser.default.selector({
|
|
176
|
+
nodes: simpleSelector
|
|
177
|
+
})).nodes);
|
|
178
|
+
simpleStart.remove();
|
|
179
|
+
simpleEnd.remove();
|
|
96
180
|
});
|
|
97
181
|
// This will make sure to move pseudo's to the correct spot (the end for
|
|
98
182
|
// pseudo elements) because otherwise the selector will never work
|
|
@@ -22,9 +22,20 @@ function getAllConfigs(config) {
|
|
|
22
22
|
// Add experimental configs here...
|
|
23
23
|
respectDefaultRingColorOpacity: {
|
|
24
24
|
theme: {
|
|
25
|
-
ringColor: {
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
ringColor: ({ theme })=>({
|
|
26
|
+
DEFAULT: "#3b82f67f",
|
|
27
|
+
...theme("colors")
|
|
28
|
+
})
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
disableColorOpacityUtilitiesByDefault: {
|
|
32
|
+
corePlugins: {
|
|
33
|
+
backgroundOpacity: false,
|
|
34
|
+
borderOpacity: false,
|
|
35
|
+
divideOpacity: false,
|
|
36
|
+
placeholderOpacity: false,
|
|
37
|
+
ringOpacity: false,
|
|
38
|
+
textOpacity: false
|
|
28
39
|
}
|
|
29
40
|
}
|
|
30
41
|
};
|
package/lib/util/nameClass.js
CHANGED
package/lib/util/negateValue.js
CHANGED
|
@@ -15,7 +15,20 @@ function _default(value) {
|
|
|
15
15
|
if (/^[+-]?(\d+|\d*\.\d+)(e[+-]?\d+)?(%|\w+)?$/.test(value)) {
|
|
16
16
|
return value.replace(/^[+-]?/, (sign)=>sign === "-" ? "" : "-");
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
// What functions we support negating numeric values for
|
|
19
|
+
// var() isn't inherently a numeric function but we support it anyway
|
|
20
|
+
// The trigonometric functions are omitted because you'll need to use calc(…) with them _anyway_
|
|
21
|
+
// to produce generally useful results and that will be covered already
|
|
22
|
+
let numericFunctions = [
|
|
23
|
+
"var",
|
|
24
|
+
"calc",
|
|
25
|
+
"min",
|
|
26
|
+
"max",
|
|
27
|
+
"clamp"
|
|
28
|
+
];
|
|
29
|
+
for (const fn of numericFunctions){
|
|
30
|
+
if (value.includes(`${fn}(`)) {
|
|
31
|
+
return `calc(${value} * -1)`;
|
|
32
|
+
}
|
|
20
33
|
}
|
|
21
34
|
}
|
|
@@ -91,9 +91,10 @@ function normalizeConfig(config) {
|
|
|
91
91
|
}
|
|
92
92
|
// When `config.content` is an object
|
|
93
93
|
if (typeof config.content === "object" && config.content !== null) {
|
|
94
|
-
// Only `files`, `extract
|
|
94
|
+
// Only `files`, `relative`, `extract`, and `transform` can exist in `config.content`
|
|
95
95
|
if (Object.keys(config.content).some((key)=>![
|
|
96
96
|
"files",
|
|
97
|
+
"relative",
|
|
97
98
|
"extract",
|
|
98
99
|
"transform"
|
|
99
100
|
].includes(key))) {
|
|
@@ -135,6 +136,10 @@ function normalizeConfig(config) {
|
|
|
135
136
|
} else if (!(config.content.transform === undefined || typeof config.content.transform === "function")) {
|
|
136
137
|
return false;
|
|
137
138
|
}
|
|
139
|
+
// `config.content.relative` is optional and can be a boolean
|
|
140
|
+
if (typeof config.content.relative !== "boolean" && typeof config.content.relative !== "undefined") {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
138
143
|
}
|
|
139
144
|
return true;
|
|
140
145
|
}
|
|
@@ -144,7 +149,7 @@ function normalizeConfig(config) {
|
|
|
144
149
|
_log.default.warn("purge-deprecation", [
|
|
145
150
|
"The `purge`/`content` options have changed in Tailwind CSS v3.0.",
|
|
146
151
|
"Update your configuration file to eliminate this warning.",
|
|
147
|
-
"https://tailwindcss.com/docs/upgrade-guide#configure-content-sources"
|
|
152
|
+
"https://tailwindcss.com/docs/upgrade-guide#configure-content-sources"
|
|
148
153
|
]);
|
|
149
154
|
}
|
|
150
155
|
// Normalize the `safelist`
|
|
@@ -162,7 +167,7 @@ function normalizeConfig(config) {
|
|
|
162
167
|
_log.default.warn("prefix-function", [
|
|
163
168
|
"As of Tailwind CSS v3.0, `prefix` cannot be a function.",
|
|
164
169
|
"Update `prefix` in your configuration to be a string to eliminate this warning.",
|
|
165
|
-
"https://tailwindcss.com/docs/upgrade-guide#prefix-cannot-be-a-function"
|
|
170
|
+
"https://tailwindcss.com/docs/upgrade-guide#prefix-cannot-be-a-function"
|
|
166
171
|
]);
|
|
167
172
|
config.prefix = "";
|
|
168
173
|
} else {
|
|
@@ -171,6 +176,15 @@ function normalizeConfig(config) {
|
|
|
171
176
|
}
|
|
172
177
|
// Normalize the `content`
|
|
173
178
|
config.content = {
|
|
179
|
+
relative: (()=>{
|
|
180
|
+
var ref;
|
|
181
|
+
let { content } = config;
|
|
182
|
+
if (content === null || content === void 0 ? void 0 : content.relative) {
|
|
183
|
+
return content.relative;
|
|
184
|
+
}
|
|
185
|
+
var ref1;
|
|
186
|
+
return (ref1 = (ref = config.future) === null || ref === void 0 ? void 0 : ref.relativeContentPathsByDefault) !== null && ref1 !== void 0 ? ref1 : false;
|
|
187
|
+
})(),
|
|
174
188
|
files: (()=>{
|
|
175
189
|
let { content , purge } = config;
|
|
176
190
|
if (Array.isArray(purge)) return purge;
|
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* @typedef {object} ScreenValue
|
|
3
|
+
* @property {number|undefined} min
|
|
4
|
+
* @property {number|undefined} max
|
|
5
|
+
* @property {string|undefined} raw
|
|
6
|
+
*/ /**
|
|
7
|
+
* @typedef {object} Screen
|
|
8
|
+
* @property {string} name
|
|
9
|
+
* @property {boolean} not
|
|
10
|
+
* @property {ScreenValue[]} values
|
|
11
|
+
*/ /**
|
|
2
12
|
* A function that normalizes the various forms that the screens object can be
|
|
3
13
|
* provided in.
|
|
4
14
|
*
|
|
@@ -10,13 +20,23 @@
|
|
|
10
20
|
*
|
|
11
21
|
* Output(s):
|
|
12
22
|
* - [{ name: 'sm', values: [{ min: '100px', max: '200px' }] }] // List of objects, that contains multiple values
|
|
23
|
+
*
|
|
24
|
+
* @returns {Screen[]}
|
|
13
25
|
*/ "use strict";
|
|
14
26
|
Object.defineProperty(exports, "__esModule", {
|
|
15
27
|
value: true
|
|
16
28
|
});
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
29
|
+
function _export(target, all) {
|
|
30
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: all[name]
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
_export(exports, {
|
|
36
|
+
normalizeScreens: ()=>normalizeScreens,
|
|
37
|
+
isScreenSortable: ()=>isScreenSortable,
|
|
38
|
+
compareScreens: ()=>compareScreens,
|
|
39
|
+
toScreen: ()=>toScreen
|
|
20
40
|
});
|
|
21
41
|
function normalizeScreens(screens, root = true) {
|
|
22
42
|
if (Array.isArray(screens)) {
|
|
@@ -27,6 +47,7 @@ function normalizeScreens(screens, root = true) {
|
|
|
27
47
|
if (typeof screen === "string") {
|
|
28
48
|
return {
|
|
29
49
|
name: screen.toString(),
|
|
50
|
+
not: false,
|
|
30
51
|
values: [
|
|
31
52
|
{
|
|
32
53
|
min: screen,
|
|
@@ -40,6 +61,7 @@ function normalizeScreens(screens, root = true) {
|
|
|
40
61
|
if (typeof options === "string") {
|
|
41
62
|
return {
|
|
42
63
|
name,
|
|
64
|
+
not: false,
|
|
43
65
|
values: [
|
|
44
66
|
{
|
|
45
67
|
min: options,
|
|
@@ -51,11 +73,13 @@ function normalizeScreens(screens, root = true) {
|
|
|
51
73
|
if (Array.isArray(options)) {
|
|
52
74
|
return {
|
|
53
75
|
name,
|
|
76
|
+
not: false,
|
|
54
77
|
values: options.map((option)=>resolveValue(option))
|
|
55
78
|
};
|
|
56
79
|
}
|
|
57
80
|
return {
|
|
58
81
|
name,
|
|
82
|
+
not: false,
|
|
59
83
|
values: [
|
|
60
84
|
resolveValue(options)
|
|
61
85
|
]
|
|
@@ -64,6 +88,79 @@ function normalizeScreens(screens, root = true) {
|
|
|
64
88
|
}
|
|
65
89
|
return normalizeScreens(Object.entries(screens !== null && screens !== void 0 ? screens : {}), false);
|
|
66
90
|
}
|
|
91
|
+
function isScreenSortable(screen) {
|
|
92
|
+
if (screen.values.length !== 1) {
|
|
93
|
+
return {
|
|
94
|
+
result: false,
|
|
95
|
+
reason: "multiple-values"
|
|
96
|
+
};
|
|
97
|
+
} else if (screen.values[0].raw !== undefined) {
|
|
98
|
+
return {
|
|
99
|
+
result: false,
|
|
100
|
+
reason: "raw-values"
|
|
101
|
+
};
|
|
102
|
+
} else if (screen.values[0].min !== undefined && screen.values[0].max !== undefined) {
|
|
103
|
+
return {
|
|
104
|
+
result: false,
|
|
105
|
+
reason: "min-and-max"
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
result: true,
|
|
110
|
+
reason: null
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function compareScreens(type, a, z) {
|
|
114
|
+
let aScreen = toScreen(a, type);
|
|
115
|
+
let zScreen = toScreen(z, type);
|
|
116
|
+
let aSorting = isScreenSortable(aScreen);
|
|
117
|
+
let bSorting = isScreenSortable(zScreen);
|
|
118
|
+
// These cases should never happen and indicate a bug in Tailwind CSS itself
|
|
119
|
+
if (aSorting.reason === "multiple-values" || bSorting.reason === "multiple-values") {
|
|
120
|
+
throw new Error("Attempted to sort a screen with multiple values. This should never happen. Please open a bug report.");
|
|
121
|
+
} else if (aSorting.reason === "raw-values" || bSorting.reason === "raw-values") {
|
|
122
|
+
throw new Error("Attempted to sort a screen with raw values. This should never happen. Please open a bug report.");
|
|
123
|
+
} else if (aSorting.reason === "min-and-max" || bSorting.reason === "min-and-max") {
|
|
124
|
+
throw new Error("Attempted to sort a screen with both min and max values. This should never happen. Please open a bug report.");
|
|
125
|
+
}
|
|
126
|
+
// Let the sorting begin
|
|
127
|
+
let { min: aMin , max: aMax } = aScreen.values[0];
|
|
128
|
+
let { min: zMin , max: zMax } = zScreen.values[0];
|
|
129
|
+
// Negating screens flip their behavior. Basically `not min-width` is `max-width`
|
|
130
|
+
if (a.not) [aMin, aMax] = [
|
|
131
|
+
aMax,
|
|
132
|
+
aMin
|
|
133
|
+
];
|
|
134
|
+
if (z.not) [zMin, zMax] = [
|
|
135
|
+
zMax,
|
|
136
|
+
zMin
|
|
137
|
+
];
|
|
138
|
+
aMin = aMin === undefined ? aMin : parseFloat(aMin);
|
|
139
|
+
aMax = aMax === undefined ? aMax : parseFloat(aMax);
|
|
140
|
+
zMin = zMin === undefined ? zMin : parseFloat(zMin);
|
|
141
|
+
zMax = zMax === undefined ? zMax : parseFloat(zMax);
|
|
142
|
+
let [aValue, zValue] = type === "min" ? [
|
|
143
|
+
aMin,
|
|
144
|
+
zMin
|
|
145
|
+
] : [
|
|
146
|
+
zMax,
|
|
147
|
+
aMax
|
|
148
|
+
];
|
|
149
|
+
return aValue - zValue;
|
|
150
|
+
}
|
|
151
|
+
function toScreen(value, type) {
|
|
152
|
+
if (typeof value === "object") {
|
|
153
|
+
return value;
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
name: "arbitrary-screen",
|
|
157
|
+
values: [
|
|
158
|
+
{
|
|
159
|
+
[type]: value
|
|
160
|
+
}
|
|
161
|
+
]
|
|
162
|
+
};
|
|
163
|
+
}
|
|
67
164
|
function resolveValue({ "min-width": _minWidth , min =_minWidth , max , raw } = {}) {
|
|
68
165
|
return {
|
|
69
166
|
min,
|
|
@@ -24,7 +24,7 @@ let SPACE = /\ +(?![^(]*\))/g // Similar to the one above, but with spaces inste
|
|
|
24
24
|
;
|
|
25
25
|
let LENGTH = /^-?(\d+|\.\d+)(.*?)$/g;
|
|
26
26
|
function parseBoxShadowValue(input) {
|
|
27
|
-
let shadows =
|
|
27
|
+
let shadows = (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(input, ",");
|
|
28
28
|
return shadows.map((shadow)=>{
|
|
29
29
|
let value = shadow.trim();
|
|
30
30
|
let result = {
|