tailwindcss 0.0.0-insiders.fe08e91 → 0.0.0-oxide.6bf5e56
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 +379 -3
- package/LICENSE +1 -2
- package/README.md +12 -8
- package/colors.d.ts +3 -0
- package/defaultConfig.d.ts +3 -0
- package/defaultTheme.d.ts +4 -0
- package/lib/cli/build/deps.js +54 -0
- package/lib/cli/build/index.js +48 -0
- package/lib/cli/build/plugin.js +367 -0
- package/lib/cli/build/utils.js +78 -0
- package/lib/cli/build/watching.js +178 -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 +13 -0
- package/lib/cli-peer-dependencies.js +20 -7
- package/lib/cli.js +107 -611
- package/lib/constants.js +27 -20
- package/lib/corePluginList.js +6 -3
- package/lib/corePlugins.js +2064 -1811
- package/lib/css/preflight.css +5 -5
- package/lib/featureFlags.js +31 -22
- package/lib/index.js +28 -10
- package/lib/lib/cacheInvalidation.js +90 -0
- package/lib/lib/collapseAdjacentRules.js +27 -9
- package/lib/lib/collapseDuplicateDeclarations.js +12 -9
- package/lib/lib/content.js +176 -0
- package/lib/lib/defaultExtractor.js +225 -31
- package/lib/lib/detectNesting.js +13 -10
- package/lib/lib/evaluateTailwindFunctions.js +118 -55
- package/lib/lib/expandApplyAtRules.js +439 -190
- package/lib/lib/expandTailwindAtRules.js +151 -134
- package/lib/lib/findAtConfigPath.js +44 -0
- package/lib/lib/generateRules.js +454 -187
- package/lib/lib/getModuleDependencies.js +11 -8
- package/lib/lib/normalizeTailwindDirectives.js +36 -32
- 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 +89 -67
- package/lib/lib/setupContextUtils.js +667 -376
- package/lib/lib/setupTrackingContext.js +38 -67
- package/lib/lib/sharedState.js +27 -14
- package/lib/lib/substituteScreenAtRules.js +11 -9
- 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 +35 -25
- package/lib/public/colors.js +247 -245
- 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 +11 -6
- package/lib/util/cloneDeep.js +7 -6
- package/lib/util/cloneNodes.js +21 -3
- package/lib/util/color.js +53 -54
- package/lib/util/configurePlugins.js +5 -2
- package/lib/util/createPlugin.js +6 -6
- package/lib/util/createUtilityPlugin.js +12 -14
- package/lib/util/dataTypes.js +119 -110
- package/lib/util/defaults.js +4 -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 +184 -85
- 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 → isSyntacticallyValidPropertyValue.js} +23 -15
- package/lib/util/log.js +20 -14
- package/lib/util/nameClass.js +20 -9
- package/lib/util/negateValue.js +23 -8
- package/lib/util/normalizeConfig.js +116 -72
- package/lib/util/normalizeScreens.js +120 -11
- package/lib/util/parseAnimationValue.js +42 -40
- package/lib/util/parseBoxShadowValue.js +30 -23
- 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 +147 -50
- package/lib/util/prefixSelector.js +10 -8
- package/lib/util/removeAlphaVariables.js +29 -0
- package/lib/util/resolveConfig.js +97 -85
- 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 +20 -4
- package/lib/util/transformThemeValue.js +37 -29
- 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 +47 -42
- package/peers/index.js +11381 -7950
- 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/deps.js +56 -0
- package/src/cli/build/index.js +49 -0
- package/src/cli/build/plugin.js +439 -0
- package/src/cli/build/utils.js +76 -0
- package/src/cli/build/watching.js +227 -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 +6 -0
- package/src/cli-peer-dependencies.js +7 -1
- package/src/cli.js +50 -629
- package/src/corePluginList.js +1 -1
- package/src/corePlugins.js +532 -217
- package/src/css/preflight.css +5 -5
- package/src/featureFlags.js +15 -9
- package/src/index.js +20 -1
- package/src/lib/cacheInvalidation.js +52 -0
- package/src/lib/collapseAdjacentRules.js +21 -2
- package/src/lib/content.js +212 -0
- package/src/lib/defaultExtractor.js +196 -33
- package/src/lib/evaluateTailwindFunctions.js +78 -7
- package/src/lib/expandApplyAtRules.js +482 -183
- package/src/lib/expandTailwindAtRules.js +106 -85
- package/src/lib/findAtConfigPath.js +48 -0
- package/src/lib/generateRules.js +418 -129
- package/src/lib/normalizeTailwindDirectives.js +1 -0
- 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 +51 -30
- package/src/lib/setupContextUtils.js +556 -208
- package/src/lib/setupTrackingContext.js +11 -48
- package/src/lib/sharedState.js +5 -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 +8 -0
- package/src/util/buildMediaQuery.js +5 -3
- package/src/util/cloneNodes.js +19 -2
- package/src/util/color.js +25 -21
- package/src/util/dataTypes.js +29 -21
- package/src/util/formatVariantSelector.js +184 -61
- package/src/util/getAllConfigs.js +19 -0
- package/src/util/{isValidArbitraryValue.js → isSyntacticallyValidPropertyValue.js} +1 -1
- package/src/util/log.js +8 -8
- package/src/util/nameClass.js +4 -0
- package/src/util/negateValue.js +11 -3
- package/src/util/normalizeConfig.js +44 -6
- package/src/util/normalizeScreens.js +99 -4
- package/src/util/parseBoxShadowValue.js +4 -3
- package/src/util/parseDependency.js +37 -42
- package/src/util/parseGlob.js +24 -0
- package/src/util/pluginUtils.js +132 -10
- package/src/util/prefixSelector.js +7 -5
- package/src/util/removeAlphaVariables.js +24 -0
- package/src/util/resolveConfig.js +70 -32
- package/src/util/splitAtTopLevelOnly.js +45 -0
- package/src/util/toPath.js +1 -1
- package/src/util/transformThemeValue.js +13 -3
- 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 +23 -20
- package/stubs/simpleConfig.stub.js +1 -0
- package/types/config.d.ts +362 -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/nesting/plugin.js +0 -41
|
@@ -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
|
@@ -18,6 +18,8 @@ import {
|
|
|
18
18
|
shadow,
|
|
19
19
|
} from './dataTypes'
|
|
20
20
|
import negateValue from './negateValue'
|
|
21
|
+
import { backgroundSize } from './validateFormalSyntax'
|
|
22
|
+
import { flagEnabled } from '../featureFlags.js'
|
|
21
23
|
|
|
22
24
|
export function updateAllClasses(selectors, updateClass) {
|
|
23
25
|
let parser = selectorParser((selectors) => {
|
|
@@ -35,6 +37,23 @@ export function updateAllClasses(selectors, updateClass) {
|
|
|
35
37
|
return result
|
|
36
38
|
}
|
|
37
39
|
|
|
40
|
+
export function filterSelectorsForClass(selectors, classCandidate) {
|
|
41
|
+
let parser = selectorParser((selectors) => {
|
|
42
|
+
selectors.each((sel) => {
|
|
43
|
+
const containsClass = sel.nodes.some(
|
|
44
|
+
(node) => node.type === 'class' && node.value === classCandidate
|
|
45
|
+
)
|
|
46
|
+
if (!containsClass) {
|
|
47
|
+
sel.remove()
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
let result = parser.processSync(selectors)
|
|
53
|
+
|
|
54
|
+
return result
|
|
55
|
+
}
|
|
56
|
+
|
|
38
57
|
function resolveArbitraryValue(modifier, validate) {
|
|
39
58
|
if (!isArbitraryValue(modifier)) {
|
|
40
59
|
return undefined
|
|
@@ -85,22 +104,51 @@ function isArbitraryValue(input) {
|
|
|
85
104
|
return input.startsWith('[') && input.endsWith(']')
|
|
86
105
|
}
|
|
87
106
|
|
|
88
|
-
function
|
|
107
|
+
function splitUtilityModifier(modifier) {
|
|
89
108
|
let slashIdx = modifier.lastIndexOf('/')
|
|
90
109
|
|
|
91
110
|
if (slashIdx === -1 || slashIdx === modifier.length - 1) {
|
|
92
|
-
return [modifier]
|
|
111
|
+
return [modifier, undefined]
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
let arbitrary = isArbitraryValue(modifier)
|
|
115
|
+
|
|
116
|
+
// The modifier could be of the form `[foo]/[bar]`
|
|
117
|
+
// We want to handle this case properly
|
|
118
|
+
// without affecting `[foo/bar]`
|
|
119
|
+
if (arbitrary && !modifier.includes(']/[')) {
|
|
120
|
+
return [modifier, undefined]
|
|
93
121
|
}
|
|
94
122
|
|
|
95
123
|
return [modifier.slice(0, slashIdx), modifier.slice(slashIdx + 1)]
|
|
96
124
|
}
|
|
97
125
|
|
|
126
|
+
export function parseColorFormat(value) {
|
|
127
|
+
if (typeof value === 'string' && value.includes('<alpha-value>')) {
|
|
128
|
+
let oldValue = value
|
|
129
|
+
|
|
130
|
+
return ({ opacityValue = 1 }) => oldValue.replace('<alpha-value>', opacityValue)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return value
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function unwrapArbitraryModifier(modifier) {
|
|
137
|
+
modifier = modifier.slice(1, -1)
|
|
138
|
+
if (modifier.startsWith('--')) {
|
|
139
|
+
modifier = `var(${modifier})`
|
|
140
|
+
}
|
|
141
|
+
return modifier
|
|
142
|
+
}
|
|
143
|
+
|
|
98
144
|
export function asColor(modifier, options = {}, { tailwindConfig = {} } = {}) {
|
|
99
145
|
if (options.values?.[modifier] !== undefined) {
|
|
100
|
-
return options.values?.[modifier]
|
|
146
|
+
return parseColorFormat(options.values?.[modifier])
|
|
101
147
|
}
|
|
102
148
|
|
|
103
|
-
|
|
149
|
+
// TODO: Hoist this up to getMatchingTypes or something
|
|
150
|
+
// We do this here because we need the alpha value (if any)
|
|
151
|
+
let [color, alpha] = splitUtilityModifier(modifier)
|
|
104
152
|
|
|
105
153
|
if (alpha !== undefined) {
|
|
106
154
|
let normalizedColor =
|
|
@@ -110,8 +158,10 @@ export function asColor(modifier, options = {}, { tailwindConfig = {} } = {}) {
|
|
|
110
158
|
return undefined
|
|
111
159
|
}
|
|
112
160
|
|
|
161
|
+
normalizedColor = parseColorFormat(normalizedColor)
|
|
162
|
+
|
|
113
163
|
if (isArbitraryValue(alpha)) {
|
|
114
|
-
return withAlphaValue(normalizedColor, alpha
|
|
164
|
+
return withAlphaValue(normalizedColor, unwrapArbitraryModifier(alpha))
|
|
115
165
|
}
|
|
116
166
|
|
|
117
167
|
if (tailwindConfig.theme?.opacity?.[alpha] === undefined) {
|
|
@@ -134,7 +184,7 @@ function guess(validate) {
|
|
|
134
184
|
}
|
|
135
185
|
}
|
|
136
186
|
|
|
137
|
-
let typeMap = {
|
|
187
|
+
export let typeMap = {
|
|
138
188
|
any: asValue,
|
|
139
189
|
color: asColor,
|
|
140
190
|
url: guess(url),
|
|
@@ -150,6 +200,7 @@ let typeMap = {
|
|
|
150
200
|
'absolute-size': guess(absoluteSize),
|
|
151
201
|
'relative-size': guess(relativeSize),
|
|
152
202
|
shadow: guess(shadow),
|
|
203
|
+
size: guess(backgroundSize),
|
|
153
204
|
}
|
|
154
205
|
|
|
155
206
|
let supportedTypes = Object.keys(typeMap)
|
|
@@ -161,6 +212,20 @@ function splitAtFirst(input, delim) {
|
|
|
161
212
|
}
|
|
162
213
|
|
|
163
214
|
export function coerceValue(types, modifier, options, tailwindConfig) {
|
|
215
|
+
if (options.values && modifier in options.values) {
|
|
216
|
+
for (let { type } of types ?? []) {
|
|
217
|
+
let result = typeMap[type](modifier, options, {
|
|
218
|
+
tailwindConfig,
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
if (result === undefined) {
|
|
222
|
+
continue
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return [result, type, null]
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
164
229
|
if (isArbitraryValue(modifier)) {
|
|
165
230
|
let arbitraryValue = modifier.slice(1, -1)
|
|
166
231
|
let [explicitType, value] = splitAtFirst(arbitraryValue, ':')
|
|
@@ -178,15 +243,72 @@ export function coerceValue(types, modifier, options, tailwindConfig) {
|
|
|
178
243
|
}
|
|
179
244
|
|
|
180
245
|
if (value.length > 0 && supportedTypes.includes(explicitType)) {
|
|
181
|
-
return [asValue(`[${value}]`, options), explicitType]
|
|
246
|
+
return [asValue(`[${value}]`, options), explicitType, null]
|
|
182
247
|
}
|
|
183
248
|
}
|
|
184
249
|
|
|
250
|
+
let matches = getMatchingTypes(types, modifier, options, tailwindConfig)
|
|
251
|
+
|
|
185
252
|
// Find first matching type
|
|
186
|
-
for (let
|
|
187
|
-
|
|
188
|
-
if (result !== undefined) return [result, type]
|
|
253
|
+
for (let match of matches) {
|
|
254
|
+
return match
|
|
189
255
|
}
|
|
190
256
|
|
|
191
257
|
return []
|
|
192
258
|
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
*
|
|
262
|
+
* @param {{type: string}[]} types
|
|
263
|
+
* @param {string} rawModifier
|
|
264
|
+
* @param {any} options
|
|
265
|
+
* @param {any} tailwindConfig
|
|
266
|
+
* @returns {Iterator<[value: string, type: string, modifier: string | null]>}
|
|
267
|
+
*/
|
|
268
|
+
export function* getMatchingTypes(types, rawModifier, options, tailwindConfig) {
|
|
269
|
+
let modifiersEnabled = flagEnabled(tailwindConfig, 'generalizedModifiers')
|
|
270
|
+
|
|
271
|
+
let [modifier, utilityModifier] = splitUtilityModifier(rawModifier)
|
|
272
|
+
|
|
273
|
+
let canUseUtilityModifier =
|
|
274
|
+
modifiersEnabled &&
|
|
275
|
+
options.modifiers != null &&
|
|
276
|
+
(options.modifiers === 'any' ||
|
|
277
|
+
(typeof options.modifiers === 'object' &&
|
|
278
|
+
((utilityModifier && isArbitraryValue(utilityModifier)) ||
|
|
279
|
+
utilityModifier in options.modifiers)))
|
|
280
|
+
|
|
281
|
+
if (!canUseUtilityModifier) {
|
|
282
|
+
modifier = rawModifier
|
|
283
|
+
utilityModifier = undefined
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if (utilityModifier !== undefined && modifier === '') {
|
|
287
|
+
modifier = 'DEFAULT'
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Check the full value first
|
|
291
|
+
// TODO: Move to asValue… somehow
|
|
292
|
+
if (utilityModifier !== undefined) {
|
|
293
|
+
if (typeof options.modifiers === 'object') {
|
|
294
|
+
let configValue = options.modifiers?.[utilityModifier] ?? null
|
|
295
|
+
if (configValue !== null) {
|
|
296
|
+
utilityModifier = configValue
|
|
297
|
+
} else if (isArbitraryValue(utilityModifier)) {
|
|
298
|
+
utilityModifier = unwrapArbitraryModifier(utilityModifier)
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
for (let { type } of types ?? []) {
|
|
304
|
+
let result = typeMap[type](modifier, options, {
|
|
305
|
+
tailwindConfig,
|
|
306
|
+
})
|
|
307
|
+
|
|
308
|
+
if (result === undefined) {
|
|
309
|
+
continue
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
yield [result, type, utilityModifier ?? null]
|
|
313
|
+
}
|
|
314
|
+
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import parser from 'postcss-selector-parser'
|
|
2
|
-
import { tap } from './tap'
|
|
3
2
|
|
|
4
|
-
export default function (prefix, selector) {
|
|
3
|
+
export default function (prefix, selector, prependNegative = false) {
|
|
5
4
|
return parser((selectors) => {
|
|
6
5
|
selectors.walkClasses((classSelector) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
let baseClass = classSelector.value
|
|
7
|
+
let shouldPlaceNegativeBeforePrefix = prependNegative && baseClass.startsWith('-')
|
|
8
|
+
|
|
9
|
+
classSelector.value = shouldPlaceNegativeBeforePrefix
|
|
10
|
+
? `-${prefix}${baseClass.slice(1)}`
|
|
11
|
+
: `${prefix}${baseClass}`
|
|
10
12
|
})
|
|
11
13
|
}).processSync(selector)
|
|
12
14
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This function removes any uses of CSS variables used as an alpha channel
|
|
3
|
+
*
|
|
4
|
+
* This is required for selectors like `:visited` which do not allow
|
|
5
|
+
* changes in opacity or external control using CSS variables.
|
|
6
|
+
*
|
|
7
|
+
* @param {import('postcss').Container} container
|
|
8
|
+
* @param {string[]} toRemove
|
|
9
|
+
*/
|
|
10
|
+
export function removeAlphaVariables(container, toRemove) {
|
|
11
|
+
container.walkDecls((decl) => {
|
|
12
|
+
if (toRemove.includes(decl.prop)) {
|
|
13
|
+
decl.remove()
|
|
14
|
+
|
|
15
|
+
return
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
for (let varName of toRemove) {
|
|
19
|
+
if (decl.value.includes(`/ var(${varName})`)) {
|
|
20
|
+
decl.value = decl.value.replace(`/ var(${varName})`, '')
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
})
|
|
24
|
+
}
|
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
import negateValue from './negateValue'
|
|
2
2
|
import corePluginList from '../corePluginList'
|
|
3
3
|
import configurePlugins from './configurePlugins'
|
|
4
|
-
import defaultConfig from '../../stubs/defaultConfig.stub'
|
|
5
4
|
import colors from '../public/colors'
|
|
6
5
|
import { defaults } from './defaults'
|
|
7
6
|
import { toPath } from './toPath'
|
|
8
7
|
import { normalizeConfig } from './normalizeConfig'
|
|
9
8
|
import isPlainObject from './isPlainObject'
|
|
10
9
|
import { cloneDeep } from './cloneDeep'
|
|
10
|
+
import { parseColorFormat } from './pluginUtils'
|
|
11
|
+
import { withAlphaValue } from './withAlphaVariable'
|
|
12
|
+
import toColorValue from './toColorValue'
|
|
11
13
|
|
|
12
14
|
function isFunction(input) {
|
|
13
15
|
return typeof input === 'function'
|
|
14
16
|
}
|
|
15
17
|
|
|
16
|
-
function isObject(input) {
|
|
17
|
-
return typeof input === 'object' && input !== null
|
|
18
|
-
}
|
|
19
|
-
|
|
20
18
|
function mergeWith(target, ...sources) {
|
|
21
19
|
let customizer = sources.pop()
|
|
22
20
|
|
|
@@ -25,8 +23,8 @@ function mergeWith(target, ...sources) {
|
|
|
25
23
|
let merged = customizer(target[k], source[k])
|
|
26
24
|
|
|
27
25
|
if (merged === undefined) {
|
|
28
|
-
if (
|
|
29
|
-
target[k] = mergeWith(target[k], source[k], customizer)
|
|
26
|
+
if (isPlainObject(target[k]) && isPlainObject(source[k])) {
|
|
27
|
+
target[k] = mergeWith({}, target[k], source[k], customizer)
|
|
30
28
|
} else {
|
|
31
29
|
target[k] = source[k]
|
|
32
30
|
}
|
|
@@ -100,12 +98,12 @@ function mergeThemes(themes) {
|
|
|
100
98
|
|
|
101
99
|
function mergeExtensionCustomizer(merged, value) {
|
|
102
100
|
// When we have an array of objects, we do want to merge it
|
|
103
|
-
if (Array.isArray(merged) &&
|
|
101
|
+
if (Array.isArray(merged) && isPlainObject(merged[0])) {
|
|
104
102
|
return merged.concat(value)
|
|
105
103
|
}
|
|
106
104
|
|
|
107
105
|
// When the incoming value is an array, and the existing config is an object, prepend the existing object
|
|
108
|
-
if (Array.isArray(value) &&
|
|
106
|
+
if (Array.isArray(value) && isPlainObject(value[0]) && isPlainObject(merged)) {
|
|
109
107
|
return [merged, ...value]
|
|
110
108
|
}
|
|
111
109
|
|
|
@@ -134,40 +132,81 @@ function mergeExtensions({ extend, ...theme }) {
|
|
|
134
132
|
})
|
|
135
133
|
}
|
|
136
134
|
|
|
135
|
+
/**
|
|
136
|
+
*
|
|
137
|
+
* @param {string} key
|
|
138
|
+
* @return {Iterable<string[] & {alpha: string | undefined}>}
|
|
139
|
+
*/
|
|
140
|
+
function* toPaths(key) {
|
|
141
|
+
let path = toPath(key)
|
|
142
|
+
|
|
143
|
+
if (path.length === 0) {
|
|
144
|
+
return
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
yield path
|
|
148
|
+
|
|
149
|
+
if (Array.isArray(key)) {
|
|
150
|
+
return
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
let pattern = /^(.*?)\s*\/\s*([^/]+)$/
|
|
154
|
+
let matches = key.match(pattern)
|
|
155
|
+
|
|
156
|
+
if (matches !== null) {
|
|
157
|
+
let [, prefix, alpha] = matches
|
|
158
|
+
|
|
159
|
+
let newPath = toPath(prefix)
|
|
160
|
+
newPath.alpha = alpha
|
|
161
|
+
|
|
162
|
+
yield newPath
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
137
166
|
function resolveFunctionKeys(object) {
|
|
167
|
+
// theme('colors.red.500 / 0.5') -> ['colors', 'red', '500 / 0', '5]
|
|
168
|
+
|
|
138
169
|
const resolvePath = (key, defaultValue) => {
|
|
139
|
-
const path
|
|
170
|
+
for (const path of toPaths(key)) {
|
|
171
|
+
let index = 0
|
|
172
|
+
let val = object
|
|
140
173
|
|
|
141
|
-
|
|
142
|
-
|
|
174
|
+
while (val !== undefined && val !== null && index < path.length) {
|
|
175
|
+
val = val[path[index++]]
|
|
143
176
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
val = isFunction(val) ? val(resolvePath, configUtils) : val
|
|
147
|
-
}
|
|
177
|
+
let shouldResolveAsFn =
|
|
178
|
+
isFunction(val) && (path.alpha === undefined || index <= path.length - 1)
|
|
148
179
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
180
|
+
val = shouldResolveAsFn ? val(resolvePath, configUtils) : val
|
|
181
|
+
}
|
|
152
182
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
183
|
+
if (val !== undefined) {
|
|
184
|
+
if (path.alpha !== undefined) {
|
|
185
|
+
let normalized = parseColorFormat(val)
|
|
156
186
|
|
|
157
|
-
|
|
158
|
-
|
|
187
|
+
return withAlphaValue(normalized, path.alpha, toColorValue(normalized))
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (isPlainObject(val)) {
|
|
191
|
+
return cloneDeep(val)
|
|
192
|
+
}
|
|
159
193
|
|
|
160
|
-
|
|
194
|
+
return val
|
|
195
|
+
}
|
|
196
|
+
}
|
|
161
197
|
|
|
162
|
-
|
|
163
|
-
resolvePath[key] = configUtils[key]
|
|
198
|
+
return defaultValue
|
|
164
199
|
}
|
|
165
200
|
|
|
201
|
+
Object.assign(resolvePath, {
|
|
202
|
+
theme: resolvePath,
|
|
203
|
+
...configUtils,
|
|
204
|
+
})
|
|
205
|
+
|
|
166
206
|
return Object.keys(object).reduce((resolved, key) => {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
207
|
+
resolved[key] = isFunction(object[key]) ? object[key](resolvePath, configUtils) : object[key]
|
|
208
|
+
|
|
209
|
+
return resolved
|
|
171
210
|
}, {})
|
|
172
211
|
}
|
|
173
212
|
|
|
@@ -220,7 +259,6 @@ export default function resolveConfig(configs) {
|
|
|
220
259
|
prefix: '',
|
|
221
260
|
important: false,
|
|
222
261
|
separator: ':',
|
|
223
|
-
variantOrder: defaultConfig.variantOrder,
|
|
224
262
|
},
|
|
225
263
|
]
|
|
226
264
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This splits a string on a top-level character.
|
|
3
|
+
*
|
|
4
|
+
* Regex doesn't support recursion (at least not the JS-flavored version).
|
|
5
|
+
* So we have to use a tiny state machine to keep track of paren placement.
|
|
6
|
+
*
|
|
7
|
+
* Expected behavior using commas:
|
|
8
|
+
* var(--a, 0 0 1px rgb(0, 0, 0)), 0 0 1px rgb(0, 0, 0)
|
|
9
|
+
* ─┬─ ┬ ┬ ┬
|
|
10
|
+
* x x x ╰──────── Split because top-level
|
|
11
|
+
* ╰──────────────┴──┴───────────── Ignored b/c inside >= 1 levels of parens
|
|
12
|
+
*
|
|
13
|
+
* @param {string} input
|
|
14
|
+
* @param {string} separator
|
|
15
|
+
*/
|
|
16
|
+
export function splitAtTopLevelOnly(input, separator) {
|
|
17
|
+
let stack = []
|
|
18
|
+
let parts = []
|
|
19
|
+
let lastPos = 0
|
|
20
|
+
|
|
21
|
+
for (let idx = 0; idx < input.length; idx++) {
|
|
22
|
+
let char = input[idx]
|
|
23
|
+
|
|
24
|
+
if (stack.length === 0 && char === separator[0]) {
|
|
25
|
+
if (separator.length === 1 || input.slice(idx, idx + separator.length) === separator) {
|
|
26
|
+
parts.push(input.slice(lastPos, idx))
|
|
27
|
+
lastPos = idx + separator.length
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (char === '(' || char === '[' || char === '{') {
|
|
32
|
+
stack.push(char)
|
|
33
|
+
} else if (
|
|
34
|
+
(char === ')' && stack[stack.length - 1] === '(') ||
|
|
35
|
+
(char === ']' && stack[stack.length - 1] === '[') ||
|
|
36
|
+
(char === '}' && stack[stack.length - 1] === '{')
|
|
37
|
+
) {
|
|
38
|
+
stack.pop()
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
parts.push(input.slice(lastPos))
|
|
43
|
+
|
|
44
|
+
return parts
|
|
45
|
+
}
|
package/src/util/toPath.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import postcss from 'postcss'
|
|
2
|
+
import isPlainObject from './isPlainObject'
|
|
2
3
|
|
|
3
4
|
export default function transformThemeValue(themeSection) {
|
|
4
5
|
if (['fontSize', 'outline'].includes(themeSection)) {
|
|
@@ -10,9 +11,16 @@ export default function transformThemeValue(themeSection) {
|
|
|
10
11
|
}
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
if (themeSection === 'fontFamily') {
|
|
15
|
+
return (value) => {
|
|
16
|
+
if (typeof value === 'function') value = value({})
|
|
17
|
+
let families = Array.isArray(value) && isPlainObject(value[1]) ? value[0] : value
|
|
18
|
+
return Array.isArray(families) ? families.join(', ') : families
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
13
22
|
if (
|
|
14
23
|
[
|
|
15
|
-
'fontFamily',
|
|
16
24
|
'boxShadow',
|
|
17
25
|
'transitionProperty',
|
|
18
26
|
'transitionDuration',
|
|
@@ -44,8 +52,10 @@ export default function transformThemeValue(themeSection) {
|
|
|
44
52
|
}
|
|
45
53
|
}
|
|
46
54
|
|
|
47
|
-
return (value) => {
|
|
48
|
-
if (typeof value === 'function')
|
|
55
|
+
return (value, opts = {}) => {
|
|
56
|
+
if (typeof value === 'function') {
|
|
57
|
+
value = value(opts)
|
|
58
|
+
}
|
|
49
59
|
|
|
50
60
|
return value
|
|
51
61
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import log from './log'
|
|
2
|
+
|
|
3
|
+
export function validateConfig(config) {
|
|
4
|
+
if (config.content.files.length === 0) {
|
|
5
|
+
log.warn('content-problems', [
|
|
6
|
+
'The `content` option in your Tailwind CSS configuration is missing or empty.',
|
|
7
|
+
'Configure your content sources or your generated CSS will be missing styles.',
|
|
8
|
+
'https://tailwindcss.com/docs/content-configuration',
|
|
9
|
+
])
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return config
|
|
13
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { length, percentage } from './dataTypes'
|
|
2
|
+
import { splitAtTopLevelOnly } from './splitAtTopLevelOnly'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* https://developer.mozilla.org/en-US/docs/Web/CSS/background-size#formal_syntax
|
|
7
|
+
*
|
|
8
|
+
* background-size =
|
|
9
|
+
* <bg-size>#
|
|
10
|
+
*
|
|
11
|
+
* <bg-size> =
|
|
12
|
+
* [ <length-percentage [0,∞]> | auto ]{1,2} |
|
|
13
|
+
* cover |
|
|
14
|
+
* contain
|
|
15
|
+
*
|
|
16
|
+
* <length-percentage> =
|
|
17
|
+
* <length> |
|
|
18
|
+
* <percentage>
|
|
19
|
+
*
|
|
20
|
+
* @param {string} value
|
|
21
|
+
*/
|
|
22
|
+
export function backgroundSize(value) {
|
|
23
|
+
let keywordValues = ['cover', 'contain']
|
|
24
|
+
// the <length-percentage> type will probably be a css function
|
|
25
|
+
// so we have to use `splitAtTopLevelOnly`
|
|
26
|
+
return splitAtTopLevelOnly(value, ',').every((part) => {
|
|
27
|
+
let sizes = splitAtTopLevelOnly(part, '_').filter(Boolean)
|
|
28
|
+
if (sizes.length === 1 && keywordValues.includes(sizes[0])) return true
|
|
29
|
+
|
|
30
|
+
if (sizes.length !== 1 && sizes.length !== 2) return false
|
|
31
|
+
|
|
32
|
+
return sizes.every((size) => length(size) || percentage(size) || size === 'auto')
|
|
33
|
+
})
|
|
34
|
+
}
|