tailwindcss 0.0.0-insiders.d3e754a → 0.0.0-insiders.d3f2221
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/README.md +13 -9
- package/colors.d.ts +3 -0
- package/defaultConfig.d.ts +3 -0
- package/defaultTheme.d.ts +4 -0
- package/index.css +5 -0
- package/lib/cli/build/index.js +57 -0
- package/lib/cli/build/plugin.js +431 -0
- package/lib/cli/build/utils.js +88 -0
- package/lib/cli/build/watching.js +182 -0
- package/lib/cli/help/index.js +73 -0
- package/lib/cli/index.js +231 -0
- package/lib/cli/init/index.js +63 -0
- package/lib/cli.js +1 -739
- package/lib/corePluginList.js +13 -3
- package/lib/corePlugins.js +1094 -478
- package/lib/css/preflight.css +17 -4
- package/lib/featureFlags.js +49 -23
- package/lib/index.js +1 -29
- package/lib/lib/cacheInvalidation.js +92 -0
- package/lib/lib/collapseAdjacentRules.js +12 -5
- package/lib/lib/collapseDuplicateDeclarations.js +12 -7
- package/lib/lib/content.js +207 -0
- package/lib/lib/defaultExtractor.js +217 -33
- package/lib/lib/detectNesting.js +15 -4
- package/lib/lib/evaluateTailwindFunctions.js +104 -37
- package/lib/lib/expandApplyAtRules.js +312 -211
- package/lib/lib/expandTailwindAtRules.js +149 -96
- package/lib/lib/findAtConfigPath.js +46 -0
- package/lib/lib/generateRules.js +437 -188
- package/lib/lib/getModuleDependencies.js +88 -37
- package/lib/lib/handleImportAtRules.js +50 -0
- package/lib/lib/load-config.js +42 -0
- package/lib/lib/normalizeTailwindDirectives.js +9 -19
- package/lib/lib/offsets.js +306 -0
- package/lib/lib/partitionApplyAtRules.js +11 -6
- package/lib/lib/regex.js +74 -0
- package/lib/lib/remap-bitfield.js +89 -0
- package/lib/lib/resolveDefaultsAtRules.js +80 -58
- package/lib/lib/setupContextUtils.js +683 -270
- package/lib/lib/setupTrackingContext.js +63 -67
- package/lib/lib/sharedState.js +39 -10
- package/lib/lib/substituteScreenAtRules.js +13 -9
- package/lib/plugin.js +164 -0
- package/lib/postcss-plugins/nesting/README.md +2 -2
- package/lib/postcss-plugins/nesting/index.js +10 -6
- package/lib/postcss-plugins/nesting/plugin.js +15 -11
- package/lib/processTailwindFeatures.js +33 -28
- package/lib/public/colors.js +55 -29
- package/lib/public/create-plugin.js +9 -5
- package/lib/public/default-config.js +10 -6
- package/lib/public/default-theme.js +10 -6
- package/lib/public/load-config.js +12 -0
- package/lib/public/resolve-config.js +11 -6
- package/lib/util/applyImportantSelector.js +36 -0
- package/lib/util/bigSign.js +6 -1
- package/lib/util/buildMediaQuery.js +12 -5
- package/lib/util/cloneDeep.js +8 -5
- package/lib/util/cloneNodes.js +11 -2
- package/lib/util/color.js +59 -42
- package/lib/util/colorNames.js +752 -0
- package/lib/util/configurePlugins.js +7 -2
- package/lib/util/createPlugin.js +8 -5
- package/lib/util/createUtilityPlugin.js +15 -11
- package/lib/util/dataTypes.js +172 -47
- package/lib/util/defaults.js +12 -7
- package/lib/util/escapeClassName.js +13 -8
- package/lib/util/escapeCommas.js +6 -1
- package/lib/util/flattenColorPalette.js +9 -8
- package/lib/util/formatVariantSelector.js +230 -151
- package/lib/util/getAllConfigs.js +34 -12
- package/lib/util/hashConfig.js +9 -4
- package/lib/util/isKeyframeRule.js +6 -1
- package/lib/util/isPlainObject.js +6 -1
- package/lib/util/{isValidArbitraryValue.js → isSyntacticallyValidPropertyValue.js} +15 -5
- package/lib/util/log.js +36 -9
- package/lib/util/nameClass.js +24 -7
- package/lib/util/negateValue.js +23 -6
- package/lib/util/normalizeConfig.js +142 -69
- package/lib/util/normalizeScreens.js +124 -5
- package/lib/util/parseAnimationValue.js +8 -4
- package/lib/util/parseBoxShadowValue.js +16 -45
- package/lib/util/parseDependency.js +38 -54
- package/lib/util/parseGlob.js +36 -0
- package/lib/util/parseObjectStyles.js +14 -9
- package/lib/util/pluginUtils.js +146 -51
- package/lib/util/prefixSelector.js +29 -10
- package/lib/util/pseudoElements.js +209 -0
- package/lib/util/removeAlphaVariables.js +31 -0
- package/lib/util/resolveConfig.js +100 -73
- package/lib/util/resolveConfigPath.js +27 -8
- package/lib/util/responsive.js +10 -5
- package/lib/util/splitAtTopLevelOnly.js +51 -0
- package/lib/util/tap.js +6 -1
- package/lib/util/toColorValue.js +6 -1
- package/lib/util/toPath.js +20 -2
- package/lib/util/transformThemeValue.js +21 -7
- package/lib/util/validateConfig.js +48 -0
- package/lib/util/validateFormalSyntax.js +26 -0
- package/lib/util/withAlphaVariable.js +24 -12
- package/lib/value-parser/LICENSE +22 -0
- package/lib/value-parser/README.md +3 -0
- package/lib/value-parser/index.d.js +2 -0
- package/lib/value-parser/index.js +22 -0
- package/lib/value-parser/parse.js +259 -0
- package/lib/value-parser/stringify.js +38 -0
- package/lib/value-parser/unit.js +86 -0
- package/lib/value-parser/walk.js +16 -0
- package/loadConfig.d.ts +4 -0
- package/loadConfig.js +2 -0
- package/package.json +58 -53
- package/plugin.d.ts +11 -0
- package/resolveConfig.d.ts +12 -0
- 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/index.js +53 -0
- package/src/cli/build/plugin.js +469 -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 +217 -0
- package/src/cli/init/index.js +79 -0
- package/src/cli.js +1 -813
- package/src/corePluginList.js +1 -1
- package/src/corePlugins.js +636 -117
- package/src/css/preflight.css +17 -4
- package/src/featureFlags.js +13 -3
- package/src/index.js +1 -28
- package/src/lib/cacheInvalidation.js +52 -0
- package/src/lib/collapseAdjacentRules.js +5 -1
- package/src/lib/content.js +240 -0
- package/src/lib/defaultExtractor.js +192 -35
- package/src/lib/detectNesting.js +9 -1
- package/src/lib/evaluateTailwindFunctions.js +82 -8
- package/src/lib/expandApplyAtRules.js +322 -189
- package/src/lib/expandTailwindAtRules.js +87 -60
- package/src/lib/findAtConfigPath.js +48 -0
- package/src/lib/generateRules.js +428 -128
- package/src/lib/getModuleDependencies.js +70 -30
- package/src/lib/handleImportAtRules.js +34 -0
- package/src/lib/load-config.ts +31 -0
- package/src/lib/normalizeTailwindDirectives.js +0 -27
- package/src/lib/offsets.js +373 -0
- package/src/lib/regex.js +74 -0
- package/src/lib/remap-bitfield.js +82 -0
- package/src/lib/resolveDefaultsAtRules.js +53 -36
- package/src/lib/setupContextUtils.js +608 -157
- package/src/lib/setupTrackingContext.js +44 -58
- package/src/lib/sharedState.js +14 -4
- package/src/plugin.js +133 -0
- package/src/postcss-plugins/nesting/README.md +2 -2
- package/src/processTailwindFeatures.js +3 -2
- package/src/public/colors.js +22 -0
- package/src/public/default-config.js +1 -1
- package/src/public/default-theme.js +2 -2
- package/src/public/load-config.js +2 -0
- package/src/util/applyImportantSelector.js +27 -0
- package/src/util/buildMediaQuery.js +5 -3
- package/src/util/cloneNodes.js +5 -1
- package/src/util/color.js +39 -20
- package/src/util/colorNames.js +150 -0
- package/src/util/dataTypes.js +115 -23
- package/src/util/formatVariantSelector.js +265 -144
- package/src/util/getAllConfigs.js +21 -2
- package/src/util/{isValidArbitraryValue.js → isSyntacticallyValidPropertyValue.js} +1 -1
- package/src/util/log.js +25 -1
- package/src/util/nameClass.js +4 -0
- package/src/util/negateValue.js +11 -3
- package/src/util/normalizeConfig.js +78 -20
- package/src/util/normalizeScreens.js +99 -4
- package/src/util/parseBoxShadowValue.js +3 -50
- package/src/util/parseDependency.js +37 -42
- package/src/util/parseGlob.js +24 -0
- package/src/util/pluginUtils.js +118 -23
- package/src/util/prefixSelector.js +29 -10
- package/src/util/pseudoElements.js +167 -0
- package/src/util/removeAlphaVariables.js +24 -0
- package/src/util/resolveConfig.js +70 -32
- package/src/util/resolveConfigPath.js +12 -1
- package/src/util/splitAtTopLevelOnly.js +52 -0
- package/src/util/toPath.js +1 -1
- package/src/util/transformThemeValue.js +13 -3
- package/src/util/validateConfig.js +36 -0
- package/src/util/validateFormalSyntax.js +34 -0
- package/src/util/withAlphaVariable.js +1 -1
- package/src/value-parser/LICENSE +22 -0
- package/src/value-parser/README.md +3 -0
- package/src/value-parser/index.d.ts +177 -0
- package/src/value-parser/index.js +28 -0
- package/src/value-parser/parse.js +303 -0
- package/src/value-parser/stringify.js +41 -0
- package/src/value-parser/unit.js +118 -0
- package/src/value-parser/walk.js +18 -0
- package/stubs/.gitignore +1 -0
- package/stubs/.prettierrc.json +6 -0
- package/stubs/{defaultConfig.stub.js → config.full.js} +224 -172
- package/stubs/{simpleConfig.stub.js → config.simple.js} +1 -1
- package/stubs/{defaultPostCssConfig.stub.js → postcss.config.cjs} +0 -1
- package/stubs/postcss.config.js +5 -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 +369 -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 +378 -0
- package/types/index.d.ts +7 -0
- package/CHANGELOG.md +0 -2075
- package/lib/cli-peer-dependencies.js +0 -15
- package/lib/constants.js +0 -37
- package/peers/index.js +0 -75077
- package/scripts/install-integrations.js +0 -27
- package/scripts/rebuildFixtures.js +0 -68
- package/src/cli-peer-dependencies.js +0 -9
- package/src/constants.js +0 -17
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { flagEnabled, featureFlags } from '../featureFlags'
|
|
1
2
|
import log, { dim } from './log'
|
|
2
3
|
|
|
3
4
|
export function normalizeConfig(config) {
|
|
@@ -17,6 +18,10 @@ export function normalizeConfig(config) {
|
|
|
17
18
|
* }
|
|
18
19
|
*/
|
|
19
20
|
let valid = (() => {
|
|
21
|
+
if (config.content === 'auto') {
|
|
22
|
+
return true
|
|
23
|
+
}
|
|
24
|
+
|
|
20
25
|
// `config.purge` should not exist anymore
|
|
21
26
|
if (config.purge) {
|
|
22
27
|
return false
|
|
@@ -56,9 +61,11 @@ export function normalizeConfig(config) {
|
|
|
56
61
|
|
|
57
62
|
// When `config.content` is an object
|
|
58
63
|
if (typeof config.content === 'object' && config.content !== null) {
|
|
59
|
-
// Only `files`, `extract
|
|
64
|
+
// Only `files`, `relative`, `extract`, and `transform` can exist in `config.content`
|
|
60
65
|
if (
|
|
61
|
-
Object.keys(config.content).some(
|
|
66
|
+
Object.keys(config.content).some(
|
|
67
|
+
(key) => !['files', 'relative', 'extract', 'transform'].includes(key)
|
|
68
|
+
)
|
|
62
69
|
) {
|
|
63
70
|
return false
|
|
64
71
|
}
|
|
@@ -112,6 +119,14 @@ export function normalizeConfig(config) {
|
|
|
112
119
|
) {
|
|
113
120
|
return false
|
|
114
121
|
}
|
|
122
|
+
|
|
123
|
+
// `config.content.relative` is optional and can be a boolean
|
|
124
|
+
if (
|
|
125
|
+
typeof config.content.relative !== 'boolean' &&
|
|
126
|
+
typeof config.content.relative !== 'undefined'
|
|
127
|
+
) {
|
|
128
|
+
return false
|
|
129
|
+
}
|
|
115
130
|
}
|
|
116
131
|
|
|
117
132
|
return true
|
|
@@ -140,6 +155,24 @@ export function normalizeConfig(config) {
|
|
|
140
155
|
return []
|
|
141
156
|
})()
|
|
142
157
|
|
|
158
|
+
// Normalize the `blocklist`
|
|
159
|
+
config.blocklist = (() => {
|
|
160
|
+
let { blocklist } = config
|
|
161
|
+
|
|
162
|
+
if (Array.isArray(blocklist)) {
|
|
163
|
+
if (blocklist.every((item) => typeof item === 'string')) {
|
|
164
|
+
return blocklist
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
log.warn('blocklist-invalid', [
|
|
168
|
+
'The `blocklist` option must be an array of strings.',
|
|
169
|
+
'https://tailwindcss.com/docs/content-configuration#discarding-classes',
|
|
170
|
+
])
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return []
|
|
174
|
+
})()
|
|
175
|
+
|
|
143
176
|
// Normalize prefix option
|
|
144
177
|
if (typeof config.prefix === 'function') {
|
|
145
178
|
log.warn('prefix-function', [
|
|
@@ -154,14 +187,30 @@ export function normalizeConfig(config) {
|
|
|
154
187
|
|
|
155
188
|
// Normalize the `content`
|
|
156
189
|
config.content = {
|
|
190
|
+
relative: (() => {
|
|
191
|
+
let { content } = config
|
|
192
|
+
|
|
193
|
+
if (content?.relative) {
|
|
194
|
+
return content.relative
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return flagEnabled(config, 'relativeContentPathsByDefault')
|
|
198
|
+
})(),
|
|
199
|
+
|
|
157
200
|
files: (() => {
|
|
158
201
|
let { content, purge } = config
|
|
159
202
|
|
|
160
|
-
if (
|
|
161
|
-
if (
|
|
203
|
+
if (content === undefined && purge === undefined) return []
|
|
204
|
+
if (purge) {
|
|
205
|
+
if (Array.isArray(purge)) return purge
|
|
206
|
+
if (Array.isArray(purge?.content)) return purge.content
|
|
207
|
+
return []
|
|
208
|
+
}
|
|
209
|
+
|
|
162
210
|
if (Array.isArray(content)) return content
|
|
163
211
|
if (Array.isArray(content?.content)) return content.content
|
|
164
212
|
if (Array.isArray(content?.files)) return content.files
|
|
213
|
+
if (content === 'auto') return ['auto']
|
|
165
214
|
|
|
166
215
|
return []
|
|
167
216
|
})(),
|
|
@@ -245,25 +294,34 @@ export function normalizeConfig(config) {
|
|
|
245
294
|
})(),
|
|
246
295
|
}
|
|
247
296
|
|
|
248
|
-
//
|
|
249
|
-
//
|
|
250
|
-
|
|
251
|
-
if (
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
297
|
+
// Force disable the `oxideParser` feature flag when using unsupported features.
|
|
298
|
+
// TODO: Remove once we have prefix or separator support in the oxide parser.
|
|
299
|
+
if (config.prefix !== '' || config.separator !== ':') {
|
|
300
|
+
if (config.experimental === 'all') {
|
|
301
|
+
config.experimental = {}
|
|
302
|
+
for (let key of featureFlags.experimental) {
|
|
303
|
+
config.experimental[key] = true
|
|
304
|
+
}
|
|
305
|
+
} else {
|
|
306
|
+
config.experimental = config.experimental ?? {}
|
|
258
307
|
}
|
|
308
|
+
|
|
309
|
+
config.experimental.oxideParser = false
|
|
259
310
|
}
|
|
260
311
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
'
|
|
266
|
-
|
|
312
|
+
// Validate globs to prevent bogus globs.
|
|
313
|
+
// E.g.: `./src/*.{html}` is invalid, the `{html}` should just be `html`
|
|
314
|
+
if (config.content.files !== 'auto') {
|
|
315
|
+
for (let file of config.content.files) {
|
|
316
|
+
if (typeof file === 'string' && /{([^,]*?)}/g.test(file)) {
|
|
317
|
+
log.warn('invalid-glob-braces', [
|
|
318
|
+
`The glob pattern ${dim(file)} in your Tailwind CSS configuration is invalid.`,
|
|
319
|
+
`Update it to ${dim(file.replace(/{([^,]*?)}/g, '$1'))} to silence this warning.`,
|
|
320
|
+
// TODO: Add https://tw.wtf/invalid-glob-braces
|
|
321
|
+
])
|
|
322
|
+
break
|
|
323
|
+
}
|
|
324
|
+
}
|
|
267
325
|
}
|
|
268
326
|
|
|
269
327
|
return config
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {object} ScreenValue
|
|
3
|
+
* @property {number|undefined} min
|
|
4
|
+
* @property {number|undefined} max
|
|
5
|
+
* @property {string|undefined} raw
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {object} Screen
|
|
10
|
+
* @property {string} name
|
|
11
|
+
* @property {boolean} not
|
|
12
|
+
* @property {ScreenValue[]} values
|
|
13
|
+
*/
|
|
14
|
+
|
|
1
15
|
/**
|
|
2
16
|
* A function that normalizes the various forms that the screens object can be
|
|
3
17
|
* provided in.
|
|
@@ -10,6 +24,8 @@
|
|
|
10
24
|
*
|
|
11
25
|
* Output(s):
|
|
12
26
|
* - [{ name: 'sm', values: [{ min: '100px', max: '200px' }] }] // List of objects, that contains multiple values
|
|
27
|
+
*
|
|
28
|
+
* @returns {Screen[]}
|
|
13
29
|
*/
|
|
14
30
|
export function normalizeScreens(screens, root = true) {
|
|
15
31
|
if (Array.isArray(screens)) {
|
|
@@ -19,27 +35,106 @@ export function normalizeScreens(screens, root = true) {
|
|
|
19
35
|
}
|
|
20
36
|
|
|
21
37
|
if (typeof screen === 'string') {
|
|
22
|
-
return { name: screen.toString(), values: [{ min: screen, max: undefined }] }
|
|
38
|
+
return { name: screen.toString(), not: false, values: [{ min: screen, max: undefined }] }
|
|
23
39
|
}
|
|
24
40
|
|
|
25
41
|
let [name, options] = screen
|
|
26
42
|
name = name.toString()
|
|
27
43
|
|
|
28
44
|
if (typeof options === 'string') {
|
|
29
|
-
return { name, values: [{ min: options, max: undefined }] }
|
|
45
|
+
return { name, not: false, values: [{ min: options, max: undefined }] }
|
|
30
46
|
}
|
|
31
47
|
|
|
32
48
|
if (Array.isArray(options)) {
|
|
33
|
-
return { name, values: options.map((option) => resolveValue(option)) }
|
|
49
|
+
return { name, not: false, values: options.map((option) => resolveValue(option)) }
|
|
34
50
|
}
|
|
35
51
|
|
|
36
|
-
return { name, values: [resolveValue(options)] }
|
|
52
|
+
return { name, not: false, values: [resolveValue(options)] }
|
|
37
53
|
})
|
|
38
54
|
}
|
|
39
55
|
|
|
40
56
|
return normalizeScreens(Object.entries(screens ?? {}), false)
|
|
41
57
|
}
|
|
42
58
|
|
|
59
|
+
/**
|
|
60
|
+
* @param {Screen} screen
|
|
61
|
+
* @returns {{result: false, reason: string} | {result: true, reason: null}}
|
|
62
|
+
*/
|
|
63
|
+
export function isScreenSortable(screen) {
|
|
64
|
+
if (screen.values.length !== 1) {
|
|
65
|
+
return { result: false, reason: 'multiple-values' }
|
|
66
|
+
} else if (screen.values[0].raw !== undefined) {
|
|
67
|
+
return { result: false, reason: 'raw-values' }
|
|
68
|
+
} else if (screen.values[0].min !== undefined && screen.values[0].max !== undefined) {
|
|
69
|
+
return { result: false, reason: 'min-and-max' }
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return { result: true, reason: null }
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @param {'min' | 'max'} type
|
|
77
|
+
* @param {Screen | 'string'} a
|
|
78
|
+
* @param {Screen | 'string'} z
|
|
79
|
+
* @returns {number}
|
|
80
|
+
*/
|
|
81
|
+
export function compareScreens(type, a, z) {
|
|
82
|
+
let aScreen = toScreen(a, type)
|
|
83
|
+
let zScreen = toScreen(z, type)
|
|
84
|
+
|
|
85
|
+
let aSorting = isScreenSortable(aScreen)
|
|
86
|
+
let bSorting = isScreenSortable(zScreen)
|
|
87
|
+
|
|
88
|
+
// These cases should never happen and indicate a bug in Tailwind CSS itself
|
|
89
|
+
if (aSorting.reason === 'multiple-values' || bSorting.reason === 'multiple-values') {
|
|
90
|
+
throw new Error(
|
|
91
|
+
'Attempted to sort a screen with multiple values. This should never happen. Please open a bug report.'
|
|
92
|
+
)
|
|
93
|
+
} else if (aSorting.reason === 'raw-values' || bSorting.reason === 'raw-values') {
|
|
94
|
+
throw new Error(
|
|
95
|
+
'Attempted to sort a screen with raw values. This should never happen. Please open a bug report.'
|
|
96
|
+
)
|
|
97
|
+
} else if (aSorting.reason === 'min-and-max' || bSorting.reason === 'min-and-max') {
|
|
98
|
+
throw new Error(
|
|
99
|
+
'Attempted to sort a screen with both min and max values. This should never happen. Please open a bug report.'
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Let the sorting begin
|
|
104
|
+
let { min: aMin, max: aMax } = aScreen.values[0]
|
|
105
|
+
let { min: zMin, max: zMax } = zScreen.values[0]
|
|
106
|
+
|
|
107
|
+
// Negating screens flip their behavior. Basically `not min-width` is `max-width`
|
|
108
|
+
if (a.not) [aMin, aMax] = [aMax, aMin]
|
|
109
|
+
if (z.not) [zMin, zMax] = [zMax, zMin]
|
|
110
|
+
|
|
111
|
+
aMin = aMin === undefined ? aMin : parseFloat(aMin)
|
|
112
|
+
aMax = aMax === undefined ? aMax : parseFloat(aMax)
|
|
113
|
+
zMin = zMin === undefined ? zMin : parseFloat(zMin)
|
|
114
|
+
zMax = zMax === undefined ? zMax : parseFloat(zMax)
|
|
115
|
+
|
|
116
|
+
let [aValue, zValue] = type === 'min' ? [aMin, zMin] : [zMax, aMax]
|
|
117
|
+
|
|
118
|
+
return aValue - zValue
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
*
|
|
123
|
+
* @param {PartialScreen> | string} value
|
|
124
|
+
* @param {'min' | 'max'} type
|
|
125
|
+
* @returns {Screen}
|
|
126
|
+
*/
|
|
127
|
+
export function toScreen(value, type) {
|
|
128
|
+
if (typeof value === 'object') {
|
|
129
|
+
return value
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
name: 'arbitrary-screen',
|
|
134
|
+
values: [{ [type]: value }],
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
43
138
|
function resolveValue({ 'min-width': _minWidth, min = _minWidth, max, raw } = {}) {
|
|
44
139
|
return { min, max, raw }
|
|
45
140
|
}
|
|
@@ -1,58 +1,11 @@
|
|
|
1
|
+
import { splitAtTopLevelOnly } from './splitAtTopLevelOnly'
|
|
2
|
+
|
|
1
3
|
let KEYWORDS = new Set(['inset', 'inherit', 'initial', 'revert', 'unset'])
|
|
2
4
|
let SPACE = /\ +(?![^(]*\))/g // Similar to the one above, but with spaces instead.
|
|
3
5
|
let LENGTH = /^-?(\d+|\.\d+)(.*?)$/g
|
|
4
6
|
|
|
5
|
-
let SPECIALS = /[(),]/g
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* This splits a string on top-level commas.
|
|
9
|
-
*
|
|
10
|
-
* Regex doesn't support recursion (at least not the JS-flavored version).
|
|
11
|
-
* So we have to use a tiny state machine to keep track of paren vs comma
|
|
12
|
-
* placement. Before we'd only exclude commas from the inner-most nested
|
|
13
|
-
* set of parens rather than any commas that were not contained in parens
|
|
14
|
-
* at all which is the intended behavior here.
|
|
15
|
-
*
|
|
16
|
-
* Expected behavior:
|
|
17
|
-
* var(--a, 0 0 1px rgb(0, 0, 0)), 0 0 1px rgb(0, 0, 0)
|
|
18
|
-
* ─┬─ ┬ ┬ ┬
|
|
19
|
-
* x x x ╰──────── Split because top-level
|
|
20
|
-
* ╰──────────────┴──┴───────────── Ignored b/c inside >= 1 levels of parens
|
|
21
|
-
*
|
|
22
|
-
* @param {string} input
|
|
23
|
-
*/
|
|
24
|
-
function* splitByTopLevelCommas(input) {
|
|
25
|
-
SPECIALS.lastIndex = -1
|
|
26
|
-
|
|
27
|
-
let depth = 0
|
|
28
|
-
let lastIndex = 0
|
|
29
|
-
let found = false
|
|
30
|
-
|
|
31
|
-
// Find all parens & commas
|
|
32
|
-
// And only split on commas if they're top-level
|
|
33
|
-
for (let match of input.matchAll(SPECIALS)) {
|
|
34
|
-
if (match[0] === '(') depth++
|
|
35
|
-
if (match[0] === ')') depth--
|
|
36
|
-
if (match[0] === ',' && depth === 0) {
|
|
37
|
-
found = true
|
|
38
|
-
|
|
39
|
-
yield input.substring(lastIndex, match.index)
|
|
40
|
-
lastIndex = match.index + match[0].length
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Provide the last segment of the string if available
|
|
45
|
-
// Otherwise the whole string since no commas were found
|
|
46
|
-
// This mirrors the behavior of string.split()
|
|
47
|
-
if (found) {
|
|
48
|
-
yield input.substring(lastIndex)
|
|
49
|
-
} else {
|
|
50
|
-
yield input
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
7
|
export function parseBoxShadowValue(input) {
|
|
55
|
-
let shadows =
|
|
8
|
+
let shadows = splitAtTopLevelOnly(input, ',')
|
|
56
9
|
return shadows.map((shadow) => {
|
|
57
10
|
let value = shadow.trim()
|
|
58
11
|
let result = { raw: value }
|
|
@@ -1,49 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
if (glob.substr(0, 2) === './') {
|
|
19
|
-
glob = glob.substr(2)
|
|
20
|
-
}
|
|
21
|
-
if (glob.charAt(0) === '/') {
|
|
22
|
-
glob = glob.substr(1)
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {{type: 'dependency', file: string} | {type: 'dir-dependency', dir: string, glob: string}} Dependency
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @param {import('../lib/content.js').ContentPath} contentPath
|
|
10
|
+
* @returns {Dependency[]}
|
|
11
|
+
*/
|
|
12
|
+
export default function parseDependency(contentPath) {
|
|
13
|
+
if (contentPath.ignore) {
|
|
14
|
+
return []
|
|
23
15
|
}
|
|
24
16
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
let message
|
|
34
|
-
|
|
35
|
-
if (isGlob(normalizedFileOrGlob)) {
|
|
36
|
-
let { base, glob } = parseGlob(normalizedFileOrGlob)
|
|
37
|
-
message = { type: 'dir-dependency', dir: path.resolve(base), glob }
|
|
38
|
-
} else {
|
|
39
|
-
message = { type: 'dependency', file: path.resolve(normalizedFileOrGlob) }
|
|
17
|
+
if (!contentPath.glob) {
|
|
18
|
+
return [
|
|
19
|
+
{
|
|
20
|
+
type: 'dependency',
|
|
21
|
+
file: contentPath.base,
|
|
22
|
+
},
|
|
23
|
+
]
|
|
40
24
|
}
|
|
41
25
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
26
|
+
if (process.env.ROLLUP_WATCH === 'true') {
|
|
27
|
+
// rollup-plugin-postcss does not support dir-dependency messages
|
|
28
|
+
// but directories can be watched in the same way as files
|
|
29
|
+
return [
|
|
30
|
+
{
|
|
31
|
+
type: 'dependency',
|
|
32
|
+
file: contentPath.base,
|
|
33
|
+
},
|
|
34
|
+
]
|
|
46
35
|
}
|
|
47
36
|
|
|
48
|
-
return
|
|
37
|
+
return [
|
|
38
|
+
{
|
|
39
|
+
type: 'dir-dependency',
|
|
40
|
+
dir: contentPath.base,
|
|
41
|
+
glob: contentPath.glob,
|
|
42
|
+
},
|
|
43
|
+
]
|
|
49
44
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import globParent from 'glob-parent'
|
|
2
|
+
|
|
3
|
+
// Based on `glob-base`
|
|
4
|
+
// https://github.com/micromatch/glob-base/blob/master/index.js
|
|
5
|
+
export function parseGlob(pattern) {
|
|
6
|
+
let glob = pattern
|
|
7
|
+
let base = globParent(pattern)
|
|
8
|
+
|
|
9
|
+
if (base !== '.') {
|
|
10
|
+
glob = pattern.substr(base.length)
|
|
11
|
+
if (glob.charAt(0) === '/') {
|
|
12
|
+
glob = glob.substr(1)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (glob.substr(0, 2) === './') {
|
|
17
|
+
glob = glob.substr(2)
|
|
18
|
+
}
|
|
19
|
+
if (glob.charAt(0) === '/') {
|
|
20
|
+
glob = glob.substr(1)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return { base, glob }
|
|
24
|
+
}
|
package/src/util/pluginUtils.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import selectorParser from 'postcss-selector-parser'
|
|
2
1
|
import escapeCommas from './escapeCommas'
|
|
3
2
|
import { withAlphaValue } from './withAlphaVariable'
|
|
4
3
|
import {
|
|
@@ -18,21 +17,21 @@ import {
|
|
|
18
17
|
shadow,
|
|
19
18
|
} from './dataTypes'
|
|
20
19
|
import negateValue from './negateValue'
|
|
20
|
+
import { backgroundSize } from './validateFormalSyntax'
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* @param {import('postcss-selector-parser').Container} selectors
|
|
24
|
+
* @param {(className: string) => string} updateClass
|
|
25
|
+
* @returns {string}
|
|
26
|
+
*/
|
|
22
27
|
export function updateAllClasses(selectors, updateClass) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
let updatedClass = updateClass(sel.value)
|
|
26
|
-
sel.value = updatedClass
|
|
27
|
-
if (sel.raws && sel.raws.value) {
|
|
28
|
-
sel.raws.value = escapeCommas(sel.raws.value)
|
|
29
|
-
}
|
|
30
|
-
})
|
|
31
|
-
})
|
|
28
|
+
selectors.walkClasses((sel) => {
|
|
29
|
+
sel.value = updateClass(sel.value)
|
|
32
30
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
if (sel.raws && sel.raws.value) {
|
|
32
|
+
sel.raws.value = escapeCommas(sel.raws.value)
|
|
33
|
+
}
|
|
34
|
+
})
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
function resolveArbitraryValue(modifier, validate) {
|
|
@@ -85,22 +84,47 @@ function isArbitraryValue(input) {
|
|
|
85
84
|
return input.startsWith('[') && input.endsWith(']')
|
|
86
85
|
}
|
|
87
86
|
|
|
88
|
-
function
|
|
87
|
+
function splitUtilityModifier(modifier) {
|
|
89
88
|
let slashIdx = modifier.lastIndexOf('/')
|
|
90
89
|
|
|
91
90
|
if (slashIdx === -1 || slashIdx === modifier.length - 1) {
|
|
92
|
-
return [modifier]
|
|
91
|
+
return [modifier, undefined]
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
let arbitrary = isArbitraryValue(modifier)
|
|
95
|
+
|
|
96
|
+
// The modifier could be of the form `[foo]/[bar]`
|
|
97
|
+
// We want to handle this case properly
|
|
98
|
+
// without affecting `[foo/bar]`
|
|
99
|
+
if (arbitrary && !modifier.includes(']/[')) {
|
|
100
|
+
return [modifier, undefined]
|
|
93
101
|
}
|
|
94
102
|
|
|
95
103
|
return [modifier.slice(0, slashIdx), modifier.slice(slashIdx + 1)]
|
|
96
104
|
}
|
|
97
105
|
|
|
106
|
+
export function parseColorFormat(value) {
|
|
107
|
+
if (typeof value === 'string' && value.includes('<alpha-value>')) {
|
|
108
|
+
let oldValue = value
|
|
109
|
+
|
|
110
|
+
return ({ opacityValue = 1 }) => oldValue.replace('<alpha-value>', opacityValue)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return value
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function unwrapArbitraryModifier(modifier) {
|
|
117
|
+
return normalize(modifier.slice(1, -1))
|
|
118
|
+
}
|
|
119
|
+
|
|
98
120
|
export function asColor(modifier, options = {}, { tailwindConfig = {} } = {}) {
|
|
99
121
|
if (options.values?.[modifier] !== undefined) {
|
|
100
|
-
return options.values?.[modifier]
|
|
122
|
+
return parseColorFormat(options.values?.[modifier])
|
|
101
123
|
}
|
|
102
124
|
|
|
103
|
-
|
|
125
|
+
// TODO: Hoist this up to getMatchingTypes or something
|
|
126
|
+
// We do this here because we need the alpha value (if any)
|
|
127
|
+
let [color, alpha] = splitUtilityModifier(modifier)
|
|
104
128
|
|
|
105
129
|
if (alpha !== undefined) {
|
|
106
130
|
let normalizedColor =
|
|
@@ -110,8 +134,10 @@ export function asColor(modifier, options = {}, { tailwindConfig = {} } = {}) {
|
|
|
110
134
|
return undefined
|
|
111
135
|
}
|
|
112
136
|
|
|
137
|
+
normalizedColor = parseColorFormat(normalizedColor)
|
|
138
|
+
|
|
113
139
|
if (isArbitraryValue(alpha)) {
|
|
114
|
-
return withAlphaValue(normalizedColor, alpha
|
|
140
|
+
return withAlphaValue(normalizedColor, unwrapArbitraryModifier(alpha))
|
|
115
141
|
}
|
|
116
142
|
|
|
117
143
|
if (tailwindConfig.theme?.opacity?.[alpha] === undefined) {
|
|
@@ -134,7 +160,7 @@ function guess(validate) {
|
|
|
134
160
|
}
|
|
135
161
|
}
|
|
136
162
|
|
|
137
|
-
let typeMap = {
|
|
163
|
+
export let typeMap = {
|
|
138
164
|
any: asValue,
|
|
139
165
|
color: asColor,
|
|
140
166
|
url: guess(url),
|
|
@@ -150,6 +176,7 @@ let typeMap = {
|
|
|
150
176
|
'absolute-size': guess(absoluteSize),
|
|
151
177
|
'relative-size': guess(relativeSize),
|
|
152
178
|
shadow: guess(shadow),
|
|
179
|
+
size: guess(backgroundSize),
|
|
153
180
|
}
|
|
154
181
|
|
|
155
182
|
let supportedTypes = Object.keys(typeMap)
|
|
@@ -161,6 +188,20 @@ function splitAtFirst(input, delim) {
|
|
|
161
188
|
}
|
|
162
189
|
|
|
163
190
|
export function coerceValue(types, modifier, options, tailwindConfig) {
|
|
191
|
+
if (options.values && modifier in options.values) {
|
|
192
|
+
for (let { type } of types ?? []) {
|
|
193
|
+
let result = typeMap[type](modifier, options, {
|
|
194
|
+
tailwindConfig,
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
if (result === undefined) {
|
|
198
|
+
continue
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return [result, type, null]
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
164
205
|
if (isArbitraryValue(modifier)) {
|
|
165
206
|
let arbitraryValue = modifier.slice(1, -1)
|
|
166
207
|
let [explicitType, value] = splitAtFirst(arbitraryValue, ':')
|
|
@@ -178,15 +219,69 @@ export function coerceValue(types, modifier, options, tailwindConfig) {
|
|
|
178
219
|
}
|
|
179
220
|
|
|
180
221
|
if (value.length > 0 && supportedTypes.includes(explicitType)) {
|
|
181
|
-
return [asValue(`[${value}]`, options), explicitType]
|
|
222
|
+
return [asValue(`[${value}]`, options), explicitType, null]
|
|
182
223
|
}
|
|
183
224
|
}
|
|
184
225
|
|
|
226
|
+
let matches = getMatchingTypes(types, modifier, options, tailwindConfig)
|
|
227
|
+
|
|
185
228
|
// Find first matching type
|
|
186
|
-
for (let
|
|
187
|
-
|
|
188
|
-
if (result !== undefined) return [result, type]
|
|
229
|
+
for (let match of matches) {
|
|
230
|
+
return match
|
|
189
231
|
}
|
|
190
232
|
|
|
191
233
|
return []
|
|
192
234
|
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
*
|
|
238
|
+
* @param {{type: string}[]} types
|
|
239
|
+
* @param {string} rawModifier
|
|
240
|
+
* @param {any} options
|
|
241
|
+
* @param {any} tailwindConfig
|
|
242
|
+
* @returns {Iterator<[value: string, type: string, modifier: string | null]>}
|
|
243
|
+
*/
|
|
244
|
+
export function* getMatchingTypes(types, rawModifier, options, tailwindConfig) {
|
|
245
|
+
let [modifier, utilityModifier] = splitUtilityModifier(rawModifier)
|
|
246
|
+
|
|
247
|
+
let canUseUtilityModifier =
|
|
248
|
+
options.modifiers != null &&
|
|
249
|
+
(options.modifiers === 'any' ||
|
|
250
|
+
(typeof options.modifiers === 'object' &&
|
|
251
|
+
((utilityModifier && isArbitraryValue(utilityModifier)) ||
|
|
252
|
+
utilityModifier in options.modifiers)))
|
|
253
|
+
|
|
254
|
+
if (!canUseUtilityModifier) {
|
|
255
|
+
modifier = rawModifier
|
|
256
|
+
utilityModifier = undefined
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (utilityModifier !== undefined && modifier === '') {
|
|
260
|
+
modifier = 'DEFAULT'
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Check the full value first
|
|
264
|
+
// TODO: Move to asValue… somehow
|
|
265
|
+
if (utilityModifier !== undefined) {
|
|
266
|
+
if (typeof options.modifiers === 'object') {
|
|
267
|
+
let configValue = options.modifiers?.[utilityModifier] ?? null
|
|
268
|
+
if (configValue !== null) {
|
|
269
|
+
utilityModifier = configValue
|
|
270
|
+
} else if (isArbitraryValue(utilityModifier)) {
|
|
271
|
+
utilityModifier = unwrapArbitraryModifier(utilityModifier)
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
for (let { type } of types ?? []) {
|
|
277
|
+
let result = typeMap[type](modifier, options, {
|
|
278
|
+
tailwindConfig,
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
if (result === undefined) {
|
|
282
|
+
continue
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
yield [result, type, utilityModifier ?? null]
|
|
286
|
+
}
|
|
287
|
+
}
|