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.
Files changed (195) hide show
  1. package/CHANGELOG.md +603 -2
  2. package/LICENSE +1 -2
  3. package/README.md +14 -6
  4. package/colors.d.ts +3 -0
  5. package/colors.js +2 -304
  6. package/defaultConfig.d.ts +3 -0
  7. package/defaultConfig.js +2 -4
  8. package/defaultTheme.d.ts +4 -0
  9. package/defaultTheme.js +2 -4
  10. package/lib/cli/build/deps.js +54 -0
  11. package/lib/cli/build/index.js +48 -0
  12. package/lib/cli/build/plugin.js +367 -0
  13. package/lib/cli/build/utils.js +78 -0
  14. package/lib/cli/build/watching.js +178 -0
  15. package/lib/cli/help/index.js +71 -0
  16. package/lib/cli/index.js +18 -0
  17. package/lib/cli/init/index.js +46 -0
  18. package/lib/cli/shared.js +13 -0
  19. package/lib/cli-peer-dependencies.js +22 -14
  20. package/lib/cli.js +217 -743
  21. package/lib/constants.js +41 -34
  22. package/lib/corePluginList.js +178 -5
  23. package/lib/corePlugins.js +3879 -2941
  24. package/lib/css/preflight.css +22 -9
  25. package/lib/featureFlags.js +61 -50
  26. package/lib/index.js +45 -28
  27. package/lib/lib/cacheInvalidation.js +90 -0
  28. package/lib/lib/collapseAdjacentRules.js +52 -36
  29. package/lib/lib/collapseDuplicateDeclarations.js +83 -0
  30. package/lib/lib/content.js +176 -0
  31. package/lib/lib/defaultExtractor.js +236 -0
  32. package/lib/lib/detectNesting.js +37 -0
  33. package/lib/lib/evaluateTailwindFunctions.js +203 -161
  34. package/lib/lib/expandApplyAtRules.js +502 -221
  35. package/lib/lib/expandTailwindAtRules.js +258 -243
  36. package/lib/lib/findAtConfigPath.js +44 -0
  37. package/lib/lib/generateRules.js +775 -320
  38. package/lib/lib/getModuleDependencies.js +44 -46
  39. package/lib/lib/normalizeTailwindDirectives.js +79 -60
  40. package/lib/lib/offsets.js +217 -0
  41. package/lib/lib/partitionApplyAtRules.js +56 -0
  42. package/lib/lib/regex.js +60 -0
  43. package/lib/lib/resolveDefaultsAtRules.js +150 -94
  44. package/lib/lib/setupContextUtils.js +1146 -599
  45. package/lib/lib/setupTrackingContext.js +129 -177
  46. package/lib/lib/sharedState.js +53 -21
  47. package/lib/lib/substituteScreenAtRules.js +26 -28
  48. package/{nesting → lib/postcss-plugins/nesting}/README.md +2 -2
  49. package/lib/postcss-plugins/nesting/index.js +19 -0
  50. package/lib/postcss-plugins/nesting/plugin.js +87 -0
  51. package/lib/processTailwindFeatures.js +58 -53
  52. package/lib/public/colors.js +331 -0
  53. package/lib/public/create-plugin.js +15 -0
  54. package/lib/public/default-config.js +16 -0
  55. package/lib/public/default-theme.js +16 -0
  56. package/lib/public/resolve-config.js +22 -0
  57. package/lib/util/bigSign.js +7 -6
  58. package/lib/util/buildMediaQuery.js +21 -32
  59. package/lib/util/cloneDeep.js +16 -14
  60. package/lib/util/cloneNodes.js +29 -15
  61. package/lib/util/color.js +90 -66
  62. package/lib/util/configurePlugins.js +17 -15
  63. package/lib/util/createPlugin.js +23 -26
  64. package/lib/util/createUtilityPlugin.js +46 -46
  65. package/lib/util/dataTypes.js +242 -0
  66. package/lib/util/defaults.js +20 -15
  67. package/lib/util/escapeClassName.js +18 -17
  68. package/lib/util/escapeCommas.js +7 -6
  69. package/lib/util/flattenColorPalette.js +13 -12
  70. package/lib/util/formatVariantSelector.js +285 -0
  71. package/lib/util/getAllConfigs.js +44 -18
  72. package/lib/util/hashConfig.js +15 -12
  73. package/lib/util/isKeyframeRule.js +7 -6
  74. package/lib/util/isPlainObject.js +11 -11
  75. package/lib/util/isSyntacticallyValidPropertyValue.js +72 -0
  76. package/lib/util/log.js +52 -33
  77. package/lib/util/nameClass.js +37 -26
  78. package/lib/util/negateValue.js +31 -17
  79. package/lib/util/normalizeConfig.js +281 -0
  80. package/lib/util/normalizeScreens.js +170 -0
  81. package/lib/util/parseAnimationValue.js +85 -54
  82. package/lib/util/parseBoxShadowValue.js +84 -0
  83. package/lib/util/parseDependency.js +41 -70
  84. package/lib/util/parseGlob.js +34 -0
  85. package/lib/util/parseObjectStyles.js +30 -24
  86. package/lib/util/pluginUtils.js +252 -287
  87. package/lib/util/prefixSelector.js +20 -20
  88. package/lib/util/removeAlphaVariables.js +29 -0
  89. package/lib/util/resolveConfig.js +221 -256
  90. package/lib/util/resolveConfigPath.js +43 -48
  91. package/lib/util/responsive.js +18 -14
  92. package/lib/util/splitAtTopLevelOnly.js +43 -0
  93. package/lib/util/tap.js +8 -7
  94. package/lib/util/toColorValue.js +7 -6
  95. package/lib/util/toPath.js +27 -8
  96. package/lib/util/transformThemeValue.js +67 -28
  97. package/lib/util/validateConfig.js +24 -0
  98. package/lib/util/validateFormalSyntax.js +24 -0
  99. package/lib/util/withAlphaVariable.js +67 -57
  100. package/nesting/index.js +2 -12
  101. package/package.json +60 -65
  102. package/peers/index.js +76445 -84221
  103. package/plugin.d.ts +11 -0
  104. package/plugin.js +1 -2
  105. package/resolveConfig.d.ts +12 -0
  106. package/resolveConfig.js +2 -7
  107. package/scripts/create-plugin-list.js +2 -2
  108. package/scripts/generate-types.js +105 -0
  109. package/scripts/release-channel.js +18 -0
  110. package/scripts/release-notes.js +21 -0
  111. package/scripts/type-utils.js +27 -0
  112. package/src/cli/build/deps.js +56 -0
  113. package/src/cli/build/index.js +49 -0
  114. package/src/cli/build/plugin.js +439 -0
  115. package/src/cli/build/utils.js +76 -0
  116. package/src/cli/build/watching.js +227 -0
  117. package/src/cli/help/index.js +70 -0
  118. package/src/cli/index.js +3 -0
  119. package/src/cli/init/index.js +50 -0
  120. package/src/cli/shared.js +6 -0
  121. package/src/cli-peer-dependencies.js +7 -1
  122. package/src/cli.js +50 -575
  123. package/src/corePluginList.js +1 -1
  124. package/src/corePlugins.js +2405 -1948
  125. package/src/css/preflight.css +22 -9
  126. package/src/featureFlags.js +26 -10
  127. package/src/index.js +19 -6
  128. package/src/lib/cacheInvalidation.js +52 -0
  129. package/src/lib/collapseAdjacentRules.js +21 -2
  130. package/src/lib/collapseDuplicateDeclarations.js +93 -0
  131. package/src/lib/content.js +212 -0
  132. package/src/lib/defaultExtractor.js +211 -0
  133. package/src/lib/detectNesting.js +39 -0
  134. package/src/lib/evaluateTailwindFunctions.js +84 -10
  135. package/src/lib/expandApplyAtRules.js +508 -153
  136. package/src/lib/expandTailwindAtRules.js +130 -104
  137. package/src/lib/findAtConfigPath.js +48 -0
  138. package/src/lib/generateRules.js +596 -70
  139. package/src/lib/normalizeTailwindDirectives.js +10 -3
  140. package/src/lib/offsets.js +270 -0
  141. package/src/lib/partitionApplyAtRules.js +52 -0
  142. package/src/lib/regex.js +74 -0
  143. package/src/lib/resolveDefaultsAtRules.js +105 -47
  144. package/src/lib/setupContextUtils.js +828 -196
  145. package/src/lib/setupTrackingContext.js +19 -54
  146. package/src/lib/sharedState.js +45 -7
  147. package/src/lib/substituteScreenAtRules.js +6 -3
  148. package/src/postcss-plugins/nesting/README.md +42 -0
  149. package/src/postcss-plugins/nesting/index.js +13 -0
  150. package/src/postcss-plugins/nesting/plugin.js +80 -0
  151. package/src/processTailwindFeatures.js +19 -2
  152. package/src/public/colors.js +300 -0
  153. package/src/public/create-plugin.js +2 -0
  154. package/src/public/default-config.js +4 -0
  155. package/src/public/default-theme.js +4 -0
  156. package/src/public/resolve-config.js +7 -0
  157. package/src/util/buildMediaQuery.js +14 -16
  158. package/src/util/cloneNodes.js +19 -2
  159. package/src/util/color.js +31 -14
  160. package/src/util/createUtilityPlugin.js +2 -11
  161. package/src/util/dataTypes.js +256 -0
  162. package/src/util/defaults.js +6 -0
  163. package/src/util/formatVariantSelector.js +319 -0
  164. package/src/util/getAllConfigs.js +19 -0
  165. package/src/util/isSyntacticallyValidPropertyValue.js +61 -0
  166. package/src/util/log.js +23 -22
  167. package/src/util/nameClass.js +14 -6
  168. package/src/util/negateValue.js +15 -5
  169. package/src/util/normalizeConfig.js +300 -0
  170. package/src/util/normalizeScreens.js +140 -0
  171. package/src/util/parseAnimationValue.js +7 -1
  172. package/src/util/parseBoxShadowValue.js +72 -0
  173. package/src/util/parseDependency.js +37 -38
  174. package/src/util/parseGlob.js +24 -0
  175. package/src/util/pluginUtils.js +216 -197
  176. package/src/util/prefixSelector.js +7 -8
  177. package/src/util/removeAlphaVariables.js +24 -0
  178. package/src/util/resolveConfig.js +86 -91
  179. package/src/util/splitAtTopLevelOnly.js +45 -0
  180. package/src/util/toPath.js +23 -1
  181. package/src/util/transformThemeValue.js +33 -8
  182. package/src/util/validateConfig.js +13 -0
  183. package/src/util/validateFormalSyntax.js +34 -0
  184. package/src/util/withAlphaVariable.js +14 -9
  185. package/stubs/defaultConfig.stub.js +186 -117
  186. package/stubs/simpleConfig.stub.js +1 -1
  187. package/types/config.d.ts +362 -0
  188. package/types/generated/.gitkeep +0 -0
  189. package/types/generated/colors.d.ts +276 -0
  190. package/types/generated/corePluginList.d.ts +1 -0
  191. package/types/generated/default-theme.d.ts +342 -0
  192. package/types/index.d.ts +7 -0
  193. package/lib/lib/setupWatchingContext.js +0 -331
  194. package/nesting/plugin.js +0 -41
  195. package/src/lib/setupWatchingContext.js +0 -306
@@ -0,0 +1,211 @@
1
+ import { flagEnabled } from '../featureFlags'
2
+ import * as regex from './regex'
3
+
4
+ export function defaultExtractor(context) {
5
+ let patterns = Array.from(buildRegExps(context))
6
+
7
+ /**
8
+ * @param {string} content
9
+ */
10
+ return (content) => {
11
+ /** @type {(string|string)[]} */
12
+ let results = []
13
+
14
+ for (let pattern of patterns) {
15
+ results = [...results, ...(content.match(pattern) ?? [])]
16
+ }
17
+
18
+ return results.filter((v) => v !== undefined).map(clipAtBalancedParens)
19
+ }
20
+ }
21
+
22
+ function* buildRegExps(context) {
23
+ let separator = context.tailwindConfig.separator
24
+ let variantGroupingEnabled = flagEnabled(context.tailwindConfig, 'variantGrouping')
25
+ let prefix =
26
+ context.tailwindConfig.prefix !== ''
27
+ ? regex.optional(regex.pattern([/-?/, regex.escape(context.tailwindConfig.prefix)]))
28
+ : ''
29
+
30
+ let utility = regex.any([
31
+ // Arbitrary properties
32
+ /\[[^\s:'"`]+:[^\s]+\]/,
33
+
34
+ // Utilities
35
+ regex.pattern([
36
+ // Utility Name / Group Name
37
+ /-?(?:\w+)/,
38
+
39
+ // Normal/Arbitrary values
40
+ regex.optional(
41
+ regex.any([
42
+ regex.pattern([
43
+ // Arbitrary values
44
+ /-(?:\w+-)*\[[^\s:]+\]/,
45
+
46
+ // Not immediately followed by an `{[(`
47
+ /(?![{([]])/,
48
+
49
+ // optionally followed by an opacity modifier
50
+ /(?:\/[^\s'"`\\><$]*)?/,
51
+ ]),
52
+
53
+ regex.pattern([
54
+ // Arbitrary values
55
+ /-(?:\w+-)*\[[^\s]+\]/,
56
+
57
+ // Not immediately followed by an `{[(`
58
+ /(?![{([]])/,
59
+
60
+ // optionally followed by an opacity modifier
61
+ /(?:\/[^\s'"`\\$]*)?/,
62
+ ]),
63
+
64
+ // Normal values w/o quotes — may include an opacity modifier
65
+ /[-\/][^\s'"`\\$={><]*/,
66
+ ])
67
+ ),
68
+ ]),
69
+ ])
70
+
71
+ let variantPatterns = [
72
+ // Without quotes
73
+ regex.any([
74
+ // This is here to provide special support for the `@` variant
75
+ regex.pattern([/@\[[^\s"'`]+\](\/[^\s"'`]+)?/, separator]),
76
+
77
+ regex.pattern([/([^\s"'`\[\\]+-)?\[[^\s"'`]+\]/, separator]),
78
+ regex.pattern([/[^\s"'`\[\\]+/, separator]),
79
+ ]),
80
+
81
+ // With quotes allowed
82
+ regex.any([
83
+ regex.pattern([/([^\s"'`\[\\]+-)?\[[^\s`]+\]/, separator]),
84
+ regex.pattern([/[^\s`\[\\]+/, separator]),
85
+ ]),
86
+ ]
87
+
88
+ for (const variantPattern of variantPatterns) {
89
+ yield regex.pattern([
90
+ // Variants
91
+ '((?=((',
92
+ variantPattern,
93
+ ')+))\\2)?',
94
+
95
+ // Important (optional)
96
+ /!?/,
97
+
98
+ prefix,
99
+
100
+ variantGroupingEnabled
101
+ ? regex.any([
102
+ // Or any of those things but grouped separated by commas
103
+ regex.pattern([/\(/, utility, regex.zeroOrMore([/,/, utility]), /\)/]),
104
+
105
+ // Arbitrary properties, constrained utilities, arbitrary values, etc…
106
+ utility,
107
+ ])
108
+ : utility,
109
+ ])
110
+ }
111
+
112
+ // 5. Inner matches
113
+ yield /[^<>"'`\s.(){}[\]#=%$]*[^<>"'`\s.(){}[\]#=%:$]/g
114
+ }
115
+
116
+ // We want to capture any "special" characters
117
+ // AND the characters immediately following them (if there is one)
118
+ let SPECIALS = /([\[\]'"`])([^\[\]'"`])?/g
119
+ let ALLOWED_CLASS_CHARACTERS = /[^"'`\s<>\]]+/
120
+
121
+ /**
122
+ * Clips a string ensuring that parentheses, quotes, etc… are balanced
123
+ * Used for arbitrary values only
124
+ *
125
+ * We will go past the end of the balanced parens until we find a non-class character
126
+ *
127
+ * Depth matching behavior:
128
+ * w-[calc(100%-theme('spacing[some_key][1.5]'))]']
129
+ * ┬ ┬ ┬┬ ┬ ┬┬ ┬┬┬┬┬┬┬
130
+ * 1 2 3 4 34 3 210 END
131
+ * ╰────┴──────────┴────────┴────────┴┴───┴─┴┴┴
132
+ *
133
+ * @param {string} input
134
+ */
135
+ function clipAtBalancedParens(input) {
136
+ // We are care about this for arbitrary values
137
+ if (!input.includes('-[')) {
138
+ return input
139
+ }
140
+
141
+ let depth = 0
142
+ let openStringTypes = []
143
+
144
+ // Find all parens, brackets, quotes, etc
145
+ // Stop when we end at a balanced pair
146
+ // This is naive and will treat mismatched parens as balanced
147
+ // This shouldn't be a problem in practice though
148
+ let matches = input.matchAll(SPECIALS)
149
+
150
+ // We can't use lookbehind assertions because we have to support Safari
151
+ // So, instead, we've emulated it using capture groups and we'll re-work the matches to accommodate
152
+ matches = Array.from(matches).flatMap((match) => {
153
+ const [, ...groups] = match
154
+
155
+ return groups.map((group, idx) =>
156
+ Object.assign([], match, {
157
+ index: match.index + idx,
158
+ 0: group,
159
+ })
160
+ )
161
+ })
162
+
163
+ for (let match of matches) {
164
+ let char = match[0]
165
+ let inStringType = openStringTypes[openStringTypes.length - 1]
166
+
167
+ if (char === inStringType) {
168
+ openStringTypes.pop()
169
+ } else if (char === "'" || char === '"' || char === '`') {
170
+ openStringTypes.push(char)
171
+ }
172
+
173
+ if (inStringType) {
174
+ continue
175
+ } else if (char === '[') {
176
+ depth++
177
+ continue
178
+ } else if (char === ']') {
179
+ depth--
180
+ continue
181
+ }
182
+
183
+ // We've gone one character past the point where we should stop
184
+ // This means that there was an extra closing `]`
185
+ // We'll clip to just before it
186
+ if (depth < 0) {
187
+ return input.substring(0, match.index)
188
+ }
189
+
190
+ // We've finished balancing the brackets but there still may be characters that can be included
191
+ // For example in the class `text-[#336699]/[.35]`
192
+ // The depth goes to `0` at the closing `]` but goes up again at the `[`
193
+
194
+ // If we're at zero and encounter a non-class character then we clip the class there
195
+ if (depth === 0 && !ALLOWED_CLASS_CHARACTERS.test(char)) {
196
+ return input.substring(0, match.index)
197
+ }
198
+ }
199
+
200
+ return input
201
+ }
202
+
203
+ // Regular utilities
204
+ // {{modifier}:}*{namespace}{-{suffix}}*{/{opacityModifier}}?
205
+
206
+ // Arbitrary values
207
+ // {{modifier}:}*{namespace}-[{arbitraryValue}]{/{opacityModifier}}?
208
+ // arbitraryValue: no whitespace, balanced quotes unless within quotes, balanced brackets unless within quotes
209
+
210
+ // Arbitrary properties
211
+ // {{modifier}:}*[{validCssPropertyName}:{arbitraryValue}]
@@ -0,0 +1,39 @@
1
+ export default function (_context) {
2
+ return (root, result) => {
3
+ let found = false
4
+
5
+ root.walkAtRules('tailwind', (node) => {
6
+ if (found) return false
7
+
8
+ if (node.parent && node.parent.type !== 'root') {
9
+ found = true
10
+ node.warn(
11
+ result,
12
+ [
13
+ 'Nested @tailwind rules were detected, but are not supported.',
14
+ "Consider using a prefix to scope Tailwind's classes: https://tailwindcss.com/docs/configuration#prefix",
15
+ 'Alternatively, use the important selector strategy: https://tailwindcss.com/docs/configuration#selector-strategy',
16
+ ].join('\n')
17
+ )
18
+ return false
19
+ }
20
+ })
21
+
22
+ root.walkRules((rule) => {
23
+ if (found) return false
24
+
25
+ rule.walkRules((nestedRule) => {
26
+ found = true
27
+ nestedRule.warn(
28
+ result,
29
+ [
30
+ 'Nested CSS was detected, but CSS nesting has not been configured correctly.',
31
+ 'Please enable a CSS nesting plugin *before* Tailwind in your configuration.',
32
+ 'See how here: https://tailwindcss.com/docs/using-with-preprocessors#nesting',
33
+ ].join('\n')
34
+ )
35
+ return false
36
+ })
37
+ })
38
+ }
39
+ }
@@ -2,8 +2,12 @@ import dlv from 'dlv'
2
2
  import didYouMean from 'didyoumean'
3
3
  import transformThemeValue from '../util/transformThemeValue'
4
4
  import parseValue from 'postcss-value-parser'
5
+ import { normalizeScreens } from '../util/normalizeScreens'
5
6
  import buildMediaQuery from '../util/buildMediaQuery'
6
7
  import { toPath } from '../util/toPath'
8
+ import { withAlphaValue } from '../util/withAlphaVariable'
9
+ import { parseColorFormat } from '../util/pluginUtils'
10
+ import log from '../util/log'
7
11
 
8
12
  function isObject(input) {
9
13
  return typeof input === 'object' && input !== null
@@ -36,12 +40,10 @@ function listKeys(obj) {
36
40
  return list(Object.keys(obj))
37
41
  }
38
42
 
39
- function validatePath(config, path, defaultValue) {
40
- const pathString = Array.isArray(path)
41
- ? pathToString(path)
42
- : path.replace(/^['"]+/g, '').replace(/['"]+$/g, '')
43
+ function validatePath(config, path, defaultValue, themeOpts = {}) {
44
+ const pathString = Array.isArray(path) ? pathToString(path) : path.replace(/^['"]+|['"]+$/g, '')
43
45
  const pathSegments = Array.isArray(path) ? path : toPath(pathString)
44
- const value = dlv(config.theme, pathString, defaultValue)
46
+ const value = dlv(config.theme, pathSegments, defaultValue)
45
47
 
46
48
  if (value === undefined) {
47
49
  let error = `'${pathString}' does not exist in your theme config.`
@@ -113,7 +115,7 @@ function validatePath(config, path, defaultValue) {
113
115
 
114
116
  return {
115
117
  isValid: true,
116
- value: transformThemeValue(themeSection)(value),
118
+ value: transformThemeValue(themeSection)(value, themeOpts),
117
119
  }
118
120
  }
119
121
 
@@ -156,29 +158,101 @@ let nodeTypePropertyMap = {
156
158
  decl: 'value',
157
159
  }
158
160
 
159
- export default function ({ tailwindConfig: config }) {
161
+ /**
162
+ * @param {string} path
163
+ * @returns {Iterable<[path: string, alpha: string|undefined]>}
164
+ */
165
+ function* toPaths(path) {
166
+ // Strip quotes from beginning and end of string
167
+ // This allows the alpha value to be present inside of quotes
168
+ path = path.replace(/^['"]+|['"]+$/g, '')
169
+
170
+ let matches = path.match(/^([^\s]+)(?![^\[]*\])(?:\s*\/\s*([^\/\s]+))$/)
171
+ let alpha = undefined
172
+
173
+ yield [path, undefined]
174
+
175
+ if (matches) {
176
+ path = matches[1]
177
+ alpha = matches[2]
178
+
179
+ yield [path, alpha]
180
+ }
181
+ }
182
+
183
+ /**
184
+ *
185
+ * @param {any} config
186
+ * @param {string} path
187
+ * @param {any} defaultValue
188
+ */
189
+ function resolvePath(config, path, defaultValue) {
190
+ const results = Array.from(toPaths(path)).map(([path, alpha]) => {
191
+ return Object.assign(validatePath(config, path, defaultValue, { opacityValue: alpha }), {
192
+ resolvedPath: path,
193
+ alpha,
194
+ })
195
+ })
196
+
197
+ return results.find((result) => result.isValid) ?? results[0]
198
+ }
199
+
200
+ export default function (context) {
201
+ let config = context.tailwindConfig
202
+
160
203
  let functions = {
161
204
  theme: (node, path, ...defaultValue) => {
162
- const { isValid, value, error } = validatePath(
205
+ let { isValid, value, error, alpha } = resolvePath(
163
206
  config,
164
207
  path,
165
208
  defaultValue.length ? defaultValue : undefined
166
209
  )
167
210
 
168
211
  if (!isValid) {
212
+ let parentNode = node.parent
213
+ let candidate = parentNode?.raws.tailwind?.candidate
214
+
215
+ if (parentNode && candidate !== undefined) {
216
+ // Remove this utility from any caches
217
+ context.markInvalidUtilityNode(parentNode)
218
+
219
+ // Remove the CSS node from the markup
220
+ parentNode.remove()
221
+
222
+ // Show a warning
223
+ log.warn('invalid-theme-key-in-class', [
224
+ `The utility \`${candidate}\` contains an invalid theme value and was not generated.`,
225
+ ])
226
+
227
+ return
228
+ }
229
+
169
230
  throw node.error(error)
170
231
  }
171
232
 
233
+ let maybeColor = parseColorFormat(value)
234
+ let isColorFunction = maybeColor !== undefined && typeof maybeColor === 'function'
235
+
236
+ if (alpha !== undefined || isColorFunction) {
237
+ if (alpha === undefined) {
238
+ alpha = 1.0
239
+ }
240
+
241
+ value = withAlphaValue(maybeColor, alpha, maybeColor)
242
+ }
243
+
172
244
  return value
173
245
  },
174
246
  screen: (node, screen) => {
175
247
  screen = screen.replace(/^['"]+/g, '').replace(/['"]+$/g, '')
248
+ let screens = normalizeScreens(config.theme.screens)
249
+ let screenDefinition = screens.find(({ name }) => name === screen)
176
250
 
177
- if (config.theme.screens[screen] === undefined) {
251
+ if (!screenDefinition) {
178
252
  throw node.error(`The '${screen}' screen does not exist in your theme.`)
179
253
  }
180
254
 
181
- return buildMediaQuery(config.theme.screens[screen])
255
+ return buildMediaQuery(screenDefinition)
182
256
  },
183
257
  }
184
258
  return (root) => {