tailwindcss 3.1.8 → 3.2.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 (101) hide show
  1. package/CHANGELOG.md +64 -3
  2. package/README.md +6 -5
  3. package/lib/cli/build/deps.js +54 -0
  4. package/lib/cli/build/index.js +44 -0
  5. package/lib/cli/build/plugin.js +351 -0
  6. package/lib/cli/build/utils.js +78 -0
  7. package/lib/cli/build/watching.js +113 -0
  8. package/lib/cli/help/index.js +71 -0
  9. package/lib/cli/index.js +18 -0
  10. package/lib/cli/init/index.js +46 -0
  11. package/lib/cli/shared.js +12 -0
  12. package/lib/cli.js +11 -590
  13. package/lib/corePlugins.js +332 -108
  14. package/lib/css/preflight.css +5 -0
  15. package/lib/featureFlags.js +7 -4
  16. package/lib/index.js +6 -1
  17. package/lib/lib/content.js +167 -0
  18. package/lib/lib/defaultExtractor.js +15 -10
  19. package/lib/lib/detectNesting.js +2 -2
  20. package/lib/lib/evaluateTailwindFunctions.js +17 -1
  21. package/lib/lib/expandApplyAtRules.js +66 -37
  22. package/lib/lib/expandTailwindAtRules.js +10 -42
  23. package/lib/lib/findAtConfigPath.js +44 -0
  24. package/lib/lib/generateRules.js +180 -93
  25. package/lib/lib/normalizeTailwindDirectives.js +1 -1
  26. package/lib/lib/offsets.js +217 -0
  27. package/lib/lib/regex.js +1 -1
  28. package/lib/lib/setupContextUtils.js +339 -100
  29. package/lib/lib/setupTrackingContext.js +5 -39
  30. package/lib/lib/sharedState.js +2 -0
  31. package/lib/public/colors.js +1 -1
  32. package/lib/util/buildMediaQuery.js +6 -3
  33. package/lib/util/configurePlugins.js +1 -1
  34. package/lib/util/dataTypes.js +15 -19
  35. package/lib/util/formatVariantSelector.js +92 -8
  36. package/lib/util/getAllConfigs.js +14 -3
  37. package/lib/util/isValidArbitraryValue.js +1 -1
  38. package/lib/util/nameClass.js +3 -0
  39. package/lib/util/negateValue.js +15 -2
  40. package/lib/util/normalizeConfig.js +17 -3
  41. package/lib/util/normalizeScreens.js +100 -3
  42. package/lib/util/parseAnimationValue.js +1 -1
  43. package/lib/util/parseBoxShadowValue.js +1 -1
  44. package/lib/util/parseDependency.js +33 -54
  45. package/lib/util/parseGlob.js +34 -0
  46. package/lib/util/parseObjectStyles.js +1 -1
  47. package/lib/util/pluginUtils.js +87 -17
  48. package/lib/util/resolveConfig.js +2 -2
  49. package/lib/util/splitAtTopLevelOnly.js +31 -81
  50. package/lib/util/transformThemeValue.js +9 -2
  51. package/lib/util/validateConfig.js +1 -1
  52. package/lib/util/validateFormalSyntax.js +24 -0
  53. package/package.json +14 -13
  54. package/peers/index.js +3263 -1887
  55. package/plugin.d.ts +3 -3
  56. package/scripts/release-channel.js +18 -0
  57. package/scripts/release-notes.js +21 -0
  58. package/src/cli/build/deps.js +56 -0
  59. package/src/cli/build/index.js +45 -0
  60. package/src/cli/build/plugin.js +417 -0
  61. package/src/cli/build/utils.js +76 -0
  62. package/src/cli/build/watching.js +134 -0
  63. package/src/cli/help/index.js +70 -0
  64. package/src/cli/index.js +3 -0
  65. package/src/cli/init/index.js +50 -0
  66. package/src/cli/shared.js +5 -0
  67. package/src/cli.js +4 -696
  68. package/src/corePlugins.js +262 -39
  69. package/src/css/preflight.css +5 -0
  70. package/src/featureFlags.js +12 -2
  71. package/src/index.js +5 -0
  72. package/src/lib/content.js +205 -0
  73. package/src/lib/defaultExtractor.js +3 -0
  74. package/src/lib/evaluateTailwindFunctions.js +22 -1
  75. package/src/lib/expandApplyAtRules.js +70 -29
  76. package/src/lib/expandTailwindAtRules.js +8 -46
  77. package/src/lib/findAtConfigPath.js +48 -0
  78. package/src/lib/generateRules.js +223 -101
  79. package/src/lib/offsets.js +270 -0
  80. package/src/lib/setupContextUtils.js +376 -89
  81. package/src/lib/setupTrackingContext.js +4 -45
  82. package/src/lib/sharedState.js +2 -0
  83. package/src/util/buildMediaQuery.js +5 -3
  84. package/src/util/dataTypes.js +15 -17
  85. package/src/util/formatVariantSelector.js +113 -9
  86. package/src/util/getAllConfigs.js +14 -2
  87. package/src/util/nameClass.js +4 -0
  88. package/src/util/negateValue.js +10 -2
  89. package/src/util/normalizeConfig.js +22 -2
  90. package/src/util/normalizeScreens.js +99 -4
  91. package/src/util/parseBoxShadowValue.js +1 -1
  92. package/src/util/parseDependency.js +37 -42
  93. package/src/util/parseGlob.js +24 -0
  94. package/src/util/pluginUtils.js +96 -14
  95. package/src/util/resolveConfig.js +1 -1
  96. package/src/util/splitAtTopLevelOnly.js +23 -49
  97. package/src/util/transformThemeValue.js +9 -1
  98. package/src/util/validateFormalSyntax.js +34 -0
  99. package/stubs/defaultConfig.stub.js +20 -3
  100. package/types/config.d.ts +48 -13
  101. package/types/generated/default-theme.d.ts +11 -0
@@ -0,0 +1,134 @@
1
+ // @ts-check
2
+
3
+ import chokidar from 'chokidar'
4
+ import fs from 'fs'
5
+ import micromatch from 'micromatch'
6
+ import normalizePath from 'normalize-path'
7
+ import path from 'path'
8
+
9
+ import { readFileWithRetries } from './utils.js'
10
+
11
+ /**
12
+ *
13
+ * @param {*} args
14
+ * @param {{ state, rebuild(changedFiles: any[]): Promise<any> }} param1
15
+ * @returns {{
16
+ * fswatcher: import('chokidar').FSWatcher,
17
+ * refreshWatchedFiles(): void,
18
+ * }}
19
+ */
20
+ export function createWatcher(args, { state, rebuild }) {
21
+ let shouldPoll = args['--poll']
22
+ let shouldCoalesceWriteEvents = shouldPoll || process.platform === 'win32'
23
+
24
+ // Polling interval in milliseconds
25
+ // Used only when polling or coalescing add/change events on Windows
26
+ let pollInterval = 10
27
+
28
+ let watcher = chokidar.watch([], {
29
+ // Force checking for atomic writes in all situations
30
+ // This causes chokidar to wait up to 100ms for a file to re-added after it's been unlinked
31
+ // This only works when watching directories though
32
+ atomic: true,
33
+
34
+ usePolling: shouldPoll,
35
+ interval: shouldPoll ? pollInterval : undefined,
36
+ ignoreInitial: true,
37
+ awaitWriteFinish: shouldCoalesceWriteEvents
38
+ ? {
39
+ stabilityThreshold: 50,
40
+ pollInterval: pollInterval,
41
+ }
42
+ : false,
43
+ })
44
+
45
+ let chain = Promise.resolve()
46
+ let pendingRebuilds = new Set()
47
+ let changedContent = []
48
+
49
+ /**
50
+ *
51
+ * @param {*} file
52
+ * @param {(() => Promise<string>) | null} content
53
+ */
54
+ function recordChangedFile(file, content = null) {
55
+ file = path.resolve(file)
56
+
57
+ content = content ?? (async () => await fs.promises.readFile(file, 'utf8'))
58
+
59
+ changedContent.push({
60
+ file,
61
+ content,
62
+ extension: path.extname(file).slice(1),
63
+ })
64
+
65
+ chain = chain.then(() => rebuild(changedContent.splice(0)))
66
+
67
+ return chain
68
+ }
69
+
70
+ watcher.on('change', (file) => recordChangedFile(file))
71
+ watcher.on('add', (file) => recordChangedFile(file))
72
+
73
+ // Restore watching any files that are "removed"
74
+ // This can happen when a file is pseudo-atomically replaced (a copy is created, overwritten, the old one is unlinked, and the new one is renamed)
75
+ // TODO: An an optimization we should allow removal when the config changes
76
+ watcher.on('unlink', (file) => {
77
+ file = normalizePath(file)
78
+
79
+ // Only re-add the file if it's not covered by a dynamic pattern
80
+ if (!micromatch.some([file], state.contentPatterns.dynamic)) {
81
+ watcher.add(file)
82
+ }
83
+ })
84
+
85
+ // Some applications such as Visual Studio (but not VS Code)
86
+ // will only fire a rename event for atomic writes and not a change event
87
+ // This is very likely a chokidar bug but it's one we need to work around
88
+ // We treat this as a change event and rebuild the CSS
89
+ watcher.on('raw', (evt, filePath, meta) => {
90
+ if (evt !== 'rename') {
91
+ return
92
+ }
93
+
94
+ let watchedPath = meta.watchedPath
95
+
96
+ // Watched path might be the file itself
97
+ // Or the directory it is in
98
+ filePath = watchedPath.endsWith(filePath) ? watchedPath : path.join(watchedPath, filePath)
99
+
100
+ // Skip this event since the files it is for does not match any of the registered content globs
101
+ if (!micromatch.some([filePath], state.contentPatterns.all)) {
102
+ return
103
+ }
104
+
105
+ // Skip since we've already queued a rebuild for this file that hasn't happened yet
106
+ if (pendingRebuilds.has(filePath)) {
107
+ return
108
+ }
109
+
110
+ pendingRebuilds.add(filePath)
111
+
112
+ chain = chain.then(async () => {
113
+ let content
114
+
115
+ try {
116
+ content = await readFileWithRetries(path.resolve(filePath))
117
+ } finally {
118
+ pendingRebuilds.delete(filePath)
119
+ }
120
+
121
+ return recordChangedFile(filePath, () => content)
122
+ })
123
+ })
124
+
125
+ return {
126
+ fswatcher: watcher,
127
+
128
+ refreshWatchedFiles() {
129
+ watcher.add(Array.from(state.contextDependencies))
130
+ watcher.add(Array.from(state.configDependencies))
131
+ watcher.add(state.contentPatterns.all)
132
+ },
133
+ }
134
+ }
@@ -0,0 +1,70 @@
1
+ // @ts-check
2
+ import packageJson from '../../../package.json'
3
+
4
+ export function help({ message, usage, commands, options }) {
5
+ let indent = 2
6
+
7
+ // Render header
8
+ console.log()
9
+ console.log(`${packageJson.name} v${packageJson.version}`)
10
+
11
+ // Render message
12
+ if (message) {
13
+ console.log()
14
+ for (let msg of message.split('\n')) {
15
+ console.log(msg)
16
+ }
17
+ }
18
+
19
+ // Render usage
20
+ if (usage && usage.length > 0) {
21
+ console.log()
22
+ console.log('Usage:')
23
+ for (let example of usage) {
24
+ console.log(' '.repeat(indent), example)
25
+ }
26
+ }
27
+
28
+ // Render commands
29
+ if (commands && commands.length > 0) {
30
+ console.log()
31
+ console.log('Commands:')
32
+ for (let command of commands) {
33
+ console.log(' '.repeat(indent), command)
34
+ }
35
+ }
36
+
37
+ // Render options
38
+ if (options) {
39
+ let groupedOptions = {}
40
+ for (let [key, value] of Object.entries(options)) {
41
+ if (typeof value === 'object') {
42
+ groupedOptions[key] = { ...value, flags: [key] }
43
+ } else {
44
+ groupedOptions[value].flags.push(key)
45
+ }
46
+ }
47
+
48
+ console.log()
49
+ console.log('Options:')
50
+ for (let { flags, description, deprecated } of Object.values(groupedOptions)) {
51
+ if (deprecated) continue
52
+
53
+ if (flags.length === 1) {
54
+ console.log(
55
+ ' '.repeat(indent + 4 /* 4 = "-i, ".length */),
56
+ flags.slice().reverse().join(', ').padEnd(20, ' '),
57
+ description
58
+ )
59
+ } else {
60
+ console.log(
61
+ ' '.repeat(indent),
62
+ flags.slice().reverse().join(', ').padEnd(24, ' '),
63
+ description
64
+ )
65
+ }
66
+ }
67
+ }
68
+
69
+ console.log()
70
+ }
@@ -0,0 +1,3 @@
1
+ export * from './build'
2
+ export * from './config'
3
+ export * from './content'
@@ -0,0 +1,50 @@
1
+ // @ts-check
2
+
3
+ import fs from 'fs'
4
+ import path from 'path'
5
+
6
+ export function init(args, configs) {
7
+ let messages = []
8
+
9
+ let tailwindConfigLocation = path.resolve(args['_'][1] ?? `./${configs.tailwind}`)
10
+ if (fs.existsSync(tailwindConfigLocation)) {
11
+ messages.push(`${path.basename(tailwindConfigLocation)} already exists.`)
12
+ } else {
13
+ let stubFile = fs.readFileSync(
14
+ args['--full']
15
+ ? path.resolve(__dirname, '../../../stubs/defaultConfig.stub.js')
16
+ : path.resolve(__dirname, '../../../stubs/simpleConfig.stub.js'),
17
+ 'utf8'
18
+ )
19
+
20
+ // Change colors import
21
+ stubFile = stubFile.replace('../colors', 'tailwindcss/colors')
22
+
23
+ fs.writeFileSync(tailwindConfigLocation, stubFile, 'utf8')
24
+
25
+ messages.push(`Created Tailwind CSS config file: ${path.basename(tailwindConfigLocation)}`)
26
+ }
27
+
28
+ if (args['--postcss']) {
29
+ let postcssConfigLocation = path.resolve(`./${configs.postcss}`)
30
+ if (fs.existsSync(postcssConfigLocation)) {
31
+ messages.push(`${path.basename(postcssConfigLocation)} already exists.`)
32
+ } else {
33
+ let stubFile = fs.readFileSync(
34
+ path.resolve(__dirname, '../../../stubs/defaultPostCssConfig.stub.js'),
35
+ 'utf8'
36
+ )
37
+
38
+ fs.writeFileSync(postcssConfigLocation, stubFile, 'utf8')
39
+
40
+ messages.push(`Created PostCSS config file: ${path.basename(postcssConfigLocation)}`)
41
+ }
42
+ }
43
+
44
+ if (messages.length > 0) {
45
+ console.log()
46
+ for (let message of messages) {
47
+ console.log(message)
48
+ }
49
+ }
50
+ }
@@ -0,0 +1,5 @@
1
+ // @ts-check
2
+
3
+ export const env = {
4
+ DEBUG: process.env.DEBUG !== undefined && process.env.DEBUG !== '0',
5
+ }