tailwindcss 0.0.0-insiders.8259dfd → 0.0.0-insiders.8293c2d

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 (93) hide show
  1. package/CHANGELOG.md +207 -2
  2. package/README.md +8 -4
  3. package/colors.js +2 -1
  4. package/defaultConfig.js +2 -1
  5. package/defaultTheme.js +2 -1
  6. package/lib/cli.js +94 -61
  7. package/lib/constants.js +1 -1
  8. package/lib/corePluginList.js +8 -1
  9. package/lib/corePlugins.js +477 -517
  10. package/lib/css/preflight.css +18 -5
  11. package/lib/featureFlags.js +5 -6
  12. package/lib/index.js +1 -3
  13. package/lib/lib/collapseDuplicateDeclarations.js +80 -0
  14. package/lib/lib/defaultExtractor.js +42 -0
  15. package/lib/lib/detectNesting.js +17 -2
  16. package/lib/lib/evaluateTailwindFunctions.js +10 -6
  17. package/lib/lib/expandApplyAtRules.js +94 -45
  18. package/lib/lib/expandTailwindAtRules.js +32 -33
  19. package/lib/lib/generateRules.js +167 -21
  20. package/lib/lib/normalizeTailwindDirectives.js +8 -1
  21. package/lib/lib/partitionApplyAtRules.js +53 -0
  22. package/lib/lib/resolveDefaultsAtRules.js +28 -14
  23. package/lib/lib/setupContextUtils.js +153 -129
  24. package/lib/lib/setupTrackingContext.js +11 -10
  25. package/lib/lib/sharedState.js +34 -5
  26. package/lib/lib/substituteScreenAtRules.js +7 -4
  27. package/lib/processTailwindFeatures.js +7 -2
  28. package/lib/util/buildMediaQuery.js +13 -24
  29. package/lib/util/color.js +23 -8
  30. package/lib/util/createPlugin.js +1 -2
  31. package/lib/util/createUtilityPlugin.js +6 -10
  32. package/lib/util/dataTypes.js +38 -7
  33. package/lib/util/defaults.js +6 -0
  34. package/lib/util/flattenColorPalette.js +1 -3
  35. package/lib/util/formatVariantSelector.js +186 -0
  36. package/lib/util/isValidArbitraryValue.js +64 -0
  37. package/lib/util/log.js +4 -0
  38. package/lib/util/nameClass.js +1 -0
  39. package/lib/util/normalizeConfig.js +63 -21
  40. package/lib/util/normalizeScreens.js +59 -0
  41. package/lib/util/parseBoxShadowValue.js +77 -0
  42. package/lib/util/pluginUtils.js +27 -158
  43. package/lib/util/prefixSelector.js +1 -3
  44. package/lib/util/resolveConfig.js +30 -31
  45. package/lib/util/resolveConfigPath.js +1 -2
  46. package/lib/util/toColorValue.js +1 -2
  47. package/lib/util/toPath.js +6 -1
  48. package/lib/util/transformThemeValue.js +19 -13
  49. package/nesting/plugin.js +4 -1
  50. package/package.json +19 -21
  51. package/peers/index.js +4621 -5626
  52. package/plugin.js +2 -1
  53. package/resolveConfig.js +2 -1
  54. package/src/cli.js +66 -14
  55. package/src/corePluginList.js +1 -1
  56. package/src/corePlugins.js +406 -518
  57. package/src/css/preflight.css +18 -5
  58. package/src/featureFlags.js +1 -1
  59. package/src/index.js +1 -7
  60. package/src/lib/collapseDuplicateDeclarations.js +93 -0
  61. package/src/lib/defaultExtractor.js +48 -0
  62. package/src/lib/detectNesting.js +22 -3
  63. package/src/lib/evaluateTailwindFunctions.js +6 -3
  64. package/src/lib/expandApplyAtRules.js +101 -45
  65. package/src/lib/expandTailwindAtRules.js +33 -27
  66. package/src/lib/generateRules.js +178 -11
  67. package/src/lib/normalizeTailwindDirectives.js +6 -1
  68. package/src/lib/partitionApplyAtRules.js +52 -0
  69. package/src/lib/resolveDefaultsAtRules.js +31 -10
  70. package/src/lib/setupContextUtils.js +140 -84
  71. package/src/lib/setupTrackingContext.js +11 -10
  72. package/src/lib/sharedState.js +40 -4
  73. package/src/lib/substituteScreenAtRules.js +6 -3
  74. package/src/processTailwindFeatures.js +8 -2
  75. package/src/util/buildMediaQuery.js +14 -18
  76. package/src/util/color.js +20 -7
  77. package/src/util/dataTypes.js +43 -11
  78. package/src/util/defaults.js +6 -0
  79. package/src/util/formatVariantSelector.js +196 -0
  80. package/src/util/isValidArbitraryValue.js +61 -0
  81. package/src/util/log.js +4 -0
  82. package/src/util/nameClass.js +1 -1
  83. package/src/util/normalizeConfig.js +37 -2
  84. package/src/util/normalizeScreens.js +45 -0
  85. package/src/util/parseBoxShadowValue.js +71 -0
  86. package/src/util/pluginUtils.js +15 -138
  87. package/src/util/prefixSelector.js +1 -4
  88. package/src/util/resolveConfig.js +11 -1
  89. package/src/util/toPath.js +23 -1
  90. package/src/util/transformThemeValue.js +22 -7
  91. package/stubs/defaultConfig.stub.js +42 -16
  92. package/lib/lib/setupWatchingContext.js +0 -284
  93. package/src/lib/setupWatchingContext.js +0 -304
@@ -10,6 +10,10 @@ var _isPlainObject = _interopRequireDefault(require("../util/isPlainObject"));
10
10
  var _prefixSelector = _interopRequireDefault(require("../util/prefixSelector"));
11
11
  var _pluginUtils = require("../util/pluginUtils");
12
12
  var _log = _interopRequireDefault(require("../util/log"));
13
+ var _formatVariantSelector = require("../util/formatVariantSelector");
14
+ var _nameClass = require("../util/nameClass");
15
+ var _dataTypes = require("../util/dataTypes");
16
+ var _isValidArbitraryValue = _interopRequireDefault(require("../util/isValidArbitraryValue"));
13
17
  function _interopRequireDefault(obj) {
14
18
  return obj && obj.__esModule ? obj : {
15
19
  default: obj
@@ -119,15 +123,27 @@ function applyVariant(variant, matches, context) {
119
123
  if (context.variantMap.has(variant)) {
120
124
  let variantFunctionTuples = context.variantMap.get(variant);
121
125
  let result = [];
122
- for (let [meta, rule] of matches){
126
+ for (let [meta, rule1] of matches){
127
+ // Don't generate variants for user css
128
+ if (meta.layer === 'user') {
129
+ continue;
130
+ }
123
131
  let container = _postcss.default.root({
124
132
  nodes: [
125
- rule.clone()
133
+ rule1.clone()
126
134
  ]
127
135
  });
128
136
  for (let [variantSort, variantFunction] of variantFunctionTuples){
129
137
  let clone = container.clone();
138
+ let collectedFormats = [];
139
+ let originals = new Map();
140
+ function prepareBackup() {
141
+ if (originals.size > 0) return; // Already prepared, chicken out
142
+ clone.walkRules((rule)=>originals.set(rule, rule.selector)
143
+ );
144
+ }
130
145
  function modifySelectors(modifierFunction) {
146
+ prepareBackup();
131
147
  clone.each((rule)=>{
132
148
  if (rule.type !== 'rule') {
133
149
  return;
@@ -144,19 +160,71 @@ function applyVariant(variant, matches, context) {
144
160
  return clone;
145
161
  }
146
162
  let ruleWithVariant = variantFunction({
147
- container: clone,
163
+ // Public API
164
+ get container () {
165
+ prepareBackup();
166
+ return clone;
167
+ },
148
168
  separator: context.tailwindConfig.separator,
149
- modifySelectors
169
+ modifySelectors,
170
+ // Private API for now
171
+ wrap (wrapper) {
172
+ let nodes = clone.nodes;
173
+ clone.removeAll();
174
+ wrapper.append(nodes);
175
+ clone.append(wrapper);
176
+ },
177
+ format (selectorFormat) {
178
+ collectedFormats.push(selectorFormat);
179
+ }
150
180
  });
181
+ if (typeof ruleWithVariant === 'string') {
182
+ collectedFormats.push(ruleWithVariant);
183
+ }
151
184
  if (ruleWithVariant === null) {
152
185
  continue;
153
186
  }
187
+ // We filled the `originals`, therefore we assume that somebody touched
188
+ // `container` or `modifySelectors`. Let's see if they did, so that we
189
+ // can restore the selectors, and collect the format strings.
190
+ if (originals.size > 0) {
191
+ clone.walkRules((rule)=>{
192
+ if (!originals.has(rule)) return;
193
+ let before = originals.get(rule);
194
+ if (before === rule.selector) return; // No mutation happened
195
+ let modified = rule.selector;
196
+ // Rebuild the base selector, this is what plugin authors would do
197
+ // as well. E.g.: `${variant}${separator}${className}`.
198
+ // However, plugin authors probably also prepend or append certain
199
+ // classes, pseudos, ids, ...
200
+ let rebuiltBase = (0, _postcssSelectorParser).default((selectors)=>{
201
+ selectors.walkClasses((classNode)=>{
202
+ classNode.value = `${variant}${context.tailwindConfig.separator}${classNode.value}`;
203
+ });
204
+ }).processSync(before);
205
+ // Now that we know the original selector, the new selector, and
206
+ // the rebuild part in between, we can replace the part that plugin
207
+ // authors need to rebuild with `&`, and eventually store it in the
208
+ // collectedFormats. Similar to what `format('...')` would do.
209
+ //
210
+ // E.g.:
211
+ // variant: foo
212
+ // selector: .markdown > p
213
+ // modified (by plugin): .foo .foo\\:markdown > p
214
+ // rebuiltBase (internal): .foo\\:markdown > p
215
+ // format: .foo &
216
+ collectedFormats.push(modified.replace(rebuiltBase, '&'));
217
+ rule.selector = before;
218
+ });
219
+ }
220
+ var _collectedFormats;
154
221
  let withOffset = [
155
222
  {
156
223
  ...meta,
157
- sort: variantSort | meta.sort
224
+ sort: variantSort | meta.sort,
225
+ collectedFormats: ((_collectedFormats = meta.collectedFormats) !== null && _collectedFormats !== void 0 ? _collectedFormats : []).concat(collectedFormats)
158
226
  },
159
- clone.nodes[0]
227
+ clone.nodes[0],
160
228
  ];
161
229
  result.push(withOffset);
162
230
  }
@@ -165,8 +233,7 @@ function applyVariant(variant, matches, context) {
165
233
  }
166
234
  return [];
167
235
  }
168
- function parseRules(rule, cache, options = {
169
- }) {
236
+ function parseRules(rule, cache, options = {}) {
170
237
  // PostCSS node
171
238
  if (!(0, _isPlainObject).default(rule) && !Array.isArray(rule)) {
172
239
  return [
@@ -189,6 +256,49 @@ function parseRules(rule, cache, options = {
189
256
  options
190
257
  ];
191
258
  }
259
+ const IS_VALID_PROPERTY_NAME = /^[a-z_-]/;
260
+ function isValidPropName(name) {
261
+ return IS_VALID_PROPERTY_NAME.test(name);
262
+ }
263
+ function isParsableCssValue(property, value) {
264
+ try {
265
+ _postcss.default.parse(`a{${property}:${value}}`).toResult();
266
+ return true;
267
+ } catch (err) {
268
+ return false;
269
+ }
270
+ }
271
+ function extractArbitraryProperty(classCandidate, context) {
272
+ var ref;
273
+ let [, property, value] = (ref = classCandidate.match(/^\[([a-zA-Z0-9-_]+):(\S+)\]$/)) !== null && ref !== void 0 ? ref : [];
274
+ if (value === undefined) {
275
+ return null;
276
+ }
277
+ if (!isValidPropName(property)) {
278
+ return null;
279
+ }
280
+ if (!(0, _isValidArbitraryValue).default(value)) {
281
+ return null;
282
+ }
283
+ let normalized = (0, _dataTypes).normalize(value);
284
+ if (!isParsableCssValue(property, normalized)) {
285
+ return null;
286
+ }
287
+ return [
288
+ [
289
+ {
290
+ sort: context.arbitraryPropertiesSort,
291
+ layer: 'utilities'
292
+ },
293
+ ()=>({
294
+ [(0, _nameClass).asClass(classCandidate)]: {
295
+ [property]: normalized
296
+ }
297
+ })
298
+ ,
299
+ ],
300
+ ];
301
+ }
192
302
  function* resolveMatchedPlugins(classCandidate, context) {
193
303
  if (context.candidateRuleMap.has(classCandidate)) {
194
304
  yield [
@@ -196,9 +306,17 @@ function* resolveMatchedPlugins(classCandidate, context) {
196
306
  'DEFAULT'
197
307
  ];
198
308
  }
309
+ yield* (function*(arbitraryPropertyRule) {
310
+ if (arbitraryPropertyRule !== null) {
311
+ yield [
312
+ arbitraryPropertyRule,
313
+ 'DEFAULT'
314
+ ];
315
+ }
316
+ })(extractArbitraryProperty(classCandidate, context));
199
317
  let candidatePrefix = classCandidate;
200
318
  let negative = false;
201
- const twConfigPrefix = context.tailwindConfig.prefix || '';
319
+ const twConfigPrefix = context.tailwindConfig.prefix;
202
320
  const twConfigPrefixLen = twConfigPrefix.length;
203
321
  if (candidatePrefix[twConfigPrefixLen] === '-') {
204
322
  negative = true;
@@ -216,7 +334,6 @@ function* resolveMatchedPlugins(classCandidate, context) {
216
334
  context.candidateRuleMap.get(prefix),
217
335
  negative ? `-${modifier}` : modifier
218
336
  ];
219
- return;
220
337
  }
221
338
  }
222
339
  }
@@ -292,9 +409,9 @@ function* resolveMatches(candidate, context) {
292
409
  // Only keep the result of the very first plugin if we are dealing with
293
410
  // arbitrary values, to protect against ambiguity.
294
411
  if (isArbitraryValue(modifier) && matches.length > 1) {
295
- var ref;
412
+ var ref1;
296
413
  let typesPerPlugin = matches.map((match)=>new Set([
297
- ...(ref = typesByMatches.get(match)) !== null && ref !== void 0 ? ref : []
414
+ ...(ref1 = typesByMatches.get(match)) !== null && ref1 !== void 0 ? ref1 : []
298
415
  ])
299
416
  );
300
417
  // Remove duplicates, so that we can detect proper unique types for each plugin.
@@ -339,8 +456,26 @@ function* resolveMatches(candidate, context) {
339
456
  for (let variant of variants){
340
457
  matches = applyVariant(variant, matches, context);
341
458
  }
342
- for (let match of matches){
343
- yield match;
459
+ for (let match1 of matches){
460
+ // Apply final format selector
461
+ if (match1[0].collectedFormats) {
462
+ let finalFormat = (0, _formatVariantSelector).formatVariantSelector('&', ...match1[0].collectedFormats);
463
+ let container = _postcss.default.root({
464
+ nodes: [
465
+ match1[1].clone()
466
+ ]
467
+ });
468
+ container.walkRules((rule)=>{
469
+ if (inKeyframes(rule)) return;
470
+ rule.selector = (0, _formatVariantSelector).finalizeSelector(finalFormat, {
471
+ selector: rule.selector,
472
+ candidate,
473
+ context
474
+ });
475
+ });
476
+ match1[1] = container.nodes[0];
477
+ }
478
+ yield match1;
344
479
  }
345
480
  }
346
481
  }
@@ -365,15 +500,28 @@ function generateRules(candidates, context) {
365
500
  context.classCache.set(candidate, matches);
366
501
  allRules.push(matches);
367
502
  }
368
- return allRules.flat(1).map(([{ sort , layer , options }, rule])=>{
369
- if (options.respectImportant) {
370
- if (context.tailwindConfig.important === true) {
503
+ // Strategy based on `tailwindConfig.important`
504
+ let strategy = ((important)=>{
505
+ if (important === true) {
506
+ return (rule)=>{
371
507
  rule.walkDecls((d)=>{
372
508
  if (d.parent.type === 'rule' && !inKeyframes(d.parent)) {
373
509
  d.important = true;
374
510
  }
375
511
  });
376
- } else if (typeof context.tailwindConfig.important === 'string') {
512
+ };
513
+ }
514
+ if (typeof important === 'string') {
515
+ return (rule)=>{
516
+ rule.selectors = rule.selectors.map((selector)=>{
517
+ return `${important} ${selector}`;
518
+ });
519
+ };
520
+ }
521
+ })(context.tailwindConfig.important);
522
+ return allRules.flat(1).map(([{ sort , layer , options }, rule])=>{
523
+ if (options.respectImportant) {
524
+ if (strategy) {
377
525
  let container = _postcss.default.root({
378
526
  nodes: [
379
527
  rule.clone()
@@ -383,9 +531,7 @@ function generateRules(candidates, context) {
383
531
  if (inKeyframes(r)) {
384
532
  return;
385
533
  }
386
- r.selectors = r.selectors.map((selector)=>{
387
- return `${context.tailwindConfig.important} ${selector}`;
388
- });
534
+ strategy(r);
389
535
  });
390
536
  rule = container.nodes[0];
391
537
  }
@@ -12,7 +12,11 @@ function _interopRequireDefault(obj) {
12
12
  function normalizeTailwindDirectives(root) {
13
13
  let tailwindDirectives = new Set();
14
14
  let layerDirectives = new Set();
15
+ let applyDirectives = new Set();
15
16
  root.walkAtRules((atRule)=>{
17
+ if (atRule.name === 'apply') {
18
+ applyDirectives.add(atRule);
19
+ }
16
20
  if (atRule.name === 'import') {
17
21
  if (atRule.params === '"tailwindcss/base"' || atRule.params === "'tailwindcss/base'") {
18
22
  atRule.name = 'tailwind';
@@ -72,5 +76,8 @@ function normalizeTailwindDirectives(root) {
72
76
  }
73
77
  }
74
78
  }
75
- return tailwindDirectives;
79
+ return {
80
+ tailwindDirectives,
81
+ applyDirectives
82
+ };
76
83
  }
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ exports.default = expandApplyAtRules;
6
+ function partitionRules(root) {
7
+ if (!root.walkAtRules) return;
8
+ let applyParents = new Set();
9
+ root.walkAtRules('apply', (rule)=>{
10
+ applyParents.add(rule.parent);
11
+ });
12
+ if (applyParents.size === 0) {
13
+ return;
14
+ }
15
+ for (let rule1 of applyParents){
16
+ let nodeGroups = [];
17
+ let lastGroup = [];
18
+ for (let node of rule1.nodes){
19
+ if (node.type === 'atrule' && node.name === 'apply') {
20
+ if (lastGroup.length > 0) {
21
+ nodeGroups.push(lastGroup);
22
+ lastGroup = [];
23
+ }
24
+ nodeGroups.push([
25
+ node
26
+ ]);
27
+ } else {
28
+ lastGroup.push(node);
29
+ }
30
+ }
31
+ if (lastGroup.length > 0) {
32
+ nodeGroups.push(lastGroup);
33
+ }
34
+ if (nodeGroups.length === 1) {
35
+ continue;
36
+ }
37
+ for (let group of [
38
+ ...nodeGroups
39
+ ].reverse()){
40
+ let clone = rule1.clone({
41
+ nodes: []
42
+ });
43
+ clone.append(group);
44
+ rule1.after(clone);
45
+ }
46
+ rule1.remove();
47
+ }
48
+ }
49
+ function expandApplyAtRules() {
50
+ return (root)=>{
51
+ partitionRules(root);
52
+ };
53
+ }
@@ -47,8 +47,8 @@ function minimumImpactSelector(nodes) {
47
47
  let splitPointIdx = rest.findIndex((n)=>searchFor.has(n.type)
48
48
  );
49
49
  if (splitPointIdx === -1) return rest.reverse().join('').trim();
50
- let node = rest[splitPointIdx];
51
- let bestNode = getNode[node.type] ? getNode[node.type](node) : node;
50
+ let node1 = rest[splitPointIdx];
51
+ let bestNode = getNode[node1.type] ? getNode[node1.type](node1) : node1;
52
52
  rest = rest.slice(0, splitPointIdx);
53
53
  let combinatorIdx = rest.findIndex((n)=>n.type === 'combinator' && n.value === '>'
54
54
  );
@@ -79,7 +79,7 @@ function extractElementSelector(selector) {
79
79
  function resolveDefaultsAtRules({ tailwindConfig }) {
80
80
  return (root)=>{
81
81
  let variableNodeMap = new Map();
82
- let universals = new Set();
82
+ /** @type {Set<import('postcss').AtRule>} */ let universals = new Set();
83
83
  root.walkAtRules('defaults', (rule)=>{
84
84
  if (rule.nodes && rule.nodes.length > 0) {
85
85
  universals.add(rule);
@@ -93,32 +93,46 @@ function resolveDefaultsAtRules({ tailwindConfig }) {
93
93
  rule.remove();
94
94
  });
95
95
  for (let universal of universals){
96
- let selectors = new Set();
96
+ /** @type {Map<string, Set<string>>} */ let selectorGroups = new Map();
97
97
  var ref;
98
98
  let rules = (ref = variableNodeMap.get(universal.params)) !== null && ref !== void 0 ? ref : [];
99
99
  for (let rule of rules){
100
100
  for (let selector of extractElementSelector(rule.selector)){
101
+ // If selector contains a vendor prefix after a pseudo element or class,
102
+ // we consider them separately because merging the declarations into
103
+ // a single rule will cause browsers that do not understand the
104
+ // vendor prefix to throw out the whole rule
105
+ let selectorGroupName = selector.includes(':-') || selector.includes('::-') ? selector : '__DEFAULT__';
106
+ var ref1;
107
+ let selectors = (ref1 = selectorGroups.get(selectorGroupName)) !== null && ref1 !== void 0 ? ref1 : new Set();
108
+ selectorGroups.set(selectorGroupName, selectors);
101
109
  selectors.add(selector);
102
110
  }
103
111
  }
104
- if (selectors.size === 0) {
105
- universal.remove();
106
- continue;
107
- }
108
- let universalRule = _postcss.default.rule();
109
112
  if ((0, _featureFlags).flagEnabled(tailwindConfig, 'optimizeUniversalDefaults')) {
110
- universalRule.selectors = [
111
- ...selectors
112
- ];
113
+ if (selectorGroups.size === 0) {
114
+ universal.remove();
115
+ continue;
116
+ }
117
+ for (let [, selectors] of selectorGroups){
118
+ let universalRule = _postcss.default.rule();
119
+ universalRule.selectors = [
120
+ ...selectors
121
+ ];
122
+ universalRule.append(universal.nodes.map((node)=>node.clone()
123
+ ));
124
+ universal.before(universalRule);
125
+ }
113
126
  } else {
127
+ let universalRule = _postcss.default.rule();
114
128
  universalRule.selectors = [
115
129
  '*',
116
130
  '::before',
117
131
  '::after'
118
132
  ];
133
+ universalRule.append(universal.nodes);
134
+ universal.before(universalRule);
119
135
  }
120
- universalRule.append(universal.nodes);
121
- universal.before(universalRule);
122
136
  universal.remove();
123
137
  }
124
138
  };