tailwindcss 0.0.0-insiders.ddec022 → 0.0.0-insiders.de00a62

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 (81) hide show
  1. package/lib/cli/build/plugin.js +6 -6
  2. package/lib/cli/build/watching.js +1 -1
  3. package/lib/corePluginList.js +5 -1
  4. package/lib/corePlugins.js +170 -13
  5. package/lib/css/preflight.css +24 -8
  6. package/lib/lib/content.js +36 -3
  7. package/lib/lib/defaultExtractor.js +33 -25
  8. package/lib/lib/evaluateTailwindFunctions.js +5 -3
  9. package/lib/lib/expandApplyAtRules.js +6 -0
  10. package/lib/lib/expandTailwindAtRules.js +23 -6
  11. package/lib/lib/generateRules.js +47 -25
  12. package/lib/lib/load-config.js +14 -3
  13. package/lib/lib/offsets.js +51 -2
  14. package/lib/lib/resolveDefaultsAtRules.js +3 -1
  15. package/lib/lib/setupContextUtils.js +76 -37
  16. package/lib/lib/setupTrackingContext.js +2 -1
  17. package/lib/oxide/cli/build/plugin.js +6 -6
  18. package/lib/plugin.js +3 -3
  19. package/lib/processTailwindFeatures.js +2 -2
  20. package/lib/util/cloneNodes.js +33 -13
  21. package/lib/util/color.js +1 -1
  22. package/lib/util/dataTypes.js +135 -16
  23. package/lib/util/formatVariantSelector.js +10 -3
  24. package/lib/util/isPlainObject.js +1 -1
  25. package/lib/util/pluginUtils.js +13 -0
  26. package/lib/util/prefixSelector.js +1 -1
  27. package/lib/util/pseudoElements.js +21 -34
  28. package/lib/value-parser/LICENSE +22 -0
  29. package/lib/value-parser/README.md +3 -0
  30. package/lib/value-parser/index.d.js +2 -0
  31. package/lib/value-parser/index.js +22 -0
  32. package/lib/value-parser/parse.js +259 -0
  33. package/lib/value-parser/stringify.js +38 -0
  34. package/lib/value-parser/unit.js +86 -0
  35. package/lib/value-parser/walk.js +16 -0
  36. package/nesting/index.d.ts +4 -0
  37. package/package.json +5 -6
  38. package/peers/index.js +701 -617
  39. package/resolveConfig.d.ts +22 -3
  40. package/scripts/generate-types.js +1 -2
  41. package/src/cli/build/plugin.js +6 -6
  42. package/src/cli/build/watching.js +1 -1
  43. package/src/corePluginList.js +1 -1
  44. package/src/corePlugins.js +149 -12
  45. package/src/css/preflight.css +24 -8
  46. package/src/featureFlags.js +1 -5
  47. package/src/lib/content.js +42 -1
  48. package/src/lib/defaultExtractor.js +30 -17
  49. package/src/lib/evaluateTailwindFunctions.js +4 -1
  50. package/src/lib/expandApplyAtRules.js +7 -0
  51. package/src/lib/expandTailwindAtRules.js +23 -6
  52. package/src/lib/generateRules.js +50 -26
  53. package/src/lib/load-config.ts +8 -0
  54. package/src/lib/offsets.js +61 -2
  55. package/src/lib/resolveDefaultsAtRules.js +5 -1
  56. package/src/lib/setupContextUtils.js +77 -38
  57. package/src/lib/setupTrackingContext.js +1 -3
  58. package/src/oxide/cli/build/plugin.ts +6 -6
  59. package/src/plugin.js +3 -3
  60. package/src/processTailwindFeatures.js +3 -2
  61. package/src/util/cloneNodes.js +35 -14
  62. package/src/util/color.js +1 -1
  63. package/src/util/dataTypes.js +143 -18
  64. package/src/util/formatVariantSelector.js +11 -3
  65. package/src/util/isPlainObject.js +1 -1
  66. package/src/util/pluginUtils.js +16 -0
  67. package/src/util/prefixSelector.js +1 -0
  68. package/src/util/pseudoElements.js +18 -17
  69. package/src/value-parser/LICENSE +22 -0
  70. package/src/value-parser/README.md +3 -0
  71. package/src/value-parser/index.d.ts +177 -0
  72. package/src/value-parser/index.js +28 -0
  73. package/src/value-parser/parse.js +303 -0
  74. package/src/value-parser/stringify.js +41 -0
  75. package/src/value-parser/unit.js +118 -0
  76. package/src/value-parser/walk.js +18 -0
  77. package/stubs/config.full.js +86 -14
  78. package/types/config.d.ts +17 -9
  79. package/types/generated/corePluginList.d.ts +1 -1
  80. package/types/generated/default-theme.d.ts +35 -9
  81. package/types/index.d.ts +7 -3
@@ -1,11 +1,30 @@
1
- import type { Config, ResolvableTo } from './types/config'
1
+ import { Config, ResolvableTo, ThemeConfig } from './types/config'
2
+ import { DefaultTheme } from './types/generated/default-theme'
3
+ import { DefaultColors } from './types/generated/colors'
4
+
5
+ type ResolvedConfig<T extends Config> = Omit<T, 'theme'> & {
6
+ theme: MergeThemes<
7
+ UnwrapResolvables<Omit<T['theme'], 'extend'>>,
8
+ T['theme'] extends { extend: infer TExtend } ? UnwrapResolvables<TExtend> : {}
9
+ >
10
+ }
2
11
 
3
12
  type UnwrapResolvables<T> = {
4
13
  [K in keyof T]: T[K] extends ResolvableTo<infer R> ? R : T[K]
5
14
  }
6
15
 
7
- type ResolvedConfig<T extends Config> = Omit<T, 'theme'> & {
8
- theme: UnwrapResolvables<T['theme']>
16
+ type ThemeConfigResolved = UnwrapResolvables<ThemeConfig>
17
+ type DefaultThemeFull = DefaultTheme & { colors: DefaultColors }
18
+
19
+ type MergeThemes<Overrides extends object, Extensions extends object> = {
20
+ [K in keyof ThemeConfigResolved | keyof Overrides]: (K extends keyof Overrides
21
+ ? Overrides[K]
22
+ : K extends keyof DefaultThemeFull
23
+ ? DefaultThemeFull[K]
24
+ : K extends keyof ThemeConfigResolved
25
+ ? ThemeConfigResolved[K]
26
+ : never) &
27
+ (K extends keyof Extensions ? Extensions[K] : {})
9
28
  }
10
29
 
11
30
  declare function resolveConfig<T extends Config>(config: T): ResolvedConfig<T>
@@ -91,9 +91,8 @@ fs.writeFileSync(
91
91
  path.join(process.cwd(), 'types', 'generated', 'default-theme.d.ts'),
92
92
  prettier.format(
93
93
  `
94
- import { Config } from '../../types'
95
94
  type CSSDeclarationList = Record<string, string>
96
- export type DefaultTheme = Config['theme'] & { ${defaultThemeTypes} }
95
+ export type DefaultTheme = { ${defaultThemeTypes} }
97
96
  `,
98
97
  {
99
98
  semi: false,
@@ -211,16 +211,16 @@ let state = {
211
211
  },
212
212
 
213
213
  getContext({ createContext, cliConfigPath, root, result, content }) {
214
+ env.DEBUG && console.time('Searching for config')
215
+ let configPath = findAtConfigPath(root, result) ?? cliConfigPath
216
+ env.DEBUG && console.timeEnd('Searching for config')
217
+
214
218
  if (this.context) {
215
219
  this.context.changedContent = this.changedContent.splice(0)
216
220
 
217
221
  return this.context
218
222
  }
219
223
 
220
- env.DEBUG && console.time('Searching for config')
221
- let configPath = findAtConfigPath(root, result) ?? cliConfigPath
222
- env.DEBUG && console.timeEnd('Searching for config')
223
-
224
224
  env.DEBUG && console.time('Loading config')
225
225
  let config = this.loadConfig(configPath, content)
226
226
  env.DEBUG && console.timeEnd('Loading config')
@@ -278,9 +278,9 @@ export async function createProcessor(args, cliConfigPath) {
278
278
  let tailwindPlugin = () => {
279
279
  return {
280
280
  postcssPlugin: 'tailwindcss',
281
- Once(root, { result }) {
281
+ async Once(root, { result }) {
282
282
  env.DEBUG && console.time('Compiling CSS')
283
- tailwind(({ createContext }) => {
283
+ await tailwind(({ createContext }) => {
284
284
  console.error()
285
285
  console.error('Rebuilding...')
286
286
 
@@ -164,7 +164,7 @@ export function createWatcher(args, { state, rebuild }) {
164
164
  // This is very likely a chokidar bug but it's one we need to work around
165
165
  // We treat this as a change event and rebuild the CSS
166
166
  watcher.on('raw', (evt, filePath, meta) => {
167
- if (evt !== 'rename') {
167
+ if (evt !== 'rename' || filePath === null) {
168
168
  return
169
169
  }
170
170
 
@@ -1 +1 @@
1
- export default ["preflight","container","accessibility","pointerEvents","visibility","position","inset","isolation","zIndex","order","gridColumn","gridColumnStart","gridColumnEnd","gridRow","gridRowStart","gridRowEnd","float","clear","margin","boxSizing","lineClamp","display","aspectRatio","height","maxHeight","minHeight","width","minWidth","maxWidth","flex","flexShrink","flexGrow","flexBasis","tableLayout","captionSide","borderCollapse","borderSpacing","transformOrigin","translate","rotate","skew","scale","transform","animation","cursor","touchAction","userSelect","resize","scrollSnapType","scrollSnapAlign","scrollSnapStop","scrollMargin","scrollPadding","listStylePosition","listStyleType","listStyleImage","appearance","columns","breakBefore","breakInside","breakAfter","gridAutoColumns","gridAutoFlow","gridAutoRows","gridTemplateColumns","gridTemplateRows","flexDirection","flexWrap","placeContent","placeItems","alignContent","alignItems","justifyContent","justifyItems","gap","space","divideWidth","divideStyle","divideColor","divideOpacity","placeSelf","alignSelf","justifySelf","overflow","overscrollBehavior","scrollBehavior","textOverflow","hyphens","whitespace","wordBreak","borderRadius","borderWidth","borderStyle","borderColor","borderOpacity","backgroundColor","backgroundOpacity","backgroundImage","gradientColorStops","boxDecorationBreak","backgroundSize","backgroundAttachment","backgroundClip","backgroundPosition","backgroundRepeat","backgroundOrigin","fill","stroke","strokeWidth","objectFit","objectPosition","padding","textAlign","textIndent","verticalAlign","fontFamily","fontSize","fontWeight","textTransform","fontStyle","fontVariantNumeric","lineHeight","letterSpacing","textColor","textOpacity","textDecoration","textDecorationColor","textDecorationStyle","textDecorationThickness","textUnderlineOffset","fontSmoothing","placeholderColor","placeholderOpacity","caretColor","accentColor","opacity","backgroundBlendMode","mixBlendMode","boxShadow","boxShadowColor","outlineStyle","outlineWidth","outlineOffset","outlineColor","ringWidth","ringColor","ringOpacity","ringOffsetWidth","ringOffsetColor","blur","brightness","contrast","dropShadow","grayscale","hueRotate","invert","saturate","sepia","filter","backdropBlur","backdropBrightness","backdropContrast","backdropGrayscale","backdropHueRotate","backdropInvert","backdropOpacity","backdropSaturate","backdropSepia","backdropFilter","transitionProperty","transitionDelay","transitionDuration","transitionTimingFunction","willChange","content"]
1
+ export default ["preflight","container","accessibility","pointerEvents","visibility","position","inset","isolation","zIndex","order","gridColumn","gridColumnStart","gridColumnEnd","gridRow","gridRowStart","gridRowEnd","float","clear","margin","boxSizing","lineClamp","display","aspectRatio","size","height","maxHeight","minHeight","width","minWidth","maxWidth","flex","flexShrink","flexGrow","flexBasis","tableLayout","captionSide","borderCollapse","borderSpacing","transformOrigin","translate","rotate","skew","scale","transform","animation","cursor","touchAction","userSelect","resize","scrollSnapType","scrollSnapAlign","scrollSnapStop","scrollMargin","scrollPadding","listStylePosition","listStyleType","listStyleImage","appearance","columns","breakBefore","breakInside","breakAfter","gridAutoColumns","gridAutoFlow","gridAutoRows","gridTemplateColumns","gridTemplateRows","flexDirection","flexWrap","placeContent","placeItems","alignContent","alignItems","justifyContent","justifyItems","gap","space","divideWidth","divideStyle","divideColor","divideOpacity","placeSelf","alignSelf","justifySelf","overflow","overscrollBehavior","scrollBehavior","textOverflow","hyphens","whitespace","textWrap","wordBreak","borderRadius","borderWidth","borderStyle","borderColor","borderOpacity","backgroundColor","backgroundOpacity","backgroundImage","gradientColorStops","boxDecorationBreak","backgroundSize","backgroundAttachment","backgroundClip","backgroundPosition","backgroundRepeat","backgroundOrigin","fill","stroke","strokeWidth","objectFit","objectPosition","padding","textAlign","textIndent","verticalAlign","fontFamily","fontSize","fontWeight","textTransform","fontStyle","fontVariantNumeric","lineHeight","letterSpacing","textColor","textOpacity","textDecoration","textDecorationColor","textDecorationStyle","textDecorationThickness","textUnderlineOffset","fontSmoothing","placeholderColor","placeholderOpacity","caretColor","accentColor","opacity","backgroundBlendMode","mixBlendMode","boxShadow","boxShadowColor","outlineStyle","outlineWidth","outlineOffset","outlineColor","ringWidth","ringColor","ringOpacity","ringOffsetWidth","ringOffsetColor","blur","brightness","contrast","dropShadow","grayscale","hueRotate","invert","saturate","sepia","filter","backdropBlur","backdropBrightness","backdropContrast","backdropGrayscale","backdropHueRotate","backdropInvert","backdropOpacity","backdropSaturate","backdropSepia","backdropFilter","transitionProperty","transitionDelay","transitionDuration","transitionTimingFunction","willChange","contain","content","forcedColorAdjust"]
@@ -22,8 +22,12 @@ import { formatBoxShadowValue, parseBoxShadowValue } from './util/parseBoxShadow
22
22
  import { removeAlphaVariables } from './util/removeAlphaVariables'
23
23
  import { flagEnabled } from './featureFlags'
24
24
  import { normalize } from './util/dataTypes'
25
+ import { INTERNAL_FEATURES } from './lib/setupContextUtils'
25
26
 
26
27
  export let variantPlugins = {
28
+ childVariant: ({ addVariant }) => {
29
+ addVariant('*', '& > *')
30
+ },
27
31
  pseudoElementVariants: ({ addVariant }) => {
28
32
  addVariant('first-letter', '&::first-letter')
29
33
  addVariant('first-line', '&::first-line')
@@ -80,7 +84,7 @@ export let variantPlugins = {
80
84
  })
81
85
  },
82
86
 
83
- pseudoClassVariants: ({ addVariant, matchVariant, config }) => {
87
+ pseudoClassVariants: ({ addVariant, matchVariant, config, prefix }) => {
84
88
  let pseudoVariants = [
85
89
  // Positional
86
90
  ['first', '&:first-child'],
@@ -151,12 +155,12 @@ export let variantPlugins = {
151
155
  let variants = {
152
156
  group: (_, { modifier }) =>
153
157
  modifier
154
- ? [`:merge(.group\\/${escapeClassName(modifier)})`, ' &']
155
- : [`:merge(.group)`, ' &'],
158
+ ? [`:merge(${prefix('.group')}\\/${escapeClassName(modifier)})`, ' &']
159
+ : [`:merge(${prefix('.group')})`, ' &'],
156
160
  peer: (_, { modifier }) =>
157
161
  modifier
158
- ? [`:merge(.peer\\/${escapeClassName(modifier)})`, ' ~ &']
159
- : [`:merge(.peer)`, ' ~ &'],
162
+ ? [`:merge(${prefix('.peer')}\\/${escapeClassName(modifier)})`, ' ~ &']
163
+ : [`:merge(${prefix('.peer')})`, ' ~ &'],
160
164
  }
161
165
 
162
166
  for (let [name, fn] of Object.entries(variants)) {
@@ -192,14 +196,19 @@ export let variantPlugins = {
192
196
 
193
197
  return result.slice(0, start) + a + result.slice(start + 1, end) + b + result.slice(end)
194
198
  },
195
- { values: Object.fromEntries(pseudoVariants) }
199
+ {
200
+ values: Object.fromEntries(pseudoVariants),
201
+ [INTERNAL_FEATURES]: {
202
+ respectPrefix: false,
203
+ },
204
+ }
196
205
  )
197
206
  }
198
207
  },
199
208
 
200
209
  directionVariants: ({ addVariant }) => {
201
- addVariant('ltr', ':is([dir="ltr"] &)')
202
- addVariant('rtl', ':is([dir="rtl"] &)')
210
+ addVariant('ltr', '&:where([dir="ltr"], [dir="ltr"] *)')
211
+ addVariant('rtl', '&:where([dir="rtl"], [dir="rtl"] *)')
203
212
  },
204
213
 
205
214
  reducedMotionVariants: ({ addVariant }) => {
@@ -208,7 +217,7 @@ export let variantPlugins = {
208
217
  },
209
218
 
210
219
  darkVariants: ({ config, addVariant }) => {
211
- let [mode, className = '.dark'] = [].concat(config('darkMode', 'media'))
220
+ let [mode, selector = '.dark'] = [].concat(config('darkMode', 'media'))
212
221
 
213
222
  if (mode === false) {
214
223
  mode = 'media'
@@ -219,10 +228,49 @@ export let variantPlugins = {
219
228
  ])
220
229
  }
221
230
 
222
- if (mode === 'class') {
223
- addVariant('dark', `:is(${className} &)`)
231
+ if (mode === 'variant') {
232
+ let formats
233
+ if (Array.isArray(selector)) {
234
+ formats = selector
235
+ } else if (typeof selector === 'function') {
236
+ formats = selector
237
+ } else if (typeof selector === 'string') {
238
+ formats = [selector]
239
+ }
240
+
241
+ // TODO: We could also add these warnings if the user passes a function that returns string | string[]
242
+ // But this is an advanced enough use case that it's probably not necessary
243
+ if (Array.isArray(formats)) {
244
+ for (let format of formats) {
245
+ if (format === '.dark') {
246
+ mode = false
247
+ log.warn('darkmode-variant-without-selector', [
248
+ 'When using `variant` for `darkMode`, you must provide a selector.',
249
+ 'Example: `darkMode: ["variant", ".your-selector &"]`',
250
+ ])
251
+ } else if (!format.includes('&')) {
252
+ mode = false
253
+ log.warn('darkmode-variant-without-ampersand', [
254
+ 'When using `variant` for `darkMode`, your selector must contain `&`.',
255
+ 'Example `darkMode: ["variant", ".your-selector &"]`',
256
+ ])
257
+ }
258
+ }
259
+ }
260
+
261
+ selector = formats
262
+ }
263
+
264
+ if (mode === 'selector') {
265
+ // New preferred behavior
266
+ addVariant('dark', `&:where(${selector}, ${selector} *)`)
224
267
  } else if (mode === 'media') {
225
268
  addVariant('dark', '@media (prefers-color-scheme: dark)')
269
+ } else if (mode === 'variant') {
270
+ addVariant('dark', selector)
271
+ } else if (mode === 'class') {
272
+ // Old behavior
273
+ addVariant('dark', `:is(${selector} &)`)
226
274
  }
227
275
  },
228
276
 
@@ -386,6 +434,26 @@ export let variantPlugins = {
386
434
  )
387
435
  },
388
436
 
437
+ hasVariants: ({ matchVariant }) => {
438
+ matchVariant('has', (value) => `&:has(${normalize(value)})`, { values: {} })
439
+ matchVariant(
440
+ 'group-has',
441
+ (value, { modifier }) =>
442
+ modifier
443
+ ? `:merge(.group\\/${modifier}):has(${normalize(value)}) &`
444
+ : `:merge(.group):has(${normalize(value)}) &`,
445
+ { values: {} }
446
+ )
447
+ matchVariant(
448
+ 'peer-has',
449
+ (value, { modifier }) =>
450
+ modifier
451
+ ? `:merge(.peer\\/${modifier}):has(${normalize(value)}) ~ &`
452
+ : `:merge(.peer):has(${normalize(value)}) ~ &`,
453
+ { values: {} }
454
+ )
455
+ },
456
+
389
457
  ariaVariants: ({ matchVariant, theme }) => {
390
458
  matchVariant('aria', (value) => `&[aria-${normalize(value)}]`, { values: theme('aria') ?? {} })
391
459
  matchVariant(
@@ -435,6 +503,10 @@ export let variantPlugins = {
435
503
  addVariant('contrast-more', '@media (prefers-contrast: more)')
436
504
  addVariant('contrast-less', '@media (prefers-contrast: less)')
437
505
  },
506
+
507
+ forcedColorsVariants: ({ addVariant }) => {
508
+ addVariant('forced-colors', '@media (forced-colors: active)')
509
+ },
438
510
  }
439
511
 
440
512
  let cssTransformValue = [
@@ -660,6 +732,8 @@ export let corePlugins = {
660
732
 
661
733
  float: ({ addUtilities }) => {
662
734
  addUtilities({
735
+ '.float-start': { float: 'inline-start' },
736
+ '.float-end': { float: 'inline-end' },
663
737
  '.float-right': { float: 'right' },
664
738
  '.float-left': { float: 'left' },
665
739
  '.float-none': { float: 'none' },
@@ -668,6 +742,8 @@ export let corePlugins = {
668
742
 
669
743
  clear: ({ addUtilities }) => {
670
744
  addUtilities({
745
+ '.clear-start': { clear: 'inline-start' },
746
+ '.clear-end': { clear: 'inline-end' },
671
747
  '.clear-left': { clear: 'left' },
672
748
  '.clear-right': { clear: 'right' },
673
749
  '.clear-both': { clear: 'both' },
@@ -753,6 +829,8 @@ export let corePlugins = {
753
829
 
754
830
  aspectRatio: createUtilityPlugin('aspectRatio', [['aspect', ['aspect-ratio']]]),
755
831
 
832
+ size: createUtilityPlugin('size', [['size', ['width', 'height']]]),
833
+
756
834
  height: createUtilityPlugin('height', [['h', ['height']]]),
757
835
  maxHeight: createUtilityPlugin('maxHeight', [['max-h', ['maxHeight']]]),
758
836
  minHeight: createUtilityPlugin('minHeight', [['min-h', ['minHeight']]]),
@@ -913,7 +991,7 @@ export let corePlugins = {
913
991
  },
914
992
 
915
993
  animation: ({ matchUtilities, theme, config }) => {
916
- let prefixName = (name) => `${config('prefix')}${escapeClassName(name)}`
994
+ let prefixName = (name) => escapeClassName(config('prefix') + name)
917
995
  let keyframes = Object.fromEntries(
918
996
  Object.entries(theme('keyframes') ?? {}).map(([key, value]) => {
919
997
  return [key, { [`@keyframes ${prefixName(key)}`]: value }]
@@ -1103,6 +1181,7 @@ export let corePlugins = {
1103
1181
  appearance: ({ addUtilities }) => {
1104
1182
  addUtilities({
1105
1183
  '.appearance-none': { appearance: 'none' },
1184
+ '.appearance-auto': { appearance: 'auto' },
1106
1185
  })
1107
1186
  },
1108
1187
 
@@ -1503,6 +1582,15 @@ export let corePlugins = {
1503
1582
  })
1504
1583
  },
1505
1584
 
1585
+ textWrap: ({ addUtilities }) => {
1586
+ addUtilities({
1587
+ '.text-wrap': { 'text-wrap': 'wrap' },
1588
+ '.text-nowrap': { 'text-wrap': 'nowrap' },
1589
+ '.text-balance': { 'text-wrap': 'balance' },
1590
+ '.text-pretty': { 'text-wrap': 'pretty' },
1591
+ })
1592
+ },
1593
+
1506
1594
  wordBreak: ({ addUtilities }) => {
1507
1595
  addUtilities({
1508
1596
  '.break-normal': { 'overflow-wrap': 'normal', 'word-break': 'normal' },
@@ -2296,6 +2384,7 @@ export let corePlugins = {
2296
2384
  '.mix-blend-saturation': { 'mix-blend-mode': 'saturation' },
2297
2385
  '.mix-blend-color': { 'mix-blend-mode': 'color' },
2298
2386
  '.mix-blend-luminosity': { 'mix-blend-mode': 'luminosity' },
2387
+ '.mix-blend-plus-darker': { 'mix-blend-mode': 'plus-darker' },
2299
2388
  '.mix-blend-plus-lighter': { 'mix-blend-mode': 'plus-lighter' },
2300
2389
  })
2301
2390
  },
@@ -2843,7 +2932,55 @@ export let corePlugins = {
2843
2932
  { filterDefault: true }
2844
2933
  ),
2845
2934
  willChange: createUtilityPlugin('willChange', [['will-change', ['will-change']]]),
2935
+ contain: ({ addDefaults, addUtilities }) => {
2936
+ let cssContainValue =
2937
+ 'var(--tw-contain-size) var(--tw-contain-layout) var(--tw-contain-paint) var(--tw-contain-style)'
2938
+
2939
+ addDefaults('contain', {
2940
+ '--tw-contain-size': ' ',
2941
+ '--tw-contain-layout': ' ',
2942
+ '--tw-contain-paint': ' ',
2943
+ '--tw-contain-style': ' ',
2944
+ })
2945
+
2946
+ addUtilities({
2947
+ '.contain-none': { contain: 'none' },
2948
+ '.contain-content': { contain: 'content' },
2949
+ '.contain-strict': { contain: 'strict' },
2950
+ '.contain-size': {
2951
+ '@defaults contain': {},
2952
+ '--tw-contain-size': 'size',
2953
+ contain: cssContainValue,
2954
+ },
2955
+ '.contain-inline-size': {
2956
+ '@defaults contain': {},
2957
+ '--tw-contain-size': 'inline-size',
2958
+ contain: cssContainValue,
2959
+ },
2960
+ '.contain-layout': {
2961
+ '@defaults contain': {},
2962
+ '--tw-contain-layout': 'layout',
2963
+ contain: cssContainValue,
2964
+ },
2965
+ '.contain-paint': {
2966
+ '@defaults contain': {},
2967
+ '--tw-contain-paint': 'paint',
2968
+ contain: cssContainValue,
2969
+ },
2970
+ '.contain-style': {
2971
+ '@defaults contain': {},
2972
+ '--tw-contain-style': 'style',
2973
+ contain: cssContainValue,
2974
+ },
2975
+ })
2976
+ },
2846
2977
  content: createUtilityPlugin('content', [
2847
2978
  ['content', ['--tw-content', ['content', 'var(--tw-content)']]],
2848
2979
  ]),
2980
+ forcedColorAdjust: ({ addUtilities }) => {
2981
+ addUtilities({
2982
+ '.forced-color-adjust-auto': { 'forced-color-adjust': 'auto' },
2983
+ '.forced-color-adjust-none': { 'forced-color-adjust': 'none' },
2984
+ })
2985
+ },
2849
2986
  }
@@ -24,16 +24,19 @@
24
24
  4. Use the user's configured `sans` font-family by default.
25
25
  5. Use the user's configured `sans` font-feature-settings by default.
26
26
  6. Use the user's configured `sans` font-variation-settings by default.
27
+ 7. Disable tap highlights on iOS
27
28
  */
28
29
 
29
- html {
30
+ html,
31
+ :host {
30
32
  line-height: 1.5; /* 1 */
31
33
  -webkit-text-size-adjust: 100%; /* 2 */
32
34
  -moz-tab-size: 4; /* 3 */
33
35
  tab-size: 4; /* 3 */
34
- font-family: theme('fontFamily.sans', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"); /* 4 */
36
+ font-family: theme('fontFamily.sans', ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"); /* 4 */
35
37
  font-feature-settings: theme('fontFamily.sans[1].fontFeatureSettings', normal); /* 5 */
36
38
  font-variation-settings: theme('fontFamily.sans[1].fontVariationSettings', normal); /* 6 */
39
+ -webkit-tap-highlight-color: transparent; /* 7 */
37
40
  }
38
41
 
39
42
  /*
@@ -99,8 +102,10 @@ strong {
99
102
  }
100
103
 
101
104
  /*
102
- 1. Use the user's configured `mono` font family by default.
103
- 2. Correct the odd `em` font sizing in all browsers.
105
+ 1. Use the user's configured `mono` font-family by default.
106
+ 2. Use the user's configured `mono` font-feature-settings by default.
107
+ 3. Use the user's configured `mono` font-variation-settings by default.
108
+ 4. Correct the odd `em` font sizing in all browsers.
104
109
  */
105
110
 
106
111
  code,
@@ -108,7 +113,9 @@ kbd,
108
113
  samp,
109
114
  pre {
110
115
  font-family: theme('fontFamily.mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace); /* 1 */
111
- font-size: 1em; /* 2 */
116
+ font-feature-settings: theme('fontFamily.mono[1].fontFeatureSettings', normal); /* 2 */
117
+ font-variation-settings: theme('fontFamily.mono[1].fontVariationSettings', normal); /* 3 */
118
+ font-size: 1em; /* 4 */
112
119
  }
113
120
 
114
121
  /*
@@ -163,6 +170,8 @@ optgroup,
163
170
  select,
164
171
  textarea {
165
172
  font-family: inherit; /* 1 */
173
+ font-feature-settings: inherit; /* 1 */
174
+ font-variation-settings: inherit; /* 1 */
166
175
  font-size: 100%; /* 1 */
167
176
  font-weight: inherit; /* 1 */
168
177
  line-height: inherit; /* 1 */
@@ -186,9 +195,9 @@ select {
186
195
  */
187
196
 
188
197
  button,
189
- [type='button'],
190
- [type='reset'],
191
- [type='submit'] {
198
+ input:where([type='button']),
199
+ input:where([type='reset']),
200
+ input:where([type='submit']) {
192
201
  -webkit-appearance: button; /* 1 */
193
202
  background-color: transparent; /* 2 */
194
203
  background-image: none; /* 2 */
@@ -300,6 +309,13 @@ menu {
300
309
  padding: 0;
301
310
  }
302
311
 
312
+ /*
313
+ Reset default styling for dialogs.
314
+ */
315
+ dialog {
316
+ padding: 0;
317
+ }
318
+
303
319
  /*
304
320
  Prevent resizing textareas horizontally by default.
305
321
  */
@@ -19,11 +19,7 @@ let featureFlags = {
19
19
  'disableColorOpacityUtilitiesByDefault',
20
20
  'relativeContentPathsByDefault',
21
21
  ],
22
- experimental: [
23
- 'optimizeUniversalDefaults',
24
- 'generalizedModifiers',
25
- // 'variantGrouping',
26
- ],
22
+ experimental: ['optimizeUniversalDefaults', 'generalizedModifiers'],
27
23
  }
28
24
 
29
25
  export function flagEnabled(config, flag) {
@@ -4,10 +4,47 @@ import fs from 'fs'
4
4
  import path from 'path'
5
5
  import isGlob from 'is-glob'
6
6
  import fastGlob from 'fast-glob'
7
- import normalizePath from 'normalize-path'
8
7
  import { parseGlob } from '../util/parseGlob'
9
8
  import { env } from './sharedState'
10
9
 
10
+ /*!
11
+ * Modified version of normalize-path, original license below
12
+ *
13
+ * normalize-path <https://github.com/jonschlinkert/normalize-path>
14
+ *
15
+ * Copyright (c) 2014-2018, Jon Schlinkert.
16
+ * Released under the MIT License.
17
+ */
18
+
19
+ function normalizePath(path) {
20
+ if (typeof path !== 'string') {
21
+ throw new TypeError('expected path to be a string')
22
+ }
23
+
24
+ if (path === '\\' || path === '/') return '/'
25
+
26
+ var len = path.length
27
+ if (len <= 1) return path
28
+
29
+ // ensure that win32 namespaces has two leading slashes, so that the path is
30
+ // handled properly by the win32 version of path.parse() after being normalized
31
+ // https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces
32
+ var prefix = ''
33
+ if (len > 4 && path[3] === '\\') {
34
+ var ch = path[2]
35
+ if ((ch === '?' || ch === '.') && path.slice(0, 2) === '\\\\') {
36
+ path = path.slice(2)
37
+ prefix = '//'
38
+ }
39
+ }
40
+
41
+ // Modified part: instead of purely splitting on `\\` and `/`, we split on
42
+ // `/` and `\\` that is _not_ followed by any of the following characters: ()[]
43
+ // This is to ensure that we keep the escaping of brackets and parentheses
44
+ let segs = path.split(/[/\\]+(?![\(\)\[\]])/)
45
+ return prefix + segs.join('/')
46
+ }
47
+
11
48
  /** @typedef {import('../../types/config.js').RawFile} RawFile */
12
49
  /** @typedef {import('../../types/config.js').FilePath} FilePath */
13
50
 
@@ -73,6 +110,10 @@ export function parseCandidateFiles(context, tailwindConfig) {
73
110
  * @returns {ContentPath}
74
111
  */
75
112
  function parseFilePath(filePath, ignore) {
113
+ // Escape special characters in the file path such as: ()[]
114
+ // But only if the special character isn't already escaped
115
+ filePath = filePath.replace(/(?<!\\)([\[\]\(\)])/g, '\\$1')
116
+
76
117
  let contentPath = {
77
118
  original: filePath,
78
119
  base: filePath,
@@ -1,4 +1,3 @@
1
- import { flagEnabled } from '../featureFlags'
2
1
  import * as regex from './regex'
3
2
 
4
3
  export function defaultExtractor(context) {
@@ -12,16 +11,17 @@ export function defaultExtractor(context) {
12
11
  let results = []
13
12
 
14
13
  for (let pattern of patterns) {
15
- results = [...results, ...(content.match(pattern) ?? [])]
14
+ for (let result of content.match(pattern) ?? []) {
15
+ results.push(clipAtBalancedParens(result))
16
+ }
16
17
  }
17
18
 
18
- return results.filter((v) => v !== undefined).map(clipAtBalancedParens)
19
+ return results
19
20
  }
20
21
  }
21
22
 
22
23
  function* buildRegExps(context) {
23
24
  let separator = context.tailwindConfig.separator
24
- let variantGroupingEnabled = flagEnabled(context.tailwindConfig, 'variantGrouping')
25
25
  let prefix =
26
26
  context.tailwindConfig.prefix !== ''
27
27
  ? regex.optional(regex.pattern([/-?/, regex.escape(context.tailwindConfig.prefix)]))
@@ -35,19 +35,29 @@ function* buildRegExps(context) {
35
35
  // This is a targeted fix to continue to allow theme()
36
36
  // with square brackets to work in arbitrary properties
37
37
  // while fixing a problem with the regex matching too much
38
- /\[[^\s:'"`]+:[^\s]+?\[[^\s]+\][^\s]+?\]/,
38
+ /\[[^\s:'"`\]]+:[^\s]+?\[[^\s]+\][^\s]+?\]/,
39
39
 
40
40
  // Utilities
41
41
  regex.pattern([
42
42
  // Utility Name / Group Name
43
- /-?(?:\w+)/,
43
+ regex.any([
44
+ /-?(?:\w+)/,
45
+
46
+ // This is here to make sure @container supports everything that other utilities do
47
+ /@(?:\w+)/,
48
+ ]),
44
49
 
45
50
  // Normal/Arbitrary values
46
51
  regex.optional(
47
52
  regex.any([
48
53
  regex.pattern([
49
54
  // Arbitrary values
50
- /-(?:\w+-)*\[[^\s:]+\]/,
55
+ regex.any([
56
+ /-(?:\w+-)*\['[^\s]+'\]/,
57
+ /-(?:\w+-)*\["[^\s]+"\]/,
58
+ /-(?:\w+-)*\[`[^\s]+`\]/,
59
+ /-(?:\w+-)*\[(?:[^\s\[\]]+\[[^\s\[\]]+\])*[^\s:\[\]]+\]/,
60
+ ]),
51
61
 
52
62
  // Not immediately followed by an `{[(`
53
63
  /(?![{([]])/,
@@ -58,7 +68,12 @@ function* buildRegExps(context) {
58
68
 
59
69
  regex.pattern([
60
70
  // Arbitrary values
61
- /-(?:\w+-)*\[[^\s]+\]/,
71
+ regex.any([
72
+ /-(?:\w+-)*\['[^\s]+'\]/,
73
+ /-(?:\w+-)*\["[^\s]+"\]/,
74
+ /-(?:\w+-)*\[`[^\s]+`\]/,
75
+ /-(?:\w+-)*\[(?:[^\s\[\]]+\[[^\s\[\]]+\])*[^\s\[\]]+\]/,
76
+ ]),
62
77
 
63
78
  // Not immediately followed by an `{[(`
64
79
  /(?![{([]])/,
@@ -80,12 +95,18 @@ function* buildRegExps(context) {
80
95
  // This is here to provide special support for the `@` variant
81
96
  regex.pattern([/@\[[^\s"'`]+\](\/[^\s"'`]+)?/, separator]),
82
97
 
98
+ // With variant modifier (e.g.: group-[..]/modifier)
99
+ regex.pattern([/([^\s"'`\[\\]+-)?\[[^\s"'`]+\]\/\w+/, separator]),
100
+
83
101
  regex.pattern([/([^\s"'`\[\\]+-)?\[[^\s"'`]+\]/, separator]),
84
102
  regex.pattern([/[^\s"'`\[\\]+/, separator]),
85
103
  ]),
86
104
 
87
105
  // With quotes allowed
88
106
  regex.any([
107
+ // With variant modifier (e.g.: group-[..]/modifier)
108
+ regex.pattern([/([^\s"'`\[\\]+-)?\[[^\s`]+\]\/\w+/, separator]),
109
+
89
110
  regex.pattern([/([^\s"'`\[\\]+-)?\[[^\s`]+\]/, separator]),
90
111
  regex.pattern([/[^\s`\[\\]+/, separator]),
91
112
  ]),
@@ -103,15 +124,7 @@ function* buildRegExps(context) {
103
124
 
104
125
  prefix,
105
126
 
106
- variantGroupingEnabled
107
- ? regex.any([
108
- // Or any of those things but grouped separated by commas
109
- regex.pattern([/\(/, utility, regex.zeroOrMore([/,/, utility]), /\)/]),
110
-
111
- // Arbitrary properties, constrained utilities, arbitrary values, etc…
112
- utility,
113
- ])
114
- : utility,
127
+ utility,
115
128
  ])
116
129
  }
117
130
 
@@ -1,7 +1,7 @@
1
1
  import dlv from 'dlv'
2
2
  import didYouMean from 'didyoumean'
3
3
  import transformThemeValue from '../util/transformThemeValue'
4
- import parseValue from 'postcss-value-parser'
4
+ import parseValue from '../value-parser/index'
5
5
  import { normalizeScreens } from '../util/normalizeScreens'
6
6
  import buildMediaQuery from '../util/buildMediaQuery'
7
7
  import { toPath } from '../util/toPath'
@@ -146,6 +146,9 @@ function resolveVNode(node, vNode, functions) {
146
146
  }
147
147
 
148
148
  function resolveFunctions(node, input, functions) {
149
+ let hasAnyFn = Object.keys(functions).some((fn) => input.includes(`${fn}(`))
150
+ if (!hasAnyFn) return input
151
+
149
152
  return parseValue(input)
150
153
  .walk((vNode) => {
151
154
  resolveVNode(node, vNode, functions)