tailwindcss 3.0.0-alpha.1 → 3.0.2
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/colors.js +2 -1
- package/defaultConfig.js +2 -1
- package/defaultTheme.js +2 -1
- package/lib/cli.js +39 -35
- package/lib/constants.js +1 -1
- package/lib/corePluginList.js +10 -1
- package/lib/corePlugins.js +393 -259
- package/lib/css/preflight.css +14 -1
- package/lib/featureFlags.js +12 -7
- package/lib/lib/collapseDuplicateDeclarations.js +29 -0
- package/lib/lib/detectNesting.js +17 -2
- package/lib/lib/evaluateTailwindFunctions.js +9 -5
- package/lib/lib/expandApplyAtRules.js +26 -9
- package/lib/lib/expandTailwindAtRules.js +4 -1
- package/lib/lib/generateRules.js +151 -19
- package/lib/lib/resolveDefaultsAtRules.js +67 -56
- package/lib/lib/setupContextUtils.js +80 -80
- package/lib/lib/setupWatchingContext.js +5 -1
- package/lib/lib/sharedState.js +2 -2
- package/lib/lib/substituteScreenAtRules.js +7 -4
- package/lib/processTailwindFeatures.js +4 -0
- package/lib/util/buildMediaQuery.js +13 -24
- package/lib/util/createUtilityPlugin.js +5 -5
- package/lib/util/dataTypes.js +38 -7
- package/lib/util/formatVariantSelector.js +186 -0
- package/lib/util/isValidArbitraryValue.js +64 -0
- package/lib/util/nameClass.js +2 -1
- package/lib/util/negateValue.js +3 -1
- package/lib/util/normalizeConfig.js +22 -8
- package/lib/util/normalizeScreens.js +61 -0
- package/lib/util/parseBoxShadowValue.js +77 -0
- package/lib/util/pluginUtils.js +62 -158
- package/lib/util/prefixSelector.js +1 -3
- package/lib/util/resolveConfig.js +17 -13
- package/lib/util/transformThemeValue.js +23 -13
- package/package.json +15 -15
- package/peers/index.js +4456 -5450
- package/plugin.js +2 -1
- package/resolveConfig.js +2 -1
- package/src/.DS_Store +0 -0
- package/src/cli.js +9 -2
- package/src/corePluginList.js +1 -1
- package/src/corePlugins.js +392 -404
- package/src/css/preflight.css +14 -1
- package/src/featureFlags.js +14 -4
- package/src/lib/collapseDuplicateDeclarations.js +28 -0
- package/src/lib/detectNesting.js +22 -3
- package/src/lib/evaluateTailwindFunctions.js +5 -2
- package/src/lib/expandApplyAtRules.js +29 -2
- package/src/lib/expandTailwindAtRules.js +5 -2
- package/src/lib/generateRules.js +155 -11
- package/src/lib/resolveDefaultsAtRules.js +67 -50
- package/src/lib/setupContextUtils.js +77 -67
- package/src/lib/setupWatchingContext.js +7 -0
- package/src/lib/sharedState.js +1 -1
- package/src/lib/substituteScreenAtRules.js +6 -3
- package/src/processTailwindFeatures.js +5 -0
- package/src/util/buildMediaQuery.js +14 -18
- package/src/util/createUtilityPlugin.js +2 -2
- package/src/util/dataTypes.js +43 -11
- package/src/util/formatVariantSelector.js +196 -0
- package/src/util/isValidArbitraryValue.js +61 -0
- package/src/util/nameClass.js +2 -2
- package/src/util/negateValue.js +4 -2
- package/src/util/normalizeConfig.js +17 -1
- package/src/util/normalizeScreens.js +45 -0
- package/src/util/parseBoxShadowValue.js +71 -0
- package/src/util/pluginUtils.js +50 -146
- package/src/util/prefixSelector.js +1 -4
- package/src/util/resolveConfig.js +7 -1
- package/src/util/transformThemeValue.js +22 -7
- package/stubs/defaultConfig.stub.js +118 -58
- package/CHANGELOG.md +0 -1759
package/lib/css/preflight.css
CHANGED
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
border-color: currentColor; /* 2 */
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
::before,
|
|
16
|
+
::after {
|
|
17
|
+
--tw-content: '';
|
|
18
|
+
}
|
|
19
|
+
|
|
15
20
|
/*
|
|
16
21
|
1. Use a consistent sensible line-height in all browsers.
|
|
17
22
|
2. Prevent adjustments of font size after orientation changes in iOS.
|
|
@@ -283,7 +288,8 @@ legend {
|
|
|
283
288
|
}
|
|
284
289
|
|
|
285
290
|
ol,
|
|
286
|
-
ul
|
|
291
|
+
ul,
|
|
292
|
+
menu {
|
|
287
293
|
list-style: none;
|
|
288
294
|
margin: 0;
|
|
289
295
|
padding: 0;
|
|
@@ -317,6 +323,13 @@ button,
|
|
|
317
323
|
cursor: pointer;
|
|
318
324
|
}
|
|
319
325
|
|
|
326
|
+
/*
|
|
327
|
+
Make sure disabled buttons don't get the pointer cursor.
|
|
328
|
+
*/
|
|
329
|
+
:disabled {
|
|
330
|
+
cursor: default;
|
|
331
|
+
}
|
|
332
|
+
|
|
320
333
|
/*
|
|
321
334
|
1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
|
|
322
335
|
2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
|
package/lib/featureFlags.js
CHANGED
|
@@ -12,7 +12,12 @@ function _interopRequireDefault(obj) {
|
|
|
12
12
|
default: obj
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
let defaults = {
|
|
16
|
+
// TODO: Drop this once we can safely rely on optimizeUniversalDefaults being
|
|
17
|
+
// the default.
|
|
18
|
+
optimizeUniversalDefaults: process.env.NODE_ENV === 'test' ? true : false
|
|
19
|
+
};
|
|
20
|
+
let featureFlags = {
|
|
16
21
|
future: [],
|
|
17
22
|
experimental: [
|
|
18
23
|
'optimizeUniversalDefaults'
|
|
@@ -21,13 +26,13 @@ const featureFlags = {
|
|
|
21
26
|
function flagEnabled(config, flag) {
|
|
22
27
|
if (featureFlags.future.includes(flag)) {
|
|
23
28
|
var ref;
|
|
24
|
-
var ref1;
|
|
25
|
-
return config.future === 'all' || ((ref1 = config === null || config === void 0 ? void 0 : (ref = config.future) === null || ref === void 0 ? void 0 : ref[flag]) !== null && ref1 !== void 0 ? ref1 : false);
|
|
29
|
+
var ref1, ref2;
|
|
30
|
+
return config.future === 'all' || ((ref2 = (ref1 = config === null || config === void 0 ? void 0 : (ref = config.future) === null || ref === void 0 ? void 0 : ref[flag]) !== null && ref1 !== void 0 ? ref1 : defaults[flag]) !== null && ref2 !== void 0 ? ref2 : false);
|
|
26
31
|
}
|
|
27
32
|
if (featureFlags.experimental.includes(flag)) {
|
|
28
|
-
var
|
|
29
|
-
var ref5;
|
|
30
|
-
return config.experimental === 'all' || ((ref5 = config === null || config === void 0 ? void 0 : (
|
|
33
|
+
var ref3;
|
|
34
|
+
var ref4, ref5;
|
|
35
|
+
return config.experimental === 'all' || ((ref5 = (ref4 = config === null || config === void 0 ? void 0 : (ref3 = config.experimental) === null || ref3 === void 0 ? void 0 : ref3[flag]) !== null && ref4 !== void 0 ? ref4 : defaults[flag]) !== null && ref5 !== void 0 ? ref5 : false);
|
|
31
36
|
}
|
|
32
37
|
return false;
|
|
33
38
|
}
|
|
@@ -45,7 +50,7 @@ function issueFlagNotices(config) {
|
|
|
45
50
|
return;
|
|
46
51
|
}
|
|
47
52
|
if (experimentalFlagsEnabled(config).length > 0) {
|
|
48
|
-
|
|
53
|
+
let changes = experimentalFlagsEnabled(config).map((s)=>_chalk.default.yellow(s)
|
|
49
54
|
).join(', ');
|
|
50
55
|
_log.default.warn('experimental-flags-enabled', [
|
|
51
56
|
`You have enabled experimental features: ${changes}`,
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
exports.default = collapseDuplicateDeclarations;
|
|
6
|
+
function collapseDuplicateDeclarations() {
|
|
7
|
+
return (root)=>{
|
|
8
|
+
root.walkRules((node)=>{
|
|
9
|
+
let seen = new Map();
|
|
10
|
+
let droppable = new Set([]);
|
|
11
|
+
node.walkDecls((decl)=>{
|
|
12
|
+
// This could happen if we have nested selectors. In that case the
|
|
13
|
+
// parent will loop over all its declarations but also the declarations
|
|
14
|
+
// of nested rules. With this we ensure that we are shallowly checking
|
|
15
|
+
// declarations.
|
|
16
|
+
if (decl.parent !== node) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (seen.has(decl.prop)) {
|
|
20
|
+
droppable.add(seen.get(decl.prop));
|
|
21
|
+
}
|
|
22
|
+
seen.set(decl.prop, decl);
|
|
23
|
+
});
|
|
24
|
+
for (let decl1 of droppable){
|
|
25
|
+
decl1.remove();
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
}
|
package/lib/lib/detectNesting.js
CHANGED
|
@@ -6,12 +6,27 @@ exports.default = _default;
|
|
|
6
6
|
function _default(_context) {
|
|
7
7
|
return (root, result)=>{
|
|
8
8
|
let found = false;
|
|
9
|
+
root.walkAtRules('tailwind', (node)=>{
|
|
10
|
+
if (found) return false;
|
|
11
|
+
if (node.parent && node.parent.type !== 'root') {
|
|
12
|
+
found = true;
|
|
13
|
+
node.warn(result, [
|
|
14
|
+
'Nested @tailwind rules were detected, but are not supported.',
|
|
15
|
+
"Consider using a prefix to scope Tailwind's classes: https://tailwindcss.com/docs/configuration#prefix",
|
|
16
|
+
'Alternatively, use the important selector strategy: https://tailwindcss.com/docs/configuration#selector-strategy',
|
|
17
|
+
].join('\n'));
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
9
21
|
root.walkRules((rule)=>{
|
|
10
22
|
if (found) return false;
|
|
11
23
|
rule.walkRules((nestedRule)=>{
|
|
12
24
|
found = true;
|
|
13
|
-
nestedRule.warn(result,
|
|
14
|
-
|
|
25
|
+
nestedRule.warn(result, [
|
|
26
|
+
'Nested CSS was detected, but CSS nesting has not been configured correctly.',
|
|
27
|
+
'Please enable a CSS nesting plugin *before* Tailwind in your configuration.',
|
|
28
|
+
'See how here: https://tailwindcss.com/docs/using-with-preprocessors#nesting',
|
|
29
|
+
].join('\n'));
|
|
15
30
|
return false;
|
|
16
31
|
});
|
|
17
32
|
});
|
|
@@ -7,6 +7,7 @@ var _dlv = _interopRequireDefault(require("dlv"));
|
|
|
7
7
|
var _didyoumean = _interopRequireDefault(require("didyoumean"));
|
|
8
8
|
var _transformThemeValue = _interopRequireDefault(require("../util/transformThemeValue"));
|
|
9
9
|
var _postcssValueParser = _interopRequireDefault(require("postcss-value-parser"));
|
|
10
|
+
var _normalizeScreens = require("../util/normalizeScreens");
|
|
10
11
|
var _buildMediaQuery = _interopRequireDefault(require("../util/buildMediaQuery"));
|
|
11
12
|
var _toPath = require("../util/toPath");
|
|
12
13
|
function _interopRequireDefault(obj) {
|
|
@@ -112,11 +113,11 @@ function extractArgs(node, vNodes, functions) {
|
|
|
112
113
|
let args = [
|
|
113
114
|
''
|
|
114
115
|
];
|
|
115
|
-
for (let
|
|
116
|
-
if (
|
|
116
|
+
for (let vNode1 of vNodes){
|
|
117
|
+
if (vNode1.type === 'div' && vNode1.value === ',') {
|
|
117
118
|
args.push('');
|
|
118
119
|
} else {
|
|
119
|
-
args[args.length - 1] += _postcssValueParser.default.stringify(
|
|
120
|
+
args[args.length - 1] += _postcssValueParser.default.stringify(vNode1);
|
|
120
121
|
}
|
|
121
122
|
}
|
|
122
123
|
return args;
|
|
@@ -149,10 +150,13 @@ function _default({ tailwindConfig: config }) {
|
|
|
149
150
|
},
|
|
150
151
|
screen: (node, screen)=>{
|
|
151
152
|
screen = screen.replace(/^['"]+/g, '').replace(/['"]+$/g, '');
|
|
152
|
-
|
|
153
|
+
let screens = (0, _normalizeScreens).normalizeScreens(config.theme.screens);
|
|
154
|
+
let screenDefinition = screens.find(({ name })=>name === screen
|
|
155
|
+
);
|
|
156
|
+
if (!screenDefinition) {
|
|
153
157
|
throw node.error(`The '${screen}' screen does not exist in your theme.`);
|
|
154
158
|
}
|
|
155
|
-
return (0, _buildMediaQuery).default(
|
|
159
|
+
return (0, _buildMediaQuery).default(screenDefinition);
|
|
156
160
|
}
|
|
157
161
|
};
|
|
158
162
|
return (root)=>{
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
});
|
|
5
5
|
exports.default = expandApplyAtRules;
|
|
6
6
|
var _postcss = _interopRequireDefault(require("postcss"));
|
|
7
|
+
var _postcssSelectorParser = _interopRequireDefault(require("postcss-selector-parser"));
|
|
7
8
|
var _generateRules = require("./generateRules");
|
|
8
9
|
var _bigSign = _interopRequireDefault(require("../util/bigSign"));
|
|
9
10
|
var _escapeClassName = _interopRequireDefault(require("../util/escapeClassName"));
|
|
@@ -12,9 +13,21 @@ function _interopRequireDefault(obj) {
|
|
|
12
13
|
default: obj
|
|
13
14
|
};
|
|
14
15
|
}
|
|
16
|
+
function containsBase(selector, classCandidateBase, separator) {
|
|
17
|
+
return (0, _postcssSelectorParser).default((selectors)=>{
|
|
18
|
+
let contains = false;
|
|
19
|
+
selectors.walkClasses((classSelector)=>{
|
|
20
|
+
if (classSelector.value.split(separator).pop() === classCandidateBase) {
|
|
21
|
+
contains = true;
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
return contains;
|
|
26
|
+
}).transformSync(selector);
|
|
27
|
+
}
|
|
15
28
|
function prefix(context, selector) {
|
|
16
|
-
let
|
|
17
|
-
return typeof
|
|
29
|
+
let prefix1 = context.tailwindConfig.prefix;
|
|
30
|
+
return typeof prefix1 === 'function' ? prefix1(selector) : prefix1 + selector;
|
|
18
31
|
}
|
|
19
32
|
function buildApplyCache(applyCandidates, context) {
|
|
20
33
|
for (let candidate of applyCandidates){
|
|
@@ -56,10 +69,10 @@ function partitionApplyParents(root) {
|
|
|
56
69
|
root.walkAtRules('apply', (rule)=>{
|
|
57
70
|
applyParents.add(rule.parent);
|
|
58
71
|
});
|
|
59
|
-
for (let
|
|
72
|
+
for (let rule1 of applyParents){
|
|
60
73
|
let nodeGroups = [];
|
|
61
74
|
let lastGroup = [];
|
|
62
|
-
for (let node of
|
|
75
|
+
for (let node of rule1.nodes){
|
|
63
76
|
if (node.type === 'atrule' && node.name === 'apply') {
|
|
64
77
|
if (lastGroup.length > 0) {
|
|
65
78
|
nodeGroups.push(lastGroup);
|
|
@@ -81,13 +94,13 @@ function partitionApplyParents(root) {
|
|
|
81
94
|
for (let group of [
|
|
82
95
|
...nodeGroups
|
|
83
96
|
].reverse()){
|
|
84
|
-
let newParent =
|
|
97
|
+
let newParent = rule1.clone({
|
|
85
98
|
nodes: []
|
|
86
99
|
});
|
|
87
100
|
newParent.append(group);
|
|
88
|
-
|
|
101
|
+
rule1.after(newParent);
|
|
89
102
|
}
|
|
90
|
-
|
|
103
|
+
rule1.remove();
|
|
91
104
|
}
|
|
92
105
|
}
|
|
93
106
|
function processApply(root, context) {
|
|
@@ -127,8 +140,8 @@ function processApply(root, context) {
|
|
|
127
140
|
*/ // TODO: Should we use postcss-selector-parser for this instead?
|
|
128
141
|
function replaceSelector(selector, utilitySelectors, candidate) {
|
|
129
142
|
let needle = `.${(0, _escapeClassName).default(candidate)}`;
|
|
130
|
-
let utilitySelectorsList = utilitySelectors.split(/\s
|
|
131
|
-
return selector.split(/\s
|
|
143
|
+
let utilitySelectorsList = utilitySelectors.split(/\s*\,(?![^(]*\))\s*/g);
|
|
144
|
+
return selector.split(/\s*\,(?![^(]*\))\s*/g).map((s)=>{
|
|
132
145
|
let replaced = [];
|
|
133
146
|
for (let utilitySelector of utilitySelectorsList){
|
|
134
147
|
let replacedSelector = utilitySelector.replace(needle, s);
|
|
@@ -173,7 +186,11 @@ function processApply(root, context) {
|
|
|
173
186
|
for (const [parent, candidates] of perParentApplies){
|
|
174
187
|
let siblings = [];
|
|
175
188
|
for (let [applyCandidate, important, rules] of candidates){
|
|
189
|
+
let base = applyCandidate.split(context.tailwindConfig.separator).pop();
|
|
176
190
|
for (let [meta, node] of rules){
|
|
191
|
+
if (containsBase(parent.selector, base, context.tailwindConfig.separator) && containsBase(node.selector, base, context.tailwindConfig.separator)) {
|
|
192
|
+
throw node.error(`Circular dependency detected when using: \`@apply ${applyCandidate}\``);
|
|
193
|
+
}
|
|
177
194
|
let root = _postcss.default.root({
|
|
178
195
|
nodes: [
|
|
179
196
|
node.clone()
|
|
@@ -42,8 +42,12 @@ const PATTERNS = [
|
|
|
42
42
|
/([^<>"'`\s]*\[\w*"[^"`\s]*"?\])/.source,
|
|
43
43
|
/([^<>"'`\s]*\[\w*\('[^"'`\s]*'\)\])/.source,
|
|
44
44
|
/([^<>"'`\s]*\[\w*\("[^"'`\s]*"\)\])/.source,
|
|
45
|
+
/([^<>"'`\s]*\[\w*\('[^"`\s]*'\)\])/.source,
|
|
46
|
+
/([^<>"'`\s]*\[\w*\("[^'`\s]*"\)\])/.source,
|
|
45
47
|
/([^<>"'`\s]*\['[^"'`\s]*'\])/.source,
|
|
46
48
|
/([^<>"'`\s]*\["[^"'`\s]*"\])/.source,
|
|
49
|
+
/([^<>"'`\s]*\[[^<>"'`\s]*:'[^"'`\s]*'\])/.source,
|
|
50
|
+
/([^<>"'`\s]*\[[^<>"'`\s]*:"[^"'`\s]*"\])/.source,
|
|
47
51
|
/([^<>"'`\s]*\[[^"'`\s]+\][^<>"'`\s]*)/.source,
|
|
48
52
|
/([^<>"'`\s]*[^"'`\s:])/.source
|
|
49
53
|
].join('|');
|
|
@@ -230,7 +234,6 @@ function expandTailwindAtRules(context) {
|
|
|
230
234
|
if (env.DEBUG) {
|
|
231
235
|
console.log('Potential classes: ', candidates.size);
|
|
232
236
|
console.log('Active contexts: ', sharedState.contextSourcesMap.size);
|
|
233
|
-
console.log('Content match entries', contentMatchCache.size);
|
|
234
237
|
}
|
|
235
238
|
// Clear the cache for the changed files
|
|
236
239
|
context.changedContent = [];
|
package/lib/lib/generateRules.js
CHANGED
|
@@ -10,6 +10,10 @@ var _isPlainObject = _interopRequireDefault(require("../util/isPlainObject"));
|
|
|
10
10
|
var _prefixSelector = _interopRequireDefault(require("../util/prefixSelector"));
|
|
11
11
|
var _pluginUtils = require("../util/pluginUtils");
|
|
12
12
|
var _log = _interopRequireDefault(require("../util/log"));
|
|
13
|
+
var _formatVariantSelector = require("../util/formatVariantSelector");
|
|
14
|
+
var _nameClass = require("../util/nameClass");
|
|
15
|
+
var _dataTypes = require("../util/dataTypes");
|
|
16
|
+
var _isValidArbitraryValue = _interopRequireDefault(require("../util/isValidArbitraryValue"));
|
|
13
17
|
function _interopRequireDefault(obj) {
|
|
14
18
|
return obj && obj.__esModule ? obj : {
|
|
15
19
|
default: obj
|
|
@@ -119,15 +123,23 @@ function applyVariant(variant, matches, context) {
|
|
|
119
123
|
if (context.variantMap.has(variant)) {
|
|
120
124
|
let variantFunctionTuples = context.variantMap.get(variant);
|
|
121
125
|
let result = [];
|
|
122
|
-
for (let [meta,
|
|
126
|
+
for (let [meta, rule1] of matches){
|
|
123
127
|
let container = _postcss.default.root({
|
|
124
128
|
nodes: [
|
|
125
|
-
|
|
129
|
+
rule1.clone()
|
|
126
130
|
]
|
|
127
131
|
});
|
|
128
132
|
for (let [variantSort, variantFunction] of variantFunctionTuples){
|
|
129
133
|
let clone = container.clone();
|
|
134
|
+
let collectedFormats = [];
|
|
135
|
+
let originals = new Map();
|
|
136
|
+
function prepareBackup() {
|
|
137
|
+
if (originals.size > 0) return; // Already prepared, chicken out
|
|
138
|
+
clone.walkRules((rule)=>originals.set(rule, rule.selector)
|
|
139
|
+
);
|
|
140
|
+
}
|
|
130
141
|
function modifySelectors(modifierFunction) {
|
|
142
|
+
prepareBackup();
|
|
131
143
|
clone.each((rule)=>{
|
|
132
144
|
if (rule.type !== 'rule') {
|
|
133
145
|
return;
|
|
@@ -144,19 +156,71 @@ function applyVariant(variant, matches, context) {
|
|
|
144
156
|
return clone;
|
|
145
157
|
}
|
|
146
158
|
let ruleWithVariant = variantFunction({
|
|
147
|
-
|
|
159
|
+
// Public API
|
|
160
|
+
get container () {
|
|
161
|
+
prepareBackup();
|
|
162
|
+
return clone;
|
|
163
|
+
},
|
|
148
164
|
separator: context.tailwindConfig.separator,
|
|
149
|
-
modifySelectors
|
|
165
|
+
modifySelectors,
|
|
166
|
+
// Private API for now
|
|
167
|
+
wrap (wrapper) {
|
|
168
|
+
let nodes = clone.nodes;
|
|
169
|
+
clone.removeAll();
|
|
170
|
+
wrapper.append(nodes);
|
|
171
|
+
clone.append(wrapper);
|
|
172
|
+
},
|
|
173
|
+
format (selectorFormat) {
|
|
174
|
+
collectedFormats.push(selectorFormat);
|
|
175
|
+
}
|
|
150
176
|
});
|
|
177
|
+
if (typeof ruleWithVariant === 'string') {
|
|
178
|
+
collectedFormats.push(ruleWithVariant);
|
|
179
|
+
}
|
|
151
180
|
if (ruleWithVariant === null) {
|
|
152
181
|
continue;
|
|
153
182
|
}
|
|
183
|
+
// We filled the `originals`, therefore we assume that somebody touched
|
|
184
|
+
// `container` or `modifySelectors`. Let's see if they did, so that we
|
|
185
|
+
// can restore the selectors, and collect the format strings.
|
|
186
|
+
if (originals.size > 0) {
|
|
187
|
+
clone.walkRules((rule)=>{
|
|
188
|
+
if (!originals.has(rule)) return;
|
|
189
|
+
let before = originals.get(rule);
|
|
190
|
+
if (before === rule.selector) return; // No mutation happened
|
|
191
|
+
let modified = rule.selector;
|
|
192
|
+
// Rebuild the base selector, this is what plugin authors would do
|
|
193
|
+
// as well. E.g.: `${variant}${separator}${className}`.
|
|
194
|
+
// However, plugin authors probably also prepend or append certain
|
|
195
|
+
// classes, pseudos, ids, ...
|
|
196
|
+
let rebuiltBase = (0, _postcssSelectorParser).default((selectors)=>{
|
|
197
|
+
selectors.walkClasses((classNode)=>{
|
|
198
|
+
classNode.value = `${variant}${context.tailwindConfig.separator}${classNode.value}`;
|
|
199
|
+
});
|
|
200
|
+
}).processSync(before);
|
|
201
|
+
// Now that we know the original selector, the new selector, and
|
|
202
|
+
// the rebuild part in between, we can replace the part that plugin
|
|
203
|
+
// authors need to rebuild with `&`, and eventually store it in the
|
|
204
|
+
// collectedFormats. Similar to what `format('...')` would do.
|
|
205
|
+
//
|
|
206
|
+
// E.g.:
|
|
207
|
+
// variant: foo
|
|
208
|
+
// selector: .markdown > p
|
|
209
|
+
// modified (by plugin): .foo .foo\\:markdown > p
|
|
210
|
+
// rebuiltBase (internal): .foo\\:markdown > p
|
|
211
|
+
// format: .foo &
|
|
212
|
+
collectedFormats.push(modified.replace(rebuiltBase, '&'));
|
|
213
|
+
rule.selector = before;
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
var _collectedFormats;
|
|
154
217
|
let withOffset = [
|
|
155
218
|
{
|
|
156
219
|
...meta,
|
|
157
|
-
sort: variantSort | meta.sort
|
|
220
|
+
sort: variantSort | meta.sort,
|
|
221
|
+
collectedFormats: ((_collectedFormats = meta.collectedFormats) !== null && _collectedFormats !== void 0 ? _collectedFormats : []).concat(collectedFormats)
|
|
158
222
|
},
|
|
159
|
-
clone.nodes[0]
|
|
223
|
+
clone.nodes[0],
|
|
160
224
|
];
|
|
161
225
|
result.push(withOffset);
|
|
162
226
|
}
|
|
@@ -189,6 +253,31 @@ function parseRules(rule, cache, options = {
|
|
|
189
253
|
options
|
|
190
254
|
];
|
|
191
255
|
}
|
|
256
|
+
function extractArbitraryProperty(classCandidate, context) {
|
|
257
|
+
var ref;
|
|
258
|
+
let [, property, value] = (ref = classCandidate.match(/^\[([a-zA-Z0-9-_]+):(\S+)\]$/)) !== null && ref !== void 0 ? ref : [];
|
|
259
|
+
if (value === undefined) {
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
let normalized = (0, _dataTypes).normalize(value);
|
|
263
|
+
if (!(0, _isValidArbitraryValue).default(normalized)) {
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
return [
|
|
267
|
+
[
|
|
268
|
+
{
|
|
269
|
+
sort: context.arbitraryPropertiesSort,
|
|
270
|
+
layer: 'utilities'
|
|
271
|
+
},
|
|
272
|
+
()=>({
|
|
273
|
+
[(0, _nameClass).asClass(classCandidate)]: {
|
|
274
|
+
[property]: normalized
|
|
275
|
+
}
|
|
276
|
+
})
|
|
277
|
+
,
|
|
278
|
+
],
|
|
279
|
+
];
|
|
280
|
+
}
|
|
192
281
|
function* resolveMatchedPlugins(classCandidate, context) {
|
|
193
282
|
if (context.candidateRuleMap.has(classCandidate)) {
|
|
194
283
|
yield [
|
|
@@ -196,14 +285,28 @@ function* resolveMatchedPlugins(classCandidate, context) {
|
|
|
196
285
|
'DEFAULT'
|
|
197
286
|
];
|
|
198
287
|
}
|
|
288
|
+
yield* (function*(arbitraryPropertyRule) {
|
|
289
|
+
if (arbitraryPropertyRule !== null) {
|
|
290
|
+
yield [
|
|
291
|
+
arbitraryPropertyRule,
|
|
292
|
+
'DEFAULT'
|
|
293
|
+
];
|
|
294
|
+
}
|
|
295
|
+
})(extractArbitraryProperty(classCandidate, context));
|
|
199
296
|
let candidatePrefix = classCandidate;
|
|
200
297
|
let negative = false;
|
|
201
|
-
const twConfigPrefix = context.tailwindConfig.prefix
|
|
298
|
+
const twConfigPrefix = context.tailwindConfig.prefix;
|
|
202
299
|
const twConfigPrefixLen = twConfigPrefix.length;
|
|
203
300
|
if (candidatePrefix[twConfigPrefixLen] === '-') {
|
|
204
301
|
negative = true;
|
|
205
302
|
candidatePrefix = twConfigPrefix + candidatePrefix.slice(twConfigPrefixLen + 1);
|
|
206
303
|
}
|
|
304
|
+
if (negative && context.candidateRuleMap.has(candidatePrefix)) {
|
|
305
|
+
yield [
|
|
306
|
+
context.candidateRuleMap.get(candidatePrefix),
|
|
307
|
+
'-DEFAULT'
|
|
308
|
+
];
|
|
309
|
+
}
|
|
207
310
|
for (let [prefix, modifier] of candidatePermutations(candidatePrefix)){
|
|
208
311
|
if (context.candidateRuleMap.has(prefix)) {
|
|
209
312
|
yield [
|
|
@@ -261,7 +364,7 @@ function* resolveMatches(candidate, context) {
|
|
|
261
364
|
]);
|
|
262
365
|
}
|
|
263
366
|
}
|
|
264
|
-
} else if (modifier === 'DEFAULT') {
|
|
367
|
+
} else if (modifier === 'DEFAULT' || modifier === '-DEFAULT') {
|
|
265
368
|
let ruleSet = plugin;
|
|
266
369
|
let [rules, options] = parseRules(ruleSet, context.postCssNodeCache);
|
|
267
370
|
for (let rule of rules){
|
|
@@ -286,9 +389,9 @@ function* resolveMatches(candidate, context) {
|
|
|
286
389
|
// Only keep the result of the very first plugin if we are dealing with
|
|
287
390
|
// arbitrary values, to protect against ambiguity.
|
|
288
391
|
if (isArbitraryValue(modifier) && matches.length > 1) {
|
|
289
|
-
var
|
|
392
|
+
var ref1;
|
|
290
393
|
let typesPerPlugin = matches.map((match)=>new Set([
|
|
291
|
-
...(
|
|
394
|
+
...(ref1 = typesByMatches.get(match)) !== null && ref1 !== void 0 ? ref1 : []
|
|
292
395
|
])
|
|
293
396
|
);
|
|
294
397
|
// Remove duplicates, so that we can detect proper unique types for each plugin.
|
|
@@ -333,8 +436,26 @@ function* resolveMatches(candidate, context) {
|
|
|
333
436
|
for (let variant of variants){
|
|
334
437
|
matches = applyVariant(variant, matches, context);
|
|
335
438
|
}
|
|
336
|
-
for (let
|
|
337
|
-
|
|
439
|
+
for (let match1 of matches){
|
|
440
|
+
// Apply final format selector
|
|
441
|
+
if (match1[0].collectedFormats) {
|
|
442
|
+
let finalFormat = (0, _formatVariantSelector).formatVariantSelector('&', ...match1[0].collectedFormats);
|
|
443
|
+
let container = _postcss.default.root({
|
|
444
|
+
nodes: [
|
|
445
|
+
match1[1].clone()
|
|
446
|
+
]
|
|
447
|
+
});
|
|
448
|
+
container.walkRules((rule)=>{
|
|
449
|
+
if (inKeyframes(rule)) return;
|
|
450
|
+
rule.selector = (0, _formatVariantSelector).finalizeSelector(finalFormat, {
|
|
451
|
+
selector: rule.selector,
|
|
452
|
+
candidate,
|
|
453
|
+
context
|
|
454
|
+
});
|
|
455
|
+
});
|
|
456
|
+
match1[1] = container.nodes[0];
|
|
457
|
+
}
|
|
458
|
+
yield match1;
|
|
338
459
|
}
|
|
339
460
|
}
|
|
340
461
|
}
|
|
@@ -359,15 +480,28 @@ function generateRules(candidates, context) {
|
|
|
359
480
|
context.classCache.set(candidate, matches);
|
|
360
481
|
allRules.push(matches);
|
|
361
482
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
483
|
+
// Strategy based on `tailwindConfig.important`
|
|
484
|
+
let strategy = ((important)=>{
|
|
485
|
+
if (important === true) {
|
|
486
|
+
return (rule)=>{
|
|
365
487
|
rule.walkDecls((d)=>{
|
|
366
488
|
if (d.parent.type === 'rule' && !inKeyframes(d.parent)) {
|
|
367
489
|
d.important = true;
|
|
368
490
|
}
|
|
369
491
|
});
|
|
370
|
-
}
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
if (typeof important === 'string') {
|
|
495
|
+
return (rule)=>{
|
|
496
|
+
rule.selectors = rule.selectors.map((selector)=>{
|
|
497
|
+
return `${important} ${selector}`;
|
|
498
|
+
});
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
})(context.tailwindConfig.important);
|
|
502
|
+
return allRules.flat(1).map(([{ sort , layer , options }, rule])=>{
|
|
503
|
+
if (options.respectImportant) {
|
|
504
|
+
if (strategy) {
|
|
371
505
|
let container = _postcss.default.root({
|
|
372
506
|
nodes: [
|
|
373
507
|
rule.clone()
|
|
@@ -377,9 +511,7 @@ function generateRules(candidates, context) {
|
|
|
377
511
|
if (inKeyframes(r)) {
|
|
378
512
|
return;
|
|
379
513
|
}
|
|
380
|
-
r
|
|
381
|
-
return `${context.tailwindConfig.important} ${selector}`;
|
|
382
|
-
});
|
|
514
|
+
strategy(r);
|
|
383
515
|
});
|
|
384
516
|
rule = container.nodes[0];
|
|
385
517
|
}
|