tailwindcss 3.0.0-alpha.1 → 3.0.2

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 (73) hide show
  1. package/colors.js +2 -1
  2. package/defaultConfig.js +2 -1
  3. package/defaultTheme.js +2 -1
  4. package/lib/cli.js +39 -35
  5. package/lib/constants.js +1 -1
  6. package/lib/corePluginList.js +10 -1
  7. package/lib/corePlugins.js +393 -259
  8. package/lib/css/preflight.css +14 -1
  9. package/lib/featureFlags.js +12 -7
  10. package/lib/lib/collapseDuplicateDeclarations.js +29 -0
  11. package/lib/lib/detectNesting.js +17 -2
  12. package/lib/lib/evaluateTailwindFunctions.js +9 -5
  13. package/lib/lib/expandApplyAtRules.js +26 -9
  14. package/lib/lib/expandTailwindAtRules.js +4 -1
  15. package/lib/lib/generateRules.js +151 -19
  16. package/lib/lib/resolveDefaultsAtRules.js +67 -56
  17. package/lib/lib/setupContextUtils.js +80 -80
  18. package/lib/lib/setupWatchingContext.js +5 -1
  19. package/lib/lib/sharedState.js +2 -2
  20. package/lib/lib/substituteScreenAtRules.js +7 -4
  21. package/lib/processTailwindFeatures.js +4 -0
  22. package/lib/util/buildMediaQuery.js +13 -24
  23. package/lib/util/createUtilityPlugin.js +5 -5
  24. package/lib/util/dataTypes.js +38 -7
  25. package/lib/util/formatVariantSelector.js +186 -0
  26. package/lib/util/isValidArbitraryValue.js +64 -0
  27. package/lib/util/nameClass.js +2 -1
  28. package/lib/util/negateValue.js +3 -1
  29. package/lib/util/normalizeConfig.js +22 -8
  30. package/lib/util/normalizeScreens.js +61 -0
  31. package/lib/util/parseBoxShadowValue.js +77 -0
  32. package/lib/util/pluginUtils.js +62 -158
  33. package/lib/util/prefixSelector.js +1 -3
  34. package/lib/util/resolveConfig.js +17 -13
  35. package/lib/util/transformThemeValue.js +23 -13
  36. package/package.json +15 -15
  37. package/peers/index.js +4456 -5450
  38. package/plugin.js +2 -1
  39. package/resolveConfig.js +2 -1
  40. package/src/.DS_Store +0 -0
  41. package/src/cli.js +9 -2
  42. package/src/corePluginList.js +1 -1
  43. package/src/corePlugins.js +392 -404
  44. package/src/css/preflight.css +14 -1
  45. package/src/featureFlags.js +14 -4
  46. package/src/lib/collapseDuplicateDeclarations.js +28 -0
  47. package/src/lib/detectNesting.js +22 -3
  48. package/src/lib/evaluateTailwindFunctions.js +5 -2
  49. package/src/lib/expandApplyAtRules.js +29 -2
  50. package/src/lib/expandTailwindAtRules.js +5 -2
  51. package/src/lib/generateRules.js +155 -11
  52. package/src/lib/resolveDefaultsAtRules.js +67 -50
  53. package/src/lib/setupContextUtils.js +77 -67
  54. package/src/lib/setupWatchingContext.js +7 -0
  55. package/src/lib/sharedState.js +1 -1
  56. package/src/lib/substituteScreenAtRules.js +6 -3
  57. package/src/processTailwindFeatures.js +5 -0
  58. package/src/util/buildMediaQuery.js +14 -18
  59. package/src/util/createUtilityPlugin.js +2 -2
  60. package/src/util/dataTypes.js +43 -11
  61. package/src/util/formatVariantSelector.js +196 -0
  62. package/src/util/isValidArbitraryValue.js +61 -0
  63. package/src/util/nameClass.js +2 -2
  64. package/src/util/negateValue.js +4 -2
  65. package/src/util/normalizeConfig.js +17 -1
  66. package/src/util/normalizeScreens.js +45 -0
  67. package/src/util/parseBoxShadowValue.js +71 -0
  68. package/src/util/pluginUtils.js +50 -146
  69. package/src/util/prefixSelector.js +1 -4
  70. package/src/util/resolveConfig.js +7 -1
  71. package/src/util/transformThemeValue.js +22 -7
  72. package/stubs/defaultConfig.stub.js +118 -58
  73. package/CHANGELOG.md +0 -1759
@@ -1,130 +1,63 @@
1
1
  import fs from 'fs'
2
+ import * as path from 'path'
2
3
  import postcss from 'postcss'
3
4
  import createUtilityPlugin from './util/createUtilityPlugin'
4
5
  import buildMediaQuery from './util/buildMediaQuery'
5
- import prefixSelector from './util/prefixSelector'
6
6
  import parseAnimationValue from './util/parseAnimationValue'
7
7
  import flattenColorPalette from './util/flattenColorPalette'
8
8
  import withAlphaVariable, { withAlphaValue } from './util/withAlphaVariable'
9
9
  import toColorValue from './util/toColorValue'
10
10
  import isPlainObject from './util/isPlainObject'
11
11
  import transformThemeValue from './util/transformThemeValue'
12
- import {
13
- applyStateToMarker,
14
- updateLastClasses,
15
- updateAllClasses,
16
- transformAllSelectors,
17
- transformAllClasses,
18
- transformLastClasses,
19
- } from './util/pluginUtils'
20
12
  import { version as tailwindVersion } from '../package.json'
21
13
  import log from './util/log'
14
+ import { normalizeScreens } from './util/normalizeScreens'
15
+ import { formatBoxShadowValue, parseBoxShadowValue } from './util/parseBoxShadowValue'
22
16
 
23
17
  export let variantPlugins = {
24
- pseudoElementVariants: ({ config, addVariant }) => {
25
- addVariant(
26
- 'first-letter',
27
- transformAllSelectors((selector) => {
28
- return updateAllClasses(selector, (className, { withPseudo }) => {
29
- return withPseudo(`first-letter${config('separator')}${className}`, '::first-letter')
30
- })
31
- })
32
- )
18
+ pseudoElementVariants: ({ addVariant }) => {
19
+ addVariant('first-letter', '&::first-letter')
20
+ addVariant('first-line', '&::first-line')
33
21
 
34
- addVariant(
35
- 'first-line',
36
- transformAllSelectors((selector) => {
37
- return updateAllClasses(selector, (className, { withPseudo }) => {
38
- return withPseudo(`first-line${config('separator')}${className}`, '::first-line')
39
- })
40
- })
41
- )
22
+ addVariant('marker', ['& *::marker', '&::marker'])
23
+ addVariant('selection', ['& *::selection', '&::selection'])
42
24
 
43
- addVariant('marker', [
44
- transformAllSelectors((selector) => {
45
- let variantSelector = updateAllClasses(selector, (className) => {
46
- return `marker${config('separator')}${className}`
47
- })
25
+ addVariant('file', '&::file-selector-button')
48
26
 
49
- return `${variantSelector} *::marker`
50
- }),
51
- transformAllSelectors((selector) => {
52
- return updateAllClasses(selector, (className, { withPseudo }) => {
53
- return withPseudo(`marker${config('separator')}${className}`, '::marker')
54
- })
55
- }),
56
- ])
27
+ addVariant('placeholder', '&::placeholder')
57
28
 
58
- addVariant('selection', [
59
- transformAllSelectors((selector) => {
60
- let variantSelector = updateAllClasses(selector, (className) => {
61
- return `selection${config('separator')}${className}`
29
+ addVariant('before', ({ container }) => {
30
+ container.walkRules((rule) => {
31
+ let foundContent = false
32
+ rule.walkDecls('content', () => {
33
+ foundContent = true
62
34
  })
63
35
 
64
- return `${variantSelector} *::selection`
65
- }),
66
- transformAllSelectors((selector) => {
67
- return updateAllClasses(selector, (className, { withPseudo }) => {
68
- return withPseudo(`selection${config('separator')}${className}`, '::selection')
69
- })
70
- }),
71
- ])
36
+ if (!foundContent) {
37
+ rule.prepend(postcss.decl({ prop: 'content', value: 'var(--tw-content)' }))
38
+ }
39
+ })
72
40
 
73
- addVariant(
74
- 'file',
75
- transformAllSelectors((selector) => {
76
- return updateAllClasses(selector, (className, { withPseudo }) => {
77
- return withPseudo(`file${config('separator')}${className}`, '::file-selector-button')
41
+ return '&::before'
42
+ })
43
+
44
+ addVariant('after', ({ container }) => {
45
+ container.walkRules((rule) => {
46
+ let foundContent = false
47
+ rule.walkDecls('content', () => {
48
+ foundContent = true
78
49
  })
79
- })
80
- )
81
50
 
82
- addVariant(
83
- 'before',
84
- transformAllSelectors(
85
- (selector) => {
86
- return updateAllClasses(selector, (className, { withPseudo }) => {
87
- return withPseudo(`before${config('separator')}${className}`, '::before')
88
- })
89
- },
90
- {
91
- withRule: (rule) => {
92
- let foundContent = false
93
- rule.walkDecls('content', () => {
94
- foundContent = true
95
- })
96
- if (!foundContent) {
97
- rule.prepend(postcss.decl({ prop: 'content', value: '""' }))
98
- }
99
- },
51
+ if (!foundContent) {
52
+ rule.prepend(postcss.decl({ prop: 'content', value: 'var(--tw-content)' }))
100
53
  }
101
- )
102
- )
54
+ })
103
55
 
104
- addVariant(
105
- 'after',
106
- transformAllSelectors(
107
- (selector) => {
108
- return updateAllClasses(selector, (className, { withPseudo }) => {
109
- return withPseudo(`after${config('separator')}${className}`, '::after')
110
- })
111
- },
112
- {
113
- withRule: (rule) => {
114
- let foundContent = false
115
- rule.walkDecls('content', () => {
116
- foundContent = true
117
- })
118
- if (!foundContent) {
119
- rule.prepend(postcss.decl({ prop: 'content', value: '""' }))
120
- }
121
- },
122
- }
123
- )
124
- )
56
+ return '&::after'
57
+ })
125
58
  },
126
59
 
127
- pseudoClassVariants: ({ config, addVariant }) => {
60
+ pseudoClassVariants: ({ addVariant }) => {
128
61
  let pseudoVariants = [
129
62
  // Positional
130
63
  ['first', ':first-child'],
@@ -164,137 +97,44 @@ export let variantPlugins = {
164
97
  'focus-visible',
165
98
  'active',
166
99
  'disabled',
167
- ]
168
-
169
- for (let variant of pseudoVariants) {
170
- let [variantName, state] = Array.isArray(variant) ? variant : [variant, `:${variant}`]
171
-
172
- addVariant(
173
- variantName,
174
- transformAllClasses((className, { withAttr, withPseudo }) => {
175
- if (state.startsWith(':')) {
176
- return withPseudo(`${variantName}${config('separator')}${className}`, state)
177
- } else if (state.startsWith('[')) {
178
- return withAttr(`${variantName}${config('separator')}${className}`, state)
179
- }
180
- })
181
- )
182
- }
183
-
184
- let groupMarker = prefixSelector(config('prefix'), '.group')
185
- for (let variant of pseudoVariants) {
186
- let [variantName, state] = Array.isArray(variant) ? variant : [variant, `:${variant}`]
187
- let groupVariantName = `group-${variantName}`
188
-
189
- addVariant(
190
- groupVariantName,
191
- transformAllSelectors((selector) => {
192
- let variantSelector = updateAllClasses(selector, (className) => {
193
- if (`.${className}` === groupMarker) return className
194
- return `${groupVariantName}${config('separator')}${className}`
195
- })
196
-
197
- if (variantSelector === selector) {
198
- return null
199
- }
100
+ ].map((variant) => (Array.isArray(variant) ? variant : [variant, `:${variant}`]))
200
101
 
201
- return applyStateToMarker(
202
- variantSelector,
203
- groupMarker,
204
- state,
205
- (marker, selector) => `${marker} ${selector}`
206
- )
207
- })
208
- )
102
+ for (let [variantName, state] of pseudoVariants) {
103
+ addVariant(variantName, `&${state}`)
209
104
  }
210
105
 
211
- let peerMarker = prefixSelector(config('prefix'), '.peer')
212
- for (let variant of pseudoVariants) {
213
- let [variantName, state] = Array.isArray(variant) ? variant : [variant, `:${variant}`]
214
- let peerVariantName = `peer-${variantName}`
215
-
216
- addVariant(
217
- peerVariantName,
218
- transformAllSelectors((selector) => {
219
- let variantSelector = updateAllClasses(selector, (className) => {
220
- if (`.${className}` === peerMarker) return className
221
- return `${peerVariantName}${config('separator')}${className}`
222
- })
223
-
224
- if (variantSelector === selector) {
225
- return null
226
- }
106
+ for (let [variantName, state] of pseudoVariants) {
107
+ addVariant(`group-${variantName}`, `:merge(.group)${state} &`)
108
+ }
227
109
 
228
- return applyStateToMarker(variantSelector, peerMarker, state, (marker, selector) =>
229
- selector.trim().startsWith('~') ? `${marker}${selector}` : `${marker} ~ ${selector}`
230
- )
231
- })
232
- )
110
+ for (let [variantName, state] of pseudoVariants) {
111
+ addVariant(`peer-${variantName}`, `:merge(.peer)${state} ~ &`)
233
112
  }
234
113
  },
235
114
 
236
- directionVariants: ({ config, addVariant }) => {
237
- addVariant(
238
- 'ltr',
239
- transformAllSelectors((selector) => {
240
- log.warn('rtl-experimental', [
241
- 'The RTL features in Tailwind CSS are currently in preview.',
242
- 'Preview features are not covered by semver, and may be improved in breaking ways at any time.',
243
- ])
244
- return `[dir="ltr"] ${updateAllClasses(
245
- selector,
246
- (className) => `ltr${config('separator')}${className}`
247
- )}`
248
- })
249
- )
115
+ directionVariants: ({ addVariant }) => {
116
+ addVariant('ltr', () => {
117
+ log.warn('rtl-experimental', [
118
+ 'The RTL features in Tailwind CSS are currently in preview.',
119
+ 'Preview features are not covered by semver, and may be improved in breaking ways at any time.',
120
+ ])
250
121
 
251
- addVariant(
252
- 'rtl',
253
- transformAllSelectors((selector) => {
254
- log.warn('rtl-experimental', [
255
- 'The RTL features in Tailwind CSS are currently in preview.',
256
- 'Preview features are not covered by semver, and may be improved in breaking ways at any time.',
257
- ])
258
- return `[dir="rtl"] ${updateAllClasses(
259
- selector,
260
- (className) => `rtl${config('separator')}${className}`
261
- )}`
262
- })
263
- )
264
- },
122
+ return '[dir="ltr"] &'
123
+ })
265
124
 
266
- reducedMotionVariants: ({ config, addVariant }) => {
267
- addVariant(
268
- 'motion-safe',
269
- transformLastClasses(
270
- (className) => {
271
- return `motion-safe${config('separator')}${className}`
272
- },
273
- {
274
- wrap: () =>
275
- postcss.atRule({
276
- name: 'media',
277
- params: '(prefers-reduced-motion: no-preference)',
278
- }),
279
- }
280
- )
281
- )
125
+ addVariant('rtl', () => {
126
+ log.warn('rtl-experimental', [
127
+ 'The RTL features in Tailwind CSS are currently in preview.',
128
+ 'Preview features are not covered by semver, and may be improved in breaking ways at any time.',
129
+ ])
282
130
 
283
- addVariant(
284
- 'motion-reduce',
285
- transformLastClasses(
286
- (className) => {
287
- return `motion-reduce${config('separator')}${className}`
288
- },
289
- {
290
- wrap: () =>
291
- postcss.atRule({
292
- name: 'media',
293
- params: '(prefers-reduced-motion: reduce)',
294
- }),
295
- }
296
- )
297
- )
131
+ return '[dir="rtl"] &'
132
+ })
133
+ },
134
+
135
+ reducedMotionVariants: ({ addVariant }) => {
136
+ addVariant('motion-safe', '@media (prefers-reduced-motion: no-preference)')
137
+ addVariant('motion-reduce', '@media (prefers-reduced-motion: reduce)')
298
138
  },
299
139
 
300
140
  darkVariants: ({ config, addVariant }) => {
@@ -308,62 +148,35 @@ export let variantPlugins = {
308
148
  }
309
149
 
310
150
  if (mode === 'class') {
311
- addVariant(
312
- 'dark',
313
- transformAllSelectors((selector) => {
314
- let variantSelector = updateLastClasses(selector, (className) => {
315
- return `dark${config('separator')}${className}`
316
- })
317
-
318
- if (variantSelector === selector) {
319
- return null
320
- }
321
-
322
- let darkSelector = prefixSelector(config('prefix'), `.dark`)
323
-
324
- return `${darkSelector} ${variantSelector}`
325
- })
326
- )
151
+ addVariant('dark', '.dark &')
327
152
  } else if (mode === 'media') {
328
- addVariant(
329
- 'dark',
330
- transformLastClasses(
331
- (className) => {
332
- return `dark${config('separator')}${className}`
333
- },
334
- {
335
- wrap: () =>
336
- postcss.atRule({
337
- name: 'media',
338
- params: '(prefers-color-scheme: dark)',
339
- }),
340
- }
341
- )
342
- )
153
+ addVariant('dark', '@media (prefers-color-scheme: dark)')
343
154
  }
344
155
  },
345
156
 
346
- screenVariants: ({ config, theme, addVariant }) => {
347
- for (let screen in theme('screens')) {
348
- let size = theme('screens')[screen]
349
- let query = buildMediaQuery(size)
157
+ printVariant: ({ addVariant }) => {
158
+ addVariant('print', '@media print')
159
+ },
160
+
161
+ screenVariants: ({ theme, addVariant }) => {
162
+ for (let screen of normalizeScreens(theme('screens'))) {
163
+ let query = buildMediaQuery(screen)
350
164
 
351
- addVariant(
352
- screen,
353
- transformLastClasses(
354
- (className) => {
355
- return `${screen}${config('separator')}${className}`
356
- },
357
- { wrap: () => postcss.atRule({ name: 'media', params: query }) }
358
- )
359
- )
165
+ addVariant(screen.name, `@media ${query}`)
360
166
  }
361
167
  },
168
+
169
+ orientationVariants: ({ addVariant }) => {
170
+ addVariant('portrait', '@media (orientation: portrait)')
171
+ addVariant('landscape', '@media (orientation: landscape)')
172
+ },
362
173
  }
363
174
 
364
175
  export let corePlugins = {
365
176
  preflight: ({ addBase }) => {
366
- let preflightStyles = postcss.parse(fs.readFileSync(`${__dirname}/css/preflight.css`, 'utf8'))
177
+ let preflightStyles = postcss.parse(
178
+ fs.readFileSync(path.join(__dirname, './css/preflight.css'), 'utf8')
179
+ )
367
180
 
368
181
  addBase([
369
182
  postcss.comment({
@@ -374,24 +187,10 @@ export let corePlugins = {
374
187
  },
375
188
 
376
189
  container: (() => {
377
- function extractMinWidths(breakpoints) {
378
- return Object.values(breakpoints ?? {}).flatMap((breakpoints) => {
379
- if (typeof breakpoints === 'string') {
380
- breakpoints = { min: breakpoints }
381
- }
382
-
383
- if (!Array.isArray(breakpoints)) {
384
- breakpoints = [breakpoints]
385
- }
386
-
387
- return breakpoints
388
- .filter((breakpoint) => {
389
- return breakpoint?.hasOwnProperty?.('min') || breakpoint?.hasOwnProperty('min-width')
390
- })
391
- .map((breakpoint) => {
392
- return breakpoint['min-width'] ?? breakpoint.min
393
- })
394
- })
190
+ function extractMinWidths(breakpoints = []) {
191
+ return breakpoints
192
+ .flatMap((breakpoint) => breakpoint.values.map((breakpoint) => breakpoint.min))
193
+ .filter((v) => v !== undefined)
395
194
  }
396
195
 
397
196
  function mapMinWidthsToPadding(minWidths, screens, paddings) {
@@ -420,16 +219,11 @@ export let corePlugins = {
420
219
  }
421
220
 
422
221
  for (let minWidth of minWidths) {
423
- for (let [screen, value] of Object.entries(screens)) {
424
- let screenMinWidth =
425
- typeof value === 'object' && value !== null ? value.min || value['min-width'] : value
426
-
427
- if (`${screenMinWidth}` === `${minWidth}`) {
428
- mapping.push({
429
- screen,
430
- minWidth,
431
- padding: paddings[screen],
432
- })
222
+ for (let screen of screens) {
223
+ for (let { min } of screen.values) {
224
+ if (min === minWidth) {
225
+ mapping.push({ minWidth, padding: paddings[screen.name] })
226
+ }
433
227
  }
434
228
  }
435
229
  }
@@ -438,12 +232,12 @@ export let corePlugins = {
438
232
  }
439
233
 
440
234
  return function ({ addComponents, theme }) {
441
- let screens = theme('container.screens', theme('screens'))
235
+ let screens = normalizeScreens(theme('container.screens', theme('screens')))
442
236
  let minWidths = extractMinWidths(screens)
443
237
  let paddings = mapMinWidthsToPadding(minWidths, screens, theme('container.padding'))
444
238
 
445
239
  let generatePaddingFor = (minWidth) => {
446
- let paddingConfig = paddings.find((padding) => `${padding.minWidth}` === `${minWidth}`)
240
+ let paddingConfig = paddings.find((padding) => padding.minWidth === minWidth)
447
241
 
448
242
  if (!paddingConfig) {
449
243
  return {}
@@ -529,19 +323,23 @@ export let corePlugins = {
529
323
  })
530
324
  },
531
325
 
532
- inset: createUtilityPlugin('inset', [
533
- ['inset', ['top', 'right', 'bottom', 'left']],
534
- [
535
- ['inset-x', ['left', 'right']],
536
- ['inset-y', ['top', 'bottom']],
537
- ],
326
+ inset: createUtilityPlugin(
327
+ 'inset',
538
328
  [
539
- ['top', ['top']],
540
- ['right', ['right']],
541
- ['bottom', ['bottom']],
542
- ['left', ['left']],
329
+ ['inset', ['top', 'right', 'bottom', 'left']],
330
+ [
331
+ ['inset-x', ['left', 'right']],
332
+ ['inset-y', ['top', 'bottom']],
333
+ ],
334
+ [
335
+ ['top', ['top']],
336
+ ['right', ['right']],
337
+ ['bottom', ['bottom']],
338
+ ['left', ['left']],
339
+ ],
543
340
  ],
544
- ]),
341
+ { supportsNegativeValues: true }
342
+ ),
545
343
 
546
344
  isolation: ({ addUtilities }) => {
547
345
  addUtilities({
@@ -550,8 +348,8 @@ export let corePlugins = {
550
348
  })
551
349
  },
552
350
 
553
- zIndex: createUtilityPlugin('zIndex', [['z', ['zIndex']]]),
554
- order: createUtilityPlugin('order'),
351
+ zIndex: createUtilityPlugin('zIndex', [['z', ['zIndex']]], { supportsNegativeValues: true }),
352
+ order: createUtilityPlugin('order', undefined, { supportsNegativeValues: true }),
555
353
  gridColumn: createUtilityPlugin('gridColumn', [['col', ['gridColumn']]]),
556
354
  gridColumnStart: createUtilityPlugin('gridColumnStart', [['col-start', ['gridColumnStart']]]),
557
355
  gridColumnEnd: createUtilityPlugin('gridColumnEnd', [['col-end', ['gridColumnEnd']]]),
@@ -576,19 +374,23 @@ export let corePlugins = {
576
374
  })
577
375
  },
578
376
 
579
- margin: createUtilityPlugin('margin', [
580
- ['m', ['margin']],
581
- [
582
- ['mx', ['margin-left', 'margin-right']],
583
- ['my', ['margin-top', 'margin-bottom']],
584
- ],
377
+ margin: createUtilityPlugin(
378
+ 'margin',
585
379
  [
586
- ['mt', ['margin-top']],
587
- ['mr', ['margin-right']],
588
- ['mb', ['margin-bottom']],
589
- ['ml', ['margin-left']],
380
+ ['m', ['margin']],
381
+ [
382
+ ['mx', ['margin-left', 'margin-right']],
383
+ ['my', ['margin-top', 'margin-bottom']],
384
+ ],
385
+ [
386
+ ['mt', ['margin-top']],
387
+ ['mr', ['margin-right']],
388
+ ['mb', ['margin-bottom']],
389
+ ['ml', ['margin-left']],
390
+ ],
590
391
  ],
591
- ]),
392
+ { supportsNegativeValues: true }
393
+ ),
592
394
 
593
395
  boxSizing: ({ addUtilities }) => {
594
396
  addUtilities({
@@ -634,8 +436,15 @@ export let corePlugins = {
634
436
  maxWidth: createUtilityPlugin('maxWidth', [['max-w', ['maxWidth']]]),
635
437
 
636
438
  flex: createUtilityPlugin('flex'),
637
- flexShrink: createUtilityPlugin('flexShrink', [['flex-shrink', ['flex-shrink']]]),
638
- flexGrow: createUtilityPlugin('flexGrow', [['flex-grow', ['flex-grow']]]),
439
+ flexShrink: createUtilityPlugin('flexShrink', [
440
+ ['flex-shrink', ['flex-shrink']], // Deprecated
441
+ ['shrink', ['flex-shrink']],
442
+ ]),
443
+ flexGrow: createUtilityPlugin('flexGrow', [
444
+ ['flex-grow', ['flex-grow']], // Deprecated
445
+ ['grow', ['flex-grow']],
446
+ ]),
447
+ flexBasis: createUtilityPlugin('flexBasis', [['basis', ['flex-basis']]]),
639
448
 
640
449
  tableLayout: ({ addUtilities }) => {
641
450
  addUtilities({
@@ -652,54 +461,73 @@ export let corePlugins = {
652
461
  },
653
462
 
654
463
  transformOrigin: createUtilityPlugin('transformOrigin', [['origin', ['transformOrigin']]]),
655
- translate: createUtilityPlugin('translate', [
464
+ translate: createUtilityPlugin(
465
+ 'translate',
656
466
  [
657
467
  [
658
- 'translate-x',
659
- [['@defaults transform', {}], '--tw-translate-x', ['transform', 'var(--tw-transform)']],
660
- ],
661
- [
662
- 'translate-y',
663
- [['@defaults transform', {}], '--tw-translate-y', ['transform', 'var(--tw-transform)']],
468
+ [
469
+ 'translate-x',
470
+ [['@defaults transform', {}], '--tw-translate-x', ['transform', 'var(--tw-transform)']],
471
+ ],
472
+ [
473
+ 'translate-y',
474
+ [['@defaults transform', {}], '--tw-translate-y', ['transform', 'var(--tw-transform)']],
475
+ ],
664
476
  ],
665
477
  ],
666
- ]),
667
- rotate: createUtilityPlugin('rotate', [
668
- ['rotate', [['@defaults transform', {}], '--tw-rotate', ['transform', 'var(--tw-transform)']]],
669
- ]),
670
- skew: createUtilityPlugin('skew', [
478
+ { supportsNegativeValues: true }
479
+ ),
480
+ rotate: createUtilityPlugin(
481
+ 'rotate',
671
482
  [
672
483
  [
673
- 'skew-x',
674
- [['@defaults transform', {}], '--tw-skew-x', ['transform', 'var(--tw-transform)']],
675
- ],
676
- [
677
- 'skew-y',
678
- [['@defaults transform', {}], '--tw-skew-y', ['transform', 'var(--tw-transform)']],
484
+ 'rotate',
485
+ [['@defaults transform', {}], '--tw-rotate', ['transform', 'var(--tw-transform)']],
679
486
  ],
680
487
  ],
681
- ]),
682
- scale: createUtilityPlugin('scale', [
488
+ { supportsNegativeValues: true }
489
+ ),
490
+ skew: createUtilityPlugin(
491
+ 'skew',
683
492
  [
684
- 'scale',
685
493
  [
686
- ['@defaults transform', {}],
687
- '--tw-scale-x',
688
- '--tw-scale-y',
689
- ['transform', 'var(--tw-transform)'],
494
+ [
495
+ 'skew-x',
496
+ [['@defaults transform', {}], '--tw-skew-x', ['transform', 'var(--tw-transform)']],
497
+ ],
498
+ [
499
+ 'skew-y',
500
+ [['@defaults transform', {}], '--tw-skew-y', ['transform', 'var(--tw-transform)']],
501
+ ],
690
502
  ],
691
503
  ],
504
+ { supportsNegativeValues: true }
505
+ ),
506
+ scale: createUtilityPlugin(
507
+ 'scale',
692
508
  [
693
509
  [
694
- 'scale-x',
695
- [['@defaults transform', {}], '--tw-scale-x', ['transform', 'var(--tw-transform)']],
510
+ 'scale',
511
+ [
512
+ ['@defaults transform', {}],
513
+ '--tw-scale-x',
514
+ '--tw-scale-y',
515
+ ['transform', 'var(--tw-transform)'],
516
+ ],
696
517
  ],
697
518
  [
698
- 'scale-y',
699
- [['@defaults transform', {}], '--tw-scale-y', ['transform', 'var(--tw-transform)']],
519
+ [
520
+ 'scale-x',
521
+ [['@defaults transform', {}], '--tw-scale-x', ['transform', 'var(--tw-transform)']],
522
+ ],
523
+ [
524
+ 'scale-y',
525
+ [['@defaults transform', {}], '--tw-scale-y', ['transform', 'var(--tw-transform)']],
526
+ ],
700
527
  ],
701
528
  ],
702
- ]),
529
+ { supportsNegativeValues: true }
530
+ ),
703
531
 
704
532
  transform: ({ addBase, addUtilities }) => {
705
533
  addBase({
@@ -783,17 +611,54 @@ export let corePlugins = {
783
611
 
784
612
  cursor: createUtilityPlugin('cursor'),
785
613
 
786
- touchAction: ({ addUtilities }) => {
614
+ touchAction: ({ addBase, addUtilities }) => {
615
+ addBase({
616
+ '@defaults touch-action': {
617
+ '--tw-pan-x': 'var(--tw-empty,/*!*/ /*!*/)',
618
+ '--tw-pan-y': 'var(--tw-empty,/*!*/ /*!*/)',
619
+ '--tw-pinch-zoom': 'var(--tw-empty,/*!*/ /*!*/)',
620
+ '--tw-touch-action': 'var(--tw-pan-x) var(--tw-pan-y) var(--tw-pinch-zoom)',
621
+ },
622
+ })
623
+
787
624
  addUtilities({
788
625
  '.touch-auto': { 'touch-action': 'auto' },
789
626
  '.touch-none': { 'touch-action': 'none' },
790
- '.touch-pan-x': { 'touch-action': 'pan-x' },
791
- '.touch-pan-left': { 'touch-action': 'pan-left' },
792
- '.touch-pan-right': { 'touch-action': 'pan-right' },
793
- '.touch-pan-y': { 'touch-action': 'pan-y' },
794
- '.touch-pan-up': { 'touch-action': 'pan-up' },
795
- '.touch-pan-down': { 'touch-action': 'pan-down' },
796
- '.touch-pinch-zoom': { 'touch-action': 'pinch-zoom' },
627
+ '.touch-pan-x': {
628
+ '@defaults touch-action': {},
629
+ '--tw-pan-x': 'pan-x',
630
+ 'touch-action': 'var(--tw-touch-action)',
631
+ },
632
+ '.touch-pan-left': {
633
+ '@defaults touch-action': {},
634
+ '--tw-pan-x': 'pan-left',
635
+ 'touch-action': 'var(--tw-touch-action)',
636
+ },
637
+ '.touch-pan-right': {
638
+ '@defaults touch-action': {},
639
+ '--tw-pan-x': 'pan-right',
640
+ 'touch-action': 'var(--tw-touch-action)',
641
+ },
642
+ '.touch-pan-y': {
643
+ '@defaults touch-action': {},
644
+ '--tw-pan-y': 'pan-y',
645
+ 'touch-action': 'var(--tw-touch-action)',
646
+ },
647
+ '.touch-pan-up': {
648
+ '@defaults touch-action': {},
649
+ '--tw-pan-y': 'pan-up',
650
+ 'touch-action': 'var(--tw-touch-action)',
651
+ },
652
+ '.touch-pan-down': {
653
+ '@defaults touch-action': {},
654
+ '--tw-pan-y': 'pan-down',
655
+ 'touch-action': 'var(--tw-touch-action)',
656
+ },
657
+ '.touch-pinch-zoom': {
658
+ '@defaults touch-action': {},
659
+ '--tw-pinch-zoom': 'pinch-zoom',
660
+ 'touch-action': 'var(--tw-touch-action)',
661
+ },
797
662
  '.touch-manipulation': { 'touch-action': 'manipulation' },
798
663
  })
799
664
  },
@@ -858,19 +723,23 @@ export let corePlugins = {
858
723
  })
859
724
  },
860
725
 
861
- scrollMargin: createUtilityPlugin('scrollMargin', [
862
- ['scroll-m', ['scroll-margin']],
726
+ scrollMargin: createUtilityPlugin(
727
+ 'scrollMargin',
863
728
  [
864
- ['scroll-mx', ['scroll-margin-left', 'scroll-margin-right']],
865
- ['scroll-my', ['scroll-margin-top', 'scroll-margin-bottom']],
866
- ],
867
- [
868
- ['scroll-mt', ['scroll-margin-top']],
869
- ['scroll-mr', ['scroll-margin-right']],
870
- ['scroll-mb', ['scroll-margin-bottom']],
871
- ['scroll-ml', ['scroll-margin-left']],
729
+ ['scroll-m', ['scroll-margin']],
730
+ [
731
+ ['scroll-mx', ['scroll-margin-left', 'scroll-margin-right']],
732
+ ['scroll-my', ['scroll-margin-top', 'scroll-margin-bottom']],
733
+ ],
734
+ [
735
+ ['scroll-mt', ['scroll-margin-top']],
736
+ ['scroll-mr', ['scroll-margin-right']],
737
+ ['scroll-mb', ['scroll-margin-bottom']],
738
+ ['scroll-ml', ['scroll-margin-left']],
739
+ ],
872
740
  ],
873
- ]),
741
+ { supportsNegativeValues: true }
742
+ ),
874
743
 
875
744
  scrollPadding: createUtilityPlugin('scrollPadding', [
876
745
  ['scroll-p', ['scroll-padding']],
@@ -1068,7 +937,7 @@ export let corePlugins = {
1068
937
  }
1069
938
  },
1070
939
  },
1071
- { values: theme('space') }
940
+ { values: theme('space'), supportsNegativeValues: true }
1072
941
  )
1073
942
 
1074
943
  addUtilities({
@@ -1531,8 +1400,10 @@ export let corePlugins = {
1531
1400
 
1532
1401
  boxDecorationBreak: ({ addUtilities }) => {
1533
1402
  addUtilities({
1534
- '.decoration-slice': { 'box-decoration-break': 'slice' },
1535
- '.decoration-clone': { 'box-decoration-break': 'clone' },
1403
+ '.decoration-slice': { 'box-decoration-break': 'slice' }, // Deprecated
1404
+ '.decoration-clone': { 'box-decoration-break': 'clone' }, // Deprecated
1405
+ '.box-decoration-slice': { 'box-decoration-break': 'slice' },
1406
+ '.box-decoration-clone': { 'box-decoration-break': 'clone' },
1536
1407
  })
1537
1408
  },
1538
1409
 
@@ -1640,7 +1511,9 @@ export let corePlugins = {
1640
1511
  })
1641
1512
  },
1642
1513
 
1643
- textIndent: createUtilityPlugin('textIndent', [['indent', ['text-indent']]]),
1514
+ textIndent: createUtilityPlugin('textIndent', [['indent', ['text-indent']]], {
1515
+ supportsNegativeValues: true,
1516
+ }),
1644
1517
 
1645
1518
  verticalAlign: ({ addUtilities, matchUtilities }) => {
1646
1519
  addUtilities({
@@ -1706,30 +1579,63 @@ export let corePlugins = {
1706
1579
 
1707
1580
  fontVariantNumeric: ({ addUtilities }) => {
1708
1581
  addUtilities({
1709
- '.ordinal, .slashed-zero, .lining-nums, .oldstyle-nums, .proportional-nums, .tabular-nums, .diagonal-fractions, .stacked-fractions':
1710
- {
1711
- '--tw-ordinal': 'var(--tw-empty,/*!*/ /*!*/)',
1712
- '--tw-slashed-zero': 'var(--tw-empty,/*!*/ /*!*/)',
1713
- '--tw-numeric-figure': 'var(--tw-empty,/*!*/ /*!*/)',
1714
- '--tw-numeric-spacing': 'var(--tw-empty,/*!*/ /*!*/)',
1715
- '--tw-numeric-fraction': 'var(--tw-empty,/*!*/ /*!*/)',
1716
- 'font-variant-numeric':
1717
- 'var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)',
1718
- },
1582
+ '@defaults font-variant-numeric': {
1583
+ '--tw-ordinal': 'var(--tw-empty,/*!*/ /*!*/)',
1584
+ '--tw-slashed-zero': 'var(--tw-empty,/*!*/ /*!*/)',
1585
+ '--tw-numeric-figure': 'var(--tw-empty,/*!*/ /*!*/)',
1586
+ '--tw-numeric-spacing': 'var(--tw-empty,/*!*/ /*!*/)',
1587
+ '--tw-numeric-fraction': 'var(--tw-empty,/*!*/ /*!*/)',
1588
+ '--tw-font-variant-numeric':
1589
+ 'var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)',
1590
+ },
1719
1591
  '.normal-nums': { 'font-variant-numeric': 'normal' },
1720
- '.ordinal': { '--tw-ordinal': 'ordinal' },
1721
- '.slashed-zero': { '--tw-slashed-zero': 'slashed-zero' },
1722
- '.lining-nums': { '--tw-numeric-figure': 'lining-nums' },
1723
- '.oldstyle-nums': { '--tw-numeric-figure': 'oldstyle-nums' },
1724
- '.proportional-nums': { '--tw-numeric-spacing': 'proportional-nums' },
1725
- '.tabular-nums': { '--tw-numeric-spacing': 'tabular-nums' },
1726
- '.diagonal-fractions': { '--tw-numeric-fraction': 'diagonal-fractions' },
1727
- '.stacked-fractions': { '--tw-numeric-fraction': 'stacked-fractions' },
1592
+ '.ordinal': {
1593
+ '@defaults font-variant-numeric': {},
1594
+ '--tw-ordinal': 'ordinal',
1595
+ 'font-variant-numeric': 'var(--tw-font-variant-numeric)',
1596
+ },
1597
+ '.slashed-zero': {
1598
+ '@defaults font-variant-numeric': {},
1599
+ '--tw-slashed-zero': 'slashed-zero',
1600
+ 'font-variant-numeric': 'var(--tw-font-variant-numeric)',
1601
+ },
1602
+ '.lining-nums': {
1603
+ '@defaults font-variant-numeric': {},
1604
+ '--tw-numeric-figure': 'lining-nums',
1605
+ 'font-variant-numeric': 'var(--tw-font-variant-numeric)',
1606
+ },
1607
+ '.oldstyle-nums': {
1608
+ '@defaults font-variant-numeric': {},
1609
+ '--tw-numeric-figure': 'oldstyle-nums',
1610
+ 'font-variant-numeric': 'var(--tw-font-variant-numeric)',
1611
+ },
1612
+ '.proportional-nums': {
1613
+ '@defaults font-variant-numeric': {},
1614
+ '--tw-numeric-spacing': 'proportional-nums',
1615
+ 'font-variant-numeric': 'var(--tw-font-variant-numeric)',
1616
+ },
1617
+ '.tabular-nums': {
1618
+ '@defaults font-variant-numeric': {},
1619
+ '--tw-numeric-spacing': 'tabular-nums',
1620
+ 'font-variant-numeric': 'var(--tw-font-variant-numeric)',
1621
+ },
1622
+ '.diagonal-fractions': {
1623
+ '@defaults font-variant-numeric': {},
1624
+ '--tw-numeric-fraction': 'diagonal-fractions',
1625
+ 'font-variant-numeric': 'var(--tw-font-variant-numeric)',
1626
+ },
1627
+ '.stacked-fractions': {
1628
+ '@defaults font-variant-numeric': {},
1629
+ '--tw-numeric-fraction': 'stacked-fractions',
1630
+ 'font-variant-numeric': 'var(--tw-font-variant-numeric)',
1631
+ },
1728
1632
  })
1729
1633
  },
1730
1634
 
1731
1635
  lineHeight: createUtilityPlugin('lineHeight', [['leading', ['lineHeight']]]),
1732
- letterSpacing: createUtilityPlugin('letterSpacing', [['tracking', ['letterSpacing']]]),
1636
+ letterSpacing: createUtilityPlugin('letterSpacing', [['tracking', ['letterSpacing']]], {
1637
+ supportsNegativeValues: true,
1638
+ }),
1733
1639
 
1734
1640
  textColor: ({ matchUtilities, theme, corePlugins }) => {
1735
1641
  matchUtilities(
@@ -1755,11 +1661,45 @@ export let corePlugins = {
1755
1661
  textDecoration: ({ addUtilities }) => {
1756
1662
  addUtilities({
1757
1663
  '.underline': { 'text-decoration': 'underline' },
1664
+ '.overline': { 'text-decoration': 'overline' },
1758
1665
  '.line-through': { 'text-decoration': 'line-through' },
1759
1666
  '.no-underline': { 'text-decoration': 'none' },
1760
1667
  })
1761
1668
  },
1762
1669
 
1670
+ textDecorationColor: ({ matchUtilities, theme }) => {
1671
+ matchUtilities(
1672
+ {
1673
+ decoration: (value) => {
1674
+ return { 'text-decoration-color': toColorValue(value) }
1675
+ },
1676
+ },
1677
+ { values: flattenColorPalette(theme('textDecorationColor')), type: ['color'] }
1678
+ )
1679
+ },
1680
+
1681
+ textDecorationStyle: ({ addUtilities }) => {
1682
+ addUtilities({
1683
+ '.decoration-solid': { 'text-decoration-style': 'solid' },
1684
+ '.decoration-double': { 'text-decoration-style': 'double' },
1685
+ '.decoration-dotted': { 'text-decoration-style': 'dotted' },
1686
+ '.decoration-dashed': { 'text-decoration-style': 'dashed' },
1687
+ '.decoration-wavy': { 'text-decoration-style': 'wavy' },
1688
+ })
1689
+ },
1690
+
1691
+ textDecorationThickness: createUtilityPlugin(
1692
+ 'textDecorationThickness',
1693
+ [['decoration', ['text-decoration-thickness']]],
1694
+ { type: ['length', 'percentage'] }
1695
+ ),
1696
+
1697
+ textUnderlineOffset: createUtilityPlugin(
1698
+ 'textUnderlineOffset',
1699
+ [['underline-offset', ['text-underline-offset']]],
1700
+ { type: ['length', 'percentage'] }
1701
+ ),
1702
+
1763
1703
  fontSmoothing: ({ addUtilities }) => {
1764
1704
  addUtilities({
1765
1705
  '.antialiased': {
@@ -1889,6 +1829,7 @@ export let corePlugins = {
1889
1829
  '--tw-ring-offset-shadow': '0 0 #0000',
1890
1830
  '--tw-ring-shadow': '0 0 #0000',
1891
1831
  '--tw-shadow': '0 0 #0000',
1832
+ '--tw-shadow-colored': '0 0 #0000',
1892
1833
  },
1893
1834
  })
1894
1835
 
@@ -1897,29 +1838,73 @@ export let corePlugins = {
1897
1838
  shadow: (value) => {
1898
1839
  value = transformValue(value)
1899
1840
 
1841
+ let ast = parseBoxShadowValue(value)
1842
+ for (let shadow of ast) {
1843
+ // Don't override color if the whole shadow is a variable
1844
+ if (!shadow.valid) {
1845
+ continue
1846
+ }
1847
+
1848
+ shadow.color = 'var(--tw-shadow-color)'
1849
+ }
1850
+
1900
1851
  return {
1901
1852
  '@defaults box-shadow': {},
1902
1853
  '--tw-shadow': value === 'none' ? '0 0 #0000' : value,
1854
+ '--tw-shadow-colored': value === 'none' ? '0 0 #0000' : formatBoxShadowValue(ast),
1903
1855
  'box-shadow': defaultBoxShadow,
1904
1856
  }
1905
1857
  },
1906
1858
  },
1907
- { values: theme('boxShadow') }
1859
+ { values: theme('boxShadow'), type: ['shadow'] }
1908
1860
  )
1909
1861
  }
1910
1862
  })(),
1911
1863
 
1912
- outline: ({ matchUtilities, theme }) => {
1864
+ boxShadowColor: ({ matchUtilities, theme }) => {
1913
1865
  matchUtilities(
1914
1866
  {
1915
- outline: (value) => {
1916
- value = Array.isArray(value) ? value : value.split(',')
1917
- let [outline, outlineOffset = '0'] = Array.isArray(value) ? value : [value]
1867
+ shadow: (value) => {
1868
+ return {
1869
+ '--tw-shadow-color': toColorValue(value),
1870
+ '--tw-shadow': 'var(--tw-shadow-colored)',
1871
+ }
1872
+ },
1873
+ },
1874
+ { values: flattenColorPalette(theme('boxShadowColor')), type: ['color'] }
1875
+ )
1876
+ },
1918
1877
 
1919
- return { outline, 'outline-offset': outlineOffset }
1878
+ outlineStyle: ({ addUtilities }) => {
1879
+ addUtilities({
1880
+ '.outline-none': {
1881
+ outline: '2px solid transparent',
1882
+ 'outline-offset': '2px',
1883
+ },
1884
+ '.outline': { 'outline-style': 'solid' },
1885
+ '.outline-dashed': { 'outline-style': 'dashed' },
1886
+ '.outline-dotted': { 'outline-style': 'dotted' },
1887
+ '.outline-double': { 'outline-style': 'double' },
1888
+ '.outline-hidden': { 'outline-style': 'hidden' },
1889
+ })
1890
+ },
1891
+
1892
+ outlineWidth: createUtilityPlugin('outlineWidth', [['outline', ['outline-width']]], {
1893
+ type: ['length', 'number', 'percentage'],
1894
+ }),
1895
+
1896
+ outlineOffset: createUtilityPlugin('outlineOffset', [['outline-offset', ['outline-offset']]], {
1897
+ type: ['length', 'number', 'percentage'],
1898
+ }),
1899
+
1900
+ outlineColor: ({ matchUtilities, theme }) => {
1901
+ matchUtilities(
1902
+ {
1903
+ outline: (value) => {
1904
+ return { 'outline-color': toColorValue(value) }
1920
1905
  },
1921
1906
  },
1922
- { values: theme('outline') }
1907
+ { values: flattenColorPalette(theme('outlineColor')), type: ['color'] }
1923
1908
  )
1924
1909
  },
1925
1910
 
@@ -1940,6 +1925,7 @@ export let corePlugins = {
1940
1925
  '--tw-ring-offset-shadow': '0 0 #0000',
1941
1926
  '--tw-ring-shadow': '0 0 #0000',
1942
1927
  '--tw-shadow': '0 0 #0000',
1928
+ '--tw-shadow-colored': '0 0 #0000',
1943
1929
  },
1944
1930
  })
1945
1931
 
@@ -2098,7 +2084,7 @@ export let corePlugins = {
2098
2084
  }
2099
2085
  },
2100
2086
  },
2101
- { values: theme('hueRotate') }
2087
+ { values: theme('hueRotate'), supportsNegativeValues: true }
2102
2088
  )
2103
2089
  },
2104
2090
 
@@ -2249,7 +2235,7 @@ export let corePlugins = {
2249
2235
  }
2250
2236
  },
2251
2237
  },
2252
- { values: theme('backdropHueRotate') }
2238
+ { values: theme('backdropHueRotate'), supportsNegativeValues: true }
2253
2239
  )
2254
2240
  },
2255
2241
 
@@ -2381,5 +2367,7 @@ export let corePlugins = {
2381
2367
  { filterDefault: true }
2382
2368
  ),
2383
2369
  willChange: createUtilityPlugin('willChange', [['will-change', ['will-change']]]),
2384
- content: createUtilityPlugin('content'),
2370
+ content: createUtilityPlugin('content', [
2371
+ ['content', ['--tw-content', ['content', 'var(--tw-content)']]],
2372
+ ]),
2385
2373
  }