tailwindcss 0.0.0-insiders.fda68f7 → 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 +603 -2
- package/LICENSE +1 -2
- package/README.md +14 -6
- 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 +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 +22 -14
- package/lib/cli.js +217 -743
- package/lib/constants.js +41 -34
- package/lib/corePluginList.js +178 -5
- package/lib/corePlugins.js +3879 -2941
- package/lib/css/preflight.css +22 -9
- package/lib/featureFlags.js +61 -50
- package/lib/index.js +45 -28
- 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 +176 -0
- package/lib/lib/defaultExtractor.js +236 -0
- package/lib/lib/detectNesting.js +37 -0
- package/lib/lib/evaluateTailwindFunctions.js +203 -161
- package/lib/lib/expandApplyAtRules.js +502 -221
- package/lib/lib/expandTailwindAtRules.js +258 -243
- package/lib/lib/findAtConfigPath.js +44 -0
- package/lib/lib/generateRules.js +775 -320
- package/lib/lib/getModuleDependencies.js +44 -46
- package/lib/lib/normalizeTailwindDirectives.js +79 -60
- 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 +150 -94
- package/lib/lib/setupContextUtils.js +1146 -599
- package/lib/lib/setupTrackingContext.js +129 -177
- package/lib/lib/sharedState.js +53 -21
- package/lib/lib/substituteScreenAtRules.js +26 -28
- 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 -53
- package/lib/public/colors.js +331 -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/resolve-config.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 +90 -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 +242 -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 +285 -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 +37 -26
- package/lib/util/negateValue.js +31 -17
- package/lib/util/normalizeConfig.js +281 -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 +252 -287
- package/lib/util/prefixSelector.js +20 -20
- package/lib/util/removeAlphaVariables.js +29 -0
- package/lib/util/resolveConfig.js +221 -256
- package/lib/util/resolveConfigPath.js +43 -48
- package/lib/util/responsive.js +18 -14
- package/lib/util/splitAtTopLevelOnly.js +43 -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/nesting/index.js +2 -12
- package/package.json +60 -65
- package/peers/index.js +76445 -84221
- 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/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 -575
- package/src/corePluginList.js +1 -1
- package/src/corePlugins.js +2405 -1948
- package/src/css/preflight.css +22 -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 +212 -0
- package/src/lib/defaultExtractor.js +211 -0
- package/src/lib/detectNesting.js +39 -0
- package/src/lib/evaluateTailwindFunctions.js +84 -10
- package/src/lib/expandApplyAtRules.js +508 -153
- package/src/lib/expandTailwindAtRules.js +130 -104
- package/src/lib/findAtConfigPath.js +48 -0
- package/src/lib/generateRules.js +596 -70
- 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 +105 -47
- package/src/lib/setupContextUtils.js +828 -196
- package/src/lib/setupTrackingContext.js +19 -54
- package/src/lib/sharedState.js +45 -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 +19 -2
- package/src/public/colors.js +300 -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/resolve-config.js +7 -0
- 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 -11
- package/src/util/dataTypes.js +256 -0
- package/src/util/defaults.js +6 -0
- package/src/util/formatVariantSelector.js +319 -0
- package/src/util/getAllConfigs.js +19 -0
- package/src/util/isSyntacticallyValidPropertyValue.js +61 -0
- package/src/util/log.js +23 -22
- package/src/util/nameClass.js +14 -6
- package/src/util/negateValue.js +15 -5
- package/src/util/normalizeConfig.js +300 -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 +216 -197
- package/src/util/prefixSelector.js +7 -8
- package/src/util/removeAlphaVariables.js +24 -0
- package/src/util/resolveConfig.js +86 -91
- 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 +14 -9
- package/stubs/defaultConfig.stub.js +186 -117
- package/stubs/simpleConfig.stub.js +1 -1
- 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/lib/lib/setupWatchingContext.js +0 -331
- package/nesting/plugin.js +0 -41
- package/src/lib/setupWatchingContext.js +0 -306
|
@@ -1,45 +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)
|
|
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 []
|
|
20
15
|
}
|
|
21
|
-
if (glob.charAt(0) === '/') {
|
|
22
|
-
glob = glob.substr(1)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return { base, glob }
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export default function parseDependency(normalizedFileOrGlob) {
|
|
29
|
-
let message
|
|
30
16
|
|
|
31
|
-
if (
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
17
|
+
if (!contentPath.glob) {
|
|
18
|
+
return [
|
|
19
|
+
{
|
|
20
|
+
type: 'dependency',
|
|
21
|
+
file: contentPath.base,
|
|
22
|
+
},
|
|
23
|
+
]
|
|
36
24
|
}
|
|
37
25
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
+
]
|
|
42
35
|
}
|
|
43
36
|
|
|
44
|
-
return
|
|
37
|
+
return [
|
|
38
|
+
{
|
|
39
|
+
type: 'dir-dependency',
|
|
40
|
+
dir: contentPath.base,
|
|
41
|
+
glob: contentPath.glob,
|
|
42
|
+
},
|
|
43
|
+
]
|
|
45
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,36 +1,30 @@
|
|
|
1
1
|
import selectorParser from 'postcss-selector-parser'
|
|
2
2
|
import escapeCommas from './escapeCommas'
|
|
3
3
|
import { withAlphaValue } from './withAlphaVariable'
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
4
|
+
import {
|
|
5
|
+
normalize,
|
|
6
|
+
length,
|
|
7
|
+
number,
|
|
8
|
+
percentage,
|
|
9
|
+
url,
|
|
10
|
+
color as validateColor,
|
|
11
|
+
genericName,
|
|
12
|
+
familyName,
|
|
13
|
+
image,
|
|
14
|
+
absoluteSize,
|
|
15
|
+
relativeSize,
|
|
16
|
+
position,
|
|
17
|
+
lineWidth,
|
|
18
|
+
shadow,
|
|
19
|
+
} from './dataTypes'
|
|
20
|
+
import negateValue from './negateValue'
|
|
21
|
+
import { backgroundSize } from './validateFormalSyntax'
|
|
22
|
+
import { flagEnabled } from '../featureFlags.js'
|
|
24
23
|
|
|
25
24
|
export function updateAllClasses(selectors, updateClass) {
|
|
26
25
|
let parser = selectorParser((selectors) => {
|
|
27
26
|
selectors.walkClasses((sel) => {
|
|
28
|
-
let updatedClass = updateClass(sel.value
|
|
29
|
-
withPseudo(className, pseudo) {
|
|
30
|
-
sel.parent.insertAfter(sel, selectorParser.pseudo({ value: `${pseudo}` }))
|
|
31
|
-
return className
|
|
32
|
-
},
|
|
33
|
-
})
|
|
27
|
+
let updatedClass = updateClass(sel.value)
|
|
34
28
|
sel.value = updatedClass
|
|
35
29
|
if (sel.raws && sel.raws.value) {
|
|
36
30
|
sel.raws.value = escapeCommas(sel.raws.value)
|
|
@@ -43,253 +37,278 @@ export function updateAllClasses(selectors, updateClass) {
|
|
|
43
37
|
return result
|
|
44
38
|
}
|
|
45
39
|
|
|
46
|
-
export function
|
|
40
|
+
export function filterSelectorsForClass(selectors, classCandidate) {
|
|
47
41
|
let parser = selectorParser((selectors) => {
|
|
48
42
|
selectors.each((sel) => {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
let updatedClass = updateClass(lastClass.value, {
|
|
56
|
-
withPseudo(className, pseudo) {
|
|
57
|
-
lastClass.parent.insertAfter(lastClass, selectorParser.pseudo({ value: `${pseudo}` }))
|
|
58
|
-
return className
|
|
59
|
-
},
|
|
60
|
-
})
|
|
61
|
-
lastClass.value = updatedClass
|
|
62
|
-
if (lastClass.raws && lastClass.raws.value) {
|
|
63
|
-
lastClass.raws.value = escapeCommas(lastClass.raws.value)
|
|
43
|
+
const containsClass = sel.nodes.some(
|
|
44
|
+
(node) => node.type === 'class' && node.value === classCandidate
|
|
45
|
+
)
|
|
46
|
+
if (!containsClass) {
|
|
47
|
+
sel.remove()
|
|
64
48
|
}
|
|
65
49
|
})
|
|
66
50
|
})
|
|
51
|
+
|
|
67
52
|
let result = parser.processSync(selectors)
|
|
68
53
|
|
|
69
54
|
return result
|
|
70
55
|
}
|
|
71
56
|
|
|
72
|
-
function
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
for (let i = 0; i < str.length; i++) {
|
|
76
|
-
if (str[i] === ',' && str[i - 1] !== '\\') {
|
|
77
|
-
chunks.push(currentChunk)
|
|
78
|
-
currentChunk = ''
|
|
79
|
-
} else {
|
|
80
|
-
currentChunk += str[i]
|
|
81
|
-
}
|
|
57
|
+
function resolveArbitraryValue(modifier, validate) {
|
|
58
|
+
if (!isArbitraryValue(modifier)) {
|
|
59
|
+
return undefined
|
|
82
60
|
}
|
|
83
|
-
chunks.push(currentChunk)
|
|
84
|
-
return chunks
|
|
85
|
-
}
|
|
86
61
|
|
|
87
|
-
|
|
88
|
-
return ({ container }) => {
|
|
89
|
-
container.walkRules((rule) => {
|
|
90
|
-
if (isKeyframeRule(rule)) {
|
|
91
|
-
return rule
|
|
92
|
-
}
|
|
93
|
-
let transformed = splitByNotEscapedCommas(rule.selector).map(transformSelector).join(',')
|
|
94
|
-
rule.selector = transformed
|
|
95
|
-
if (withRule) {
|
|
96
|
-
withRule(rule)
|
|
97
|
-
}
|
|
98
|
-
return rule
|
|
99
|
-
})
|
|
62
|
+
let value = modifier.slice(1, -1)
|
|
100
63
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
let nodes = container.nodes
|
|
104
|
-
container.removeAll()
|
|
105
|
-
wrapper.append(nodes)
|
|
106
|
-
container.append(wrapper)
|
|
107
|
-
}
|
|
64
|
+
if (!validate(value)) {
|
|
65
|
+
return undefined
|
|
108
66
|
}
|
|
67
|
+
|
|
68
|
+
return normalize(value)
|
|
109
69
|
}
|
|
110
70
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
container.walkRules((rule) => {
|
|
114
|
-
let selector = rule.selector
|
|
115
|
-
let variantSelector = updateAllClasses(selector, transformClass)
|
|
116
|
-
rule.selector = variantSelector
|
|
117
|
-
if (withRule) {
|
|
118
|
-
withRule(rule)
|
|
119
|
-
}
|
|
120
|
-
return rule
|
|
121
|
-
})
|
|
71
|
+
function asNegativeValue(modifier, lookup = {}, validate) {
|
|
72
|
+
let positiveValue = lookup[modifier]
|
|
122
73
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
let nodes = container.nodes
|
|
126
|
-
container.removeAll()
|
|
127
|
-
wrapper.append(nodes)
|
|
128
|
-
container.append(wrapper)
|
|
129
|
-
}
|
|
74
|
+
if (positiveValue !== undefined) {
|
|
75
|
+
return negateValue(positiveValue)
|
|
130
76
|
}
|
|
131
|
-
}
|
|
132
77
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
container.walkRules((rule) => {
|
|
136
|
-
let selector = rule.selector
|
|
137
|
-
let variantSelector = updateLastClasses(selector, transformClass)
|
|
138
|
-
rule.selector = variantSelector
|
|
139
|
-
if (withRule) {
|
|
140
|
-
withRule(rule)
|
|
141
|
-
}
|
|
142
|
-
return rule
|
|
143
|
-
})
|
|
78
|
+
if (isArbitraryValue(modifier)) {
|
|
79
|
+
let resolved = resolveArbitraryValue(modifier, validate)
|
|
144
80
|
|
|
145
|
-
if (
|
|
146
|
-
|
|
147
|
-
let nodes = container.nodes
|
|
148
|
-
container.removeAll()
|
|
149
|
-
wrapper.append(nodes)
|
|
150
|
-
container.append(wrapper)
|
|
81
|
+
if (resolved === undefined) {
|
|
82
|
+
return undefined
|
|
151
83
|
}
|
|
84
|
+
|
|
85
|
+
return negateValue(resolved)
|
|
152
86
|
}
|
|
153
87
|
}
|
|
154
88
|
|
|
155
|
-
export function asValue(modifier,
|
|
156
|
-
let value =
|
|
89
|
+
export function asValue(modifier, options = {}, { validate = () => true } = {}) {
|
|
90
|
+
let value = options.values?.[modifier]
|
|
157
91
|
|
|
158
92
|
if (value !== undefined) {
|
|
159
93
|
return value
|
|
160
94
|
}
|
|
161
95
|
|
|
162
|
-
if (
|
|
163
|
-
return
|
|
96
|
+
if (options.supportsNegativeValues && modifier.startsWith('-')) {
|
|
97
|
+
return asNegativeValue(modifier.slice(1), options.values, validate)
|
|
164
98
|
}
|
|
165
99
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
if (!validate(value)) {
|
|
169
|
-
return undefined
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// convert `_` to ` `, escept for escaped underscores `\_`
|
|
173
|
-
value = value
|
|
174
|
-
.replace(/([^\\])_/g, '$1 ')
|
|
175
|
-
.replace(/^_/g, ' ')
|
|
176
|
-
.replace(/\\_/g, '_')
|
|
177
|
-
|
|
178
|
-
// add spaces around operators inside calc() that do not follow an operator or (
|
|
179
|
-
return value.replace(
|
|
180
|
-
/(-?\d*\.?\d(?!\b-.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g,
|
|
181
|
-
'$1 $2 '
|
|
182
|
-
)
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
export function asUnit(modifier, units, lookup = {}) {
|
|
186
|
-
return asValue(modifier, lookup, {
|
|
187
|
-
validate: (value) => {
|
|
188
|
-
let unitsPattern = `(?:${units.join('|')})`
|
|
189
|
-
return (
|
|
190
|
-
new RegExp(`${unitsPattern}$`).test(value) ||
|
|
191
|
-
new RegExp(`^calc\\(.+?${unitsPattern}`).test(value)
|
|
192
|
-
)
|
|
193
|
-
},
|
|
194
|
-
})
|
|
100
|
+
return resolveArbitraryValue(modifier, validate)
|
|
195
101
|
}
|
|
196
102
|
|
|
197
103
|
function isArbitraryValue(input) {
|
|
198
104
|
return input.startsWith('[') && input.endsWith(']')
|
|
199
105
|
}
|
|
200
106
|
|
|
201
|
-
function
|
|
107
|
+
function splitUtilityModifier(modifier) {
|
|
202
108
|
let slashIdx = modifier.lastIndexOf('/')
|
|
203
109
|
|
|
204
110
|
if (slashIdx === -1 || slashIdx === modifier.length - 1) {
|
|
205
|
-
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]
|
|
206
121
|
}
|
|
207
122
|
|
|
208
123
|
return [modifier.slice(0, slashIdx), modifier.slice(slashIdx + 1)]
|
|
209
124
|
}
|
|
210
125
|
|
|
211
|
-
export function
|
|
212
|
-
if (
|
|
213
|
-
|
|
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
|
+
|
|
144
|
+
export function asColor(modifier, options = {}, { tailwindConfig = {} } = {}) {
|
|
145
|
+
if (options.values?.[modifier] !== undefined) {
|
|
146
|
+
return parseColorFormat(options.values?.[modifier])
|
|
214
147
|
}
|
|
215
148
|
|
|
216
|
-
|
|
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)
|
|
152
|
+
|
|
153
|
+
if (alpha !== undefined) {
|
|
154
|
+
let normalizedColor =
|
|
155
|
+
options.values?.[color] ?? (isArbitraryValue(color) ? color.slice(1, -1) : undefined)
|
|
156
|
+
|
|
157
|
+
if (normalizedColor === undefined) {
|
|
158
|
+
return undefined
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
normalizedColor = parseColorFormat(normalizedColor)
|
|
217
162
|
|
|
218
|
-
if (lookup[color] !== undefined) {
|
|
219
163
|
if (isArbitraryValue(alpha)) {
|
|
220
|
-
return withAlphaValue(
|
|
164
|
+
return withAlphaValue(normalizedColor, unwrapArbitraryModifier(alpha))
|
|
221
165
|
}
|
|
222
166
|
|
|
223
167
|
if (tailwindConfig.theme?.opacity?.[alpha] === undefined) {
|
|
224
168
|
return undefined
|
|
225
169
|
}
|
|
226
170
|
|
|
227
|
-
return withAlphaValue(
|
|
171
|
+
return withAlphaValue(normalizedColor, tailwindConfig.theme.opacity[alpha])
|
|
228
172
|
}
|
|
229
173
|
|
|
230
|
-
return asValue(modifier,
|
|
231
|
-
validate: (value) => parseColor(value) !== null,
|
|
232
|
-
})
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
export function asAngle(modifier, lookup = {}) {
|
|
236
|
-
return asUnit(modifier, ['deg', 'grad', 'rad', 'turn'], lookup)
|
|
174
|
+
return asValue(modifier, options, { validate: validateColor })
|
|
237
175
|
}
|
|
238
176
|
|
|
239
|
-
export function
|
|
240
|
-
return
|
|
241
|
-
modifier,
|
|
242
|
-
[
|
|
243
|
-
'cm',
|
|
244
|
-
'mm',
|
|
245
|
-
'Q',
|
|
246
|
-
'in',
|
|
247
|
-
'pc',
|
|
248
|
-
'pt',
|
|
249
|
-
'px',
|
|
250
|
-
'em',
|
|
251
|
-
'ex',
|
|
252
|
-
'ch',
|
|
253
|
-
'rem',
|
|
254
|
-
'lh',
|
|
255
|
-
'vw',
|
|
256
|
-
'vh',
|
|
257
|
-
'vmin',
|
|
258
|
-
'vmax',
|
|
259
|
-
'%',
|
|
260
|
-
],
|
|
261
|
-
lookup
|
|
262
|
-
)
|
|
177
|
+
export function asLookupValue(modifier, options = {}) {
|
|
178
|
+
return options.values?.[modifier]
|
|
263
179
|
}
|
|
264
180
|
|
|
265
|
-
|
|
266
|
-
return
|
|
181
|
+
function guess(validate) {
|
|
182
|
+
return (modifier, options) => {
|
|
183
|
+
return asValue(modifier, options, { validate })
|
|
184
|
+
}
|
|
267
185
|
}
|
|
268
186
|
|
|
269
|
-
let typeMap = {
|
|
187
|
+
export let typeMap = {
|
|
270
188
|
any: asValue,
|
|
271
189
|
color: asColor,
|
|
272
|
-
|
|
273
|
-
|
|
190
|
+
url: guess(url),
|
|
191
|
+
image: guess(image),
|
|
192
|
+
length: guess(length),
|
|
193
|
+
percentage: guess(percentage),
|
|
194
|
+
position: guess(position),
|
|
274
195
|
lookup: asLookupValue,
|
|
196
|
+
'generic-name': guess(genericName),
|
|
197
|
+
'family-name': guess(familyName),
|
|
198
|
+
number: guess(number),
|
|
199
|
+
'line-width': guess(lineWidth),
|
|
200
|
+
'absolute-size': guess(absoluteSize),
|
|
201
|
+
'relative-size': guess(relativeSize),
|
|
202
|
+
shadow: guess(shadow),
|
|
203
|
+
size: guess(backgroundSize),
|
|
275
204
|
}
|
|
276
205
|
|
|
206
|
+
let supportedTypes = Object.keys(typeMap)
|
|
207
|
+
|
|
277
208
|
function splitAtFirst(input, delim) {
|
|
278
|
-
|
|
209
|
+
let idx = input.indexOf(delim)
|
|
210
|
+
if (idx === -1) return [undefined, input]
|
|
211
|
+
return [input.slice(0, idx), input.slice(idx + 1)]
|
|
279
212
|
}
|
|
280
213
|
|
|
281
|
-
export function coerceValue(
|
|
282
|
-
|
|
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
|
+
}
|
|
283
228
|
|
|
284
229
|
if (isArbitraryValue(modifier)) {
|
|
285
|
-
let
|
|
230
|
+
let arbitraryValue = modifier.slice(1, -1)
|
|
231
|
+
let [explicitType, value] = splitAtFirst(arbitraryValue, ':')
|
|
232
|
+
|
|
233
|
+
// It could be that this resolves to `url(https` which is not a valid
|
|
234
|
+
// identifier. We currently only support "simple" words with dashes or
|
|
235
|
+
// underscores. E.g.: family-name
|
|
236
|
+
if (!/^[\w-_]+$/g.test(explicitType)) {
|
|
237
|
+
value = arbitraryValue
|
|
238
|
+
}
|
|
286
239
|
|
|
287
|
-
|
|
288
|
-
|
|
240
|
+
//
|
|
241
|
+
else if (explicitType !== undefined && !supportedTypes.includes(explicitType)) {
|
|
242
|
+
return []
|
|
289
243
|
}
|
|
290
244
|
|
|
291
|
-
|
|
245
|
+
if (value.length > 0 && supportedTypes.includes(explicitType)) {
|
|
246
|
+
return [asValue(`[${value}]`, options), explicitType, null]
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
let matches = getMatchingTypes(types, modifier, options, tailwindConfig)
|
|
251
|
+
|
|
252
|
+
// Find first matching type
|
|
253
|
+
for (let match of matches) {
|
|
254
|
+
return match
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return []
|
|
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
|
|
292
284
|
}
|
|
293
285
|
|
|
294
|
-
|
|
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
|
+
}
|
|
295
314
|
}
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import parser from 'postcss-selector-parser'
|
|
2
|
-
import { tap } from './tap'
|
|
3
|
-
|
|
4
|
-
export default function (prefix, selector) {
|
|
5
|
-
const getPrefix =
|
|
6
|
-
typeof prefix === 'function' ? prefix : () => (prefix === undefined ? '' : prefix)
|
|
7
2
|
|
|
3
|
+
export default function (prefix, selector, prependNegative = false) {
|
|
8
4
|
return parser((selectors) => {
|
|
9
5
|
selectors.walkClasses((classSelector) => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
let baseClass = classSelector.value
|
|
7
|
+
let shouldPlaceNegativeBeforePrefix = prependNegative && baseClass.startsWith('-')
|
|
8
|
+
|
|
9
|
+
classSelector.value = shouldPlaceNegativeBeforePrefix
|
|
10
|
+
? `-${prefix}${baseClass.slice(1)}`
|
|
11
|
+
: `${prefix}${baseClass}`
|
|
13
12
|
})
|
|
14
13
|
}).processSync(selector)
|
|
15
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
|
+
}
|