tailwindcss 0.0.0-insiders.ca1dfd6 → 0.0.0-insiders.cb6e45a
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 +526 -2
- package/LICENSE +1 -2
- package/README.md +13 -6
- package/colors.d.ts +3 -0
- package/colors.js +2 -1
- package/defaultConfig.d.ts +3 -0
- package/defaultConfig.js +2 -1
- package/defaultTheme.d.ts +4 -0
- package/defaultTheme.js +2 -1
- package/lib/cli/build/deps.js +54 -0
- package/lib/cli/build/index.js +44 -0
- package/lib/cli/build/plugin.js +335 -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-peer-dependencies.js +20 -7
- package/lib/cli.js +91 -569
- package/lib/constants.js +27 -20
- package/lib/corePluginList.js +16 -4
- package/lib/corePlugins.js +2247 -1873
- package/lib/css/preflight.css +20 -9
- package/lib/featureFlags.js +37 -23
- package/lib/index.js +28 -12
- package/lib/lib/cacheInvalidation.js +90 -0
- package/lib/lib/collapseAdjacentRules.js +27 -9
- package/lib/lib/collapseDuplicateDeclarations.js +83 -0
- package/lib/lib/content.js +167 -0
- package/lib/lib/defaultExtractor.js +236 -0
- package/lib/lib/detectNesting.js +21 -3
- package/lib/lib/evaluateTailwindFunctions.js +117 -50
- package/lib/lib/expandApplyAtRules.js +439 -160
- package/lib/lib/expandTailwindAtRules.js +141 -151
- package/lib/lib/findAtConfigPath.js +44 -0
- package/lib/lib/generateRules.js +572 -105
- package/lib/lib/getModuleDependencies.js +11 -8
- package/lib/lib/normalizeTailwindDirectives.js +45 -33
- package/lib/lib/offsets.js +217 -0
- package/lib/lib/partitionApplyAtRules.js +56 -0
- package/lib/lib/regex.js +60 -0
- package/lib/lib/resolveDefaultsAtRules.js +114 -81
- package/lib/lib/setupContextUtils.js +777 -385
- package/lib/lib/setupTrackingContext.js +43 -71
- package/lib/lib/sharedState.js +49 -18
- package/lib/lib/substituteScreenAtRules.js +13 -8
- package/{nesting → lib/postcss-plugins/nesting}/README.md +2 -2
- package/lib/postcss-plugins/nesting/index.js +19 -0
- package/lib/postcss-plugins/nesting/plugin.js +87 -0
- package/lib/processTailwindFeatures.js +36 -21
- package/lib/public/colors.js +250 -252
- package/lib/public/create-plugin.js +6 -4
- package/lib/public/default-config.js +7 -5
- package/lib/public/default-theme.js +7 -5
- package/lib/public/resolve-config.js +8 -5
- package/lib/util/bigSign.js +4 -1
- package/lib/util/buildMediaQuery.js +18 -24
- package/lib/util/cloneDeep.js +7 -6
- package/lib/util/cloneNodes.js +21 -3
- package/lib/util/color.js +54 -40
- package/lib/util/configurePlugins.js +5 -2
- package/lib/util/createPlugin.js +6 -6
- package/lib/util/createUtilityPlugin.js +11 -13
- package/lib/util/dataTypes.js +137 -100
- package/lib/util/defaults.js +10 -1
- package/lib/util/escapeClassName.js +7 -4
- package/lib/util/escapeCommas.js +5 -2
- package/lib/util/flattenColorPalette.js +9 -12
- package/lib/util/formatVariantSelector.js +285 -0
- package/lib/util/getAllConfigs.js +27 -8
- package/lib/util/hashConfig.js +6 -3
- package/lib/util/isKeyframeRule.js +5 -2
- package/lib/util/isPlainObject.js +5 -2
- package/lib/util/isValidArbitraryValue.js +72 -0
- package/lib/util/log.js +44 -22
- package/lib/util/nameClass.js +20 -8
- package/lib/util/negateValue.js +23 -6
- package/lib/util/normalizeConfig.js +267 -0
- package/lib/util/normalizeScreens.js +170 -0
- package/lib/util/parseAnimationValue.js +42 -40
- package/lib/util/parseBoxShadowValue.js +84 -0
- package/lib/util/parseDependency.js +38 -56
- package/lib/util/parseGlob.js +34 -0
- package/lib/util/parseObjectStyles.js +11 -8
- package/lib/util/pluginUtils.js +171 -189
- package/lib/util/prefixSelector.js +10 -10
- package/lib/util/removeAlphaVariables.js +29 -0
- package/lib/util/resolveConfig.js +92 -126
- package/lib/util/resolveConfigPath.js +11 -9
- package/lib/util/responsive.js +8 -5
- package/lib/util/splitAtTopLevelOnly.js +43 -0
- package/lib/util/tap.js +4 -1
- package/lib/util/toColorValue.js +5 -3
- package/lib/util/toPath.js +24 -3
- package/lib/util/transformThemeValue.js +49 -31
- package/lib/util/validateConfig.js +24 -0
- package/lib/util/validateFormalSyntax.js +24 -0
- package/lib/util/withAlphaVariable.js +23 -15
- package/nesting/index.js +2 -12
- package/package.json +48 -46
- package/peers/index.js +14817 -12471
- package/plugin.d.ts +11 -0
- package/plugin.js +2 -1
- package/resolveConfig.d.ts +3 -0
- package/resolveConfig.js +2 -1
- package/scripts/create-plugin-list.js +2 -2
- package/scripts/generate-types.js +105 -0
- package/scripts/release-channel.js +18 -0
- package/scripts/release-notes.js +21 -0
- package/scripts/type-utils.js +27 -0
- package/src/cli/build/deps.js +56 -0
- package/src/cli/build/index.js +45 -0
- package/src/cli/build/plugin.js +397 -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-peer-dependencies.js +7 -1
- package/src/cli.js +26 -565
- package/src/corePluginList.js +1 -1
- package/src/corePlugins.js +905 -615
- package/src/css/preflight.css +20 -9
- package/src/featureFlags.js +26 -10
- package/src/index.js +19 -6
- package/src/lib/cacheInvalidation.js +52 -0
- package/src/lib/collapseAdjacentRules.js +21 -2
- package/src/lib/collapseDuplicateDeclarations.js +93 -0
- package/src/lib/content.js +205 -0
- package/src/lib/defaultExtractor.js +211 -0
- package/src/lib/detectNesting.js +22 -3
- package/src/lib/evaluateTailwindFunctions.js +84 -10
- package/src/lib/expandApplyAtRules.js +488 -153
- package/src/lib/expandTailwindAtRules.js +94 -106
- package/src/lib/findAtConfigPath.js +50 -0
- package/src/lib/generateRules.js +589 -67
- package/src/lib/normalizeTailwindDirectives.js +10 -3
- package/src/lib/offsets.js +270 -0
- package/src/lib/partitionApplyAtRules.js +52 -0
- package/src/lib/regex.js +74 -0
- package/src/lib/resolveDefaultsAtRules.js +98 -60
- package/src/lib/setupContextUtils.js +737 -246
- package/src/lib/setupTrackingContext.js +16 -54
- package/src/lib/sharedState.js +44 -7
- package/src/lib/substituteScreenAtRules.js +6 -3
- package/src/postcss-plugins/nesting/README.md +42 -0
- package/src/postcss-plugins/nesting/index.js +13 -0
- package/src/postcss-plugins/nesting/plugin.js +80 -0
- package/src/processTailwindFeatures.js +17 -2
- package/src/public/colors.js +4 -9
- package/src/util/buildMediaQuery.js +14 -16
- package/src/util/cloneNodes.js +19 -2
- package/src/util/color.js +31 -14
- package/src/util/createUtilityPlugin.js +2 -2
- package/src/util/dataTypes.js +57 -21
- package/src/util/defaults.js +6 -0
- package/src/util/formatVariantSelector.js +319 -0
- package/src/util/getAllConfigs.js +19 -0
- package/src/util/isValidArbitraryValue.js +61 -0
- package/src/util/log.js +23 -22
- package/src/util/nameClass.js +6 -2
- package/src/util/negateValue.js +14 -4
- package/src/util/normalizeConfig.js +282 -0
- package/src/util/normalizeScreens.js +140 -0
- package/src/util/parseBoxShadowValue.js +72 -0
- package/src/util/parseDependency.js +37 -42
- package/src/util/parseGlob.js +24 -0
- package/src/util/pluginUtils.js +144 -152
- package/src/util/prefixSelector.js +7 -8
- package/src/util/removeAlphaVariables.js +24 -0
- package/src/util/resolveConfig.js +82 -81
- package/src/util/splitAtTopLevelOnly.js +45 -0
- package/src/util/toPath.js +23 -1
- package/src/util/transformThemeValue.js +33 -8
- package/src/util/validateConfig.js +13 -0
- package/src/util/validateFormalSyntax.js +34 -0
- package/src/util/withAlphaVariable.js +1 -1
- package/stubs/defaultConfig.stub.js +173 -93
- package/stubs/simpleConfig.stub.js +1 -1
- package/types/config.d.ts +361 -0
- package/types/generated/.gitkeep +0 -0
- package/types/generated/colors.d.ts +276 -0
- package/types/generated/corePluginList.d.ts +1 -0
- package/types/generated/default-theme.d.ts +342 -0
- package/types/index.d.ts +7 -0
- package/lib/lib/setupWatchingContext.js +0 -284
- package/nesting/plugin.js +0 -41
- package/src/lib/setupWatchingContext.js +0 -306
|
@@ -1,31 +1,14 @@
|
|
|
1
|
+
import LRU from 'quick-lru'
|
|
1
2
|
import * as sharedState from './sharedState'
|
|
2
3
|
import { generateRules } from './generateRules'
|
|
3
|
-
import
|
|
4
|
+
import log from '../util/log'
|
|
4
5
|
import cloneNodes from '../util/cloneNodes'
|
|
6
|
+
import { defaultExtractor } from './defaultExtractor'
|
|
5
7
|
|
|
6
8
|
let env = sharedState.env
|
|
7
|
-
let contentMatchCache = sharedState.contentMatchCache
|
|
8
|
-
|
|
9
|
-
const PATTERNS = [
|
|
10
|
-
/([^<>"'`\s]*\[\w*'[^"`\s]*'?\])/.source, // font-['some_font',sans-serif]
|
|
11
|
-
/([^<>"'`\s]*\[\w*"[^"`\s]*"?\])/.source, // font-["some_font",sans-serif]
|
|
12
|
-
/([^<>"'`\s]*\[\w*\('[^"'`\s]*'\)\])/.source, // bg-[url('...')]
|
|
13
|
-
/([^<>"'`\s]*\[\w*\("[^"'`\s]*"\)\])/.source, // bg-[url("...")]
|
|
14
|
-
/([^<>"'`\s]*\['[^"'`\s]*'\])/.source, // `content-['hello']` but not `content-['hello']']`
|
|
15
|
-
/([^<>"'`\s]*\["[^"'`\s]*"\])/.source, // `content-["hello"]` but not `content-["hello"]"]`
|
|
16
|
-
/([^<>"'`\s]*\[[^"'`\s]+\][^<>"'`\s]*)/.source, // `fill-[#bada55]`, `fill-[#bada55]/50`
|
|
17
|
-
/([^<>"'`\s]*[^"'`\s:])/.source, // `px-1.5`, `uppercase` but not `uppercase:`].join('|')
|
|
18
|
-
].join('|')
|
|
19
|
-
const BROAD_MATCH_GLOBAL_REGEXP = new RegExp(PATTERNS, 'g')
|
|
20
|
-
const INNER_MATCH_GLOBAL_REGEXP = /[^<>"'`\s.(){}[\]#=%]*[^<>"'`\s.(){}[\]#=%:]/g
|
|
21
9
|
|
|
22
10
|
const builtInExtractors = {
|
|
23
|
-
DEFAULT:
|
|
24
|
-
let broadMatches = content.match(BROAD_MATCH_GLOBAL_REGEXP) || []
|
|
25
|
-
let innerMatches = content.match(INNER_MATCH_GLOBAL_REGEXP) || []
|
|
26
|
-
|
|
27
|
-
return [...broadMatches, ...innerMatches]
|
|
28
|
-
},
|
|
11
|
+
DEFAULT: defaultExtractor,
|
|
29
12
|
}
|
|
30
13
|
|
|
31
14
|
const builtInTransformers = {
|
|
@@ -33,41 +16,20 @@ const builtInTransformers = {
|
|
|
33
16
|
svelte: (content) => content.replace(/(?:^|\s)class:/g, ' '),
|
|
34
17
|
}
|
|
35
18
|
|
|
36
|
-
function getExtractor(
|
|
37
|
-
let extractors = tailwindConfig.content.extract
|
|
38
|
-
let contentOptions = tailwindConfig.content.options
|
|
39
|
-
|
|
40
|
-
if (typeof extractors === 'function') {
|
|
41
|
-
extractors = {
|
|
42
|
-
DEFAULT: extractors,
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
if (contentOptions.defaultExtractor) {
|
|
46
|
-
extractors.DEFAULT = contentOptions.defaultExtractor
|
|
47
|
-
}
|
|
48
|
-
for (let { extensions, extractor } of contentOptions.extractors || []) {
|
|
49
|
-
for (let extension of extensions) {
|
|
50
|
-
extractors[extension] = extractor
|
|
51
|
-
}
|
|
52
|
-
}
|
|
19
|
+
function getExtractor(context, fileExtension) {
|
|
20
|
+
let extractors = context.tailwindConfig.content.extract
|
|
53
21
|
|
|
54
22
|
return (
|
|
55
23
|
extractors[fileExtension] ||
|
|
56
24
|
extractors.DEFAULT ||
|
|
57
25
|
builtInExtractors[fileExtension] ||
|
|
58
|
-
builtInExtractors.DEFAULT
|
|
26
|
+
builtInExtractors.DEFAULT(context)
|
|
59
27
|
)
|
|
60
28
|
}
|
|
61
29
|
|
|
62
30
|
function getTransformer(tailwindConfig, fileExtension) {
|
|
63
31
|
let transformers = tailwindConfig.content.transform
|
|
64
32
|
|
|
65
|
-
if (typeof transformers === 'function') {
|
|
66
|
-
transformers = {
|
|
67
|
-
DEFAULT: transformers,
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
33
|
return (
|
|
72
34
|
transformers[fileExtension] ||
|
|
73
35
|
transformers.DEFAULT ||
|
|
@@ -76,10 +38,16 @@ function getTransformer(tailwindConfig, fileExtension) {
|
|
|
76
38
|
)
|
|
77
39
|
}
|
|
78
40
|
|
|
41
|
+
let extractorCache = new WeakMap()
|
|
42
|
+
|
|
79
43
|
// Scans template contents for possible classes. This is a hot path on initial build but
|
|
80
44
|
// not too important for subsequent builds. The faster the better though — if we can speed
|
|
81
45
|
// up these regexes by 50% that could cut initial build time by like 20%.
|
|
82
|
-
function getClassCandidates(content, extractor,
|
|
46
|
+
function getClassCandidates(content, extractor, candidates, seen) {
|
|
47
|
+
if (!extractorCache.has(extractor)) {
|
|
48
|
+
extractorCache.set(extractor, new LRU({ maxSize: 25000 }))
|
|
49
|
+
}
|
|
50
|
+
|
|
83
51
|
for (let line of content.split('\n')) {
|
|
84
52
|
line = line.trim()
|
|
85
53
|
|
|
@@ -88,8 +56,8 @@ function getClassCandidates(content, extractor, contentMatchCache, candidates, s
|
|
|
88
56
|
}
|
|
89
57
|
seen.add(line)
|
|
90
58
|
|
|
91
|
-
if (
|
|
92
|
-
for (let match of
|
|
59
|
+
if (extractorCache.get(extractor).has(line)) {
|
|
60
|
+
for (let match of extractorCache.get(extractor).get(line)) {
|
|
93
61
|
candidates.add(match)
|
|
94
62
|
}
|
|
95
63
|
} else {
|
|
@@ -100,56 +68,29 @@ function getClassCandidates(content, extractor, contentMatchCache, candidates, s
|
|
|
100
68
|
candidates.add(match)
|
|
101
69
|
}
|
|
102
70
|
|
|
103
|
-
|
|
71
|
+
extractorCache.get(extractor).set(line, lineMatchesSet)
|
|
104
72
|
}
|
|
105
73
|
}
|
|
106
74
|
}
|
|
107
75
|
|
|
76
|
+
/**
|
|
77
|
+
*
|
|
78
|
+
* @param {[import('./offsets.js').RuleOffset, import('postcss').Node][]} rules
|
|
79
|
+
* @param {*} context
|
|
80
|
+
*/
|
|
108
81
|
function buildStylesheet(rules, context) {
|
|
109
|
-
let sortedRules =
|
|
82
|
+
let sortedRules = context.offsets.sort(rules)
|
|
110
83
|
|
|
111
84
|
let returnValue = {
|
|
112
85
|
base: new Set(),
|
|
86
|
+
defaults: new Set(),
|
|
113
87
|
components: new Set(),
|
|
114
88
|
utilities: new Set(),
|
|
115
89
|
variants: new Set(),
|
|
116
|
-
|
|
117
|
-
// All the CSS that is not Tailwind related can be put in this bucket. This
|
|
118
|
-
// will make it easier to later use this information when we want to
|
|
119
|
-
// `@apply` for example. The main reason we do this here is because we
|
|
120
|
-
// still need to make sure the order is correct. Last but not least, we
|
|
121
|
-
// will make sure to always re-inject this section into the css, even if
|
|
122
|
-
// certain rules were not used. This means that it will look like a no-op
|
|
123
|
-
// from the user's perspective, but we gathered all the useful information
|
|
124
|
-
// we need.
|
|
125
|
-
user: new Set(),
|
|
126
90
|
}
|
|
127
91
|
|
|
128
92
|
for (let [sort, rule] of sortedRules) {
|
|
129
|
-
|
|
130
|
-
returnValue.variants.add(rule)
|
|
131
|
-
continue
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (sort & context.layerOrder.base) {
|
|
135
|
-
returnValue.base.add(rule)
|
|
136
|
-
continue
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
if (sort & context.layerOrder.components) {
|
|
140
|
-
returnValue.components.add(rule)
|
|
141
|
-
continue
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (sort & context.layerOrder.utilities) {
|
|
145
|
-
returnValue.utilities.add(rule)
|
|
146
|
-
continue
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if (sort & context.layerOrder.user) {
|
|
150
|
-
returnValue.user.add(rule)
|
|
151
|
-
continue
|
|
152
|
-
}
|
|
93
|
+
returnValue[sort.layer].add(rule)
|
|
153
94
|
}
|
|
154
95
|
|
|
155
96
|
return returnValue
|
|
@@ -164,13 +105,15 @@ export default function expandTailwindAtRules(context) {
|
|
|
164
105
|
variants: null,
|
|
165
106
|
}
|
|
166
107
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if (
|
|
173
|
-
layerNodes
|
|
108
|
+
root.walkAtRules((rule) => {
|
|
109
|
+
// Make sure this file contains Tailwind directives. If not, we can save
|
|
110
|
+
// a lot of work and bail early. Also we don't have to register our touch
|
|
111
|
+
// file as a dependency since the output of this CSS does not depend on
|
|
112
|
+
// the source of any templates. Think Vue <style> blocks for example.
|
|
113
|
+
if (rule.name === 'tailwind') {
|
|
114
|
+
if (Object.keys(layerNodes).includes(rule.params)) {
|
|
115
|
+
layerNodes[rule.params] = rule
|
|
116
|
+
}
|
|
174
117
|
}
|
|
175
118
|
})
|
|
176
119
|
|
|
@@ -181,38 +124,37 @@ export default function expandTailwindAtRules(context) {
|
|
|
181
124
|
// ---
|
|
182
125
|
|
|
183
126
|
// Find potential rules in changed files
|
|
184
|
-
let candidates = new Set([
|
|
127
|
+
let candidates = new Set([sharedState.NOT_ON_DEMAND])
|
|
185
128
|
let seen = new Set()
|
|
186
129
|
|
|
187
130
|
env.DEBUG && console.time('Reading changed files')
|
|
188
131
|
|
|
189
132
|
for (let { content, extension } of context.changedContent) {
|
|
190
133
|
let transformer = getTransformer(context.tailwindConfig, extension)
|
|
191
|
-
let extractor = getExtractor(context
|
|
192
|
-
getClassCandidates(transformer(content), extractor,
|
|
134
|
+
let extractor = getExtractor(context, extension)
|
|
135
|
+
getClassCandidates(transformer(content), extractor, candidates, seen)
|
|
193
136
|
}
|
|
194
137
|
|
|
138
|
+
env.DEBUG && console.timeEnd('Reading changed files')
|
|
139
|
+
|
|
195
140
|
// ---
|
|
196
141
|
|
|
197
142
|
// Generate the actual CSS
|
|
198
143
|
let classCacheCount = context.classCache.size
|
|
199
144
|
|
|
200
145
|
env.DEBUG && console.time('Generate rules')
|
|
201
|
-
|
|
146
|
+
generateRules(candidates, context)
|
|
202
147
|
env.DEBUG && console.timeEnd('Generate rules')
|
|
203
148
|
|
|
204
149
|
// We only ever add to the classCache, so if it didn't grow, there is nothing new.
|
|
205
150
|
env.DEBUG && console.time('Build stylesheet')
|
|
206
151
|
if (context.stylesheetCache === null || context.classCache.size !== classCacheCount) {
|
|
207
|
-
for (let rule of rules) {
|
|
208
|
-
context.ruleCache.add(rule)
|
|
209
|
-
}
|
|
210
|
-
|
|
211
152
|
context.stylesheetCache = buildStylesheet([...context.ruleCache], context)
|
|
212
153
|
}
|
|
213
154
|
env.DEBUG && console.timeEnd('Build stylesheet')
|
|
214
155
|
|
|
215
156
|
let {
|
|
157
|
+
defaults: defaultNodes,
|
|
216
158
|
base: baseNodes,
|
|
217
159
|
components: componentNodes,
|
|
218
160
|
utilities: utilityNodes,
|
|
@@ -224,25 +166,72 @@ export default function expandTailwindAtRules(context) {
|
|
|
224
166
|
// Replace any Tailwind directives with generated CSS
|
|
225
167
|
|
|
226
168
|
if (layerNodes.base) {
|
|
227
|
-
layerNodes.base.before(
|
|
169
|
+
layerNodes.base.before(
|
|
170
|
+
cloneNodes([...baseNodes, ...defaultNodes], layerNodes.base.source, {
|
|
171
|
+
layer: 'base',
|
|
172
|
+
})
|
|
173
|
+
)
|
|
228
174
|
layerNodes.base.remove()
|
|
229
175
|
}
|
|
230
176
|
|
|
231
177
|
if (layerNodes.components) {
|
|
232
|
-
layerNodes.components.before(
|
|
178
|
+
layerNodes.components.before(
|
|
179
|
+
cloneNodes([...componentNodes], layerNodes.components.source, {
|
|
180
|
+
layer: 'components',
|
|
181
|
+
})
|
|
182
|
+
)
|
|
233
183
|
layerNodes.components.remove()
|
|
234
184
|
}
|
|
235
185
|
|
|
236
186
|
if (layerNodes.utilities) {
|
|
237
|
-
layerNodes.utilities.before(
|
|
187
|
+
layerNodes.utilities.before(
|
|
188
|
+
cloneNodes([...utilityNodes], layerNodes.utilities.source, {
|
|
189
|
+
layer: 'utilities',
|
|
190
|
+
})
|
|
191
|
+
)
|
|
238
192
|
layerNodes.utilities.remove()
|
|
239
193
|
}
|
|
240
194
|
|
|
195
|
+
// We do post-filtering to not alter the emitted order of the variants
|
|
196
|
+
const variantNodes = Array.from(screenNodes).filter((node) => {
|
|
197
|
+
const parentLayer = node.raws.tailwind?.parentLayer
|
|
198
|
+
|
|
199
|
+
if (parentLayer === 'components') {
|
|
200
|
+
return layerNodes.components !== null
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (parentLayer === 'utilities') {
|
|
204
|
+
return layerNodes.utilities !== null
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return true
|
|
208
|
+
})
|
|
209
|
+
|
|
241
210
|
if (layerNodes.variants) {
|
|
242
|
-
layerNodes.variants.before(
|
|
211
|
+
layerNodes.variants.before(
|
|
212
|
+
cloneNodes(variantNodes, layerNodes.variants.source, {
|
|
213
|
+
layer: 'variants',
|
|
214
|
+
})
|
|
215
|
+
)
|
|
243
216
|
layerNodes.variants.remove()
|
|
244
|
-
} else {
|
|
245
|
-
root.append(
|
|
217
|
+
} else if (variantNodes.length > 0) {
|
|
218
|
+
root.append(
|
|
219
|
+
cloneNodes(variantNodes, root.source, {
|
|
220
|
+
layer: 'variants',
|
|
221
|
+
})
|
|
222
|
+
)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// If we've got a utility layer and no utilities are generated there's likely something wrong
|
|
226
|
+
const hasUtilityVariants = variantNodes.some(
|
|
227
|
+
(node) => node.raws.tailwind?.parentLayer === 'utilities'
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
if (layerNodes.utilities && utilityNodes.size === 0 && !hasUtilityVariants) {
|
|
231
|
+
log.warn('content-problems', [
|
|
232
|
+
'No utility classes were detected in your source files. If this is unexpected, double-check the `content` option in your Tailwind CSS configuration.',
|
|
233
|
+
'https://tailwindcss.com/docs/content-configuration',
|
|
234
|
+
])
|
|
246
235
|
}
|
|
247
236
|
|
|
248
237
|
// ---
|
|
@@ -250,7 +239,6 @@ export default function expandTailwindAtRules(context) {
|
|
|
250
239
|
if (env.DEBUG) {
|
|
251
240
|
console.log('Potential classes: ', candidates.size)
|
|
252
241
|
console.log('Active contexts: ', sharedState.contextSourcesMap.size)
|
|
253
|
-
console.log('Content match entries', contentMatchCache.size)
|
|
254
242
|
}
|
|
255
243
|
|
|
256
244
|
// Clear the cache for the changed files
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Find the @config at-rule in the given CSS AST and return the relative path to the config file
|
|
6
|
+
*
|
|
7
|
+
* @param {import('postcss').Root} root
|
|
8
|
+
* @param {import('postcss').Result} result
|
|
9
|
+
*/
|
|
10
|
+
export function findAtConfigPath(root, result) {
|
|
11
|
+
let configPath = null
|
|
12
|
+
let relativeTo = null
|
|
13
|
+
|
|
14
|
+
root.walkAtRules('config', (rule) => {
|
|
15
|
+
relativeTo = rule.source?.input.file ?? result.opts.from ?? null
|
|
16
|
+
|
|
17
|
+
if (relativeTo === null) {
|
|
18
|
+
throw rule.error(
|
|
19
|
+
'The `@config` at-rule cannot be used without a `from` option being set on the PostCSS config.'
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (configPath) {
|
|
24
|
+
throw rule.error('Only `@config` at-rule is allowed per file.')
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let matches = rule.params.match(/(['"])(.*?)\1/)
|
|
28
|
+
if (!matches) {
|
|
29
|
+
throw rule.error(
|
|
30
|
+
'The `@config` at-rule must be followed by a string containing the path to the config file.'
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let inputPath = matches[2]
|
|
35
|
+
if (path.isAbsolute(inputPath)) {
|
|
36
|
+
throw rule.error('The `@config` at-rule cannot be used with an absolute path.')
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
configPath = path.resolve(path.dirname(relativeTo), inputPath)
|
|
40
|
+
if (!fs.existsSync(configPath)) {
|
|
41
|
+
throw rule.error(
|
|
42
|
+
`The config file at "${inputPath}" does not exist. Make sure the path is correct and the file exists.`
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
rule.remove()
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
return configPath ? configPath : null
|
|
50
|
+
}
|