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
@@ -1,20 +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
- import colors from '../../colors'
6
- import log from './log'
4
+ import colors from '../public/colors'
7
5
  import { defaults } from './defaults'
8
6
  import { toPath } from './toPath'
7
+ import { normalizeConfig } from './normalizeConfig'
8
+ import isPlainObject from './isPlainObject'
9
+ import { cloneDeep } from './cloneDeep'
10
+ import { parseColorFormat } from './pluginUtils'
11
+ import { withAlphaValue } from './withAlphaVariable'
12
+ import toColorValue from './toColorValue'
9
13
 
10
14
  function isFunction(input) {
11
15
  return typeof input === 'function'
12
16
  }
13
17
 
14
- function isObject(input) {
15
- return typeof input === 'object' && input !== null
16
- }
17
-
18
18
  function mergeWith(target, ...sources) {
19
19
  let customizer = sources.pop()
20
20
 
@@ -23,8 +23,8 @@ function mergeWith(target, ...sources) {
23
23
  let merged = customizer(target[k], source[k])
24
24
 
25
25
  if (merged === undefined) {
26
- if (isObject(target[k]) && isObject(source[k])) {
27
- 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)
28
28
  } else {
29
29
  target[k] = source[k]
30
30
  }
@@ -40,15 +40,18 @@ function mergeWith(target, ...sources) {
40
40
  const configUtils = {
41
41
  colors,
42
42
  negative(scale) {
43
+ // TODO: Log that this function isn't really needed anymore?
43
44
  return Object.keys(scale)
44
45
  .filter((key) => scale[key] !== '0')
45
- .reduce(
46
- (negativeScale, key) => ({
47
- ...negativeScale,
48
- [`-${key}`]: negateValue(scale[key]),
49
- }),
50
- {}
51
- )
46
+ .reduce((negativeScale, key) => {
47
+ let negativeValue = negateValue(scale[key])
48
+
49
+ if (negativeValue !== undefined) {
50
+ negativeScale[`-${key}`] = negativeValue
51
+ }
52
+
53
+ return negativeScale
54
+ }, {})
52
55
  },
53
56
  breakpoints(screens) {
54
57
  return Object.keys(screens)
@@ -95,12 +98,12 @@ function mergeThemes(themes) {
95
98
 
96
99
  function mergeExtensionCustomizer(merged, value) {
97
100
  // When we have an array of objects, we do want to merge it
98
- if (Array.isArray(merged) && isObject(merged[0])) {
101
+ if (Array.isArray(merged) && isPlainObject(merged[0])) {
99
102
  return merged.concat(value)
100
103
  }
101
104
 
102
105
  // When the incoming value is an array, and the existing config is an object, prepend the existing object
103
- if (Array.isArray(value) && isObject(value[0]) && isObject(merged)) {
106
+ if (Array.isArray(value) && isPlainObject(value[0]) && isPlainObject(merged)) {
104
107
  return [merged, ...value]
105
108
  }
106
109
 
@@ -129,32 +132,81 @@ function mergeExtensions({ extend, ...theme }) {
129
132
  })
130
133
  }
131
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
+
132
166
  function resolveFunctionKeys(object) {
167
+ // theme('colors.red.500 / 0.5') -> ['colors', 'red', '500 / 0', '5]
168
+
133
169
  const resolvePath = (key, defaultValue) => {
134
- const path = toPath(key)
170
+ for (const path of toPaths(key)) {
171
+ let index = 0
172
+ let val = object
135
173
 
136
- let index = 0
137
- let val = object
174
+ while (val !== undefined && val !== null && index < path.length) {
175
+ val = val[path[index++]]
138
176
 
139
- while (val !== undefined && val !== null && index < path.length) {
140
- val = val[path[index++]]
141
- val = isFunction(val) ? val(resolvePath, configUtils) : val
142
- }
177
+ let shouldResolveAsFn =
178
+ isFunction(val) && (path.alpha === undefined || index <= path.length - 1)
143
179
 
144
- return val === undefined ? defaultValue : val
145
- }
180
+ val = shouldResolveAsFn ? val(resolvePath, configUtils) : val
181
+ }
182
+
183
+ if (val !== undefined) {
184
+ if (path.alpha !== undefined) {
185
+ let normalized = parseColorFormat(val)
186
+
187
+ return withAlphaValue(normalized, path.alpha, toColorValue(normalized))
188
+ }
189
+
190
+ if (isPlainObject(val)) {
191
+ return cloneDeep(val)
192
+ }
146
193
 
147
- resolvePath.theme = resolvePath
194
+ return val
195
+ }
196
+ }
148
197
 
149
- for (let key in configUtils) {
150
- resolvePath[key] = configUtils[key]
198
+ return defaultValue
151
199
  }
152
200
 
201
+ Object.assign(resolvePath, {
202
+ theme: resolvePath,
203
+ ...configUtils,
204
+ })
205
+
153
206
  return Object.keys(object).reduce((resolved, key) => {
154
- return {
155
- ...resolved,
156
- [key]: isFunction(object[key]) ? object[key](resolvePath, configUtils) : object[key],
157
- }
207
+ resolved[key] = isFunction(object[key]) ? object[key](resolvePath, configUtils) : object[key]
208
+
209
+ return resolved
158
210
  }, {})
159
211
  }
160
212
 
@@ -207,7 +259,6 @@ export default function resolveConfig(configs) {
207
259
  prefix: '',
208
260
  important: false,
209
261
  separator: ':',
210
- variantOrder: defaultConfig.variantOrder,
211
262
  },
212
263
  ]
213
264
 
@@ -224,59 +275,3 @@ export default function resolveConfig(configs) {
224
275
  )
225
276
  )
226
277
  }
227
-
228
- let warnedAbout = new Set()
229
- function normalizeConfig(config) {
230
- if (!warnedAbout.has('purge-deprecation') && config.hasOwnProperty('purge')) {
231
- log.warn([
232
- 'The `purge` option in your tailwind.config.js file has been deprecated.',
233
- 'Please rename this to `content` instead.',
234
- ])
235
- warnedAbout.add('purge-deprecation')
236
- }
237
-
238
- config.content = {
239
- content: (() => {
240
- let { content, purge } = config
241
-
242
- if (Array.isArray(purge)) return purge
243
- if (Array.isArray(purge?.content)) return purge.content
244
- if (Array.isArray(content)) return content
245
- if (Array.isArray(content?.content)) return content.content
246
-
247
- return []
248
- })(),
249
- safelist: (() => {
250
- let { content, purge } = config
251
-
252
- let [safelistKey, safelistPaths] = (() => {
253
- if (Array.isArray(content?.safelist)) return ['content.safelist', content.safelist]
254
- if (Array.isArray(purge?.safelist)) return ['purge.safelist', purge.safelist]
255
- if (Array.isArray(purge?.options?.safelist))
256
- return ['purge.options.safelist', purge.options.safelist]
257
- return [null, []]
258
- })()
259
-
260
- return safelistPaths.map((content) => {
261
- if (typeof content === 'string') {
262
- return { raw: content, extension: 'html' }
263
- }
264
-
265
- if (content instanceof RegExp) {
266
- throw new Error(
267
- `Values inside '${safelistKey}' can only be of type 'string', found 'regex'.`
268
- )
269
- }
270
-
271
- throw new Error(
272
- `Values inside '${safelistKey}' can only be of type 'string', found '${typeof content}'.`
273
- )
274
- })
275
- })(),
276
- extract: config.content?.extract || config.purge?.extract || {},
277
- options: config.content?.options || config.purge?.options || {},
278
- transform: config.content?.transform || config.purge?.transform || {},
279
- }
280
-
281
- return config
282
- }
@@ -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
+ }
@@ -1,4 +1,26 @@
1
+ /**
2
+ * Parse a path string into an array of path segments.
3
+ *
4
+ * Square bracket notation `a[b]` may be used to "escape" dots that would otherwise be interpreted as path separators.
5
+ *
6
+ * Example:
7
+ * a -> ['a']
8
+ * a.b.c -> ['a', 'b', 'c']
9
+ * a[b].c -> ['a', 'b', 'c']
10
+ * a[b.c].e.f -> ['a', 'b.c', 'e', 'f']
11
+ * a[b][c][d] -> ['a', 'b', 'c', 'd']
12
+ *
13
+ * @param {string|string[]} path
14
+ **/
1
15
  export function toPath(path) {
2
16
  if (Array.isArray(path)) return path
3
- return path.split(/[\.\]\[]+/g)
17
+
18
+ let openBrackets = path.split('[').length - 1
19
+ let closedBrackets = path.split(']').length - 1
20
+
21
+ if (openBrackets !== closedBrackets) {
22
+ throw new Error(`Path is invalid. Has unbalanced brackets: ${path}`)
23
+ }
24
+
25
+ return path.split(/\.(?![^\[]*\])|[\[\]]/g).filter(Boolean)
4
26
  }
@@ -1,13 +1,26 @@
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)) {
5
- return (value) => (Array.isArray(value) ? value[0] : value)
6
+ return (value) => {
7
+ if (typeof value === 'function') value = value({})
8
+ if (Array.isArray(value)) value = value[0]
9
+
10
+ return value
11
+ }
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
+ }
6
20
  }
7
21
 
8
22
  if (
9
23
  [
10
- 'fontFamily',
11
24
  'boxShadow',
12
25
  'transitionProperty',
13
26
  'transitionDuration',
@@ -20,18 +33,30 @@ export default function transformThemeValue(themeSection) {
20
33
  'animation',
21
34
  ].includes(themeSection)
22
35
  ) {
23
- return (value) => (Array.isArray(value) ? value.join(', ') : value)
36
+ return (value) => {
37
+ if (typeof value === 'function') value = value({})
38
+ if (Array.isArray(value)) value = value.join(', ')
39
+
40
+ return value
41
+ }
24
42
  }
25
43
 
26
44
  // For backwards compatibility reasons, before we switched to underscores
27
45
  // instead of commas for arbitrary values.
28
46
  if (['gridTemplateColumns', 'gridTemplateRows', 'objectPosition'].includes(themeSection)) {
29
- return (value) => (typeof value === 'string' ? postcss.list.comma(value).join(' ') : value)
30
- }
47
+ return (value) => {
48
+ if (typeof value === 'function') value = value({})
49
+ if (typeof value === 'string') value = postcss.list.comma(value).join(' ')
31
50
 
32
- if (themeSection === 'colors') {
33
- return (value) => (typeof value === 'function' ? value({}) : value)
51
+ return value
52
+ }
34
53
  }
35
54
 
36
- return (value) => value
55
+ return (value, opts = {}) => {
56
+ if (typeof value === 'function') {
57
+ value = value(opts)
58
+ }
59
+
60
+ return value
61
+ }
37
62
  }
@@ -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
+ }
@@ -5,7 +5,7 @@ export function withAlphaValue(color, alphaValue, defaultValue) {
5
5
  return color({ opacityValue: alphaValue })
6
6
  }
7
7
 
8
- let parsed = parseColor(color)
8
+ let parsed = parseColor(color, { loose: true })
9
9
 
10
10
  if (parsed === null) {
11
11
  return defaultValue
@@ -15,30 +15,35 @@ export function withAlphaValue(color, alphaValue, defaultValue) {
15
15
  }
16
16
 
17
17
  export default function withAlphaVariable({ color, property, variable }) {
18
+ let properties = [].concat(property)
18
19
  if (typeof color === 'function') {
19
20
  return {
20
21
  [variable]: '1',
21
- [property]: color({ opacityVariable: variable, opacityValue: `var(${variable})` }),
22
+ ...Object.fromEntries(
23
+ properties.map((p) => {
24
+ return [p, color({ opacityVariable: variable, opacityValue: `var(${variable})` })]
25
+ })
26
+ ),
22
27
  }
23
28
  }
24
29
 
25
30
  const parsed = parseColor(color)
26
31
 
27
32
  if (parsed === null) {
28
- return {
29
- [property]: color,
30
- }
33
+ return Object.fromEntries(properties.map((p) => [p, color]))
31
34
  }
32
35
 
33
36
  if (parsed.alpha !== undefined) {
34
37
  // Has an alpha value, return color as-is
35
- return {
36
- [property]: color,
37
- }
38
+ return Object.fromEntries(properties.map((p) => [p, color]))
38
39
  }
39
40
 
40
41
  return {
41
42
  [variable]: '1',
42
- [property]: formatColor({ ...parsed, alpha: `var(${variable})` }),
43
+ ...Object.fromEntries(
44
+ properties.map((p) => {
45
+ return [p, formatColor({ ...parsed, alpha: `var(${variable})` })]
46
+ })
47
+ ),
43
48
  }
44
49
  }