tailwindcss 3.0.24 → 3.1.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 (88) hide show
  1. package/CHANGELOG.md +57 -3
  2. package/colors.d.ts +3 -0
  3. package/defaultConfig.d.ts +3 -0
  4. package/defaultTheme.d.ts +3 -0
  5. package/lib/cli-peer-dependencies.js +8 -3
  6. package/lib/cli.js +118 -77
  7. package/lib/corePluginList.js +1 -0
  8. package/lib/corePlugins.js +146 -117
  9. package/lib/css/preflight.css +1 -8
  10. package/lib/featureFlags.js +8 -6
  11. package/lib/index.js +10 -13
  12. package/lib/lib/cacheInvalidation.js +32 -14
  13. package/lib/lib/collapseAdjacentRules.js +5 -3
  14. package/lib/lib/defaultExtractor.js +191 -32
  15. package/lib/lib/evaluateTailwindFunctions.js +22 -13
  16. package/lib/lib/expandApplyAtRules.js +232 -195
  17. package/lib/lib/expandTailwindAtRules.js +40 -26
  18. package/lib/lib/generateRules.js +106 -42
  19. package/lib/lib/regex.js +52 -0
  20. package/lib/lib/resolveDefaultsAtRules.js +6 -9
  21. package/lib/lib/setupContextUtils.js +131 -79
  22. package/lib/lib/setupTrackingContext.js +7 -9
  23. package/lib/lib/sharedState.js +1 -2
  24. package/lib/lib/substituteScreenAtRules.js +1 -2
  25. package/lib/postcss-plugins/nesting/plugin.js +1 -2
  26. package/lib/util/buildMediaQuery.js +1 -2
  27. package/lib/util/cloneDeep.js +2 -4
  28. package/lib/util/color.js +26 -36
  29. package/lib/util/createPlugin.js +1 -2
  30. package/lib/util/createUtilityPlugin.js +1 -2
  31. package/lib/util/dataTypes.js +14 -12
  32. package/lib/util/flattenColorPalette.js +2 -5
  33. package/lib/util/formatVariantSelector.js +64 -57
  34. package/lib/util/getAllConfigs.js +10 -5
  35. package/lib/util/isValidArbitraryValue.js +1 -2
  36. package/lib/util/log.js +2 -3
  37. package/lib/util/negateValue.js +1 -2
  38. package/lib/util/normalizeConfig.js +33 -23
  39. package/lib/util/normalizeScreens.js +1 -2
  40. package/lib/util/parseAnimationValue.js +1 -2
  41. package/lib/util/parseBoxShadowValue.js +2 -43
  42. package/lib/util/pluginUtils.js +11 -3
  43. package/lib/util/resolveConfig.js +57 -34
  44. package/lib/util/splitAtTopLevelOnly.js +90 -0
  45. package/lib/util/transformThemeValue.js +4 -2
  46. package/lib/util/validateConfig.js +21 -0
  47. package/lib/util/withAlphaVariable.js +5 -5
  48. package/package.json +21 -16
  49. package/peers/index.js +3264 -1330
  50. package/plugin.d.ts +11 -0
  51. package/src/cli-peer-dependencies.js +7 -1
  52. package/src/cli.js +97 -33
  53. package/src/corePluginList.js +1 -1
  54. package/src/corePlugins.js +57 -40
  55. package/src/css/preflight.css +1 -8
  56. package/src/featureFlags.js +2 -2
  57. package/src/index.js +0 -2
  58. package/src/lib/collapseAdjacentRules.js +5 -1
  59. package/src/lib/defaultExtractor.js +177 -35
  60. package/src/lib/evaluateTailwindFunctions.js +20 -4
  61. package/src/lib/expandApplyAtRules.js +247 -188
  62. package/src/lib/expandTailwindAtRules.js +4 -4
  63. package/src/lib/generateRules.js +69 -5
  64. package/src/lib/regex.js +74 -0
  65. package/src/lib/resolveDefaultsAtRules.js +1 -1
  66. package/src/lib/setupContextUtils.js +103 -39
  67. package/src/lib/setupTrackingContext.js +4 -0
  68. package/src/util/color.js +20 -18
  69. package/src/util/dataTypes.js +11 -5
  70. package/src/util/formatVariantSelector.js +79 -62
  71. package/src/util/getAllConfigs.js +7 -0
  72. package/src/util/log.js +1 -1
  73. package/src/util/normalizeConfig.js +0 -8
  74. package/src/util/parseBoxShadowValue.js +3 -50
  75. package/src/util/pluginUtils.js +13 -1
  76. package/src/util/resolveConfig.js +66 -54
  77. package/src/util/splitAtTopLevelOnly.js +71 -0
  78. package/src/util/toPath.js +1 -1
  79. package/src/util/transformThemeValue.js +4 -2
  80. package/src/util/validateConfig.js +13 -0
  81. package/src/util/withAlphaVariable.js +1 -1
  82. package/stubs/defaultConfig.stub.js +2 -3
  83. package/stubs/simpleConfig.stub.js +1 -0
  84. package/types/config.d.ts +325 -0
  85. package/types/generated/.gitkeep +0 -0
  86. package/types/generated/colors.d.ts +276 -0
  87. package/types/generated/corePluginList.d.ts +1 -0
  88. package/types/index.d.ts +1 -0
@@ -95,9 +95,19 @@ function splitAlpha(modifier) {
95
95
  return [modifier.slice(0, slashIdx), modifier.slice(slashIdx + 1)]
96
96
  }
97
97
 
98
+ export function parseColorFormat(value) {
99
+ if (typeof value === 'string' && value.includes('<alpha-value>')) {
100
+ let oldValue = value
101
+
102
+ return ({ opacityValue = 1 }) => oldValue.replace('<alpha-value>', opacityValue)
103
+ }
104
+
105
+ return value
106
+ }
107
+
98
108
  export function asColor(modifier, options = {}, { tailwindConfig = {} } = {}) {
99
109
  if (options.values?.[modifier] !== undefined) {
100
- return options.values?.[modifier]
110
+ return parseColorFormat(options.values?.[modifier])
101
111
  }
102
112
 
103
113
  let [color, alpha] = splitAlpha(modifier)
@@ -110,6 +120,8 @@ export function asColor(modifier, options = {}, { tailwindConfig = {} } = {}) {
110
120
  return undefined
111
121
  }
112
122
 
123
+ normalizedColor = parseColorFormat(normalizedColor)
124
+
113
125
  if (isArbitraryValue(alpha)) {
114
126
  return withAlphaValue(normalizedColor, alpha.slice(1, -1))
115
127
  }
@@ -8,6 +8,9 @@ import { toPath } from './toPath'
8
8
  import { normalizeConfig } from './normalizeConfig'
9
9
  import isPlainObject from './isPlainObject'
10
10
  import { cloneDeep } from './cloneDeep'
11
+ import { parseColorFormat } from './pluginUtils'
12
+ import { withAlphaValue } from './withAlphaVariable'
13
+ import toColorValue from './toColorValue'
11
14
 
12
15
  function isFunction(input) {
13
16
  return typeof input === 'function'
@@ -66,38 +69,6 @@ const configUtils = {
66
69
  {}
67
70
  )
68
71
  },
69
- /*
70
- rgb(property) {
71
- if (!property.startsWith('--')) {
72
- throw new Error(
73
- 'The rgb() helper requires a custom property name to be passed as the first argument.'
74
- )
75
- }
76
-
77
- return ({ opacityValue }) => {
78
- if (opacityValue === undefined || opacityValue === 1) {
79
- return `rgb(var(${property}) / 1.0)`
80
- }
81
-
82
- return `rgb(var(${property}) / ${opacityValue})`
83
- }
84
- },
85
- hsl(property) {
86
- if (!property.startsWith('--')) {
87
- throw new Error(
88
- 'The hsl() helper requires a custom property name to be passed as the first argument.'
89
- )
90
- }
91
-
92
- return ({ opacityValue }) => {
93
- if (opacityValue === undefined || opacityValue === 1) {
94
- return `hsl(var(${property}) / 1)`
95
- }
96
-
97
- return `hsl(var(${property}) / ${opacityValue})`
98
- }
99
- },
100
- */
101
72
  }
102
73
 
103
74
  function value(valueToResolve, ...args) {
@@ -166,40 +137,81 @@ function mergeExtensions({ extend, ...theme }) {
166
137
  })
167
138
  }
168
139
 
140
+ /**
141
+ *
142
+ * @param {string} key
143
+ * @return {Iterable<string[] & {alpha: string | undefined}>}
144
+ */
145
+ function* toPaths(key) {
146
+ let path = toPath(key)
147
+
148
+ if (path.length === 0) {
149
+ return
150
+ }
151
+
152
+ yield path
153
+
154
+ if (Array.isArray(key)) {
155
+ return
156
+ }
157
+
158
+ let pattern = /^(.*?)\s*\/\s*([^/]+)$/
159
+ let matches = key.match(pattern)
160
+
161
+ if (matches !== null) {
162
+ let [, prefix, alpha] = matches
163
+
164
+ let newPath = toPath(prefix)
165
+ newPath.alpha = alpha
166
+
167
+ yield newPath
168
+ }
169
+ }
170
+
169
171
  function resolveFunctionKeys(object) {
172
+ // theme('colors.red.500 / 0.5') -> ['colors', 'red', '500 / 0', '5]
173
+
170
174
  const resolvePath = (key, defaultValue) => {
171
- const path = toPath(key)
175
+ for (const path of toPaths(key)) {
176
+ let index = 0
177
+ let val = object
172
178
 
173
- let index = 0
174
- let val = object
179
+ while (val !== undefined && val !== null && index < path.length) {
180
+ val = val[path[index++]]
175
181
 
176
- while (val !== undefined && val !== null && index < path.length) {
177
- val = val[path[index++]]
178
- val = isFunction(val) ? val(resolvePath, configUtils) : val
179
- }
182
+ let shouldResolveAsFn =
183
+ isFunction(val) && (path.alpha === undefined || index < path.length - 1)
180
184
 
181
- if (val === undefined) {
182
- return defaultValue
183
- }
185
+ val = shouldResolveAsFn ? val(resolvePath, configUtils) : val
186
+ }
184
187
 
185
- if (isPlainObject(val)) {
186
- return cloneDeep(val)
187
- }
188
+ if (val !== undefined) {
189
+ if (path.alpha !== undefined) {
190
+ let normalized = parseColorFormat(val)
188
191
 
189
- return val
190
- }
192
+ return withAlphaValue(normalized, path.alpha, toColorValue(normalized))
193
+ }
191
194
 
192
- resolvePath.theme = resolvePath
195
+ if (isPlainObject(val)) {
196
+ return cloneDeep(val)
197
+ }
198
+
199
+ return val
200
+ }
201
+ }
193
202
 
194
- for (let key in configUtils) {
195
- resolvePath[key] = configUtils[key]
203
+ return defaultValue
196
204
  }
197
205
 
206
+ Object.assign(resolvePath, {
207
+ theme: resolvePath,
208
+ ...configUtils,
209
+ })
210
+
198
211
  return Object.keys(object).reduce((resolved, key) => {
199
- return {
200
- ...resolved,
201
- [key]: isFunction(object[key]) ? object[key](resolvePath, configUtils) : object[key],
202
- }
212
+ resolved[key] = isFunction(object[key]) ? object[key](resolvePath, configUtils) : object[key]
213
+
214
+ return resolved
203
215
  }, {})
204
216
  }
205
217
 
@@ -0,0 +1,71 @@
1
+ import * as regex from '../lib/regex'
2
+
3
+ /**
4
+ * This splits a string on a top-level character.
5
+ *
6
+ * Regex doesn't support recursion (at least not the JS-flavored version).
7
+ * So we have to use a tiny state machine to keep track of paren placement.
8
+ *
9
+ * Expected behavior using commas:
10
+ * var(--a, 0 0 1px rgb(0, 0, 0)), 0 0 1px rgb(0, 0, 0)
11
+ * ─┬─ ┬ ┬ ┬
12
+ * x x x ╰──────── Split because top-level
13
+ * ╰──────────────┴──┴───────────── Ignored b/c inside >= 1 levels of parens
14
+ *
15
+ * @param {string} input
16
+ * @param {string} separator
17
+ */
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
45
+ }
46
+
47
+ separatorIndex++
48
+ }
49
+
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
60
+ }
61
+ }
62
+
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
+ }
71
+ }
@@ -4,7 +4,7 @@
4
4
  * Square bracket notation `a[b]` may be used to "escape" dots that would otherwise be interpreted as path separators.
5
5
  *
6
6
  * Example:
7
- * a -> ['a]
7
+ * a -> ['a']
8
8
  * a.b.c -> ['a', 'b', 'c']
9
9
  * a[b].c -> ['a', 'b', 'c']
10
10
  * a[b.c].e.f -> ['a', 'b.c', 'e', 'f']
@@ -44,8 +44,10 @@ export default function transformThemeValue(themeSection) {
44
44
  }
45
45
  }
46
46
 
47
- return (value) => {
48
- if (typeof value === 'function') value = value({})
47
+ return (value, opts = {}) => {
48
+ if (typeof value === 'function') {
49
+ value = value(opts)
50
+ }
49
51
 
50
52
  return value
51
53
  }
@@ -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
+ }
@@ -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
@@ -1,3 +1,4 @@
1
+ /** @type {import('tailwindcss').Config} */
1
2
  module.exports = {
2
3
  content: [],
3
4
  presets: [],
@@ -194,11 +195,9 @@ module.exports = {
194
195
  '3xl': '1.5rem',
195
196
  full: '9999px',
196
197
  },
197
- /*
198
198
  borderSpacing: ({ theme }) => ({
199
199
  ...theme('spacing'),
200
200
  }),
201
- */
202
201
  borderWidth: {
203
202
  DEFAULT: '1px',
204
203
  0: '0px',
@@ -722,7 +721,7 @@ module.exports = {
722
721
  8: '8px',
723
722
  },
724
723
  ringColor: ({ theme }) => ({
725
- DEFAULT: theme('colors.blue.500', '#3b82f6'),
724
+ DEFAULT: theme(`colors.blue.500`, '#3b82f6'),
726
725
  ...theme('colors'),
727
726
  }),
728
727
  ringOffsetColor: ({ theme }) => theme('colors'),
@@ -1,3 +1,4 @@
1
+ /** @type {import('tailwindcss').Config} */
1
2
  module.exports = {
2
3
  content: [],
3
4
  theme: {
@@ -0,0 +1,325 @@
1
+ import type { CorePluginList } from './generated/CorePluginList'
2
+ import type { DefaultColors } from './generated/colors'
3
+
4
+ // Helpers
5
+ type Expand<T> = T extends object
6
+ ? T extends infer O
7
+ ? { [K in keyof O]: Expand<O[K]> }
8
+ : never
9
+ : T
10
+ type KeyValuePair<K extends keyof any = string, V = string> = Record<K, V>
11
+ interface RecursiveKeyValuePair<K extends keyof any = string, V = string> {
12
+ [key: string]: V | RecursiveKeyValuePair<K, V>
13
+ }
14
+ type ResolvableTo<T> = T | ((utils: PluginUtils) => T)
15
+
16
+ interface PluginUtils {
17
+ colors: DefaultColors
18
+ theme(path: string, defaultValue?: unknown): any
19
+ breakpoints<I = Record<string, unknown>, O = I>(arg: I): O
20
+ rgb(arg: string): (arg: Partial<{ opacityVariable: string; opacityValue: number }>) => string
21
+ hsl(arg: string): (arg: Partial<{ opacityVariable: string; opacityValue: number }>) => string
22
+ }
23
+
24
+ // Content related config
25
+ type FilePath = string
26
+ type RawFile = { raw: string; extension?: string }
27
+ type ExtractorFn = (content: string) => string[]
28
+ type TransformerFn = (content: string) => string
29
+ type ContentConfig =
30
+ | (FilePath | RawFile)[]
31
+ | {
32
+ files: (FilePath | RawFile)[]
33
+ extract?: ExtractorFn | { [extension: string]: ExtractorFn }
34
+ transform?: TransformerFn | { [extension: string]: TransformerFn }
35
+ }
36
+
37
+ // Important related config
38
+ type ImportantConfig = boolean | string
39
+
40
+ // Prefix related config
41
+ type PrefixConfig = string
42
+
43
+ // Separator related config
44
+ type SeparatorConfig = string
45
+
46
+ // Safelist related config
47
+ type SafelistConfig =
48
+ | string[]
49
+ | {
50
+ pattern: RegExp
51
+ variants: string[]
52
+ }[]
53
+
54
+ // Presets related config
55
+ type PresetsConfig = Config[]
56
+
57
+ // Future related config
58
+ type FutureConfigValues = never // Replace with 'future-feature-1' | 'future-feature-2'
59
+ type FutureConfig = Expand<'all' | Partial<Record<FutureConfigValues, boolean>>> | []
60
+
61
+ // Experimental related config
62
+ type ExperimentalConfigValues = 'optimizeUniversalDefaults' // Replace with 'experimental-feature-1' | 'experimental-feature-2'
63
+ type ExperimentalConfig = Expand<'all' | Partial<Record<ExperimentalConfigValues, boolean>>> | []
64
+
65
+ // DarkMode related config
66
+ type DarkModeConfig =
67
+ // Use the `media` query strategy.
68
+ | 'media'
69
+ // Use the `class` stategy, which requires a `.dark` class on the `html`.
70
+ | 'class'
71
+ // Use the `class` stategy with a custom class instead of `.dark`.
72
+ | ['class', string]
73
+
74
+ type Screen = { raw: string } | { min: string } | { max: string } | { min: string; max: string }
75
+ type ScreensConfig = string[] | KeyValuePair<string, string | Screen | Screen[]>
76
+
77
+ // Theme related config
78
+ interface ThemeConfig {
79
+ // Responsiveness
80
+ screens: ResolvableTo<ScreensConfig>
81
+
82
+ // Reusable base configs
83
+ colors: ResolvableTo<RecursiveKeyValuePair>
84
+ spacing: ResolvableTo<KeyValuePair>
85
+
86
+ // Components
87
+ container: ResolvableTo<
88
+ Partial<{
89
+ screens: ScreensConfig
90
+ center: boolean
91
+ padding: string | Record<string, string>
92
+ }>
93
+ >
94
+
95
+ // Utilities
96
+ inset: ThemeConfig['spacing']
97
+ zIndex: ResolvableTo<KeyValuePair>
98
+ order: ResolvableTo<KeyValuePair>
99
+ gridColumn: ResolvableTo<KeyValuePair>
100
+ gridColumnStart: ResolvableTo<KeyValuePair>
101
+ gridColumnEnd: ResolvableTo<KeyValuePair>
102
+ gridRow: ResolvableTo<KeyValuePair>
103
+ gridRowStart: ResolvableTo<KeyValuePair>
104
+ gridRowEnd: ResolvableTo<KeyValuePair>
105
+ margin: ThemeConfig['spacing']
106
+ aspectRatio: ResolvableTo<KeyValuePair>
107
+ height: ThemeConfig['spacing']
108
+ maxHeight: ThemeConfig['spacing']
109
+ minHeight: ResolvableTo<KeyValuePair>
110
+ width: ThemeConfig['spacing']
111
+ maxWidth: ResolvableTo<KeyValuePair>
112
+ minWidth: ResolvableTo<KeyValuePair>
113
+ flex: ResolvableTo<KeyValuePair>
114
+ flexShrink: ResolvableTo<KeyValuePair>
115
+ flexGrow: ResolvableTo<KeyValuePair>
116
+ flexBasis: ThemeConfig['spacing']
117
+ borderSpacing: ThemeConfig['spacing']
118
+ transformOrigin: ResolvableTo<KeyValuePair>
119
+ translate: ThemeConfig['spacing']
120
+ rotate: ResolvableTo<KeyValuePair>
121
+ skew: ResolvableTo<KeyValuePair>
122
+ scale: ResolvableTo<KeyValuePair>
123
+ animation: ResolvableTo<KeyValuePair>
124
+ keyframes: ResolvableTo<KeyValuePair<string, KeyValuePair<string, KeyValuePair>>>
125
+ cursor: ResolvableTo<KeyValuePair>
126
+ scrollMargin: ThemeConfig['spacing']
127
+ scrollPadding: ThemeConfig['spacing']
128
+ listStyleType: ResolvableTo<KeyValuePair>
129
+ columns: ResolvableTo<KeyValuePair>
130
+ gridAutoColumns: ResolvableTo<KeyValuePair>
131
+ gridAutoRows: ResolvableTo<KeyValuePair>
132
+ gridTemplateColumns: ResolvableTo<KeyValuePair>
133
+ gridTemplateRows: ResolvableTo<KeyValuePair>
134
+ gap: ThemeConfig['spacing']
135
+ space: ThemeConfig['spacing']
136
+ divideWidth: ThemeConfig['borderWidth']
137
+ divideColor: ThemeConfig['borderColor']
138
+ divideOpacity: ThemeConfig['borderOpacity']
139
+ borderRadius: ResolvableTo<KeyValuePair>
140
+ borderWidth: ResolvableTo<KeyValuePair>
141
+ borderColor: ThemeConfig['colors']
142
+ borderOpacity: ThemeConfig['opacity']
143
+ backgroundColor: ThemeConfig['colors']
144
+ backgroundOpacity: ThemeConfig['opacity']
145
+ backgroundImage: ResolvableTo<KeyValuePair>
146
+ gradientColorStops: ThemeConfig['colors']
147
+ backgroundSize: ResolvableTo<KeyValuePair>
148
+ backgroundPosition: ResolvableTo<KeyValuePair>
149
+ fill: ThemeConfig['colors']
150
+ stroke: ThemeConfig['colors']
151
+ strokeWidth: ResolvableTo<KeyValuePair>
152
+ objectPosition: ResolvableTo<KeyValuePair>
153
+ padding: ThemeConfig['spacing']
154
+ textIndent: ThemeConfig['spacing']
155
+ fontFamily: ResolvableTo<KeyValuePair<string, string[]>>
156
+ fontSize: ResolvableTo<
157
+ KeyValuePair<
158
+ string,
159
+ | string
160
+ | [fontSize: string, lineHeight: string]
161
+ | [
162
+ fontSize: string,
163
+ configuration: Partial<{
164
+ lineHeight: string
165
+ letterSpacing: string
166
+ }>
167
+ ]
168
+ >
169
+ >
170
+ fontWeight: ResolvableTo<KeyValuePair>
171
+ lineHeight: ResolvableTo<KeyValuePair>
172
+ letterSpacing: ResolvableTo<KeyValuePair>
173
+ textColor: ThemeConfig['colors']
174
+ textOpacity: ThemeConfig['opacity']
175
+ textDecorationColor: ThemeConfig['colors']
176
+ textDecorationThickness: ResolvableTo<KeyValuePair>
177
+ textUnderlineOffset: ResolvableTo<KeyValuePair>
178
+ placeholderColor: ThemeConfig['colors']
179
+ placeholderOpacity: ThemeConfig['opacity']
180
+ caretColor: ThemeConfig['colors']
181
+ accentColor: ThemeConfig['colors']
182
+ opacity: ResolvableTo<KeyValuePair>
183
+ boxShadow: ResolvableTo<KeyValuePair>
184
+ boxShadowColor: ThemeConfig['colors']
185
+ outlineWidth: ResolvableTo<KeyValuePair>
186
+ outlineOffset: ResolvableTo<KeyValuePair>
187
+ outlineColor: ThemeConfig['colors']
188
+ ringWidth: ResolvableTo<KeyValuePair>
189
+ ringColor: ThemeConfig['colors']
190
+ ringOpacity: ThemeConfig['opacity']
191
+ ringOffsetWidth: ResolvableTo<KeyValuePair>
192
+ ringOffsetColor: ThemeConfig['colors']
193
+ blur: ResolvableTo<KeyValuePair>
194
+ brightness: ResolvableTo<KeyValuePair>
195
+ contrast: ResolvableTo<KeyValuePair>
196
+ dropShadow: ResolvableTo<KeyValuePair>
197
+ grayscale: ResolvableTo<KeyValuePair>
198
+ hueRotate: ResolvableTo<KeyValuePair>
199
+ invert: ResolvableTo<KeyValuePair>
200
+ saturate: ResolvableTo<KeyValuePair>
201
+ sepia: ResolvableTo<KeyValuePair>
202
+ backdropBlur: ThemeConfig['blur']
203
+ backdropBrightness: ThemeConfig['brightness']
204
+ backdropContrast: ThemeConfig['contrast']
205
+ backdropGrayscale: ThemeConfig['grayscale']
206
+ backdropHueRotate: ThemeConfig['hueRotate']
207
+ backdropInvert: ThemeConfig['invert']
208
+ backdropOpacity: ThemeConfig['opacity']
209
+ backdropSaturate: ThemeConfig['saturate']
210
+ backdropSepia: ThemeConfig['sepia']
211
+ transitionProperty: ResolvableTo<KeyValuePair>
212
+ transitionTimingFunction: ResolvableTo<KeyValuePair>
213
+ transitionDelay: ResolvableTo<KeyValuePair>
214
+ transitionDuration: ResolvableTo<KeyValuePair>
215
+ willChange: ResolvableTo<KeyValuePair>
216
+ content: ResolvableTo<KeyValuePair>
217
+
218
+ // Custom
219
+ [key: string]: any
220
+ }
221
+
222
+ // Core plugins related config
223
+ type CorePluginsConfig = CorePluginList[] | Expand<Partial<Record<CorePluginList, boolean>>>
224
+
225
+ // Plugins related config
226
+ type ValueType =
227
+ | 'any'
228
+ | 'color'
229
+ | 'url'
230
+ | 'image'
231
+ | 'length'
232
+ | 'percentage'
233
+ | 'position'
234
+ | 'lookup'
235
+ | 'generic-name'
236
+ | 'family-name'
237
+ | 'number'
238
+ | 'line-width'
239
+ | 'absolute-size'
240
+ | 'relative-size'
241
+ | 'shadow'
242
+ export interface PluginAPI {
243
+ // for registering new static utility styles
244
+ addUtilities(
245
+ utilities: RecursiveKeyValuePair | RecursiveKeyValuePair[],
246
+ options?: Partial<{
247
+ respectPrefix: boolean
248
+ respectImportant: boolean
249
+ }>
250
+ ): void
251
+ // for registering new dynamic utility styles
252
+ matchUtilities<T>(
253
+ utilities: KeyValuePair<string, (value: T) => RecursiveKeyValuePair>,
254
+ options?: Partial<{
255
+ respectPrefix: boolean
256
+ respectImportant: boolean
257
+ type: ValueType | ValueType[]
258
+ values: KeyValuePair<string, T>
259
+ supportsNegativeValues: boolean
260
+ }>
261
+ ): void
262
+ // for registering new static component styles
263
+ addComponents(
264
+ components: RecursiveKeyValuePair | RecursiveKeyValuePair[],
265
+ options?: Partial<{
266
+ respectPrefix: boolean
267
+ respectImportant: boolean
268
+ }>
269
+ ): void
270
+ // for registering new dynamic component styles
271
+ matchComponents<T>(
272
+ components: KeyValuePair<string, (value: T) => RecursiveKeyValuePair>,
273
+ options?: Partial<{
274
+ respectPrefix: boolean
275
+ respectImportant: boolean
276
+ type: ValueType | ValueType[]
277
+ values: KeyValuePair<string, T>
278
+ supportsNegativeValues: boolean
279
+ }>
280
+ ): void
281
+ // for registering new base styles
282
+ addBase(base: RecursiveKeyValuePair | RecursiveKeyValuePair[]): void
283
+ // for registering custom variants
284
+ addVariant(name: string, definition: string | string[] | (() => string) | (() => string)[]): void
285
+ // for looking up values in the user’s theme configuration
286
+ theme: <TDefaultValue = Config['theme']>(
287
+ path?: string,
288
+ defaultValue?: TDefaultValue
289
+ ) => TDefaultValue
290
+ // for looking up values in the user’s Tailwind configuration
291
+ config: <TDefaultValue = Config>(path?: string, defaultValue?: TDefaultValue) => TDefaultValue
292
+ // for checking if a core plugin is enabled
293
+ corePlugins(path: string): boolean
294
+ // for manually escaping strings meant to be used in class names
295
+ e: (className: string) => string
296
+ }
297
+ export type PluginCreator = (api: PluginAPI) => void
298
+ export type PluginsConfig = (
299
+ | PluginCreator
300
+ | { handler: PluginCreator; config?: Config }
301
+ | { (options: any): { handler: PluginCreator; config?: Config }; __isOptionsFunction: true }
302
+ )[]
303
+
304
+ // Top level config related
305
+ interface RequiredConfig {
306
+ content: ContentConfig
307
+ }
308
+
309
+ interface OptionalConfig {
310
+ important: Partial<ImportantConfig>
311
+ prefix: Partial<PrefixConfig>
312
+ separator: Partial<SeparatorConfig>
313
+ safelist: Partial<SafelistConfig>
314
+ presets: Partial<PresetsConfig>
315
+ future: Partial<FutureConfig>
316
+ experimental: Partial<ExperimentalConfig>
317
+ darkMode: Partial<DarkModeConfig>
318
+ theme: Partial<ThemeConfig & { extend: Partial<ThemeConfig> }>
319
+ corePlugins: Partial<CorePluginsConfig>
320
+ plugins: Partial<PluginsConfig>
321
+ // Custom
322
+ [key: string]: any
323
+ }
324
+
325
+ export type Config = RequiredConfig & Partial<OptionalConfig>
File without changes