tailwindcss 0.0.0-insiders.deefbf5 → 0.0.0-insiders.df96ea5

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 (218) hide show
  1. package/README.md +16 -17
  2. package/dist/chunk-GFBUASX3.mjs +1 -0
  3. package/dist/chunk-HTB5LLOP.mjs +1 -0
  4. package/dist/chunk-KV2PFGBW.mjs +38 -0
  5. package/dist/colors-b_6i0Oi7.d.ts +295 -0
  6. package/dist/colors.d.mts +295 -0
  7. package/dist/colors.d.ts +5 -0
  8. package/dist/colors.js +1 -0
  9. package/dist/colors.mjs +1 -0
  10. package/dist/default-theme.d.mts +1147 -0
  11. package/dist/default-theme.d.ts +1147 -0
  12. package/dist/default-theme.js +1 -0
  13. package/dist/default-theme.mjs +1 -0
  14. package/dist/flatten-color-palette.d.mts +6 -0
  15. package/dist/flatten-color-palette.d.ts +6 -0
  16. package/dist/flatten-color-palette.js +3 -0
  17. package/dist/flatten-color-palette.mjs +1 -0
  18. package/dist/lib.d.mts +378 -0
  19. package/dist/lib.d.ts +3 -0
  20. package/dist/lib.js +38 -0
  21. package/dist/lib.mjs +1 -0
  22. package/dist/plugin.d.mts +11 -0
  23. package/dist/plugin.d.ts +134 -0
  24. package/dist/plugin.js +1 -0
  25. package/dist/plugin.mjs +1 -0
  26. package/dist/resolve-config-BIFUA2FY.d.ts +29 -0
  27. package/dist/resolve-config-QUZ9b-Gn.d.mts +190 -0
  28. package/dist/types-CJYAW1ql.d.mts +128 -0
  29. package/index.css +896 -0
  30. package/package.json +76 -100
  31. package/preflight.css +393 -0
  32. package/theme.css +462 -0
  33. package/CHANGELOG.md +0 -2206
  34. package/base.css +0 -1
  35. package/colors.d.ts +0 -3
  36. package/colors.js +0 -2
  37. package/components.css +0 -1
  38. package/defaultConfig.d.ts +0 -3
  39. package/defaultConfig.js +0 -2
  40. package/defaultTheme.d.ts +0 -4
  41. package/defaultTheme.js +0 -2
  42. package/lib/cli-peer-dependencies.js +0 -20
  43. package/lib/cli.js +0 -805
  44. package/lib/constants.js +0 -37
  45. package/lib/corePluginList.js +0 -179
  46. package/lib/corePlugins.js +0 -3662
  47. package/lib/css/LICENSE +0 -25
  48. package/lib/css/preflight.css +0 -360
  49. package/lib/featureFlags.js +0 -61
  50. package/lib/index.js +0 -40
  51. package/lib/lib/cacheInvalidation.js +0 -87
  52. package/lib/lib/collapseAdjacentRules.js +0 -56
  53. package/lib/lib/collapseDuplicateDeclarations.js +0 -80
  54. package/lib/lib/defaultExtractor.js +0 -228
  55. package/lib/lib/detectNesting.js +0 -34
  56. package/lib/lib/evaluateTailwindFunctions.js +0 -215
  57. package/lib/lib/expandApplyAtRules.js +0 -470
  58. package/lib/lib/expandTailwindAtRules.js +0 -276
  59. package/lib/lib/generateRules.js +0 -722
  60. package/lib/lib/getModuleDependencies.js +0 -48
  61. package/lib/lib/normalizeTailwindDirectives.js +0 -84
  62. package/lib/lib/partitionApplyAtRules.js +0 -53
  63. package/lib/lib/regex.js +0 -52
  64. package/lib/lib/resolveDefaultsAtRules.js +0 -154
  65. package/lib/lib/setupContextUtils.js +0 -932
  66. package/lib/lib/setupTrackingContext.js +0 -169
  67. package/lib/lib/sharedState.js +0 -51
  68. package/lib/lib/substituteScreenAtRules.js +0 -26
  69. package/lib/postcss-plugins/nesting/README.md +0 -42
  70. package/lib/postcss-plugins/nesting/index.js +0 -17
  71. package/lib/postcss-plugins/nesting/plugin.js +0 -84
  72. package/lib/processTailwindFeatures.js +0 -59
  73. package/lib/public/colors.js +0 -329
  74. package/lib/public/create-plugin.js +0 -13
  75. package/lib/public/default-config.js +0 -14
  76. package/lib/public/default-theme.js +0 -14
  77. package/lib/public/resolve-config.js +0 -19
  78. package/lib/util/bigSign.js +0 -8
  79. package/lib/util/buildMediaQuery.js +0 -19
  80. package/lib/util/cloneDeep.js +0 -17
  81. package/lib/util/cloneNodes.js +0 -25
  82. package/lib/util/color.js +0 -90
  83. package/lib/util/configurePlugins.js +0 -18
  84. package/lib/util/createPlugin.js +0 -28
  85. package/lib/util/createUtilityPlugin.js +0 -48
  86. package/lib/util/dataTypes.js +0 -235
  87. package/lib/util/defaults.js +0 -22
  88. package/lib/util/escapeClassName.js +0 -19
  89. package/lib/util/escapeCommas.js +0 -8
  90. package/lib/util/flattenColorPalette.js +0 -14
  91. package/lib/util/formatVariantSelector.js +0 -194
  92. package/lib/util/getAllConfigs.js +0 -34
  93. package/lib/util/hashConfig.js +0 -16
  94. package/lib/util/isKeyframeRule.js +0 -8
  95. package/lib/util/isPlainObject.js +0 -12
  96. package/lib/util/isValidArbitraryValue.js +0 -63
  97. package/lib/util/log.js +0 -50
  98. package/lib/util/nameClass.js +0 -32
  99. package/lib/util/negateValue.js +0 -18
  100. package/lib/util/normalizeConfig.js +0 -250
  101. package/lib/util/normalizeScreens.js +0 -58
  102. package/lib/util/parseAnimationValue.js +0 -88
  103. package/lib/util/parseBoxShadowValue.js +0 -76
  104. package/lib/util/parseDependency.js +0 -63
  105. package/lib/util/parseObjectStyles.js +0 -31
  106. package/lib/util/pluginUtils.js +0 -187
  107. package/lib/util/prefixSelector.js +0 -20
  108. package/lib/util/removeAlphaVariables.js +0 -18
  109. package/lib/util/resolveConfig.js +0 -256
  110. package/lib/util/resolveConfigPath.js +0 -51
  111. package/lib/util/responsive.js +0 -19
  112. package/lib/util/splitAtTopLevelOnly.js +0 -90
  113. package/lib/util/tap.js +0 -9
  114. package/lib/util/toColorValue.js +0 -8
  115. package/lib/util/toPath.js +0 -14
  116. package/lib/util/transformThemeValue.js +0 -61
  117. package/lib/util/validateConfig.js +0 -21
  118. package/lib/util/withAlphaVariable.js +0 -67
  119. package/nesting/index.js +0 -2
  120. package/peers/index.js +0 -77956
  121. package/plugin.d.ts +0 -11
  122. package/plugin.js +0 -2
  123. package/prettier.config.js +0 -19
  124. package/resolveConfig.js +0 -2
  125. package/screens.css +0 -1
  126. package/scripts/create-plugin-list.js +0 -10
  127. package/scripts/generate-types.js +0 -105
  128. package/scripts/install-integrations.js +0 -27
  129. package/scripts/rebuildFixtures.js +0 -68
  130. package/scripts/type-utils.js +0 -27
  131. package/src/cli-peer-dependencies.js +0 -15
  132. package/src/cli.js +0 -915
  133. package/src/constants.js +0 -17
  134. package/src/corePluginList.js +0 -1
  135. package/src/corePlugins.js +0 -2442
  136. package/src/css/LICENSE +0 -25
  137. package/src/css/preflight.css +0 -360
  138. package/src/featureFlags.js +0 -54
  139. package/src/index.js +0 -42
  140. package/src/lib/cacheInvalidation.js +0 -52
  141. package/src/lib/collapseAdjacentRules.js +0 -58
  142. package/src/lib/collapseDuplicateDeclarations.js +0 -93
  143. package/src/lib/defaultExtractor.js +0 -208
  144. package/src/lib/detectNesting.js +0 -39
  145. package/src/lib/evaluateTailwindFunctions.js +0 -248
  146. package/src/lib/expandApplyAtRules.js +0 -539
  147. package/src/lib/expandTailwindAtRules.js +0 -292
  148. package/src/lib/generateRules.js +0 -719
  149. package/src/lib/getModuleDependencies.js +0 -39
  150. package/src/lib/normalizeTailwindDirectives.js +0 -84
  151. package/src/lib/partitionApplyAtRules.js +0 -52
  152. package/src/lib/regex.js +0 -74
  153. package/src/lib/resolveDefaultsAtRules.js +0 -163
  154. package/src/lib/setupContextUtils.js +0 -977
  155. package/src/lib/setupTrackingContext.js +0 -187
  156. package/src/lib/sharedState.js +0 -48
  157. package/src/lib/substituteScreenAtRules.js +0 -19
  158. package/src/postcss-plugins/nesting/README.md +0 -42
  159. package/src/postcss-plugins/nesting/index.js +0 -13
  160. package/src/postcss-plugins/nesting/plugin.js +0 -80
  161. package/src/processTailwindFeatures.js +0 -58
  162. package/src/public/colors.js +0 -300
  163. package/src/public/create-plugin.js +0 -2
  164. package/src/public/default-config.js +0 -4
  165. package/src/public/default-theme.js +0 -4
  166. package/src/public/resolve-config.js +0 -7
  167. package/src/util/bigSign.js +0 -3
  168. package/src/util/buildMediaQuery.js +0 -20
  169. package/src/util/cloneDeep.js +0 -11
  170. package/src/util/cloneNodes.js +0 -24
  171. package/src/util/color.js +0 -73
  172. package/src/util/configurePlugins.js +0 -23
  173. package/src/util/createPlugin.js +0 -27
  174. package/src/util/createUtilityPlugin.js +0 -37
  175. package/src/util/dataTypes.js +0 -254
  176. package/src/util/defaults.js +0 -17
  177. package/src/util/escapeClassName.js +0 -8
  178. package/src/util/escapeCommas.js +0 -3
  179. package/src/util/flattenColorPalette.js +0 -13
  180. package/src/util/formatVariantSelector.js +0 -215
  181. package/src/util/getAllConfigs.js +0 -26
  182. package/src/util/hashConfig.js +0 -5
  183. package/src/util/isKeyframeRule.js +0 -3
  184. package/src/util/isPlainObject.js +0 -8
  185. package/src/util/isValidArbitraryValue.js +0 -61
  186. package/src/util/log.js +0 -29
  187. package/src/util/nameClass.js +0 -26
  188. package/src/util/negateValue.js +0 -16
  189. package/src/util/normalizeConfig.js +0 -262
  190. package/src/util/normalizeScreens.js +0 -45
  191. package/src/util/parseAnimationValue.js +0 -68
  192. package/src/util/parseBoxShadowValue.js +0 -72
  193. package/src/util/parseDependency.js +0 -49
  194. package/src/util/parseObjectStyles.js +0 -19
  195. package/src/util/pluginUtils.js +0 -204
  196. package/src/util/prefixSelector.js +0 -14
  197. package/src/util/removeAlphaVariables.js +0 -24
  198. package/src/util/resolveConfig.js +0 -283
  199. package/src/util/resolveConfigPath.js +0 -55
  200. package/src/util/responsive.js +0 -10
  201. package/src/util/splitAtTopLevelOnly.js +0 -71
  202. package/src/util/tap.js +0 -4
  203. package/src/util/toColorValue.js +0 -3
  204. package/src/util/toPath.js +0 -26
  205. package/src/util/transformThemeValue.js +0 -54
  206. package/src/util/validateConfig.js +0 -13
  207. package/src/util/withAlphaVariable.js +0 -49
  208. package/stubs/defaultConfig.stub.js +0 -954
  209. package/stubs/defaultPostCssConfig.stub.js +0 -6
  210. package/stubs/simpleConfig.stub.js +0 -8
  211. package/tailwind.css +0 -5
  212. package/types/config.d.ts +0 -327
  213. package/types/generated/.gitkeep +0 -0
  214. package/types/generated/colors.d.ts +0 -276
  215. package/types/generated/corePluginList.d.ts +0 -1
  216. package/types/generated/default-theme.d.ts +0 -331
  217. package/types/index.d.ts +0 -7
  218. package/variants.css +0 -1
@@ -1,719 +0,0 @@
1
- import postcss from 'postcss'
2
- import selectorParser from 'postcss-selector-parser'
3
- import parseObjectStyles from '../util/parseObjectStyles'
4
- import isPlainObject from '../util/isPlainObject'
5
- import prefixSelector from '../util/prefixSelector'
6
- import { updateAllClasses } from '../util/pluginUtils'
7
- import log from '../util/log'
8
- import * as sharedState from './sharedState'
9
- import { formatVariantSelector, finalizeSelector } from '../util/formatVariantSelector'
10
- import { asClass } from '../util/nameClass'
11
- import { normalize } from '../util/dataTypes'
12
- import { isValidVariantFormatString, parseVariant } from './setupContextUtils'
13
- import isValidArbitraryValue from '../util/isValidArbitraryValue'
14
- import { splitAtTopLevelOnly } from '../util/splitAtTopLevelOnly.js'
15
- import { flagEnabled } from '../featureFlags'
16
-
17
- let classNameParser = selectorParser((selectors) => {
18
- return selectors.first.filter(({ type }) => type === 'class').pop().value
19
- })
20
-
21
- function getClassNameFromSelector(selector) {
22
- return classNameParser.transformSync(selector)
23
- }
24
-
25
- // Generate match permutations for a class candidate, like:
26
- // ['ring-offset-blue', '100']
27
- // ['ring-offset', 'blue-100']
28
- // ['ring', 'offset-blue-100']
29
- // Example with dynamic classes:
30
- // ['grid-cols', '[[linename],1fr,auto]']
31
- // ['grid', 'cols-[[linename],1fr,auto]']
32
- function* candidatePermutations(candidate) {
33
- let lastIndex = Infinity
34
-
35
- while (lastIndex >= 0) {
36
- let dashIdx
37
-
38
- if (lastIndex === Infinity && candidate.endsWith(']')) {
39
- let bracketIdx = candidate.indexOf('[')
40
-
41
- // If character before `[` isn't a dash or a slash, this isn't a dynamic class
42
- // eg. string[]
43
- dashIdx = ['-', '/'].includes(candidate[bracketIdx - 1]) ? bracketIdx - 1 : -1
44
- } else {
45
- dashIdx = candidate.lastIndexOf('-', lastIndex)
46
- }
47
-
48
- if (dashIdx < 0) {
49
- break
50
- }
51
-
52
- let prefix = candidate.slice(0, dashIdx)
53
- let modifier = candidate.slice(dashIdx + 1)
54
-
55
- yield [prefix, modifier]
56
-
57
- lastIndex = dashIdx - 1
58
- }
59
- }
60
-
61
- function applyPrefix(matches, context) {
62
- if (matches.length === 0 || context.tailwindConfig.prefix === '') {
63
- return matches
64
- }
65
-
66
- for (let match of matches) {
67
- let [meta] = match
68
- if (meta.options.respectPrefix) {
69
- let container = postcss.root({ nodes: [match[1].clone()] })
70
- let classCandidate = match[1].raws.tailwind.classCandidate
71
-
72
- container.walkRules((r) => {
73
- // If this is a negative utility with a dash *before* the prefix we
74
- // have to ensure that the generated selector matches the candidate
75
-
76
- // Not doing this will cause `-tw-top-1` to generate the class `.tw--top-1`
77
- // The disconnect between candidate <-> class can cause @apply to hard crash.
78
- let shouldPrependNegative = classCandidate.startsWith('-')
79
-
80
- r.selector = prefixSelector(
81
- context.tailwindConfig.prefix,
82
- r.selector,
83
- shouldPrependNegative
84
- )
85
- })
86
-
87
- match[1] = container.nodes[0]
88
- }
89
- }
90
-
91
- return matches
92
- }
93
-
94
- function applyImportant(matches, classCandidate) {
95
- if (matches.length === 0) {
96
- return matches
97
- }
98
- let result = []
99
-
100
- for (let [meta, rule] of matches) {
101
- let container = postcss.root({ nodes: [rule.clone()] })
102
- container.walkRules((r) => {
103
- r.selector = updateAllClasses(r.selector, (className) => {
104
- if (className === classCandidate) {
105
- return `!${className}`
106
- }
107
- return className
108
- })
109
- r.walkDecls((d) => (d.important = true))
110
- })
111
- result.push([{ ...meta, important: true }, container.nodes[0]])
112
- }
113
-
114
- return result
115
- }
116
-
117
- // Takes a list of rule tuples and applies a variant like `hover`, sm`,
118
- // whatever to it. We used to do some extra caching here to avoid generating
119
- // a variant of the same rule more than once, but this was never hit because
120
- // we cache at the entire selector level further up the tree.
121
- //
122
- // Technically you can get a cache hit if you have `hover:focus:text-center`
123
- // and `focus:hover:text-center` in the same project, but it doesn't feel
124
- // worth the complexity for that case.
125
-
126
- function applyVariant(variant, matches, context) {
127
- if (matches.length === 0) {
128
- return matches
129
- }
130
-
131
- let args
132
- let isArbitraryVariant = false
133
-
134
- // Find partial arbitrary variants
135
- if (variant.endsWith(']') && !variant.startsWith('[')) {
136
- args = variant.slice(variant.lastIndexOf('[') + 1, -1)
137
- variant = variant.slice(0, variant.indexOf(args) - 1 /* - */ - 1 /* [ */)
138
- }
139
-
140
- // Register arbitrary variants
141
- if (isArbitraryValue(variant) && !context.variantMap.has(variant)) {
142
- let selector = normalize(variant.slice(1, -1))
143
-
144
- if (!isValidVariantFormatString(selector)) {
145
- return []
146
- }
147
-
148
- isArbitraryVariant = true
149
-
150
- let fn = parseVariant(selector)
151
-
152
- let sort = Array.from(context.variantOrder.values()).pop() << 1n
153
- context.variantMap.set(variant, [[sort, fn]])
154
- context.variantOrder.set(variant, sort)
155
- }
156
-
157
- if (context.variantMap.has(variant)) {
158
- let variantFunctionTuples = context.variantMap.get(variant).slice()
159
- let result = []
160
-
161
- for (let [meta, rule] of matches) {
162
- // Don't generate variants for user css
163
- if (meta.layer === 'user') {
164
- continue
165
- }
166
-
167
- let container = postcss.root({ nodes: [rule.clone()] })
168
-
169
- for (let [variantSort, variantFunction, containerFromArray] of variantFunctionTuples) {
170
- let clone = containerFromArray ?? container.clone()
171
- let collectedFormats = []
172
-
173
- function prepareBackup() {
174
- // Already prepared, chicken out
175
- if (clone.raws.neededBackup) {
176
- return
177
- }
178
- clone.raws.neededBackup = true
179
- clone.walkRules((rule) => (rule.raws.originalSelector = rule.selector))
180
- }
181
-
182
- function modifySelectors(modifierFunction) {
183
- prepareBackup()
184
- clone.each((rule) => {
185
- if (rule.type !== 'rule') {
186
- return
187
- }
188
-
189
- rule.selectors = rule.selectors.map((selector) => {
190
- return modifierFunction({
191
- get className() {
192
- return getClassNameFromSelector(selector)
193
- },
194
- selector,
195
- })
196
- })
197
- })
198
-
199
- return clone
200
- }
201
-
202
- let ruleWithVariant = variantFunction({
203
- // Public API
204
- get container() {
205
- prepareBackup()
206
- return clone
207
- },
208
- separator: context.tailwindConfig.separator,
209
- modifySelectors,
210
-
211
- // Private API for now
212
- wrap(wrapper) {
213
- let nodes = clone.nodes
214
- clone.removeAll()
215
- wrapper.append(nodes)
216
- clone.append(wrapper)
217
- },
218
- format(selectorFormat) {
219
- collectedFormats.push(selectorFormat)
220
- },
221
- args,
222
- })
223
-
224
- // It can happen that a list of format strings is returned from within the function. In that
225
- // case, we have to process them as well. We can use the existing `variantSort`.
226
- if (Array.isArray(ruleWithVariant)) {
227
- for (let [idx, variantFunction] of ruleWithVariant.entries()) {
228
- // This is a little bit scary since we are pushing to an array of items that we are
229
- // currently looping over. However, you can also think of it like a processing queue
230
- // where you keep handling jobs until everything is done and each job can queue more
231
- // jobs if needed.
232
- variantFunctionTuples.push([
233
- // TODO: This could have potential bugs if we shift the sort order from variant A far
234
- // enough into the sort space of variant B. The chances are low, but if this happens
235
- // then this might be the place too look at. One potential solution to this problem is
236
- // reserving additional X places for these 'unknown' variants in between.
237
- variantSort | BigInt(idx << ruleWithVariant.length),
238
- variantFunction,
239
-
240
- // If the clone has been modified we have to pass that back
241
- // though so each rule can use the modified container
242
- clone.clone(),
243
- ])
244
- }
245
- continue
246
- }
247
-
248
- if (typeof ruleWithVariant === 'string') {
249
- collectedFormats.push(ruleWithVariant)
250
- }
251
-
252
- if (ruleWithVariant === null) {
253
- continue
254
- }
255
-
256
- // We had to backup selectors, therefore we assume that somebody touched
257
- // `container` or `modifySelectors`. Let's see if they did, so that we
258
- // can restore the selectors, and collect the format strings.
259
- if (clone.raws.neededBackup) {
260
- delete clone.raws.neededBackup
261
- clone.walkRules((rule) => {
262
- let before = rule.raws.originalSelector
263
- if (!before) return
264
- delete rule.raws.originalSelector
265
- if (before === rule.selector) return // No mutation happened
266
-
267
- let modified = rule.selector
268
-
269
- // Rebuild the base selector, this is what plugin authors would do
270
- // as well. E.g.: `${variant}${separator}${className}`.
271
- // However, plugin authors probably also prepend or append certain
272
- // classes, pseudos, ids, ...
273
- let rebuiltBase = selectorParser((selectors) => {
274
- selectors.walkClasses((classNode) => {
275
- classNode.value = `${variant}${context.tailwindConfig.separator}${classNode.value}`
276
- })
277
- }).processSync(before)
278
-
279
- // Now that we know the original selector, the new selector, and
280
- // the rebuild part in between, we can replace the part that plugin
281
- // authors need to rebuild with `&`, and eventually store it in the
282
- // collectedFormats. Similar to what `format('...')` would do.
283
- //
284
- // E.g.:
285
- // variant: foo
286
- // selector: .markdown > p
287
- // modified (by plugin): .foo .foo\\:markdown > p
288
- // rebuiltBase (internal): .foo\\:markdown > p
289
- // format: .foo &
290
- collectedFormats.push(modified.replace(rebuiltBase, '&'))
291
- rule.selector = before
292
- })
293
- }
294
-
295
- // This tracks the originating layer for the variant
296
- // For example:
297
- // .sm:underline {} is a variant of something in the utilities layer
298
- // .sm:container {} is a variant of the container component
299
- clone.nodes[0].raws.tailwind = { ...clone.nodes[0].raws.tailwind, parentLayer: meta.layer }
300
-
301
- let withOffset = [
302
- {
303
- ...meta,
304
- sort: variantSort | meta.sort,
305
- collectedFormats: (meta.collectedFormats ?? []).concat(collectedFormats),
306
- isArbitraryVariant,
307
- },
308
- clone.nodes[0],
309
- ]
310
- result.push(withOffset)
311
- }
312
- }
313
-
314
- return result
315
- }
316
-
317
- return []
318
- }
319
-
320
- function parseRules(rule, cache, options = {}) {
321
- // PostCSS node
322
- if (!isPlainObject(rule) && !Array.isArray(rule)) {
323
- return [[rule], options]
324
- }
325
-
326
- // Tuple
327
- if (Array.isArray(rule)) {
328
- return parseRules(rule[0], cache, rule[1])
329
- }
330
-
331
- // Simple object
332
- if (!cache.has(rule)) {
333
- cache.set(rule, parseObjectStyles(rule))
334
- }
335
-
336
- return [cache.get(rule), options]
337
- }
338
-
339
- const IS_VALID_PROPERTY_NAME = /^[a-z_-]/
340
-
341
- function isValidPropName(name) {
342
- return IS_VALID_PROPERTY_NAME.test(name)
343
- }
344
-
345
- /**
346
- * @param {string} declaration
347
- * @returns {boolean}
348
- */
349
- function looksLikeUri(declaration) {
350
- // Quick bailout for obvious non-urls
351
- // This doesn't support schemes that don't use a leading // but that's unlikely to be a problem
352
- if (!declaration.includes('://')) {
353
- return false
354
- }
355
-
356
- try {
357
- const url = new URL(declaration)
358
- return url.scheme !== '' && url.host !== ''
359
- } catch (err) {
360
- // Definitely not a valid url
361
- return false
362
- }
363
- }
364
-
365
- function isParsableNode(node) {
366
- let isParsable = true
367
-
368
- node.walkDecls((decl) => {
369
- if (!isParsableCssValue(decl.name, decl.value)) {
370
- isParsable = false
371
- return false
372
- }
373
- })
374
-
375
- return isParsable
376
- }
377
-
378
- function isParsableCssValue(property, value) {
379
- // We don't want to to treat [https://example.com] as a custom property
380
- // Even though, according to the CSS grammar, it's a totally valid CSS declaration
381
- // So we short-circuit here by checking if the custom property looks like a url
382
- if (looksLikeUri(`${property}:${value}`)) {
383
- return false
384
- }
385
-
386
- try {
387
- postcss.parse(`a{${property}:${value}}`).toResult()
388
- return true
389
- } catch (err) {
390
- return false
391
- }
392
- }
393
-
394
- function extractArbitraryProperty(classCandidate, context) {
395
- let [, property, value] = classCandidate.match(/^\[([a-zA-Z0-9-_]+):(\S+)\]$/) ?? []
396
-
397
- if (value === undefined) {
398
- return null
399
- }
400
-
401
- if (!isValidPropName(property)) {
402
- return null
403
- }
404
-
405
- if (!isValidArbitraryValue(value)) {
406
- return null
407
- }
408
-
409
- let normalized = normalize(value)
410
-
411
- if (!isParsableCssValue(property, normalized)) {
412
- return null
413
- }
414
-
415
- return [
416
- [
417
- { sort: context.arbitraryPropertiesSort, layer: 'utilities' },
418
- () => ({
419
- [asClass(classCandidate)]: {
420
- [property]: normalized,
421
- },
422
- }),
423
- ],
424
- ]
425
- }
426
-
427
- function* resolveMatchedPlugins(classCandidate, context) {
428
- if (context.candidateRuleMap.has(classCandidate)) {
429
- yield [context.candidateRuleMap.get(classCandidate), 'DEFAULT']
430
- }
431
-
432
- yield* (function* (arbitraryPropertyRule) {
433
- if (arbitraryPropertyRule !== null) {
434
- yield [arbitraryPropertyRule, 'DEFAULT']
435
- }
436
- })(extractArbitraryProperty(classCandidate, context))
437
-
438
- let candidatePrefix = classCandidate
439
- let negative = false
440
-
441
- const twConfigPrefix = context.tailwindConfig.prefix
442
-
443
- const twConfigPrefixLen = twConfigPrefix.length
444
-
445
- const hasMatchingPrefix =
446
- candidatePrefix.startsWith(twConfigPrefix) || candidatePrefix.startsWith(`-${twConfigPrefix}`)
447
-
448
- if (candidatePrefix[twConfigPrefixLen] === '-' && hasMatchingPrefix) {
449
- negative = true
450
- candidatePrefix = twConfigPrefix + candidatePrefix.slice(twConfigPrefixLen + 1)
451
- }
452
-
453
- if (negative && context.candidateRuleMap.has(candidatePrefix)) {
454
- yield [context.candidateRuleMap.get(candidatePrefix), '-DEFAULT']
455
- }
456
-
457
- for (let [prefix, modifier] of candidatePermutations(candidatePrefix)) {
458
- if (context.candidateRuleMap.has(prefix)) {
459
- yield [context.candidateRuleMap.get(prefix), negative ? `-${modifier}` : modifier]
460
- }
461
- }
462
- }
463
-
464
- function splitWithSeparator(input, separator) {
465
- if (input === sharedState.NOT_ON_DEMAND) {
466
- return [sharedState.NOT_ON_DEMAND]
467
- }
468
-
469
- return Array.from(splitAtTopLevelOnly(input, separator))
470
- }
471
-
472
- function* recordCandidates(matches, classCandidate) {
473
- for (const match of matches) {
474
- match[1].raws.tailwind = { ...match[1].raws.tailwind, classCandidate }
475
-
476
- yield match
477
- }
478
- }
479
-
480
- function* resolveMatches(candidate, context, original = candidate) {
481
- let separator = context.tailwindConfig.separator
482
- let [classCandidate, ...variants] = splitWithSeparator(candidate, separator).reverse()
483
- let important = false
484
-
485
- if (classCandidate.startsWith('!')) {
486
- important = true
487
- classCandidate = classCandidate.slice(1)
488
- }
489
-
490
- if (flagEnabled(context.tailwindConfig, 'variantGrouping')) {
491
- if (classCandidate.startsWith('(') && classCandidate.endsWith(')')) {
492
- let base = variants.slice().reverse().join(separator)
493
- for (let part of splitAtTopLevelOnly(classCandidate.slice(1, -1), ',')) {
494
- yield* resolveMatches(base + separator + part, context, original)
495
- }
496
- }
497
- }
498
-
499
- // TODO: Reintroduce this in ways that doesn't break on false positives
500
- // function sortAgainst(toSort, against) {
501
- // return toSort.slice().sort((a, z) => {
502
- // return bigSign(against.get(a)[0] - against.get(z)[0])
503
- // })
504
- // }
505
- // let sorted = sortAgainst(variants, context.variantMap)
506
- // if (sorted.toString() !== variants.toString()) {
507
- // let corrected = sorted.reverse().concat(classCandidate).join(':')
508
- // throw new Error(`Class ${candidate} should be written as ${corrected}`)
509
- // }
510
-
511
- for (let matchedPlugins of resolveMatchedPlugins(classCandidate, context)) {
512
- let matches = []
513
- let typesByMatches = new Map()
514
-
515
- let [plugins, modifier] = matchedPlugins
516
- let isOnlyPlugin = plugins.length === 1
517
-
518
- for (let [sort, plugin] of plugins) {
519
- let matchesPerPlugin = []
520
-
521
- if (typeof plugin === 'function') {
522
- for (let ruleSet of [].concat(plugin(modifier, { isOnlyPlugin }))) {
523
- let [rules, options] = parseRules(ruleSet, context.postCssNodeCache)
524
- for (let rule of rules) {
525
- matchesPerPlugin.push([{ ...sort, options: { ...sort.options, ...options } }, rule])
526
- }
527
- }
528
- }
529
- // Only process static plugins on exact matches
530
- else if (modifier === 'DEFAULT' || modifier === '-DEFAULT') {
531
- let ruleSet = plugin
532
- let [rules, options] = parseRules(ruleSet, context.postCssNodeCache)
533
- for (let rule of rules) {
534
- matchesPerPlugin.push([{ ...sort, options: { ...sort.options, ...options } }, rule])
535
- }
536
- }
537
-
538
- if (matchesPerPlugin.length > 0) {
539
- typesByMatches.set(matchesPerPlugin, sort.options?.type)
540
- matches.push(matchesPerPlugin)
541
- }
542
- }
543
-
544
- if (isArbitraryValue(modifier)) {
545
- // When generated arbitrary values are ambiguous, we can't know
546
- // which to pick so don't generate any utilities for them
547
- if (matches.length > 1) {
548
- let typesPerPlugin = matches.map((match) => new Set([...(typesByMatches.get(match) ?? [])]))
549
-
550
- // Remove duplicates, so that we can detect proper unique types for each plugin.
551
- for (let pluginTypes of typesPerPlugin) {
552
- for (let type of pluginTypes) {
553
- let removeFromOwnGroup = false
554
-
555
- for (let otherGroup of typesPerPlugin) {
556
- if (pluginTypes === otherGroup) continue
557
-
558
- if (otherGroup.has(type)) {
559
- otherGroup.delete(type)
560
- removeFromOwnGroup = true
561
- }
562
- }
563
-
564
- if (removeFromOwnGroup) pluginTypes.delete(type)
565
- }
566
- }
567
-
568
- let messages = []
569
-
570
- for (let [idx, group] of typesPerPlugin.entries()) {
571
- for (let type of group) {
572
- let rules = matches[idx]
573
- .map(([, rule]) => rule)
574
- .flat()
575
- .map((rule) =>
576
- rule
577
- .toString()
578
- .split('\n')
579
- .slice(1, -1) // Remove selector and closing '}'
580
- .map((line) => line.trim())
581
- .map((x) => ` ${x}`) // Re-indent
582
- .join('\n')
583
- )
584
- .join('\n\n')
585
-
586
- messages.push(
587
- ` Use \`${candidate.replace('[', `[${type}:`)}\` for \`${rules.trim()}\``
588
- )
589
- break
590
- }
591
- }
592
-
593
- log.warn([
594
- `The class \`${candidate}\` is ambiguous and matches multiple utilities.`,
595
- ...messages,
596
- `If this is content and not a class, replace it with \`${candidate
597
- .replace('[', '&lsqb;')
598
- .replace(']', '&rsqb;')}\` to silence this warning.`,
599
- ])
600
- continue
601
- }
602
-
603
- matches = matches.map((list) => list.filter((match) => isParsableNode(match[1])))
604
- }
605
-
606
- matches = matches.flat()
607
- matches = Array.from(recordCandidates(matches, classCandidate))
608
- matches = applyPrefix(matches, context)
609
-
610
- if (important) {
611
- matches = applyImportant(matches, classCandidate)
612
- }
613
-
614
- for (let variant of variants) {
615
- matches = applyVariant(variant, matches, context)
616
- }
617
-
618
- for (let match of matches) {
619
- match[1].raws.tailwind = { ...match[1].raws.tailwind, candidate }
620
-
621
- // Apply final format selector
622
- if (match[0].collectedFormats) {
623
- let finalFormat = formatVariantSelector('&', ...match[0].collectedFormats)
624
- let container = postcss.root({ nodes: [match[1].clone()] })
625
- container.walkRules((rule) => {
626
- if (inKeyframes(rule)) return
627
-
628
- rule.selector = finalizeSelector(finalFormat, {
629
- selector: rule.selector,
630
- candidate: original,
631
- base: candidate
632
- .split(new RegExp(`\\${context?.tailwindConfig?.separator ?? ':'}(?![^[]*\\])`))
633
- .pop(),
634
- isArbitraryVariant: match[0].isArbitraryVariant,
635
-
636
- context,
637
- })
638
- })
639
- match[1] = container.nodes[0]
640
- }
641
-
642
- yield match
643
- }
644
- }
645
- }
646
-
647
- function inKeyframes(rule) {
648
- return rule.parent && rule.parent.type === 'atrule' && rule.parent.name === 'keyframes'
649
- }
650
-
651
- function generateRules(candidates, context) {
652
- let allRules = []
653
-
654
- for (let candidate of candidates) {
655
- if (context.notClassCache.has(candidate)) {
656
- continue
657
- }
658
-
659
- if (context.classCache.has(candidate)) {
660
- allRules.push(context.classCache.get(candidate))
661
- continue
662
- }
663
-
664
- let matches = Array.from(resolveMatches(candidate, context))
665
-
666
- if (matches.length === 0) {
667
- context.notClassCache.add(candidate)
668
- continue
669
- }
670
-
671
- context.classCache.set(candidate, matches)
672
- allRules.push(matches)
673
- }
674
-
675
- // Strategy based on `tailwindConfig.important`
676
- let strategy = ((important) => {
677
- if (important === true) {
678
- return (rule) => {
679
- rule.walkDecls((d) => {
680
- if (d.parent.type === 'rule' && !inKeyframes(d.parent)) {
681
- d.important = true
682
- }
683
- })
684
- }
685
- }
686
-
687
- if (typeof important === 'string') {
688
- return (rule) => {
689
- rule.selectors = rule.selectors.map((selector) => {
690
- return `${important} ${selector}`
691
- })
692
- }
693
- }
694
- })(context.tailwindConfig.important)
695
-
696
- return allRules.flat(1).map(([{ sort, layer, options }, rule]) => {
697
- if (options.respectImportant) {
698
- if (strategy) {
699
- let container = postcss.root({ nodes: [rule.clone()] })
700
- container.walkRules((r) => {
701
- if (inKeyframes(r)) {
702
- return
703
- }
704
-
705
- strategy(r)
706
- })
707
- rule = container.nodes[0]
708
- }
709
- }
710
-
711
- return [sort | context.layerOrder[layer], rule]
712
- })
713
- }
714
-
715
- function isArbitraryValue(input) {
716
- return input.startsWith('[') && input.endsWith(']')
717
- }
718
-
719
- export { resolveMatches, generateRules }