tailwindcss 3.0.9 → 3.0.13
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 +43 -1
- package/lib/cli.js +57 -28
- package/lib/corePlugins.js +183 -280
- package/lib/css/preflight.css +1 -1
- package/lib/featureFlags.js +2 -5
- package/lib/lib/expandApplyAtRules.js +0 -40
- package/lib/lib/expandTailwindAtRules.js +14 -29
- package/lib/lib/generateRules.js +1 -2
- package/lib/lib/normalizeTailwindDirectives.js +8 -1
- package/lib/lib/partitionApplyAtRules.js +53 -0
- package/lib/lib/resolveDefaultsAtRules.js +4 -4
- package/lib/lib/setupContextUtils.js +48 -52
- package/lib/lib/setupTrackingContext.js +11 -10
- package/lib/processTailwindFeatures.js +5 -2
- package/lib/util/createPlugin.js +1 -2
- package/lib/util/createUtilityPlugin.js +4 -8
- package/lib/util/flattenColorPalette.js +1 -3
- package/lib/util/normalizeConfig.js +6 -12
- package/lib/util/normalizeScreens.js +2 -4
- package/lib/util/pluginUtils.js +6 -13
- package/lib/util/resolveConfig.js +9 -18
- package/lib/util/resolveConfigPath.js +1 -2
- package/lib/util/toColorValue.js +1 -2
- package/lib/util/transformThemeValue.js +4 -8
- package/package.json +8 -10
- package/peers/index.js +652 -651
- package/src/cli.js +57 -12
- 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 +12 -21
- package/src/lib/normalizeTailwindDirectives.js +6 -1
- package/src/lib/partitionApplyAtRules.js +52 -0
- package/src/lib/resolveDefaultsAtRules.js +5 -5
- package/src/lib/setupContextUtils.js +37 -17
- package/src/lib/setupTrackingContext.js +11 -10
- package/src/processTailwindFeatures.js +6 -2
- package/src/util/pluginUtils.js +1 -1
package/src/css/preflight.css
CHANGED
package/src/featureFlags.js
CHANGED
|
@@ -2,11 +2,7 @@ import chalk from 'chalk'
|
|
|
2
2
|
import log from './util/log'
|
|
3
3
|
|
|
4
4
|
let defaults = {
|
|
5
|
-
|
|
6
|
-
// the default.
|
|
7
|
-
optimizeUniversalDefaults: process.env.NODE_ENV === 'test' ? true : false,
|
|
8
|
-
|
|
9
|
-
// optimizeUniversalDefaults: true
|
|
5
|
+
optimizeUniversalDefaults: false,
|
|
10
6
|
}
|
|
11
7
|
|
|
12
8
|
let featureFlags = {
|
|
@@ -72,47 +72,6 @@ function extractApplyCandidates(params) {
|
|
|
72
72
|
return [candidates, false]
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
function partitionApplyParents(root) {
|
|
76
|
-
let applyParents = new Set()
|
|
77
|
-
|
|
78
|
-
root.walkAtRules('apply', (rule) => {
|
|
79
|
-
applyParents.add(rule.parent)
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
for (let rule of applyParents) {
|
|
83
|
-
let nodeGroups = []
|
|
84
|
-
let lastGroup = []
|
|
85
|
-
|
|
86
|
-
for (let node of rule.nodes) {
|
|
87
|
-
if (node.type === 'atrule' && node.name === 'apply') {
|
|
88
|
-
if (lastGroup.length > 0) {
|
|
89
|
-
nodeGroups.push(lastGroup)
|
|
90
|
-
lastGroup = []
|
|
91
|
-
}
|
|
92
|
-
nodeGroups.push([node])
|
|
93
|
-
} else {
|
|
94
|
-
lastGroup.push(node)
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (lastGroup.length > 0) {
|
|
99
|
-
nodeGroups.push(lastGroup)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (nodeGroups.length === 1) {
|
|
103
|
-
continue
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
for (let group of [...nodeGroups].reverse()) {
|
|
107
|
-
let newParent = rule.clone({ nodes: [] })
|
|
108
|
-
newParent.append(group)
|
|
109
|
-
rule.after(newParent)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
rule.remove()
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
75
|
function processApply(root, context) {
|
|
117
76
|
let applyCandidates = new Set()
|
|
118
77
|
|
|
@@ -343,7 +302,6 @@ function processApply(root, context) {
|
|
|
343
302
|
|
|
344
303
|
export default function expandApplyAtRules(context) {
|
|
345
304
|
return (root) => {
|
|
346
|
-
partitionApplyParents(root)
|
|
347
305
|
processApply(root, context)
|
|
348
306
|
}
|
|
349
307
|
}
|
|
@@ -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,13 +138,15 @@ export default function expandTailwindAtRules(context) {
|
|
|
140
138
|
variants: null,
|
|
141
139
|
}
|
|
142
140
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
if (
|
|
149
|
-
layerNodes
|
|
141
|
+
root.walkAtRules((rule) => {
|
|
142
|
+
// Make sure this file contains Tailwind directives. If not, we can save
|
|
143
|
+
// a lot of work and bail early. Also we don't have to register our touch
|
|
144
|
+
// file as a dependency since the output of this CSS does not depend on
|
|
145
|
+
// the source of any templates. Think Vue <style> blocks for example.
|
|
146
|
+
if (rule.name === 'tailwind') {
|
|
147
|
+
if (Object.keys(layerNodes).includes(rule.params)) {
|
|
148
|
+
layerNodes[rule.params] = rule
|
|
149
|
+
}
|
|
150
150
|
}
|
|
151
151
|
})
|
|
152
152
|
|
|
@@ -168,6 +168,8 @@ export default function expandTailwindAtRules(context) {
|
|
|
168
168
|
getClassCandidates(transformer(content), extractor, candidates, seen)
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
env.DEBUG && console.timeEnd('Reading changed files')
|
|
172
|
+
|
|
171
173
|
// ---
|
|
172
174
|
|
|
173
175
|
// Generate the actual CSS
|
|
@@ -201,18 +203,7 @@ export default function expandTailwindAtRules(context) {
|
|
|
201
203
|
// Replace any Tailwind directives with generated CSS
|
|
202
204
|
|
|
203
205
|
if (layerNodes.base) {
|
|
204
|
-
layerNodes.base.before(cloneNodes([...baseNodes], layerNodes.base.source))
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// @defaults rules are unconditionally added first to ensure that
|
|
208
|
-
// using any utility that relies on defaults will work even when
|
|
209
|
-
// compiled in an isolated environment like CSS modules
|
|
210
|
-
if (context.tailwindConfig[DEFAULTS_LAYER] !== false) {
|
|
211
|
-
if (layerNodes.base) {
|
|
212
|
-
layerNodes.base.after(cloneNodes([...defaultNodes], root.source))
|
|
213
|
-
} else {
|
|
214
|
-
root.prepend(cloneNodes([...defaultNodes], root.source))
|
|
215
|
-
}
|
|
206
|
+
layerNodes.base.before(cloneNodes([...baseNodes, ...defaultNodes], layerNodes.base.source))
|
|
216
207
|
}
|
|
217
208
|
|
|
218
209
|
if (layerNodes.base) {
|
|
@@ -3,8 +3,13 @@ import log from '../util/log'
|
|
|
3
3
|
export default function normalizeTailwindDirectives(root) {
|
|
4
4
|
let tailwindDirectives = new Set()
|
|
5
5
|
let layerDirectives = new Set()
|
|
6
|
+
let applyDirectives = new Set()
|
|
6
7
|
|
|
7
8
|
root.walkAtRules((atRule) => {
|
|
9
|
+
if (atRule.name === 'apply') {
|
|
10
|
+
applyDirectives.add(atRule)
|
|
11
|
+
}
|
|
12
|
+
|
|
8
13
|
if (atRule.name === 'import') {
|
|
9
14
|
if (atRule.params === '"tailwindcss/base"' || atRule.params === "'tailwindcss/base'") {
|
|
10
15
|
atRule.name = 'tailwind'
|
|
@@ -74,5 +79,5 @@ export default function normalizeTailwindDirectives(root) {
|
|
|
74
79
|
}
|
|
75
80
|
}
|
|
76
81
|
|
|
77
|
-
return tailwindDirectives
|
|
82
|
+
return { tailwindDirectives, applyDirectives }
|
|
78
83
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
function partitionRules(root) {
|
|
2
|
+
if (!root.walkAtRules) return
|
|
3
|
+
|
|
4
|
+
let applyParents = new Set()
|
|
5
|
+
|
|
6
|
+
root.walkAtRules('apply', (rule) => {
|
|
7
|
+
applyParents.add(rule.parent)
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
if (applyParents.size === 0) {
|
|
11
|
+
return
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
for (let rule of applyParents) {
|
|
15
|
+
let nodeGroups = []
|
|
16
|
+
let lastGroup = []
|
|
17
|
+
|
|
18
|
+
for (let node of rule.nodes) {
|
|
19
|
+
if (node.type === 'atrule' && node.name === 'apply') {
|
|
20
|
+
if (lastGroup.length > 0) {
|
|
21
|
+
nodeGroups.push(lastGroup)
|
|
22
|
+
lastGroup = []
|
|
23
|
+
}
|
|
24
|
+
nodeGroups.push([node])
|
|
25
|
+
} else {
|
|
26
|
+
lastGroup.push(node)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (lastGroup.length > 0) {
|
|
31
|
+
nodeGroups.push(lastGroup)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (nodeGroups.length === 1) {
|
|
35
|
+
continue
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
for (let group of [...nodeGroups].reverse()) {
|
|
39
|
+
let clone = rule.clone({ nodes: [] })
|
|
40
|
+
clone.append(group)
|
|
41
|
+
rule.after(clone)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
rule.remove()
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export default function expandApplyAtRules() {
|
|
49
|
+
return (root) => {
|
|
50
|
+
partitionRules(root)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -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
|
|
|
@@ -89,39 +89,55 @@ function getClasses(selector) {
|
|
|
89
89
|
return parser.transformSync(selector)
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
function extractCandidates(node) {
|
|
92
|
+
function extractCandidates(node, state = { containsNonOnDemandable: false }, depth = 0) {
|
|
93
93
|
let classes = []
|
|
94
94
|
|
|
95
|
+
// Handle normal rules
|
|
95
96
|
if (node.type === 'rule') {
|
|
96
97
|
for (let selector of node.selectors) {
|
|
97
98
|
let classCandidates = getClasses(selector)
|
|
98
99
|
// At least one of the selectors contains non-"on-demandable" candidates.
|
|
99
|
-
if (classCandidates.length === 0)
|
|
100
|
+
if (classCandidates.length === 0) {
|
|
101
|
+
state.containsNonOnDemandable = true
|
|
102
|
+
}
|
|
100
103
|
|
|
101
|
-
|
|
104
|
+
for (let classCandidate of classCandidates) {
|
|
105
|
+
classes.push(classCandidate)
|
|
106
|
+
}
|
|
102
107
|
}
|
|
103
|
-
return classes
|
|
104
108
|
}
|
|
105
109
|
|
|
106
|
-
|
|
110
|
+
// Handle at-rules (which contains nested rules)
|
|
111
|
+
else if (node.type === 'atrule') {
|
|
107
112
|
node.walkRules((rule) => {
|
|
108
|
-
|
|
113
|
+
for (let classCandidate of rule.selectors.flatMap((selector) =>
|
|
114
|
+
getClasses(selector, state, depth + 1)
|
|
115
|
+
)) {
|
|
116
|
+
classes.push(classCandidate)
|
|
117
|
+
}
|
|
109
118
|
})
|
|
110
119
|
}
|
|
111
120
|
|
|
121
|
+
if (depth === 0) {
|
|
122
|
+
return [state.containsNonOnDemandable || classes.length === 0, classes]
|
|
123
|
+
}
|
|
124
|
+
|
|
112
125
|
return classes
|
|
113
126
|
}
|
|
114
127
|
|
|
115
128
|
function withIdentifiers(styles) {
|
|
116
129
|
return parseStyles(styles).flatMap((node) => {
|
|
117
130
|
let nodeMap = new Map()
|
|
118
|
-
let candidates = extractCandidates(node)
|
|
131
|
+
let [containsNonOnDemandableSelectors, candidates] = extractCandidates(node)
|
|
119
132
|
|
|
120
|
-
// If this isn't "on-demandable", assign it a universal candidate.
|
|
121
|
-
if (
|
|
122
|
-
|
|
133
|
+
// If this isn't "on-demandable", assign it a universal candidate to always include it.
|
|
134
|
+
if (containsNonOnDemandableSelectors) {
|
|
135
|
+
candidates.unshift('*')
|
|
123
136
|
}
|
|
124
137
|
|
|
138
|
+
// However, it could be that it also contains "on-demandable" candidates.
|
|
139
|
+
// E.g.: `span, .foo {}`, in that case it should still be possible to use
|
|
140
|
+
// `@apply foo` for example.
|
|
125
141
|
return candidates.map((c) => {
|
|
126
142
|
if (!nodeMap.has(node)) {
|
|
127
143
|
nodeMap.set(node, node)
|
|
@@ -244,7 +260,6 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|
|
244
260
|
|
|
245
261
|
for (let [identifier, rule] of withIdentifiers(groups)) {
|
|
246
262
|
let prefixedIdentifier = prefixIdentifier(identifier, {})
|
|
247
|
-
let offset = offsets.base++
|
|
248
263
|
|
|
249
264
|
if (!context.candidateRuleMap.has(prefixedIdentifier)) {
|
|
250
265
|
context.candidateRuleMap.set(prefixedIdentifier, [])
|
|
@@ -252,7 +267,7 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|
|
252
267
|
|
|
253
268
|
context.candidateRuleMap
|
|
254
269
|
.get(prefixedIdentifier)
|
|
255
|
-
.push([{ sort:
|
|
270
|
+
.push([{ sort: offsets.base++, layer: 'defaults' }, rule])
|
|
256
271
|
}
|
|
257
272
|
},
|
|
258
273
|
addComponents(components, options) {
|
|
@@ -265,7 +280,6 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|
|
265
280
|
|
|
266
281
|
for (let [identifier, rule] of withIdentifiers(components)) {
|
|
267
282
|
let prefixedIdentifier = prefixIdentifier(identifier, options)
|
|
268
|
-
let offset = offsets.components++
|
|
269
283
|
|
|
270
284
|
classList.add(prefixedIdentifier)
|
|
271
285
|
|
|
@@ -275,7 +289,7 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|
|
275
289
|
|
|
276
290
|
context.candidateRuleMap
|
|
277
291
|
.get(prefixedIdentifier)
|
|
278
|
-
.push([{ sort:
|
|
292
|
+
.push([{ sort: offsets.components++, layer: 'components', options }, rule])
|
|
279
293
|
}
|
|
280
294
|
},
|
|
281
295
|
addUtilities(utilities, options) {
|
|
@@ -288,7 +302,6 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|
|
288
302
|
|
|
289
303
|
for (let [identifier, rule] of withIdentifiers(utilities)) {
|
|
290
304
|
let prefixedIdentifier = prefixIdentifier(identifier, options)
|
|
291
|
-
let offset = offsets.utilities++
|
|
292
305
|
|
|
293
306
|
classList.add(prefixedIdentifier)
|
|
294
307
|
|
|
@@ -298,7 +311,7 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|
|
298
311
|
|
|
299
312
|
context.candidateRuleMap
|
|
300
313
|
.get(prefixedIdentifier)
|
|
301
|
-
.push([{ sort:
|
|
314
|
+
.push([{ sort: offsets.utilities++, layer: 'utilities', options }, rule])
|
|
302
315
|
}
|
|
303
316
|
},
|
|
304
317
|
matchUtilities: function (utilities, options) {
|
|
@@ -435,7 +448,14 @@ function trackModified(files, fileModifiedMap) {
|
|
|
435
448
|
let parsed = url.parse(file)
|
|
436
449
|
let pathname = parsed.hash ? parsed.href.replace(parsed.hash, '') : parsed.href
|
|
437
450
|
pathname = parsed.search ? pathname.replace(parsed.search, '') : pathname
|
|
438
|
-
let newModified = fs.statSync(decodeURIComponent(pathname))
|
|
451
|
+
let newModified = fs.statSync(decodeURIComponent(pathname), { throwIfNoEntry: false })?.mtimeMs
|
|
452
|
+
if (!newModified) {
|
|
453
|
+
// It could happen that a file is passed in that doesn't exist. E.g.:
|
|
454
|
+
// postcss-cli will provide you a fake path when reading from stdin. This
|
|
455
|
+
// path then looks like /path-to-your-project/stdin In that case we just
|
|
456
|
+
// want to ignore it and don't track changes at all.
|
|
457
|
+
continue
|
|
458
|
+
}
|
|
439
459
|
|
|
440
460
|
if (!fileModifiedMap.has(file) || newModified > fileModifiedMap.get(file)) {
|
|
441
461
|
changed = true
|
|
@@ -112,19 +112,20 @@ function resolveChangedFiles(candidateFiles, fileModifiedMap) {
|
|
|
112
112
|
// source path), or set up a new one (including setting up watchers and registering
|
|
113
113
|
// plugins) then return it
|
|
114
114
|
export default function setupTrackingContext(configOrPath) {
|
|
115
|
-
return ({ tailwindDirectives, registerDependency }) => {
|
|
115
|
+
return ({ tailwindDirectives, registerDependency, applyDirectives }) => {
|
|
116
116
|
return (root, result) => {
|
|
117
117
|
let [tailwindConfig, userConfigPath, tailwindConfigHash, configDependencies] =
|
|
118
118
|
getTailwindConfig(configOrPath)
|
|
119
119
|
|
|
120
120
|
let contextDependencies = new Set(configDependencies)
|
|
121
121
|
|
|
122
|
-
// If there are no @tailwind rules, we don't consider this CSS
|
|
123
|
-
// to be dependencies of the context. Can reuse
|
|
124
|
-
// We may want to think about `@layer`
|
|
125
|
-
//
|
|
126
|
-
// in
|
|
127
|
-
|
|
122
|
+
// If there are no @tailwind or @apply rules, we don't consider this CSS
|
|
123
|
+
// file or its dependencies to be dependencies of the context. Can reuse
|
|
124
|
+
// the context even if they change. We may want to think about `@layer`
|
|
125
|
+
// being part of this trigger too, but it's tough because it's impossible
|
|
126
|
+
// for a layer in one file to end up in the actual @tailwind rule in
|
|
127
|
+
// another file since independent sources are effectively isolated.
|
|
128
|
+
if (tailwindDirectives.size > 0 || applyDirectives.size > 0) {
|
|
128
129
|
// Add current css file as a context dependencies.
|
|
129
130
|
contextDependencies.add(result.opts.from)
|
|
130
131
|
|
|
@@ -147,12 +148,12 @@ export default function setupTrackingContext(configOrPath) {
|
|
|
147
148
|
|
|
148
149
|
let candidateFiles = getCandidateFiles(context, tailwindConfig)
|
|
149
150
|
|
|
150
|
-
// If there are no @tailwind rules, we don't consider this CSS file or it's
|
|
151
|
-
// to be dependencies of the context. Can reuse the context even if they change.
|
|
151
|
+
// If there are no @tailwind or @apply rules, we don't consider this CSS file or it's
|
|
152
|
+
// dependencies to be dependencies of the context. Can reuse the context even if they change.
|
|
152
153
|
// We may want to think about `@layer` being part of this trigger too, but it's tough
|
|
153
154
|
// because it's impossible for a layer in one file to end up in the actual @tailwind rule
|
|
154
155
|
// in another file since independent sources are effectively isolated.
|
|
155
|
-
if (tailwindDirectives.size > 0) {
|
|
156
|
+
if (tailwindDirectives.size > 0 || applyDirectives.size > 0) {
|
|
156
157
|
let fileModifiedMap = getFileModifiedMap(context)
|
|
157
158
|
|
|
158
159
|
// Add template paths as postcss dependencies.
|
|
@@ -6,16 +6,21 @@ import substituteScreenAtRules from './lib/substituteScreenAtRules'
|
|
|
6
6
|
import resolveDefaultsAtRules from './lib/resolveDefaultsAtRules'
|
|
7
7
|
import collapseAdjacentRules from './lib/collapseAdjacentRules'
|
|
8
8
|
import collapseDuplicateDeclarations from './lib/collapseDuplicateDeclarations'
|
|
9
|
+
import partitionApplyAtRules from './lib/partitionApplyAtRules'
|
|
9
10
|
import detectNesting from './lib/detectNesting'
|
|
10
11
|
import { createContext } from './lib/setupContextUtils'
|
|
11
12
|
import { issueFlagNotices } from './featureFlags'
|
|
12
13
|
|
|
13
14
|
export default function processTailwindFeatures(setupContext) {
|
|
14
15
|
return function (root, result) {
|
|
15
|
-
let tailwindDirectives = normalizeTailwindDirectives(root)
|
|
16
|
+
let { tailwindDirectives, applyDirectives } = normalizeTailwindDirectives(root)
|
|
17
|
+
|
|
18
|
+
detectNesting()(root, result)
|
|
19
|
+
partitionApplyAtRules()(root, result)
|
|
16
20
|
|
|
17
21
|
let context = setupContext({
|
|
18
22
|
tailwindDirectives,
|
|
23
|
+
applyDirectives,
|
|
19
24
|
registerDependency(dependency) {
|
|
20
25
|
result.messages.push({
|
|
21
26
|
plugin: 'tailwindcss',
|
|
@@ -36,7 +41,6 @@ export default function processTailwindFeatures(setupContext) {
|
|
|
36
41
|
|
|
37
42
|
issueFlagNotices(context.tailwindConfig)
|
|
38
43
|
|
|
39
|
-
detectNesting(context)(root, result)
|
|
40
44
|
expandTailwindAtRules(context)(root, result)
|
|
41
45
|
expandApplyAtRules(context)(root, result)
|
|
42
46
|
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 []
|