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