tailwindcss 3.1.8 → 3.2.0

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 (112) hide show
  1. package/README.md +6 -5
  2. package/lib/cli/build/deps.js +54 -0
  3. package/lib/cli/build/index.js +44 -0
  4. package/lib/cli/build/plugin.js +335 -0
  5. package/lib/cli/build/utils.js +78 -0
  6. package/lib/cli/build/watching.js +113 -0
  7. package/lib/cli/help/index.js +71 -0
  8. package/lib/cli/index.js +18 -0
  9. package/lib/cli/init/index.js +46 -0
  10. package/lib/cli/shared.js +12 -0
  11. package/lib/cli.js +11 -590
  12. package/lib/corePlugins.js +332 -108
  13. package/lib/css/preflight.css +5 -0
  14. package/lib/featureFlags.js +7 -4
  15. package/lib/index.js +6 -1
  16. package/lib/lib/content.js +167 -0
  17. package/lib/lib/defaultExtractor.js +15 -10
  18. package/lib/lib/detectNesting.js +2 -2
  19. package/lib/lib/evaluateTailwindFunctions.js +17 -1
  20. package/lib/lib/expandApplyAtRules.js +66 -37
  21. package/lib/lib/expandTailwindAtRules.js +10 -42
  22. package/lib/lib/findAtConfigPath.js +44 -0
  23. package/lib/lib/generateRules.js +180 -93
  24. package/lib/lib/normalizeTailwindDirectives.js +1 -1
  25. package/lib/lib/offsets.js +217 -0
  26. package/lib/lib/regex.js +1 -1
  27. package/lib/lib/setupContextUtils.js +339 -100
  28. package/lib/lib/setupTrackingContext.js +5 -39
  29. package/lib/lib/sharedState.js +2 -0
  30. package/lib/public/colors.js +1 -1
  31. package/lib/util/buildMediaQuery.js +6 -3
  32. package/lib/util/configurePlugins.js +1 -1
  33. package/lib/util/dataTypes.js +15 -19
  34. package/lib/util/formatVariantSelector.js +92 -8
  35. package/lib/util/getAllConfigs.js +14 -3
  36. package/lib/util/isValidArbitraryValue.js +1 -1
  37. package/lib/util/nameClass.js +3 -0
  38. package/lib/util/negateValue.js +15 -2
  39. package/lib/util/normalizeConfig.js +17 -3
  40. package/lib/util/normalizeScreens.js +100 -3
  41. package/lib/util/parseAnimationValue.js +1 -1
  42. package/lib/util/parseBoxShadowValue.js +1 -1
  43. package/lib/util/parseDependency.js +33 -54
  44. package/lib/util/parseGlob.js +34 -0
  45. package/lib/util/parseObjectStyles.js +1 -1
  46. package/lib/util/pluginUtils.js +86 -17
  47. package/lib/util/resolveConfig.js +2 -2
  48. package/lib/util/splitAtTopLevelOnly.js +31 -81
  49. package/lib/util/transformThemeValue.js +9 -2
  50. package/lib/util/validateConfig.js +1 -1
  51. package/lib/util/validateFormalSyntax.js +24 -0
  52. package/package.json +13 -11
  53. package/peers/.DS_Store +0 -0
  54. package/peers/.svgo.yml +75 -0
  55. package/peers/index.js +3332 -2032
  56. package/peers/orders/concentric-css.json +299 -0
  57. package/peers/orders/smacss.json +299 -0
  58. package/peers/orders/source.json +295 -0
  59. package/plugin.d.ts +3 -3
  60. package/scripts/release-channel.js +18 -0
  61. package/scripts/release-notes.js +21 -0
  62. package/src/.DS_Store +0 -0
  63. package/src/cli/build/deps.js +56 -0
  64. package/src/cli/build/index.js +45 -0
  65. package/src/cli/build/plugin.js +397 -0
  66. package/src/cli/build/utils.js +76 -0
  67. package/src/cli/build/watching.js +134 -0
  68. package/src/cli/help/index.js +70 -0
  69. package/src/cli/index.js +3 -0
  70. package/src/cli/init/index.js +50 -0
  71. package/src/cli/shared.js +5 -0
  72. package/src/cli.js +4 -696
  73. package/src/corePlugins.js +262 -39
  74. package/src/css/preflight.css +5 -0
  75. package/src/featureFlags.js +12 -2
  76. package/src/index.js +5 -0
  77. package/src/lib/content.js +205 -0
  78. package/src/lib/defaultExtractor.js +3 -0
  79. package/src/lib/evaluateTailwindFunctions.js +22 -1
  80. package/src/lib/expandApplyAtRules.js +70 -29
  81. package/src/lib/expandTailwindAtRules.js +8 -46
  82. package/src/lib/findAtConfigPath.js +48 -0
  83. package/src/lib/generateRules.js +223 -101
  84. package/src/lib/offsets.js +270 -0
  85. package/src/lib/setupContextUtils.js +376 -89
  86. package/src/lib/setupTrackingContext.js +4 -45
  87. package/src/lib/sharedState.js +2 -0
  88. package/src/util/buildMediaQuery.js +5 -3
  89. package/src/util/dataTypes.js +15 -17
  90. package/src/util/formatVariantSelector.js +113 -9
  91. package/src/util/getAllConfigs.js +14 -2
  92. package/src/util/nameClass.js +4 -0
  93. package/src/util/negateValue.js +10 -2
  94. package/src/util/normalizeConfig.js +22 -2
  95. package/src/util/normalizeScreens.js +99 -4
  96. package/src/util/parseBoxShadowValue.js +1 -1
  97. package/src/util/parseDependency.js +37 -42
  98. package/src/util/parseGlob.js +24 -0
  99. package/src/util/pluginUtils.js +90 -14
  100. package/src/util/resolveConfig.js +1 -1
  101. package/src/util/splitAtTopLevelOnly.js +23 -49
  102. package/src/util/transformThemeValue.js +9 -1
  103. package/src/util/validateFormalSyntax.js +34 -0
  104. package/stubs/defaultConfig.stub.js +19 -3
  105. package/tmp.css +11 -0
  106. package/tmp.dependency-graph.js +2 -0
  107. package/tmp.in.css +3 -0
  108. package/tmp.js +0 -0
  109. package/tmp.out.css +524 -0
  110. package/types/config.d.ts +47 -13
  111. package/types/generated/default-theme.d.ts +11 -0
  112. package/CHANGELOG.md +0 -2231
@@ -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
+ }
@@ -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) => {
@@ -85,11 +87,20 @@ function isArbitraryValue(input) {
85
87
  return input.startsWith('[') && input.endsWith(']')
86
88
  }
87
89
 
88
- function splitAlpha(modifier) {
90
+ function splitUtilityModifier(modifier) {
89
91
  let slashIdx = modifier.lastIndexOf('/')
90
92
 
91
93
  if (slashIdx === -1 || slashIdx === modifier.length - 1) {
92
- return [modifier]
94
+ return [modifier, undefined]
95
+ }
96
+
97
+ let arbitrary = isArbitraryValue(modifier)
98
+
99
+ // The modifier could be of the form `[foo]/[bar]`
100
+ // We want to handle this case properly
101
+ // without affecting `[foo/bar]`
102
+ if (arbitrary && !modifier.includes(']/[')) {
103
+ return [modifier, undefined]
93
104
  }
94
105
 
95
106
  return [modifier.slice(0, slashIdx), modifier.slice(slashIdx + 1)]
@@ -105,12 +116,18 @@ export function parseColorFormat(value) {
105
116
  return value
106
117
  }
107
118
 
108
- export function asColor(modifier, options = {}, { tailwindConfig = {} } = {}) {
109
- if (options.values?.[modifier] !== undefined) {
110
- return parseColorFormat(options.values?.[modifier])
119
+ export function asColor(
120
+ _,
121
+ options = {},
122
+ { tailwindConfig = {}, utilityModifier, rawModifier } = {}
123
+ ) {
124
+ if (options.values?.[rawModifier] !== undefined) {
125
+ return parseColorFormat(options.values?.[rawModifier])
111
126
  }
112
127
 
113
- let [color, alpha] = splitAlpha(modifier)
128
+ // TODO: Hoist this up to getMatchingTypes or something
129
+ // We do this here because we need the alpha value (if any)
130
+ let [color, alpha] = splitUtilityModifier(rawModifier)
114
131
 
115
132
  if (alpha !== undefined) {
116
133
  let normalizedColor =
@@ -133,7 +150,7 @@ export function asColor(modifier, options = {}, { tailwindConfig = {} } = {}) {
133
150
  return withAlphaValue(normalizedColor, tailwindConfig.theme.opacity[alpha])
134
151
  }
135
152
 
136
- return asValue(modifier, options, { validate: validateColor })
153
+ return asValue(rawModifier, options, { rawModifier, utilityModifier, validate: validateColor })
137
154
  }
138
155
 
139
156
  export function asLookupValue(modifier, options = {}) {
@@ -141,12 +158,12 @@ export function asLookupValue(modifier, options = {}) {
141
158
  }
142
159
 
143
160
  function guess(validate) {
144
- return (modifier, options) => {
145
- return asValue(modifier, options, { validate })
161
+ return (modifier, options, extras) => {
162
+ return asValue(modifier, options, { ...extras, validate })
146
163
  }
147
164
  }
148
165
 
149
- let typeMap = {
166
+ export let typeMap = {
150
167
  any: asValue,
151
168
  color: asColor,
152
169
  url: guess(url),
@@ -162,6 +179,7 @@ let typeMap = {
162
179
  'absolute-size': guess(absoluteSize),
163
180
  'relative-size': guess(relativeSize),
164
181
  shadow: guess(shadow),
182
+ size: guess(backgroundSize),
165
183
  }
166
184
 
167
185
  let supportedTypes = Object.keys(typeMap)
@@ -190,15 +208,73 @@ export function coerceValue(types, modifier, options, tailwindConfig) {
190
208
  }
191
209
 
192
210
  if (value.length > 0 && supportedTypes.includes(explicitType)) {
193
- return [asValue(`[${value}]`, options), explicitType]
211
+ return [asValue(`[${value}]`, options), explicitType, null]
194
212
  }
195
213
  }
196
214
 
215
+ let matches = getMatchingTypes(types, modifier, options, tailwindConfig)
216
+
197
217
  // Find first matching type
198
- for (let type of [].concat(types)) {
199
- let result = typeMap[type](modifier, options, { tailwindConfig })
200
- if (result !== undefined) return [result, type]
218
+ for (let match of matches) {
219
+ return match
201
220
  }
202
221
 
203
222
  return []
204
223
  }
224
+
225
+ /**
226
+ *
227
+ * @param {{type: string}[]} types
228
+ * @param {string} rawModifier
229
+ * @param {any} options
230
+ * @param {any} tailwindConfig
231
+ * @returns {Iterator<[value: string, type: string, modifier: string | null]>}
232
+ */
233
+ export function* getMatchingTypes(types, rawModifier, options, tailwindConfig) {
234
+ let modifiersEnabled = flagEnabled(tailwindConfig, 'generalizedModifiers')
235
+
236
+ let canUseUtilityModifier =
237
+ modifiersEnabled &&
238
+ options.modifiers != null &&
239
+ (options.modifiers === 'any' || typeof options.modifiers === 'object')
240
+
241
+ let [modifier, utilityModifier] = canUseUtilityModifier
242
+ ? splitUtilityModifier(rawModifier)
243
+ : [rawModifier, undefined]
244
+
245
+ if (utilityModifier !== undefined && modifier === '') {
246
+ modifier = 'DEFAULT'
247
+ }
248
+
249
+ // Check the full value first
250
+ // TODO: Move to asValue… somehow
251
+ if (utilityModifier !== undefined) {
252
+ if (typeof options.modifiers === 'object') {
253
+ let configValue = options.modifiers?.[utilityModifier] ?? null
254
+ if (configValue !== null) {
255
+ utilityModifier = configValue
256
+ } else if (isArbitraryValue(utilityModifier)) {
257
+ utilityModifier = utilityModifier.slice(1, -1)
258
+ }
259
+ }
260
+
261
+ let result = asValue(rawModifier, options, { rawModifier, utilityModifier, tailwindConfig })
262
+ if (result !== undefined) {
263
+ yield [result, 'any', null]
264
+ }
265
+ }
266
+
267
+ for (const { type } of types ?? []) {
268
+ let result = typeMap[type](modifier, options, {
269
+ rawModifier,
270
+ utilityModifier,
271
+ tailwindConfig,
272
+ })
273
+
274
+ if (result === undefined) {
275
+ continue
276
+ }
277
+
278
+ yield [result, type, utilityModifier ?? null]
279
+ }
280
+ }
@@ -29,7 +29,7 @@ function mergeWith(target, ...sources) {
29
29
 
30
30
  if (merged === undefined) {
31
31
  if (isObject(target[k]) && isObject(source[k])) {
32
- target[k] = mergeWith(target[k], source[k], customizer)
32
+ target[k] = mergeWith({}, target[k], source[k], customizer)
33
33
  } else {
34
34
  target[k] = source[k]
35
35
  }
@@ -1,5 +1,3 @@
1
- import * as regex from '../lib/regex'
2
-
3
1
  /**
4
2
  * This splits a string on a top-level character.
5
3
  *
@@ -15,57 +13,33 @@ import * as regex from '../lib/regex'
15
13
  * @param {string} input
16
14
  * @param {string} separator
17
15
  */
18
- export function* splitAtTopLevelOnly(input, separator) {
19
- let SPECIALS = new RegExp(`[(){}\\[\\]${regex.escape(separator)}]`, 'g')
20
-
21
- let depth = 0
22
- let lastIndex = 0
23
- let found = false
24
- let separatorIndex = 0
25
- let separatorStart = 0
26
- let separatorLength = separator.length
27
-
28
- // Find all paren-like things & character
29
- // And only split on commas if they're top-level
30
- for (let match of input.matchAll(SPECIALS)) {
31
- let matchesSeparator = match[0] === separator[separatorIndex]
32
- let atEndOfSeparator = separatorIndex === separatorLength - 1
33
- let matchesFullSeparator = matchesSeparator && atEndOfSeparator
34
-
35
- if (match[0] === '(') depth++
36
- if (match[0] === ')') depth--
37
- if (match[0] === '[') depth++
38
- if (match[0] === ']') depth--
39
- if (match[0] === '{') depth++
40
- if (match[0] === '}') depth--
41
-
42
- if (matchesSeparator && depth === 0) {
43
- if (separatorStart === 0) {
44
- separatorStart = match.index
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
45
28
  }
46
-
47
- separatorIndex++
48
29
  }
49
30
 
50
- if (matchesFullSeparator && depth === 0) {
51
- found = true
52
-
53
- yield input.substring(lastIndex, separatorStart)
54
- lastIndex = separatorStart + separatorLength
55
- }
56
-
57
- if (separatorIndex === separatorLength) {
58
- separatorIndex = 0
59
- separatorStart = 0
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()
60
39
  }
61
40
  }
62
41
 
63
- // Provide the last segment of the string if available
64
- // Otherwise the whole string since no `char`s were found
65
- // This mirrors the behavior of string.split()
66
- if (found) {
67
- yield input.substring(lastIndex)
68
- } else {
69
- yield input
70
- }
42
+ parts.push(input.slice(lastPos))
43
+
44
+ return parts
71
45
  }
@@ -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',
@@ -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
+ }
@@ -112,6 +112,16 @@ module.exports = {
112
112
  pulse: 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite',
113
113
  bounce: 'bounce 1s infinite',
114
114
  },
115
+ aria: {
116
+ checked: 'checked="true"',
117
+ disabled: 'disabled="true"',
118
+ expanded: 'expanded="true"',
119
+ hidden: 'hidden="true"',
120
+ pressed: 'pressed="true"',
121
+ readonly: 'readonly="true"',
122
+ required: 'required="true"',
123
+ selected: 'selected="true"',
124
+ },
115
125
  aspectRatio: {
116
126
  auto: 'auto',
117
127
  square: '1 / 1',
@@ -284,7 +294,10 @@ module.exports = {
284
294
  '2xl': '0 25px 25px rgb(0 0 0 / 0.15)',
285
295
  none: '0 0 #0000',
286
296
  },
287
- fill: ({ theme }) => theme('colors'),
297
+ fill: ({ theme }) => ({
298
+ none: 'none',
299
+ ...theme('colors'),
300
+ }),
288
301
  grayscale: {
289
302
  0: '0',
290
303
  DEFAULT: '100%',
@@ -721,7 +734,7 @@ module.exports = {
721
734
  8: '8px',
722
735
  },
723
736
  ringColor: ({ theme }) => ({
724
- DEFAULT: theme(`colors.blue.500`, '#3b82f6'),
737
+ DEFAULT: theme('colors.blue.500', '#3b82f6'),
725
738
  ...theme('colors'),
726
739
  }),
727
740
  ringOffsetColor: ({ theme }) => theme('colors'),
@@ -793,7 +806,10 @@ module.exports = {
793
806
  space: ({ theme }) => ({
794
807
  ...theme('spacing'),
795
808
  }),
796
- stroke: ({ theme }) => theme('colors'),
809
+ stroke: ({ theme }) => ({
810
+ none: 'none',
811
+ ...theme('colors'),
812
+ }),
797
813
  strokeWidth: {
798
814
  0: '0',
799
815
  1: '1',
package/tmp.css ADDED
@@ -0,0 +1,11 @@
1
+ @media (prefers-color-scheme: dark) {
2
+ @supports (hover: hover) {
3
+ .dark\:\[\@supports\(hover\:hover\)\]\:hover\:\[\&\>\*\]\:\(\[--potato\:baked\]\2c
4
+ bg-\[\#0088cc\]\)
5
+ > *:hover {
6
+ --tw-bg-opacity: 1;
7
+ background-color: rgb(0 136 204 / var(--tw-bg-opacity));
8
+ --potato: baked;
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,2 @@
1
+ 1. Push tag
2
+ 2. Draft release
package/tmp.in.css ADDED
@@ -0,0 +1,3 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
package/tmp.js ADDED
File without changes