tailwindcss 3.0.0-alpha.2 → 3.0.3

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 (53) hide show
  1. package/CHANGELOG.md +59 -2
  2. package/colors.js +2 -1
  3. package/defaultConfig.js +2 -1
  4. package/defaultTheme.js +2 -1
  5. package/lib/cli.js +58 -58
  6. package/lib/corePluginList.js +3 -0
  7. package/lib/corePlugins.js +227 -172
  8. package/lib/css/preflight.css +5 -3
  9. package/lib/featureFlags.js +3 -1
  10. package/lib/lib/detectNesting.js +17 -2
  11. package/lib/lib/evaluateTailwindFunctions.js +6 -2
  12. package/lib/lib/expandApplyAtRules.js +23 -6
  13. package/lib/lib/expandTailwindAtRules.js +19 -1
  14. package/lib/lib/generateRules.js +54 -0
  15. package/lib/lib/resolveDefaultsAtRules.js +23 -9
  16. package/lib/lib/setupContextUtils.js +48 -71
  17. package/lib/lib/substituteScreenAtRules.js +7 -4
  18. package/lib/util/buildMediaQuery.js +13 -24
  19. package/lib/util/dataTypes.js +14 -3
  20. package/lib/util/defaults.js +6 -0
  21. package/lib/util/formatVariantSelector.js +88 -4
  22. package/lib/util/isValidArbitraryValue.js +64 -0
  23. package/lib/util/log.js +4 -0
  24. package/lib/util/nameClass.js +1 -0
  25. package/lib/util/normalizeConfig.js +34 -5
  26. package/lib/util/normalizeScreens.js +61 -0
  27. package/lib/util/resolveConfig.js +8 -8
  28. package/package.json +14 -13
  29. package/peers/index.js +3739 -3027
  30. package/plugin.js +2 -1
  31. package/resolveConfig.js +2 -1
  32. package/src/corePluginList.js +1 -1
  33. package/src/corePlugins.js +205 -165
  34. package/src/css/preflight.css +5 -3
  35. package/src/featureFlags.js +5 -1
  36. package/src/lib/detectNesting.js +22 -3
  37. package/src/lib/evaluateTailwindFunctions.js +5 -2
  38. package/src/lib/expandApplyAtRules.js +29 -2
  39. package/src/lib/expandTailwindAtRules.js +18 -0
  40. package/src/lib/generateRules.js +57 -0
  41. package/src/lib/resolveDefaultsAtRules.js +28 -7
  42. package/src/lib/setupContextUtils.js +45 -64
  43. package/src/lib/substituteScreenAtRules.js +6 -3
  44. package/src/util/buildMediaQuery.js +14 -18
  45. package/src/util/dataTypes.js +11 -6
  46. package/src/util/defaults.js +6 -0
  47. package/src/util/formatVariantSelector.js +92 -1
  48. package/src/util/isValidArbitraryValue.js +61 -0
  49. package/src/util/log.js +4 -0
  50. package/src/util/nameClass.js +1 -1
  51. package/src/util/normalizeConfig.js +14 -1
  52. package/src/util/normalizeScreens.js +45 -0
  53. package/stubs/defaultConfig.stub.js +17 -0
@@ -0,0 +1,61 @@
1
+ let matchingBrackets = new Map([
2
+ ['{', '}'],
3
+ ['[', ']'],
4
+ ['(', ')'],
5
+ ])
6
+ let inverseMatchingBrackets = new Map(
7
+ Array.from(matchingBrackets.entries()).map(([k, v]) => [v, k])
8
+ )
9
+
10
+ let quotes = new Set(['"', "'", '`'])
11
+
12
+ // Arbitrary values must contain balanced brackets (), [] and {}. Escaped
13
+ // values don't count, and brackets inside quotes also don't count.
14
+ //
15
+ // E.g.: w-[this-is]w-[weird-and-invalid]
16
+ // E.g.: w-[this-is\\]w-\\[weird-but-valid]
17
+ // E.g.: content-['this-is-also-valid]-weirdly-enough']
18
+ export default function isValidArbitraryValue(value) {
19
+ let stack = []
20
+ let inQuotes = false
21
+
22
+ for (let i = 0; i < value.length; i++) {
23
+ let char = value[i]
24
+
25
+ if (char === ':' && !inQuotes && stack.length === 0) {
26
+ return false
27
+ }
28
+
29
+ // Non-escaped quotes allow us to "allow" anything in between
30
+ if (quotes.has(char) && value[i - 1] !== '\\') {
31
+ inQuotes = !inQuotes
32
+ }
33
+
34
+ if (inQuotes) continue
35
+ if (value[i - 1] === '\\') continue // Escaped
36
+
37
+ if (matchingBrackets.has(char)) {
38
+ stack.push(char)
39
+ } else if (inverseMatchingBrackets.has(char)) {
40
+ let inverse = inverseMatchingBrackets.get(char)
41
+
42
+ // Nothing to pop from, therefore it is unbalanced
43
+ if (stack.length <= 0) {
44
+ return false
45
+ }
46
+
47
+ // Popped value must match the inverse value, otherwise it is unbalanced
48
+ if (stack.pop() !== inverse) {
49
+ return false
50
+ }
51
+ }
52
+ }
53
+
54
+ // If there is still something on the stack, it is also unbalanced
55
+ if (stack.length > 0) {
56
+ return false
57
+ }
58
+
59
+ // All good, totally balanced!
60
+ return true
61
+ }
package/src/util/log.js CHANGED
@@ -12,6 +12,10 @@ function log(chalk, messages, key) {
12
12
  messages.forEach((message) => console.warn(chalk, '-', message))
13
13
  }
14
14
 
15
+ export function dim(input) {
16
+ return chalk.dim(input)
17
+ }
18
+
15
19
  export default {
16
20
  info(key, messages) {
17
21
  log(chalk.bold.cyan('info'), ...(Array.isArray(key) ? [key] : [messages, key]))
@@ -1,7 +1,7 @@
1
1
  import escapeClassName from './escapeClassName'
2
2
  import escapeCommas from './escapeCommas'
3
3
 
4
- function asClass(name) {
4
+ export function asClass(name) {
5
5
  return escapeCommas(`.${escapeClassName(name)}`)
6
6
  }
7
7
 
@@ -1,4 +1,4 @@
1
- import log from './log'
1
+ import log, { dim } from './log'
2
2
 
3
3
  export function normalizeConfig(config) {
4
4
  // Quick structure validation
@@ -245,5 +245,18 @@ export function normalizeConfig(config) {
245
245
  })(),
246
246
  }
247
247
 
248
+ // Validate globs to prevent bogus globs.
249
+ // E.g.: `./src/*.{html}` is invalid, the `{html}` should just be `html`
250
+ for (let file of config.content.files) {
251
+ if (typeof file === 'string' && /{([^,]*?)}/g.test(file)) {
252
+ log.warn('invalid-glob-braces', [
253
+ `The glob pattern ${dim(file)} in your config is invalid.`,
254
+ ` Update it to ${dim(file.replace(/{([^,]*?)}/g, '$1'))} to silence this warning.`,
255
+ // TODO: Add https://tw.wtf/invalid-glob-braces
256
+ ])
257
+ break
258
+ }
259
+ }
260
+
248
261
  return config
249
262
  }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * A function that normalizes the various forms that the screens object can be
3
+ * provided in.
4
+ *
5
+ * Input(s):
6
+ * - ['100px', '200px'] // Raw strings
7
+ * - { sm: '100px', md: '200px' } // Object with string values
8
+ * - { sm: { min: '100px' }, md: { max: '100px' } } // Object with object values
9
+ * - { sm: [{ min: '100px' }, { max: '200px' }] } // Object with object array (multiple values)
10
+ *
11
+ * Output(s):
12
+ * - [{ name: 'sm', values: [{ min: '100px', max: '200px' }] }] // List of objects, that contains multiple values
13
+ */
14
+ export function normalizeScreens(screens, root = true) {
15
+ if (Array.isArray(screens)) {
16
+ return screens.map((screen) => {
17
+ if (root && Array.isArray(screen)) {
18
+ throw new Error('The tuple syntax is not supported for `screens`.')
19
+ }
20
+
21
+ if (typeof screen === 'string') {
22
+ return { name: screen.toString(), values: [{ min: screen, max: undefined }] }
23
+ }
24
+
25
+ let [name, options] = screen
26
+ name = name.toString()
27
+
28
+ if (typeof options === 'string') {
29
+ return { name, values: [{ min: options, max: undefined }] }
30
+ }
31
+
32
+ if (Array.isArray(options)) {
33
+ return { name, values: options.map((option) => resolveValue(option)) }
34
+ }
35
+
36
+ return { name, values: [resolveValue(options)] }
37
+ })
38
+ }
39
+
40
+ return normalizeScreens(Object.entries(screens ?? {}), false)
41
+ }
42
+
43
+ function resolveValue({ 'min-width': _minWidth, min = _minWidth, max, raw } = {}) {
44
+ return { min, max, raw }
45
+ }
@@ -797,6 +797,23 @@ module.exports = {
797
797
  },
798
798
  textColor: ({ theme }) => theme('colors'),
799
799
  textDecorationColor: ({ theme }) => theme('colors'),
800
+ textDecorationThickness: {
801
+ auto: 'auto',
802
+ 'from-font': 'from-font',
803
+ 0: '0px',
804
+ 1: '1px',
805
+ 2: '2px',
806
+ 4: '4px',
807
+ 8: '8px',
808
+ },
809
+ textUnderlineOffset: {
810
+ auto: 'auto',
811
+ 0: '0px',
812
+ 1: '1px',
813
+ 2: '2px',
814
+ 4: '4px',
815
+ 8: '8px',
816
+ },
800
817
  textIndent: ({ theme }) => ({
801
818
  ...theme('spacing'),
802
819
  }),