tailwindcss 3.0.11 → 3.0.12
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 +18 -4
- package/lib/corePlugins.js +114 -142
- package/lib/css/preflight.css +1 -1
- package/lib/featureFlags.js +1 -3
- package/lib/lib/expandApplyAtRules.js +0 -40
- package/lib/lib/expandTailwindAtRules.js +3 -25
- package/lib/lib/resolveDefaultsAtRules.js +4 -4
- package/lib/lib/setupContextUtils.js +124 -68
- package/lib/processTailwindFeatures.js +1 -1
- package/lib/util/pluginUtils.js +1 -1
- package/package.json +3 -3
- package/peers/index.js +606 -606
- package/src/corePlugins.js +121 -155
- package/src/css/preflight.css +1 -1
- package/src/featureFlags.js +1 -5
- package/src/lib/expandApplyAtRules.js +0 -42
- package/src/lib/expandTailwindAtRules.js +3 -23
- package/src/lib/resolveDefaultsAtRules.js +5 -5
- package/src/lib/setupContextUtils.js +100 -18
- package/src/processTailwindFeatures.js +2 -1
- package/src/util/pluginUtils.js +1 -1
|
@@ -129,8 +129,6 @@ function buildStylesheet(rules, context) {
|
|
|
129
129
|
return returnValue
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
export const DEFAULTS_LAYER = Symbol('defaults-layer')
|
|
133
|
-
|
|
134
132
|
export default function expandTailwindAtRules(context) {
|
|
135
133
|
return (root) => {
|
|
136
134
|
let layerNodes = {
|
|
@@ -140,8 +138,6 @@ export default function expandTailwindAtRules(context) {
|
|
|
140
138
|
variants: null,
|
|
141
139
|
}
|
|
142
140
|
|
|
143
|
-
// let hasApply = false
|
|
144
|
-
|
|
145
141
|
root.walkAtRules((rule) => {
|
|
146
142
|
// Make sure this file contains Tailwind directives. If not, we can save
|
|
147
143
|
// a lot of work and bail early. Also we don't have to register our touch
|
|
@@ -152,13 +148,6 @@ export default function expandTailwindAtRules(context) {
|
|
|
152
148
|
layerNodes[rule.params] = rule
|
|
153
149
|
}
|
|
154
150
|
}
|
|
155
|
-
|
|
156
|
-
// We also want to check for @apply because the user can
|
|
157
|
-
// apply classes in an isolated environment like CSS
|
|
158
|
-
// modules and we still need to inject defaults
|
|
159
|
-
// if (rule.name === 'apply') {
|
|
160
|
-
// hasApply = true
|
|
161
|
-
// }
|
|
162
151
|
})
|
|
163
152
|
|
|
164
153
|
if (Object.values(layerNodes).every((n) => n === null)) {
|
|
@@ -179,6 +168,8 @@ export default function expandTailwindAtRules(context) {
|
|
|
179
168
|
getClassCandidates(transformer(content), extractor, candidates, seen)
|
|
180
169
|
}
|
|
181
170
|
|
|
171
|
+
env.DEBUG && console.timeEnd('Reading changed files')
|
|
172
|
+
|
|
182
173
|
// ---
|
|
183
174
|
|
|
184
175
|
// Generate the actual CSS
|
|
@@ -212,18 +203,7 @@ export default function expandTailwindAtRules(context) {
|
|
|
212
203
|
// Replace any Tailwind directives with generated CSS
|
|
213
204
|
|
|
214
205
|
if (layerNodes.base) {
|
|
215
|
-
layerNodes.base.before(cloneNodes([...baseNodes], layerNodes.base.source))
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// @defaults rules are unconditionally added first to ensure that
|
|
219
|
-
// using any utility that relies on defaults will work even when
|
|
220
|
-
// compiled in an isolated environment like CSS modules
|
|
221
|
-
if (context.tailwindConfig[DEFAULTS_LAYER] !== false) {
|
|
222
|
-
if (layerNodes.base) {
|
|
223
|
-
layerNodes.base.after(cloneNodes([...defaultNodes], root.source))
|
|
224
|
-
} else {
|
|
225
|
-
root.prepend(cloneNodes([...defaultNodes], root.source))
|
|
226
|
-
}
|
|
206
|
+
layerNodes.base.before(cloneNodes([...baseNodes, ...defaultNodes], layerNodes.base.source))
|
|
227
207
|
}
|
|
228
208
|
|
|
229
209
|
if (layerNodes.base) {
|
|
@@ -113,12 +113,12 @@ export default function resolveDefaultsAtRules({ tailwindConfig }) {
|
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
if (selectorGroups.size === 0) {
|
|
117
|
-
universal.remove()
|
|
118
|
-
continue
|
|
119
|
-
}
|
|
120
|
-
|
|
121
116
|
if (flagEnabled(tailwindConfig, 'optimizeUniversalDefaults')) {
|
|
117
|
+
if (selectorGroups.size === 0) {
|
|
118
|
+
universal.remove()
|
|
119
|
+
continue
|
|
120
|
+
}
|
|
121
|
+
|
|
122
122
|
for (let [, selectors] of selectorGroups) {
|
|
123
123
|
let universalRule = postcss.rule()
|
|
124
124
|
|
|
@@ -20,6 +20,58 @@ import log from '../util/log'
|
|
|
20
20
|
import negateValue from '../util/negateValue'
|
|
21
21
|
import isValidArbitraryValue from '../util/isValidArbitraryValue'
|
|
22
22
|
|
|
23
|
+
function partitionRules(root) {
|
|
24
|
+
if (!root.walkAtRules) return [root]
|
|
25
|
+
|
|
26
|
+
let applyParents = new Set()
|
|
27
|
+
let rules = []
|
|
28
|
+
|
|
29
|
+
root.walkAtRules('apply', (rule) => {
|
|
30
|
+
applyParents.add(rule.parent)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
if (applyParents.size === 0) {
|
|
34
|
+
rules.push(root)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
for (let rule of applyParents) {
|
|
38
|
+
let nodeGroups = []
|
|
39
|
+
let lastGroup = []
|
|
40
|
+
|
|
41
|
+
for (let node of rule.nodes) {
|
|
42
|
+
if (node.type === 'atrule' && node.name === 'apply') {
|
|
43
|
+
if (lastGroup.length > 0) {
|
|
44
|
+
nodeGroups.push(lastGroup)
|
|
45
|
+
lastGroup = []
|
|
46
|
+
}
|
|
47
|
+
nodeGroups.push([node])
|
|
48
|
+
} else {
|
|
49
|
+
lastGroup.push(node)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (lastGroup.length > 0) {
|
|
54
|
+
nodeGroups.push(lastGroup)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (nodeGroups.length === 1) {
|
|
58
|
+
rules.push(rule)
|
|
59
|
+
continue
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
for (let group of [...nodeGroups].reverse()) {
|
|
63
|
+
let clone = rule.clone({ nodes: [] })
|
|
64
|
+
clone.append(group)
|
|
65
|
+
rules.unshift(clone)
|
|
66
|
+
rule.after(clone)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
rule.remove()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return rules
|
|
73
|
+
}
|
|
74
|
+
|
|
23
75
|
function parseVariantFormatString(input) {
|
|
24
76
|
if (input.includes('{')) {
|
|
25
77
|
if (!isBalanced(input)) throw new Error(`Your { and } are unbalanced.`)
|
|
@@ -89,39 +141,55 @@ function getClasses(selector) {
|
|
|
89
141
|
return parser.transformSync(selector)
|
|
90
142
|
}
|
|
91
143
|
|
|
92
|
-
function extractCandidates(node) {
|
|
144
|
+
function extractCandidates(node, state = { containsNonOnDemandable: false }, depth = 0) {
|
|
93
145
|
let classes = []
|
|
94
146
|
|
|
147
|
+
// Handle normal rules
|
|
95
148
|
if (node.type === 'rule') {
|
|
96
149
|
for (let selector of node.selectors) {
|
|
97
150
|
let classCandidates = getClasses(selector)
|
|
98
151
|
// At least one of the selectors contains non-"on-demandable" candidates.
|
|
99
|
-
if (classCandidates.length === 0)
|
|
152
|
+
if (classCandidates.length === 0) {
|
|
153
|
+
state.containsNonOnDemandable = true
|
|
154
|
+
}
|
|
100
155
|
|
|
101
|
-
|
|
156
|
+
for (let classCandidate of classCandidates) {
|
|
157
|
+
classes.push(classCandidate)
|
|
158
|
+
}
|
|
102
159
|
}
|
|
103
|
-
return classes
|
|
104
160
|
}
|
|
105
161
|
|
|
106
|
-
|
|
162
|
+
// Handle at-rules (which contains nested rules)
|
|
163
|
+
else if (node.type === 'atrule') {
|
|
107
164
|
node.walkRules((rule) => {
|
|
108
|
-
|
|
165
|
+
for (let classCandidate of rule.selectors.flatMap((selector) =>
|
|
166
|
+
getClasses(selector, state, depth + 1)
|
|
167
|
+
)) {
|
|
168
|
+
classes.push(classCandidate)
|
|
169
|
+
}
|
|
109
170
|
})
|
|
110
171
|
}
|
|
111
172
|
|
|
173
|
+
if (depth === 0) {
|
|
174
|
+
return [state.containsNonOnDemandable || classes.length === 0, classes]
|
|
175
|
+
}
|
|
176
|
+
|
|
112
177
|
return classes
|
|
113
178
|
}
|
|
114
179
|
|
|
115
180
|
function withIdentifiers(styles) {
|
|
116
181
|
return parseStyles(styles).flatMap((node) => {
|
|
117
182
|
let nodeMap = new Map()
|
|
118
|
-
let candidates = extractCandidates(node)
|
|
183
|
+
let [containsNonOnDemandableSelectors, candidates] = extractCandidates(node)
|
|
119
184
|
|
|
120
|
-
// If this isn't "on-demandable", assign it a universal candidate.
|
|
121
|
-
if (
|
|
122
|
-
|
|
185
|
+
// If this isn't "on-demandable", assign it a universal candidate to always include it.
|
|
186
|
+
if (containsNonOnDemandableSelectors) {
|
|
187
|
+
candidates.unshift('*')
|
|
123
188
|
}
|
|
124
189
|
|
|
190
|
+
// However, it could be that it also contains "on-demandable" candidates.
|
|
191
|
+
// E.g.: `span, .foo {}`, in that case it should still be possible to use
|
|
192
|
+
// `@apply foo` for example.
|
|
125
193
|
return candidates.map((c) => {
|
|
126
194
|
if (!nodeMap.has(node)) {
|
|
127
195
|
nodeMap.set(node, node)
|
|
@@ -216,7 +284,9 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|
|
216
284
|
context.candidateRuleMap.set(identifier, [])
|
|
217
285
|
}
|
|
218
286
|
|
|
219
|
-
context.candidateRuleMap
|
|
287
|
+
context.candidateRuleMap
|
|
288
|
+
.get(identifier)
|
|
289
|
+
.push(...partitionRules(rule).map((rule) => [{ sort: offset, layer: 'user' }, rule]))
|
|
220
290
|
}
|
|
221
291
|
},
|
|
222
292
|
addBase(base) {
|
|
@@ -230,7 +300,7 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|
|
230
300
|
|
|
231
301
|
context.candidateRuleMap
|
|
232
302
|
.get(prefixedIdentifier)
|
|
233
|
-
.push([{ sort: offset, layer: 'base' }, rule])
|
|
303
|
+
.push(...partitionRules(rule).map((rule) => [{ sort: offset, layer: 'base' }, rule]))
|
|
234
304
|
}
|
|
235
305
|
},
|
|
236
306
|
/**
|
|
@@ -244,7 +314,6 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|
|
244
314
|
|
|
245
315
|
for (let [identifier, rule] of withIdentifiers(groups)) {
|
|
246
316
|
let prefixedIdentifier = prefixIdentifier(identifier, {})
|
|
247
|
-
let offset = offsets.base++
|
|
248
317
|
|
|
249
318
|
if (!context.candidateRuleMap.has(prefixedIdentifier)) {
|
|
250
319
|
context.candidateRuleMap.set(prefixedIdentifier, [])
|
|
@@ -252,7 +321,12 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|
|
252
321
|
|
|
253
322
|
context.candidateRuleMap
|
|
254
323
|
.get(prefixedIdentifier)
|
|
255
|
-
.push(
|
|
324
|
+
.push(
|
|
325
|
+
...partitionRules(rule).map((rule) => [
|
|
326
|
+
{ sort: offsets.base++, layer: 'defaults' },
|
|
327
|
+
rule,
|
|
328
|
+
])
|
|
329
|
+
)
|
|
256
330
|
}
|
|
257
331
|
},
|
|
258
332
|
addComponents(components, options) {
|
|
@@ -265,7 +339,6 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|
|
265
339
|
|
|
266
340
|
for (let [identifier, rule] of withIdentifiers(components)) {
|
|
267
341
|
let prefixedIdentifier = prefixIdentifier(identifier, options)
|
|
268
|
-
let offset = offsets.components++
|
|
269
342
|
|
|
270
343
|
classList.add(prefixedIdentifier)
|
|
271
344
|
|
|
@@ -275,7 +348,12 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|
|
275
348
|
|
|
276
349
|
context.candidateRuleMap
|
|
277
350
|
.get(prefixedIdentifier)
|
|
278
|
-
.push(
|
|
351
|
+
.push(
|
|
352
|
+
...partitionRules(rule).map((rule) => [
|
|
353
|
+
{ sort: offsets.components++, layer: 'components', options },
|
|
354
|
+
rule,
|
|
355
|
+
])
|
|
356
|
+
)
|
|
279
357
|
}
|
|
280
358
|
},
|
|
281
359
|
addUtilities(utilities, options) {
|
|
@@ -288,7 +366,6 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|
|
288
366
|
|
|
289
367
|
for (let [identifier, rule] of withIdentifiers(utilities)) {
|
|
290
368
|
let prefixedIdentifier = prefixIdentifier(identifier, options)
|
|
291
|
-
let offset = offsets.utilities++
|
|
292
369
|
|
|
293
370
|
classList.add(prefixedIdentifier)
|
|
294
371
|
|
|
@@ -298,7 +375,12 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|
|
298
375
|
|
|
299
376
|
context.candidateRuleMap
|
|
300
377
|
.get(prefixedIdentifier)
|
|
301
|
-
.push(
|
|
378
|
+
.push(
|
|
379
|
+
...partitionRules(rule).map((rule) => [
|
|
380
|
+
{ sort: offsets.utilities++, layer: 'utilities', options },
|
|
381
|
+
rule,
|
|
382
|
+
])
|
|
383
|
+
)
|
|
302
384
|
}
|
|
303
385
|
},
|
|
304
386
|
matchUtilities: function (utilities, options) {
|
|
@@ -14,6 +14,8 @@ export default function processTailwindFeatures(setupContext) {
|
|
|
14
14
|
return function (root, result) {
|
|
15
15
|
let { tailwindDirectives, applyDirectives } = normalizeTailwindDirectives(root)
|
|
16
16
|
|
|
17
|
+
detectNesting()(root, result)
|
|
18
|
+
|
|
17
19
|
let context = setupContext({
|
|
18
20
|
tailwindDirectives,
|
|
19
21
|
applyDirectives,
|
|
@@ -37,7 +39,6 @@ export default function processTailwindFeatures(setupContext) {
|
|
|
37
39
|
|
|
38
40
|
issueFlagNotices(context.tailwindConfig)
|
|
39
41
|
|
|
40
|
-
detectNesting(context)(root, result)
|
|
41
42
|
expandTailwindAtRules(context)(root, result)
|
|
42
43
|
expandApplyAtRules(context)(root, result)
|
|
43
44
|
evaluateTailwindFunctions(context)(root, result)
|
package/src/util/pluginUtils.js
CHANGED
|
@@ -185,7 +185,7 @@ export function coerceValue(types, modifier, options, tailwindConfig) {
|
|
|
185
185
|
// Find first matching type
|
|
186
186
|
for (let type of [].concat(types)) {
|
|
187
187
|
let result = typeMap[type](modifier, options, { tailwindConfig })
|
|
188
|
-
if (result) return [result, type]
|
|
188
|
+
if (result !== undefined) return [result, type]
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
return []
|