tailwindcss 3.2.7 → 3.3.1

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 (87) hide show
  1. package/CHANGELOG.md +55 -8
  2. package/lib/cli/build/index.js +7 -3
  3. package/lib/cli/build/plugin.js +28 -19
  4. package/lib/cli/build/watching.js +4 -2
  5. package/lib/cli/index.js +12 -21
  6. package/lib/cli/init/index.js +21 -6
  7. package/lib/corePluginList.js +4 -0
  8. package/lib/corePlugins.js +282 -26
  9. package/lib/css/preflight.css +2 -0
  10. package/lib/featureFlags.js +8 -1
  11. package/lib/lib/expandApplyAtRules.js +12 -1
  12. package/lib/lib/generateRules.js +14 -10
  13. package/lib/lib/getModuleDependencies.js +79 -33
  14. package/lib/lib/load-config.js +40 -0
  15. package/lib/lib/setupContextUtils.js +10 -2
  16. package/lib/lib/setupTrackingContext.js +4 -4
  17. package/lib/lib/sharedState.js +6 -1
  18. package/lib/oxide/cli/build/index.js +7 -3
  19. package/lib/oxide/cli/build/plugin.js +27 -18
  20. package/lib/oxide/cli/build/watching.js +1 -1
  21. package/lib/oxide/cli/index.js +10 -16
  22. package/lib/oxide/cli/init/index.js +19 -4
  23. package/lib/public/colors.js +44 -22
  24. package/lib/public/default-config.js +2 -2
  25. package/lib/public/default-theme.js +2 -2
  26. package/lib/public/load-config.js +10 -0
  27. package/lib/util/applyImportantSelector.js +37 -0
  28. package/lib/util/dataTypes.js +3 -0
  29. package/lib/util/formatVariantSelector.js +34 -32
  30. package/lib/util/getAllConfigs.js +2 -2
  31. package/lib/util/normalizeConfig.js +2 -3
  32. package/lib/util/pluginUtils.js +9 -2
  33. package/lib/util/resolveConfigPath.js +19 -7
  34. package/lib/util/splitAtTopLevelOnly.js +7 -1
  35. package/lib/util/validateConfig.js +11 -0
  36. package/loadConfig.d.ts +4 -0
  37. package/loadConfig.js +2 -0
  38. package/package.json +5 -4
  39. package/src/cli/build/index.js +7 -7
  40. package/src/cli/build/plugin.js +28 -23
  41. package/src/cli/build/watching.js +4 -2
  42. package/src/cli/index.js +8 -26
  43. package/src/cli/init/index.js +37 -8
  44. package/src/corePluginList.js +1 -1
  45. package/src/corePlugins.js +184 -27
  46. package/src/css/preflight.css +2 -0
  47. package/src/featureFlags.js +7 -0
  48. package/src/lib/expandApplyAtRules.js +14 -1
  49. package/src/lib/generateRules.js +15 -5
  50. package/src/lib/getModuleDependencies.js +70 -30
  51. package/src/lib/load-config.ts +31 -0
  52. package/src/lib/setupContextUtils.js +9 -2
  53. package/src/lib/setupTrackingContext.js +4 -4
  54. package/src/lib/sharedState.js +15 -6
  55. package/src/oxide/cli/build/index.ts +7 -7
  56. package/src/oxide/cli/build/plugin.ts +28 -22
  57. package/src/oxide/cli/build/watching.ts +1 -1
  58. package/src/oxide/cli/index.ts +7 -15
  59. package/src/oxide/cli/init/index.ts +34 -7
  60. package/src/public/colors.js +22 -0
  61. package/src/public/default-config.js +1 -1
  62. package/src/public/default-theme.js +2 -2
  63. package/src/public/load-config.js +2 -0
  64. package/src/util/applyImportantSelector.js +30 -0
  65. package/src/util/dataTypes.js +4 -0
  66. package/src/util/formatVariantSelector.js +36 -10
  67. package/src/util/getAllConfigs.js +2 -2
  68. package/src/util/normalizeConfig.js +2 -1
  69. package/src/util/pluginUtils.js +10 -2
  70. package/src/util/resolveConfigPath.js +12 -1
  71. package/src/util/splitAtTopLevelOnly.js +8 -1
  72. package/src/util/validateConfig.js +13 -0
  73. package/stubs/.gitignore +1 -0
  74. package/stubs/.prettierrc.json +6 -0
  75. package/stubs/{defaultConfig.stub.js → config.full.js} +36 -1
  76. package/stubs/{simpleConfig.stub.js → config.simple.js} +0 -1
  77. package/stubs/postcss.config.js +6 -0
  78. package/stubs/tailwind.config.cjs +2 -0
  79. package/stubs/tailwind.config.js +2 -0
  80. package/stubs/tailwind.config.ts +3 -0
  81. package/types/config.d.ts +8 -7
  82. package/types/generated/colors.d.ts +22 -0
  83. package/types/generated/corePluginList.d.ts +1 -1
  84. package/types/generated/default-theme.d.ts +31 -2
  85. package/lib/constants.js +0 -44
  86. package/src/constants.js +0 -17
  87. /package/stubs/{defaultPostCssConfig.stub.js → postcss.config.cjs} +0 -0
@@ -1,6 +1,7 @@
1
1
  import fs from 'fs'
2
2
  import * as path from 'path'
3
3
  import postcss from 'postcss'
4
+ import { env } from './lib/sharedState'
4
5
  import createUtilityPlugin from './util/createUtilityPlugin'
5
6
  import buildMediaQuery from './util/buildMediaQuery'
6
7
  import escapeClassName from './util/escapeClassName'
@@ -198,23 +199,8 @@ export let variantPlugins = {
198
199
  },
199
200
 
200
201
  directionVariants: ({ addVariant }) => {
201
- addVariant('ltr', () => {
202
- log.warn('rtl-experimental', [
203
- 'The RTL features in Tailwind CSS are currently in preview.',
204
- 'Preview features are not covered by semver, and may be improved in breaking ways at any time.',
205
- ])
206
-
207
- return '[dir="ltr"] &'
208
- })
209
-
210
- addVariant('rtl', () => {
211
- log.warn('rtl-experimental', [
212
- 'The RTL features in Tailwind CSS are currently in preview.',
213
- 'Preview features are not covered by semver, and may be improved in breaking ways at any time.',
214
- ])
215
-
216
- return '[dir="rtl"] &'
217
- })
202
+ addVariant('ltr', ':is([dir="ltr"] &)')
203
+ addVariant('rtl', ':is([dir="rtl"] &)')
218
204
  },
219
205
 
220
206
  reducedMotionVariants: ({ addVariant }) => {
@@ -235,7 +221,7 @@ export let variantPlugins = {
235
221
  }
236
222
 
237
223
  if (mode === 'class') {
238
- addVariant('dark', `${className} &`)
224
+ addVariant('dark', `:is(${className} &)`)
239
225
  } else if (mode === 'media') {
240
226
  addVariant('dark', '@media (prefers-color-scheme: dark)')
241
227
  }
@@ -640,12 +626,14 @@ export let corePlugins = {
640
626
  inset: createUtilityPlugin(
641
627
  'inset',
642
628
  [
643
- ['inset', ['top', 'right', 'bottom', 'left']],
629
+ ['inset', ['inset']],
644
630
  [
645
631
  ['inset-x', ['left', 'right']],
646
632
  ['inset-y', ['top', 'bottom']],
647
633
  ],
648
634
  [
635
+ ['start', ['inset-inline-start']],
636
+ ['end', ['inset-inline-end']],
649
637
  ['top', ['top']],
650
638
  ['right', ['right']],
651
639
  ['bottom', ['bottom']],
@@ -697,6 +685,8 @@ export let corePlugins = {
697
685
  ['my', ['margin-top', 'margin-bottom']],
698
686
  ],
699
687
  [
688
+ ['ms', ['margin-inline-start']],
689
+ ['me', ['margin-inline-end']],
700
690
  ['mt', ['margin-top']],
701
691
  ['mr', ['margin-right']],
702
692
  ['mb', ['margin-bottom']],
@@ -713,6 +703,29 @@ export let corePlugins = {
713
703
  })
714
704
  },
715
705
 
706
+ lineClamp: ({ matchUtilities, addUtilities, theme }) => {
707
+ matchUtilities(
708
+ {
709
+ 'line-clamp': (value) => ({
710
+ overflow: 'hidden',
711
+ display: '-webkit-box',
712
+ '-webkit-box-orient': 'vertical',
713
+ '-webkit-line-clamp': `${value}`,
714
+ }),
715
+ },
716
+ { values: theme('lineClamp') }
717
+ )
718
+
719
+ addUtilities({
720
+ '.line-clamp-none': {
721
+ overflow: 'visible',
722
+ display: 'block',
723
+ '-webkit-box-orient': 'horizontal',
724
+ '-webkit-line-clamp': 'none',
725
+ },
726
+ })
727
+ },
728
+
716
729
  display: ({ addUtilities }) => {
717
730
  addUtilities({
718
731
  '.block': { display: 'block' },
@@ -767,6 +780,13 @@ export let corePlugins = {
767
780
  })
768
781
  },
769
782
 
783
+ captionSide: ({ addUtilities }) => {
784
+ addUtilities({
785
+ '.caption-top': { 'caption-side': 'top' },
786
+ '.caption-bottom': { 'caption-side': 'bottom' },
787
+ })
788
+ },
789
+
770
790
  borderCollapse: ({ addUtilities }) => {
771
791
  addUtilities({
772
792
  '.border-collapse': { 'border-collapse': 'collapse' },
@@ -1045,6 +1065,8 @@ export let corePlugins = {
1045
1065
  ['scroll-my', ['scroll-margin-top', 'scroll-margin-bottom']],
1046
1066
  ],
1047
1067
  [
1068
+ ['scroll-ms', ['scroll-margin-inline-start']],
1069
+ ['scroll-me', ['scroll-margin-inline-end']],
1048
1070
  ['scroll-mt', ['scroll-margin-top']],
1049
1071
  ['scroll-mr', ['scroll-margin-right']],
1050
1072
  ['scroll-mb', ['scroll-margin-bottom']],
@@ -1061,6 +1083,8 @@ export let corePlugins = {
1061
1083
  ['scroll-py', ['scroll-padding-top', 'scroll-padding-bottom']],
1062
1084
  ],
1063
1085
  [
1086
+ ['scroll-ps', ['scroll-padding-inline-start']],
1087
+ ['scroll-pe', ['scroll-padding-inline-end']],
1064
1088
  ['scroll-pt', ['scroll-padding-top']],
1065
1089
  ['scroll-pr', ['scroll-padding-right']],
1066
1090
  ['scroll-pb', ['scroll-padding-bottom']],
@@ -1074,8 +1098,8 @@ export let corePlugins = {
1074
1098
  '.list-outside': { 'list-style-position': 'outside' },
1075
1099
  })
1076
1100
  },
1077
-
1078
1101
  listStyleType: createUtilityPlugin('listStyleType', [['list', ['listStyleType']]]),
1102
+ listStyleImage: createUtilityPlugin('listStyleImage', [['list-image', ['listStyleImage']]]),
1079
1103
 
1080
1104
  appearance: ({ addUtilities }) => {
1081
1105
  addUtilities({
@@ -1180,6 +1204,7 @@ export let corePlugins = {
1180
1204
 
1181
1205
  alignContent: ({ addUtilities }) => {
1182
1206
  addUtilities({
1207
+ '.content-normal': { 'align-content': 'normal' },
1183
1208
  '.content-center': { 'align-content': 'center' },
1184
1209
  '.content-start': { 'align-content': 'flex-start' },
1185
1210
  '.content-end': { 'align-content': 'flex-end' },
@@ -1187,6 +1212,7 @@ export let corePlugins = {
1187
1212
  '.content-around': { 'align-content': 'space-around' },
1188
1213
  '.content-evenly': { 'align-content': 'space-evenly' },
1189
1214
  '.content-baseline': { 'align-content': 'baseline' },
1215
+ '.content-stretch': { 'align-content': 'stretch' },
1190
1216
  })
1191
1217
  },
1192
1218
 
@@ -1202,12 +1228,14 @@ export let corePlugins = {
1202
1228
 
1203
1229
  justifyContent: ({ addUtilities }) => {
1204
1230
  addUtilities({
1231
+ '.justify-normal': { 'justify-content': 'normal' },
1205
1232
  '.justify-start': { 'justify-content': 'flex-start' },
1206
1233
  '.justify-end': { 'justify-content': 'flex-end' },
1207
1234
  '.justify-center': { 'justify-content': 'center' },
1208
1235
  '.justify-between': { 'justify-content': 'space-between' },
1209
1236
  '.justify-around': { 'justify-content': 'space-around' },
1210
1237
  '.justify-evenly': { 'justify-content': 'space-evenly' },
1238
+ '.justify-stretch': { 'justify-content': 'stretch' },
1211
1239
  })
1212
1240
  },
1213
1241
 
@@ -1234,6 +1262,16 @@ export let corePlugins = {
1234
1262
  'space-x': (value) => {
1235
1263
  value = value === '0' ? '0px' : value
1236
1264
 
1265
+ if (env.OXIDE) {
1266
+ return {
1267
+ '& > :not([hidden]) ~ :not([hidden])': {
1268
+ '--tw-space-x-reverse': '0',
1269
+ 'margin-inline-end': `calc(${value} * var(--tw-space-x-reverse))`,
1270
+ 'margin-inline-start': `calc(${value} * calc(1 - var(--tw-space-x-reverse)))`,
1271
+ },
1272
+ }
1273
+ }
1274
+
1237
1275
  return {
1238
1276
  '& > :not([hidden]) ~ :not([hidden])': {
1239
1277
  '--tw-space-x-reverse': '0',
@@ -1269,6 +1307,17 @@ export let corePlugins = {
1269
1307
  'divide-x': (value) => {
1270
1308
  value = value === '0' ? '0px' : value
1271
1309
 
1310
+ if (env.OXIDE) {
1311
+ return {
1312
+ '& > :not([hidden]) ~ :not([hidden])': {
1313
+ '@defaults border-width': {},
1314
+ '--tw-divide-x-reverse': '0',
1315
+ 'border-inline-end-width': `calc(${value} * var(--tw-divide-x-reverse))`,
1316
+ 'border-inline-start-width': `calc(${value} * calc(1 - var(--tw-divide-x-reverse)))`,
1317
+ },
1318
+ }
1319
+ }
1320
+
1272
1321
  return {
1273
1322
  '& > :not([hidden]) ~ :not([hidden])': {
1274
1323
  '@defaults border-width': {},
@@ -1436,6 +1485,14 @@ export let corePlugins = {
1436
1485
  })
1437
1486
  },
1438
1487
 
1488
+ hyphens: ({ addUtilities }) => {
1489
+ addUtilities({
1490
+ '.hyphens-none': { hyphens: 'none' },
1491
+ '.hyphens-manual': { hyphens: 'manual' },
1492
+ '.hyphens-auto': { hyphens: 'auto' },
1493
+ })
1494
+ },
1495
+
1439
1496
  whitespace: ({ addUtilities }) => {
1440
1497
  addUtilities({
1441
1498
  '.whitespace-normal': { 'white-space': 'normal' },
@@ -1443,6 +1500,7 @@ export let corePlugins = {
1443
1500
  '.whitespace-pre': { 'white-space': 'pre' },
1444
1501
  '.whitespace-pre-line': { 'white-space': 'pre-line' },
1445
1502
  '.whitespace-pre-wrap': { 'white-space': 'pre-wrap' },
1503
+ '.whitespace-break-spaces': { 'white-space': 'break-spaces' },
1446
1504
  })
1447
1505
  },
1448
1506
 
@@ -1458,12 +1516,18 @@ export let corePlugins = {
1458
1516
  borderRadius: createUtilityPlugin('borderRadius', [
1459
1517
  ['rounded', ['border-radius']],
1460
1518
  [
1519
+ ['rounded-s', ['border-start-start-radius', 'border-end-start-radius']],
1520
+ ['rounded-e', ['border-start-end-radius', 'border-end-end-radius']],
1461
1521
  ['rounded-t', ['border-top-left-radius', 'border-top-right-radius']],
1462
1522
  ['rounded-r', ['border-top-right-radius', 'border-bottom-right-radius']],
1463
1523
  ['rounded-b', ['border-bottom-right-radius', 'border-bottom-left-radius']],
1464
1524
  ['rounded-l', ['border-top-left-radius', 'border-bottom-left-radius']],
1465
1525
  ],
1466
1526
  [
1527
+ ['rounded-ss', ['border-start-start-radius']],
1528
+ ['rounded-se', ['border-start-end-radius']],
1529
+ ['rounded-ee', ['border-end-end-radius']],
1530
+ ['rounded-es', ['border-end-start-radius']],
1467
1531
  ['rounded-tl', ['border-top-left-radius']],
1468
1532
  ['rounded-tr', ['border-top-right-radius']],
1469
1533
  ['rounded-br', ['border-bottom-right-radius']],
@@ -1480,6 +1544,8 @@ export let corePlugins = {
1480
1544
  ['border-y', [['@defaults border-width', {}], 'border-top-width', 'border-bottom-width']],
1481
1545
  ],
1482
1546
  [
1547
+ ['border-s', [['@defaults border-width', {}], 'border-inline-start-width']],
1548
+ ['border-e', [['@defaults border-width', {}], 'border-inline-end-width']],
1483
1549
  ['border-t', [['@defaults border-width', {}], 'border-top-width']],
1484
1550
  ['border-r', [['@defaults border-width', {}], 'border-right-width']],
1485
1551
  ['border-b', [['@defaults border-width', {}], 'border-bottom-width']],
@@ -1562,6 +1628,32 @@ export let corePlugins = {
1562
1628
 
1563
1629
  matchUtilities(
1564
1630
  {
1631
+ 'border-s': (value) => {
1632
+ if (!corePlugins('borderOpacity')) {
1633
+ return {
1634
+ 'border-inline-start-color': toColorValue(value),
1635
+ }
1636
+ }
1637
+
1638
+ return withAlphaVariable({
1639
+ color: value,
1640
+ property: 'border-inline-start-color',
1641
+ variable: '--tw-border-opacity',
1642
+ })
1643
+ },
1644
+ 'border-e': (value) => {
1645
+ if (!corePlugins('borderOpacity')) {
1646
+ return {
1647
+ 'border-inline-end-color': toColorValue(value),
1648
+ }
1649
+ }
1650
+
1651
+ return withAlphaVariable({
1652
+ color: value,
1653
+ property: 'border-inline-end-color',
1654
+ variable: '--tw-border-opacity',
1655
+ })
1656
+ },
1565
1657
  'border-t': (value) => {
1566
1658
  if (!corePlugins('borderOpacity')) {
1567
1659
  return {
@@ -1664,40 +1756,92 @@ export let corePlugins = {
1664
1756
  type: ['color', 'any'],
1665
1757
  }
1666
1758
 
1759
+ let positionOptions = {
1760
+ values: theme('gradientColorStopPositions'),
1761
+ type: ['length', 'percentage'],
1762
+ }
1763
+
1667
1764
  matchUtilities(
1668
1765
  {
1669
1766
  from: (value) => {
1670
1767
  let transparentToValue = transparentTo(value)
1671
1768
 
1672
1769
  return {
1673
- '--tw-gradient-from': toColorValue(value, 'from'),
1674
- '--tw-gradient-to': transparentToValue,
1770
+ '--tw-gradient-from': `${toColorValue(
1771
+ value,
1772
+ 'from'
1773
+ )} var(--tw-gradient-from-position)`,
1774
+ '--tw-gradient-from-position': ' ',
1775
+ '--tw-gradient-to': `${transparentToValue} var(--tw-gradient-from-position)`,
1776
+ '--tw-gradient-to-position': ' ',
1675
1777
  '--tw-gradient-stops': `var(--tw-gradient-from), var(--tw-gradient-to)`,
1676
1778
  }
1677
1779
  },
1678
1780
  },
1679
1781
  options
1680
1782
  )
1783
+
1784
+ matchUtilities(
1785
+ {
1786
+ from: (value) => {
1787
+ return {
1788
+ '--tw-gradient-from-position': value,
1789
+ }
1790
+ },
1791
+ },
1792
+ positionOptions
1793
+ )
1794
+
1681
1795
  matchUtilities(
1682
1796
  {
1683
1797
  via: (value) => {
1684
1798
  let transparentToValue = transparentTo(value)
1685
1799
 
1686
1800
  return {
1687
- '--tw-gradient-to': transparentToValue,
1801
+ '--tw-gradient-via-position': ' ',
1802
+ '--tw-gradient-to': `${transparentToValue} var(--tw-gradient-to-position)`,
1803
+ '--tw-gradient-to-position': ' ',
1688
1804
  '--tw-gradient-stops': `var(--tw-gradient-from), ${toColorValue(
1689
1805
  value,
1690
1806
  'via'
1691
- )}, var(--tw-gradient-to)`,
1807
+ )} var(--tw-gradient-via-position), var(--tw-gradient-to)`,
1692
1808
  }
1693
1809
  },
1694
1810
  },
1695
1811
  options
1696
1812
  )
1813
+
1697
1814
  matchUtilities(
1698
- { to: (value) => ({ '--tw-gradient-to': toColorValue(value, 'to') }) },
1815
+ {
1816
+ via: (value) => {
1817
+ return {
1818
+ '--tw-gradient-via-position': value,
1819
+ }
1820
+ },
1821
+ },
1822
+ positionOptions
1823
+ )
1824
+
1825
+ matchUtilities(
1826
+ {
1827
+ to: (value) => ({
1828
+ '--tw-gradient-to': `${toColorValue(value, 'to')} var(--tw-gradient-to-position)`,
1829
+ '--tw-gradient-to-position': ' ',
1830
+ }),
1831
+ },
1699
1832
  options
1700
1833
  )
1834
+
1835
+ matchUtilities(
1836
+ {
1837
+ to: (value) => {
1838
+ return {
1839
+ '--tw-gradient-to-position': value,
1840
+ }
1841
+ },
1842
+ },
1843
+ positionOptions
1844
+ )
1701
1845
  }
1702
1846
  })(),
1703
1847
 
@@ -1798,6 +1942,8 @@ export let corePlugins = {
1798
1942
  ['py', ['padding-top', 'padding-bottom']],
1799
1943
  ],
1800
1944
  [
1945
+ ['ps', ['padding-inline-start']],
1946
+ ['pe', ['padding-inline-end']],
1801
1947
  ['pt', ['padding-top']],
1802
1948
  ['pr', ['padding-right']],
1803
1949
  ['pb', ['padding-bottom']],
@@ -1841,13 +1987,16 @@ export let corePlugins = {
1841
1987
  font: (value) => {
1842
1988
  let [families, options = {}] =
1843
1989
  Array.isArray(value) && isPlainObject(value[1]) ? value : [value]
1844
- let { fontFeatureSettings } = options
1990
+ let { fontFeatureSettings, fontVariationSettings } = options
1845
1991
 
1846
1992
  return {
1847
1993
  'font-family': Array.isArray(families) ? families.join(', ') : families,
1848
1994
  ...(fontFeatureSettings === undefined
1849
1995
  ? {}
1850
1996
  : { 'font-feature-settings': fontFeatureSettings }),
1997
+ ...(fontVariationSettings === undefined
1998
+ ? {}
1999
+ : { 'font-variation-settings': fontVariationSettings }),
1851
2000
  }
1852
2001
  },
1853
2002
  },
@@ -1861,9 +2010,16 @@ export let corePlugins = {
1861
2010
  fontSize: ({ matchUtilities, theme }) => {
1862
2011
  matchUtilities(
1863
2012
  {
1864
- text: (value) => {
2013
+ text: (value, { modifier }) => {
1865
2014
  let [fontSize, options] = Array.isArray(value) ? value : [value]
1866
2015
 
2016
+ if (modifier) {
2017
+ return {
2018
+ 'font-size': fontSize,
2019
+ 'line-height': modifier,
2020
+ }
2021
+ }
2022
+
1867
2023
  let { lineHeight, letterSpacing, fontWeight } = isPlainObject(options)
1868
2024
  ? options
1869
2025
  : { lineHeight: options }
@@ -1878,6 +2034,7 @@ export let corePlugins = {
1878
2034
  },
1879
2035
  {
1880
2036
  values: theme('fontSize'),
2037
+ modifiers: theme('lineHeight'),
1881
2038
  type: ['absolute-size', 'relative-size', 'length', 'percentage'],
1882
2039
  }
1883
2040
  )
@@ -23,6 +23,7 @@
23
23
  3. Use a more readable tab size.
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
+ 6. Use the user's configured `sans` font-variation-settings by default.
26
27
  */
27
28
 
28
29
  html {
@@ -32,6 +33,7 @@ html {
32
33
  tab-size: 4; /* 3 */
33
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 */
34
35
  font-feature-settings: theme('fontFamily.sans[1].fontFeatureSettings', normal); /* 5 */
36
+ font-variation-settings: theme('fontFamily.sans[1].fontVariationSettings', normal); /* 6 */
35
37
  }
36
38
 
37
39
  /*
@@ -1,9 +1,16 @@
1
1
  import colors from 'picocolors'
2
2
  import log from './util/log'
3
+ import { env } from './lib/sharedState'
3
4
 
4
5
  let defaults = {
5
6
  optimizeUniversalDefaults: false,
6
7
  generalizedModifiers: true,
8
+ get disableColorOpacityUtilitiesByDefault() {
9
+ return env.OXIDE
10
+ },
11
+ get relativeContentPathsByDefault() {
12
+ return env.OXIDE
13
+ },
7
14
  }
8
15
 
9
16
  let featureFlags = {
@@ -3,6 +3,8 @@ import parser from 'postcss-selector-parser'
3
3
 
4
4
  import { resolveMatches } from './generateRules'
5
5
  import escapeClassName from '../util/escapeClassName'
6
+ import { applyImportantSelector } from '../util/applyImportantSelector'
7
+ import { collectPseudoElements, sortSelector } from '../util/formatVariantSelector.js'
6
8
 
7
9
  /** @typedef {Map<string, [any, import('postcss').Rule[]]>} ApplyCache */
8
10
 
@@ -555,12 +557,23 @@ function processApply(root, context, localCache) {
555
557
 
556
558
  // And then re-add it if it was removed
557
559
  if (importantSelector && parentSelector !== parent.selector) {
558
- rule.selector = `${importantSelector} ${rule.selector}`
560
+ rule.selector = applyImportantSelector(rule.selector, importantSelector)
559
561
  }
560
562
 
561
563
  rule.walkDecls((d) => {
562
564
  d.important = meta.important || important
563
565
  })
566
+
567
+ // Move pseudo elements to the end of the selector (if necessary)
568
+ let selector = parser().astSync(rule.selector)
569
+ selector.each((sel) => {
570
+ let [pseudoElements] = collectPseudoElements(sel)
571
+ if (pseudoElements.length > 0) {
572
+ sel.nodes.push(...pseudoElements.sort(sortSelector))
573
+ }
574
+ })
575
+
576
+ rule.selector = selector.toString()
564
577
  })
565
578
  }
566
579
 
@@ -17,6 +17,7 @@ import { isValidVariantFormatString, parseVariant } from './setupContextUtils'
17
17
  import isValidArbitraryValue from '../util/isSyntacticallyValidPropertyValue'
18
18
  import { splitAtTopLevelOnly } from '../util/splitAtTopLevelOnly.js'
19
19
  import { flagEnabled } from '../featureFlags'
20
+ import { applyImportantSelector } from '../util/applyImportantSelector'
20
21
 
21
22
  let classNameParser = selectorParser((selectors) => {
22
23
  return selectors.first.filter(({ type }) => type === 'class').pop().value
@@ -205,17 +206,26 @@ function applyVariant(variant, matches, context) {
205
206
 
206
207
  // Register arbitrary variants
207
208
  if (isArbitraryValue(variant) && !context.variantMap.has(variant)) {
209
+ let sort = context.offsets.recordVariant(variant)
210
+
208
211
  let selector = normalize(variant.slice(1, -1))
212
+ let selectors = splitAtTopLevelOnly(selector, ',')
209
213
 
210
- if (!isValidVariantFormatString(selector)) {
214
+ // We do not support multiple selectors for arbitrary variants
215
+ if (selectors.length > 1) {
211
216
  return []
212
217
  }
213
218
 
214
- let fn = parseVariant(selector)
219
+ if (!selectors.every(isValidVariantFormatString)) {
220
+ return []
221
+ }
215
222
 
216
- let sort = context.offsets.recordVariant(variant)
223
+ let records = selectors.map((sel, idx) => [
224
+ context.offsets.applyParallelOffset(sort, idx),
225
+ parseVariant(sel.trim()),
226
+ ])
217
227
 
218
- context.variantMap.set(variant, [[sort, fn]])
228
+ context.variantMap.set(variant, records)
219
229
  }
220
230
 
221
231
  if (context.variantMap.has(variant)) {
@@ -859,7 +869,7 @@ function getImportantStrategy(important) {
859
869
  }
860
870
 
861
871
  rule.selectors = rule.selectors.map((selector) => {
862
- return `${important} ${selector}`
872
+ return applyImportantSelector(selector, important)
863
873
  })
864
874
  }
865
875
  }
@@ -1,39 +1,79 @@
1
1
  import fs from 'fs'
2
2
  import path from 'path'
3
- import resolve from 'resolve'
4
- import detective from 'detective'
5
3
 
6
- function createModule(file) {
7
- const source = fs.readFileSync(file, 'utf-8')
8
- const requires = detective(source)
4
+ let jsExtensions = ['.js', '.cjs', '.mjs']
9
5
 
10
- return { file, requires }
6
+ // Given the current file `a.ts`, we want to make sure that when importing `b` that we resolve
7
+ // `b.ts` before `b.js`
8
+ //
9
+ // E.g.:
10
+ //
11
+ // a.ts
12
+ // b // .ts
13
+ // c // .ts
14
+ // a.js
15
+ // b // .js or .ts
16
+
17
+ let jsResolutionOrder = ['', '.js', '.cjs', '.mjs', '.ts', '.cts', '.mts', '.jsx', '.tsx']
18
+ let tsResolutionOrder = ['', '.ts', '.cts', '.mts', '.tsx', '.js', '.cjs', '.mjs', '.jsx']
19
+
20
+ function resolveWithExtension(file, extensions) {
21
+ // Try to find `./a.ts`, `./a.ts`, ... from `./a`
22
+ for (let ext of extensions) {
23
+ let full = `${file}${ext}`
24
+ if (fs.existsSync(full) && fs.statSync(full).isFile()) {
25
+ return full
26
+ }
27
+ }
28
+
29
+ // Try to find `./a/index.js` from `./a`
30
+ for (let ext of extensions) {
31
+ let full = `${file}/index${ext}`
32
+ if (fs.existsSync(full)) {
33
+ return full
34
+ }
35
+ }
36
+
37
+ return null
11
38
  }
12
39
 
13
- export default function getModuleDependencies(entryFile) {
14
- const rootModule = createModule(entryFile)
15
- const modules = [rootModule]
16
-
17
- // Iterate over the modules, even when new
18
- // ones are being added
19
- for (const mdl of modules) {
20
- mdl.requires
21
- .filter((dep) => {
22
- // Only track local modules, not node_modules
23
- return dep.startsWith('./') || dep.startsWith('../')
24
- })
25
- .forEach((dep) => {
26
- try {
27
- const basedir = path.dirname(mdl.file)
28
- const depPath = resolve.sync(dep, { basedir })
29
- const depModule = createModule(depPath)
30
-
31
- modules.push(depModule)
32
- } catch (_err) {
33
- // eslint-disable-next-line no-empty
34
- }
35
- })
40
+ function* _getModuleDependencies(filename, base, seen, ext = path.extname(filename)) {
41
+ // Try to find the file
42
+ let absoluteFile = resolveWithExtension(
43
+ path.resolve(base, filename),
44
+ jsExtensions.includes(ext) ? jsResolutionOrder : tsResolutionOrder
45
+ )
46
+ if (absoluteFile === null) return // File doesn't exist
47
+
48
+ // Prevent infinite loops when there are circular dependencies
49
+ if (seen.has(absoluteFile)) return // Already seen
50
+ seen.add(absoluteFile)
51
+
52
+ // Mark the file as a dependency
53
+ yield absoluteFile
54
+
55
+ // Resolve new base for new imports/requires
56
+ base = path.dirname(absoluteFile)
57
+ ext = path.extname(absoluteFile)
58
+
59
+ let contents = fs.readFileSync(absoluteFile, 'utf-8')
60
+
61
+ // Find imports/requires
62
+ for (let match of [
63
+ ...contents.matchAll(/import[\s\S]*?['"](.{3,}?)['"]/gi),
64
+ ...contents.matchAll(/import[\s\S]*from[\s\S]*?['"](.{3,}?)['"]/gi),
65
+ ...contents.matchAll(/require\(['"`](.+)['"`]\)/gi),
66
+ ]) {
67
+ // Bail out if it's not a relative file
68
+ if (!match[1].startsWith('.')) continue
69
+
70
+ yield* _getModuleDependencies(match[1], base, seen, ext)
36
71
  }
72
+ }
37
73
 
38
- return modules
74
+ export default function getModuleDependencies(absoluteFilePath) {
75
+ if (absoluteFilePath === null) return new Set()
76
+ return new Set(
77
+ _getModuleDependencies(absoluteFilePath, path.dirname(absoluteFilePath), new Set())
78
+ )
39
79
  }