tailwindcss 3.0.24 → 3.1.2

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 (88) hide show
  1. package/CHANGELOG.md +75 -3
  2. package/colors.d.ts +3 -0
  3. package/defaultConfig.d.ts +3 -0
  4. package/defaultTheme.d.ts +3 -0
  5. package/lib/cli-peer-dependencies.js +8 -3
  6. package/lib/cli.js +125 -83
  7. package/lib/corePluginList.js +1 -0
  8. package/lib/corePlugins.js +146 -117
  9. package/lib/css/preflight.css +1 -8
  10. package/lib/featureFlags.js +8 -6
  11. package/lib/index.js +10 -13
  12. package/lib/lib/cacheInvalidation.js +32 -14
  13. package/lib/lib/collapseAdjacentRules.js +5 -3
  14. package/lib/lib/defaultExtractor.js +191 -32
  15. package/lib/lib/evaluateTailwindFunctions.js +22 -13
  16. package/lib/lib/expandApplyAtRules.js +232 -195
  17. package/lib/lib/expandTailwindAtRules.js +40 -26
  18. package/lib/lib/generateRules.js +106 -42
  19. package/lib/lib/regex.js +52 -0
  20. package/lib/lib/resolveDefaultsAtRules.js +56 -45
  21. package/lib/lib/setupContextUtils.js +131 -79
  22. package/lib/lib/setupTrackingContext.js +7 -9
  23. package/lib/lib/sharedState.js +1 -2
  24. package/lib/lib/substituteScreenAtRules.js +1 -2
  25. package/lib/postcss-plugins/nesting/plugin.js +1 -2
  26. package/lib/util/buildMediaQuery.js +1 -2
  27. package/lib/util/cloneDeep.js +2 -4
  28. package/lib/util/color.js +26 -36
  29. package/lib/util/createPlugin.js +1 -2
  30. package/lib/util/createUtilityPlugin.js +1 -2
  31. package/lib/util/dataTypes.js +14 -12
  32. package/lib/util/flattenColorPalette.js +2 -5
  33. package/lib/util/formatVariantSelector.js +64 -57
  34. package/lib/util/getAllConfigs.js +10 -5
  35. package/lib/util/isValidArbitraryValue.js +1 -2
  36. package/lib/util/log.js +2 -3
  37. package/lib/util/negateValue.js +1 -2
  38. package/lib/util/normalizeConfig.js +33 -23
  39. package/lib/util/normalizeScreens.js +1 -2
  40. package/lib/util/parseAnimationValue.js +1 -2
  41. package/lib/util/parseBoxShadowValue.js +2 -43
  42. package/lib/util/pluginUtils.js +11 -3
  43. package/lib/util/resolveConfig.js +57 -34
  44. package/lib/util/splitAtTopLevelOnly.js +90 -0
  45. package/lib/util/transformThemeValue.js +4 -2
  46. package/lib/util/validateConfig.js +21 -0
  47. package/lib/util/withAlphaVariable.js +5 -5
  48. package/package.json +21 -16
  49. package/peers/index.js +3264 -1330
  50. package/plugin.d.ts +11 -0
  51. package/src/cli-peer-dependencies.js +7 -1
  52. package/src/cli.js +104 -34
  53. package/src/corePluginList.js +1 -1
  54. package/src/corePlugins.js +57 -40
  55. package/src/css/preflight.css +1 -8
  56. package/src/featureFlags.js +2 -2
  57. package/src/index.js +0 -2
  58. package/src/lib/collapseAdjacentRules.js +5 -1
  59. package/src/lib/defaultExtractor.js +177 -35
  60. package/src/lib/evaluateTailwindFunctions.js +20 -4
  61. package/src/lib/expandApplyAtRules.js +247 -188
  62. package/src/lib/expandTailwindAtRules.js +4 -4
  63. package/src/lib/generateRules.js +69 -5
  64. package/src/lib/regex.js +74 -0
  65. package/src/lib/resolveDefaultsAtRules.js +53 -36
  66. package/src/lib/setupContextUtils.js +103 -39
  67. package/src/lib/setupTrackingContext.js +4 -0
  68. package/src/util/color.js +20 -18
  69. package/src/util/dataTypes.js +11 -5
  70. package/src/util/formatVariantSelector.js +79 -62
  71. package/src/util/getAllConfigs.js +7 -0
  72. package/src/util/log.js +1 -1
  73. package/src/util/normalizeConfig.js +0 -8
  74. package/src/util/parseBoxShadowValue.js +3 -50
  75. package/src/util/pluginUtils.js +13 -1
  76. package/src/util/resolveConfig.js +66 -54
  77. package/src/util/splitAtTopLevelOnly.js +71 -0
  78. package/src/util/toPath.js +1 -1
  79. package/src/util/transformThemeValue.js +4 -2
  80. package/src/util/validateConfig.js +13 -0
  81. package/src/util/withAlphaVariable.js +1 -1
  82. package/stubs/defaultConfig.stub.js +2 -3
  83. package/stubs/simpleConfig.stub.js +1 -0
  84. package/types/config.d.ts +325 -0
  85. package/types/generated/.gitkeep +0 -0
  86. package/types/generated/colors.d.ts +276 -0
  87. package/types/generated/corePluginList.d.ts +1 -0
  88. package/types/index.d.ts +7 -0
@@ -14,6 +14,7 @@ function _interopRequireDefault(obj) {
14
14
  default: obj
15
15
  };
16
16
  }
17
+ var ref;
17
18
  let MERGE = ":merge";
18
19
  let PARENT = "&";
19
20
  let selectorFunctions = new Set([
@@ -37,23 +38,31 @@ function formatVariantSelector(current, ...others) {
37
38
  }
38
39
  return current;
39
40
  }
40
- function finalizeSelector(format, { selector: selector1 , candidate , context }) {
41
- var ref, ref1;
41
+ var ref1;
42
+ function finalizeSelector(format, { selector: selector1 , candidate , context , // Split by the separator, but ignore the separator inside square brackets:
43
+ //
44
+ // E.g.: dark:lg:hover:[paint-order:markers]
45
+ // ┬ ┬ ┬ ┬
46
+ // │ │ │ ╰── We will not split here
47
+ // ╰──┴─────┴─────────────── We will split here
48
+ //
49
+ base =candidate.split(new RegExp(`\\${(ref1 = context === null || context === void 0 ? void 0 : (ref = context.tailwindConfig) === null || ref === void 0 ? void 0 : ref.separator) !== null && ref1 !== void 0 ? ref1 : ":"}(?![^[]*\\])`)).pop() , }) {
42
50
  var ref2;
43
- let separator = (ref2 = context === null || context === void 0 ? void 0 : (ref = context.tailwindConfig) === null || ref === void 0 ? void 0 : ref.separator) !== null && ref2 !== void 0 ? ref2 : ":";
44
- // Split by the separator, but ignore the separator inside square brackets:
45
- //
46
- // E.g.: dark:lg:hover:[paint-order:markers]
47
- // ┬ ┬ ┬ ┬
48
- // │ │ │ ╰── We will not split here
49
- // ╰──┴─────┴─────────────── We will split here
50
- //
51
- let splitter = new RegExp(`\\${separator}(?![^[]*\\])`);
52
- let base = candidate.split(splitter).pop();
53
- if (context === null || context === void 0 ? void 0 : (ref1 = context.tailwindConfig) === null || ref1 === void 0 ? void 0 : ref1.prefix) {
51
+ let ast = (0, _postcssSelectorParser).default().astSync(selector1);
52
+ if (context === null || context === void 0 ? void 0 : (ref2 = context.tailwindConfig) === null || ref2 === void 0 ? void 0 : ref2.prefix) {
54
53
  format = (0, _prefixSelector).default(context.tailwindConfig.prefix, format);
55
54
  }
56
55
  format = format.replace(PARENT, `.${(0, _escapeClassName).default(candidate)}`);
56
+ let formatAst = (0, _postcssSelectorParser).default().astSync(format);
57
+ // Remove extraneous selectors that do not include the base class/candidate being matched against
58
+ // For example if we have a utility defined `.a, .b { color: red}`
59
+ // And the formatted variant is sm:b then we want the final selector to be `.sm\:b` and not `.a, .sm\:b`
60
+ ast.each((node)=>{
61
+ let hasClassesMatchingCandidate = node.some((n)=>n.type === "class" && n.value === base);
62
+ if (!hasClassesMatchingCandidate) {
63
+ node.remove();
64
+ }
65
+ });
57
66
  // Normalize escaped classes, e.g.:
58
67
  //
59
68
  // The idea would be to replace the escaped `base` in the selector with the
@@ -65,55 +74,53 @@ function finalizeSelector(format, { selector: selector1 , candidate , context }
65
74
  // base in selector: bg-\\[rgb\\(255\\,0\\,0\\)\\]
66
75
  // escaped base: bg-\\[rgb\\(255\\2c 0\\2c 0\\)\\]
67
76
  //
68
- selector1 = (0, _postcssSelectorParser).default((selectors)=>{
69
- return selectors.walkClasses((node)=>{
70
- if (node.raws && node.value.includes(base)) {
71
- node.raws.value = (0, _escapeClassName).default((0, _unesc).default(node.raws.value));
72
- }
73
- return node;
74
- });
75
- }).processSync(selector1);
77
+ ast.walkClasses((node)=>{
78
+ if (node.raws && node.value.includes(base)) {
79
+ node.raws.value = (0, _escapeClassName).default((0, _unesc).default(node.raws.value));
80
+ }
81
+ });
76
82
  // We can safely replace the escaped base now, since the `base` section is
77
83
  // now in a normalized escaped value.
78
- selector1 = selector1.replace(`.${(0, _escapeClassName).default(base)}`, format);
79
- // Remove unnecessary pseudo selectors that we used as placeholders
80
- return (0, _postcssSelectorParser).default((selectors)=>{
81
- return selectors.map((selector2)=>{
82
- selector2.walkPseudos((p)=>{
83
- if (selectorFunctions.has(p.value)) {
84
- p.replaceWith(p.nodes);
85
- }
86
- return p;
87
- });
88
- // This will make sure to move pseudo's to the correct spot (the end for
89
- // pseudo elements) because otherwise the selector will never work
90
- // anyway.
91
- //
92
- // E.g.:
93
- // - `before:hover:text-center` would result in `.before\:hover\:text-center:hover::before`
94
- // - `hover:before:text-center` would result in `.hover\:before\:text-center:hover::before`
95
- //
96
- // `::before:hover` doesn't work, which means that we can make it work for you by flipping the order.
97
- function collectPseudoElements(selector) {
98
- let nodes = [];
99
- for (let node of selector.nodes){
100
- if (isPseudoElement(node)) {
101
- nodes.push(node);
102
- selector.removeChild(node);
103
- }
104
- if (node === null || node === void 0 ? void 0 : node.nodes) {
105
- nodes.push(...collectPseudoElements(node));
106
- }
107
- }
108
- return nodes;
84
+ ast.walkClasses((node)=>{
85
+ if (node.value === base) {
86
+ node.replaceWith(...formatAst.nodes);
87
+ }
88
+ });
89
+ // This will make sure to move pseudo's to the correct spot (the end for
90
+ // pseudo elements) because otherwise the selector will never work
91
+ // anyway.
92
+ //
93
+ // E.g.:
94
+ // - `before:hover:text-center` would result in `.before\:hover\:text-center:hover::before`
95
+ // - `hover:before:text-center` would result in `.hover\:before\:text-center:hover::before`
96
+ //
97
+ // `::before:hover` doesn't work, which means that we can make it work for you by flipping the order.
98
+ function collectPseudoElements(selector) {
99
+ let nodes = [];
100
+ for (let node of selector.nodes){
101
+ if (isPseudoElement(node)) {
102
+ nodes.push(node);
103
+ selector.removeChild(node);
104
+ }
105
+ if (node === null || node === void 0 ? void 0 : node.nodes) {
106
+ nodes.push(...collectPseudoElements(node));
109
107
  }
110
- let pseudoElements = collectPseudoElements(selector2);
111
- if (pseudoElements.length > 0) {
112
- selector2.nodes.push(pseudoElements.sort(sortSelector));
108
+ }
109
+ return nodes;
110
+ }
111
+ // Remove unnecessary pseudo selectors that we used as placeholders
112
+ ast.each((selector)=>{
113
+ selector.walkPseudos((p)=>{
114
+ if (selectorFunctions.has(p.value)) {
115
+ p.replaceWith(p.nodes);
113
116
  }
114
- return selector2;
115
117
  });
116
- }).processSync(selector1);
118
+ let pseudoElements = collectPseudoElements(selector);
119
+ if (pseudoElements.length > 0) {
120
+ selector.nodes.push(pseudoElements.sort(sortSelector));
121
+ }
122
+ });
123
+ return ast.toString();
117
124
  }
118
125
  // Note: As a rule, double colons (::) should be used instead of a single colon
119
126
  // (:). This distinguishes pseudo-classes from pseudo-elements. However, since
@@ -9,13 +9,18 @@ function getAllConfigs(config) {
9
9
  var ref;
10
10
  const configs = ((ref = config === null || config === void 0 ? void 0 : config.presets) !== null && ref !== void 0 ? ref : [
11
11
  _defaultConfigStubJs.default
12
- ]).slice().reverse().flatMap((preset)=>getAllConfigs(preset instanceof Function ? preset() : preset)
13
- );
12
+ ]).slice().reverse().flatMap((preset)=>getAllConfigs(preset instanceof Function ? preset() : preset));
14
13
  const features = {
14
+ // Add experimental configs here...
15
+ respectDefaultRingColorOpacity: {
16
+ theme: {
17
+ ringColor: {
18
+ DEFAULT: "#3b82f67f"
19
+ }
20
+ }
21
+ }
15
22
  };
16
- const experimentals = Object.keys(features).filter((feature)=>(0, _featureFlags).flagEnabled(config, feature)
17
- ).map((feature)=>features[feature]
18
- );
23
+ const experimentals = Object.keys(features).filter((feature)=>(0, _featureFlags).flagEnabled(config, feature)).map((feature)=>features[feature]);
19
24
  return [
20
25
  config,
21
26
  ...experimentals,
@@ -55,8 +55,7 @@ let matchingBrackets = new Map([
55
55
  let inverseMatchingBrackets = new Map(Array.from(matchingBrackets.entries()).map(([k, v])=>[
56
56
  v,
57
57
  k
58
- ]
59
- ));
58
+ ]));
60
59
  let quotes = new Set([
61
60
  '"',
62
61
  "'",
package/lib/util/log.js CHANGED
@@ -12,12 +12,11 @@ function _interopRequireDefault(obj) {
12
12
  }
13
13
  let alreadyShown = new Set();
14
14
  function log(type, messages, key) {
15
- if (process.env.JEST_WORKER_ID !== undefined) return;
15
+ if (typeof process !== "undefined" && process.env.JEST_WORKER_ID) return;
16
16
  if (key && alreadyShown.has(key)) return;
17
17
  if (key) alreadyShown.add(key);
18
18
  console.warn("");
19
- messages.forEach((message)=>console.warn(type, "-", message)
20
- );
19
+ messages.forEach((message)=>console.warn(type, "-", message));
21
20
  }
22
21
  function dim(input) {
23
22
  return _picocolors.default.dim(input);
@@ -10,8 +10,7 @@ function _default(value) {
10
10
  }
11
11
  // Flip sign of numbers
12
12
  if (/^[+-]?(\d+|\d*\.\d+)(e[+-]?\d+)?(%|\w+)?$/.test(value)) {
13
- return value.replace(/^[+-]?/, (sign)=>sign === "-" ? "" : "-"
14
- );
13
+ return value.replace(/^[+-]?/, (sign)=>sign === "-" ? "" : "-");
15
14
  }
16
15
  if (value.includes("var(") || value.includes("calc(")) {
17
16
  return `calc(${value} * -1)`;
@@ -4,26 +4,44 @@ Object.defineProperty(exports, "__esModule", {
4
4
  });
5
5
  exports.normalizeConfig = normalizeConfig;
6
6
  var _log = _interopRequireWildcard(require("./log"));
7
+ function _getRequireWildcardCache() {
8
+ if (typeof WeakMap !== "function") return null;
9
+ var cache = new WeakMap();
10
+ _getRequireWildcardCache = function() {
11
+ return cache;
12
+ };
13
+ return cache;
14
+ }
7
15
  function _interopRequireWildcard(obj) {
8
16
  if (obj && obj.__esModule) {
9
17
  return obj;
10
- } else {
11
- var newObj = {};
12
- if (obj != null) {
13
- for(var key in obj){
14
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
15
- var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {};
16
- if (desc.get || desc.set) {
17
- Object.defineProperty(newObj, key, desc);
18
- } else {
19
- newObj[key] = obj[key];
20
- }
21
- }
18
+ }
19
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
20
+ return {
21
+ default: obj
22
+ };
23
+ }
24
+ var cache = _getRequireWildcardCache();
25
+ if (cache && cache.has(obj)) {
26
+ return cache.get(obj);
27
+ }
28
+ var newObj = {};
29
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
30
+ for(var key in obj){
31
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
32
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
33
+ if (desc && (desc.get || desc.set)) {
34
+ Object.defineProperty(newObj, key, desc);
35
+ } else {
36
+ newObj[key] = obj[key];
22
37
  }
23
38
  }
24
- newObj.default = obj;
25
- return newObj;
26
39
  }
40
+ newObj.default = obj;
41
+ if (cache) {
42
+ cache.set(obj, newObj);
43
+ }
44
+ return newObj;
27
45
  }
28
46
  function normalizeConfig(config) {
29
47
  // Quick structure validation
@@ -75,8 +93,7 @@ function normalizeConfig(config) {
75
93
  "files",
76
94
  "extract",
77
95
  "transform"
78
- ].includes(key)
79
- )) {
96
+ ].includes(key))) {
80
97
  return false;
81
98
  }
82
99
  // `config.content.files` should exist of FilePaths or RawFiles
@@ -229,12 +246,5 @@ function normalizeConfig(config) {
229
246
  break;
230
247
  }
231
248
  }
232
- if (config.content.files.length === 0) {
233
- _log.default.warn("content-problems", [
234
- "The `content` option in your Tailwind CSS configuration is missing or empty.",
235
- "Configure your content sources or your generated CSS will be missing styles.",
236
- "https://tailwindcss.com/docs/content-configuration",
237
- ]);
238
- }
239
249
  return config;
240
250
  }
@@ -36,8 +36,7 @@ function normalizeScreens(screens, root = true) {
36
36
  if (Array.isArray(options)) {
37
37
  return {
38
38
  name,
39
- values: options.map((option)=>resolveValue(option)
40
- )
39
+ values: options.map((option)=>resolveValue(option))
41
40
  };
42
41
  }
43
42
  return {
@@ -28,8 +28,7 @@ function parseAnimationValue(input) {
28
28
  } else if (!seen.has("TIMING_FUNCTION") && TIMINGS.has(part)) {
29
29
  result.timingFunction = part;
30
30
  seen.add("TIMING_FUNCTION");
31
- } else if (!seen.has("TIMING_FUNCTION") && TIMING_FNS.some((f)=>part.startsWith(`${f}(`)
32
- )) {
31
+ } else if (!seen.has("TIMING_FUNCTION") && TIMING_FNS.some((f)=>part.startsWith(`${f}(`))) {
33
32
  result.timingFunction = part;
34
33
  seen.add("TIMING_FUNCTION");
35
34
  } else if (!seen.has("DURATION") && TIME.test(part)) {
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  });
5
5
  exports.parseBoxShadowValue = parseBoxShadowValue;
6
6
  exports.formatBoxShadowValue = formatBoxShadowValue;
7
+ var _splitAtTopLevelOnly = require("./splitAtTopLevelOnly");
7
8
  let KEYWORDS = new Set([
8
9
  "inset",
9
10
  "inherit",
@@ -14,50 +15,8 @@ let KEYWORDS = new Set([
14
15
  let SPACE = /\ +(?![^(]*\))/g // Similar to the one above, but with spaces instead.
15
16
  ;
16
17
  let LENGTH = /^-?(\d+|\.\d+)(.*?)$/g;
17
- let SPECIALS = /[(),]/g;
18
- /**
19
- * This splits a string on top-level commas.
20
- *
21
- * Regex doesn't support recursion (at least not the JS-flavored version).
22
- * So we have to use a tiny state machine to keep track of paren vs comma
23
- * placement. Before we'd only exclude commas from the inner-most nested
24
- * set of parens rather than any commas that were not contained in parens
25
- * at all which is the intended behavior here.
26
- *
27
- * Expected behavior:
28
- * var(--a, 0 0 1px rgb(0, 0, 0)), 0 0 1px rgb(0, 0, 0)
29
- * ─┬─ ┬ ┬ ┬
30
- * x x x ╰──────── Split because top-level
31
- * ╰──────────────┴──┴───────────── Ignored b/c inside >= 1 levels of parens
32
- *
33
- * @param {string} input
34
- */ function* splitByTopLevelCommas(input) {
35
- SPECIALS.lastIndex = -1;
36
- let depth = 0;
37
- let lastIndex = 0;
38
- let found = false;
39
- // Find all parens & commas
40
- // And only split on commas if they're top-level
41
- for (let match of input.matchAll(SPECIALS)){
42
- if (match[0] === "(") depth++;
43
- if (match[0] === ")") depth--;
44
- if (match[0] === "," && depth === 0) {
45
- found = true;
46
- yield input.substring(lastIndex, match.index);
47
- lastIndex = match.index + match[0].length;
48
- }
49
- }
50
- // Provide the last segment of the string if available
51
- // Otherwise the whole string since no commas were found
52
- // This mirrors the behavior of string.split()
53
- if (found) {
54
- yield input.substring(lastIndex);
55
- } else {
56
- yield input;
57
- }
58
- }
59
18
  function parseBoxShadowValue(input) {
60
- let shadows = Array.from(splitByTopLevelCommas(input));
19
+ let shadows = Array.from((0, _splitAtTopLevelOnly).splitAtTopLevelOnly(input, ","));
61
20
  return shadows.map((shadow)=>{
62
21
  let value = shadow.trim();
63
22
  let result = {
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  });
5
5
  exports.updateAllClasses = updateAllClasses;
6
6
  exports.asValue = asValue;
7
+ exports.parseColorFormat = parseColorFormat;
7
8
  exports.asColor = asColor;
8
9
  exports.asLookupValue = asLookupValue;
9
10
  exports.coerceValue = coerceValue;
@@ -53,8 +54,7 @@ function asNegativeValue(modifier, lookup = {}, validate) {
53
54
  return (0, _negateValue).default(resolved);
54
55
  }
55
56
  }
56
- function asValue(modifier, options = {}, { validate =()=>true
57
- } = {}) {
57
+ function asValue(modifier, options = {}, { validate =()=>true } = {}) {
58
58
  var ref;
59
59
  let value = (ref = options.values) === null || ref === void 0 ? void 0 : ref[modifier];
60
60
  if (value !== undefined) {
@@ -80,11 +80,18 @@ function splitAlpha(modifier) {
80
80
  modifier.slice(slashIdx + 1)
81
81
  ];
82
82
  }
83
+ function parseColorFormat(value) {
84
+ if (typeof value === "string" && value.includes("<alpha-value>")) {
85
+ let oldValue = value;
86
+ return ({ opacityValue =1 })=>oldValue.replace("<alpha-value>", opacityValue);
87
+ }
88
+ return value;
89
+ }
83
90
  function asColor(modifier, options = {}, { tailwindConfig ={} } = {}) {
84
91
  var ref;
85
92
  if (((ref = options.values) === null || ref === void 0 ? void 0 : ref[modifier]) !== undefined) {
86
93
  var ref1;
87
- return (ref1 = options.values) === null || ref1 === void 0 ? void 0 : ref1[modifier];
94
+ return parseColorFormat((ref1 = options.values) === null || ref1 === void 0 ? void 0 : ref1[modifier]);
88
95
  }
89
96
  let [color, alpha] = splitAlpha(modifier);
90
97
  if (alpha !== undefined) {
@@ -94,6 +101,7 @@ function asColor(modifier, options = {}, { tailwindConfig ={} } = {}) {
94
101
  if (normalizedColor === undefined) {
95
102
  return undefined;
96
103
  }
104
+ normalizedColor = parseColorFormat(normalizedColor);
97
105
  if (isArbitraryValue(alpha)) {
98
106
  return (0, _withAlphaVariable).withAlphaValue(normalizedColor, alpha.slice(1, -1));
99
107
  }
@@ -13,6 +13,9 @@ var _toPath = require("./toPath");
13
13
  var _normalizeConfig = require("./normalizeConfig");
14
14
  var _isPlainObject = _interopRequireDefault(require("./isPlainObject"));
15
15
  var _cloneDeep = require("./cloneDeep");
16
+ var _pluginUtils = require("./pluginUtils");
17
+ var _withAlphaVariable = require("./withAlphaVariable");
18
+ var _toColorValue = _interopRequireDefault(require("./toColorValue"));
16
19
  function resolveConfig(configs) {
17
20
  let allConfigs = [
18
21
  ...extractPluginConfigs(configs),
@@ -28,8 +31,7 @@ function resolveConfig(configs) {
28
31
  theme: resolveFunctionKeys(mergeExtensions(mergeThemes(allConfigs.map((t)=>{
29
32
  return (ref = t === null || t === void 0 ? void 0 : t.theme) !== null && ref !== void 0 ? ref : {};
30
33
  })))),
31
- corePlugins: resolveCorePlugins(allConfigs.map((c)=>c.corePlugins
32
- )),
34
+ corePlugins: resolveCorePlugins(allConfigs.map((c)=>c.corePlugins)),
33
35
  plugins: resolvePluginLists(configs.map((c)=>{
34
36
  return (ref1 = c === null || c === void 0 ? void 0 : c.plugins) !== null && ref1 !== void 0 ? ref1 : [];
35
37
  }))
@@ -68,8 +70,7 @@ const configUtils = {
68
70
  colors: _colors.default,
69
71
  negative (scale) {
70
72
  // TODO: Log that this function isn't really needed anymore?
71
- return Object.keys(scale).filter((key)=>scale[key] !== "0"
72
- ).reduce((negativeScale, key)=>{
73
+ return Object.keys(scale).filter((key)=>scale[key] !== "0").reduce((negativeScale, key)=>{
73
74
  let negativeValue = (0, _negateValue).default(scale[key]);
74
75
  if (negativeValue !== undefined) {
75
76
  negativeScale[`-${key}`] = negativeValue;
@@ -78,12 +79,10 @@ const configUtils = {
78
79
  }, {});
79
80
  },
80
81
  breakpoints (screens) {
81
- return Object.keys(screens).filter((key)=>typeof screens[key] === "string"
82
- ).reduce((breakpoints, key)=>({
82
+ return Object.keys(screens).filter((key)=>typeof screens[key] === "string").reduce((breakpoints, key)=>({
83
83
  ...breakpoints,
84
84
  [`screen-${key}`]: screens[key]
85
- })
86
- , {});
85
+ }), {});
87
86
  }
88
87
  };
89
88
  function value(valueToResolve, ...args) {
@@ -112,8 +111,7 @@ function collectExtends(items) {
112
111
  }
113
112
  function mergeThemes(themes) {
114
113
  return {
115
- ...themes.reduce((merged, theme)=>(0, _defaults).defaults(merged, theme)
116
- , {}),
114
+ ...themes.reduce((merged, theme)=>(0, _defaults).defaults(merged, theme), {}),
117
115
  // In order to resolve n config objects, we combine all of their `extend` properties
118
116
  // into arrays instead of objects so they aren't overridden.
119
117
  extend: collectExtends(themes)
@@ -147,37 +145,62 @@ function mergeExtensions({ extend , ...theme }) {
147
145
  return (resolveThemePath, utils)=>mergeWith({}, ...[
148
146
  themeValue,
149
147
  ...extensions
150
- ].map((e)=>value(e, resolveThemePath, utils)
151
- ), mergeExtensionCustomizer)
152
- ;
148
+ ].map((e)=>value(e, resolveThemePath, utils)), mergeExtensionCustomizer);
153
149
  });
154
150
  }
151
+ /**
152
+ *
153
+ * @param {string} key
154
+ * @return {Iterable<string[] & {alpha: string | undefined}>}
155
+ */ function* toPaths(key) {
156
+ let path = (0, _toPath).toPath(key);
157
+ if (path.length === 0) {
158
+ return;
159
+ }
160
+ yield path;
161
+ if (Array.isArray(key)) {
162
+ return;
163
+ }
164
+ let pattern = /^(.*?)\s*\/\s*([^/]+)$/;
165
+ let matches = key.match(pattern);
166
+ if (matches !== null) {
167
+ let [, prefix, alpha] = matches;
168
+ let newPath = (0, _toPath).toPath(prefix);
169
+ newPath.alpha = alpha;
170
+ yield newPath;
171
+ }
172
+ }
155
173
  function resolveFunctionKeys(object) {
174
+ // theme('colors.red.500 / 0.5') -> ['colors', 'red', '500 / 0', '5]
156
175
  const resolvePath = (key, defaultValue)=>{
157
- const path = (0, _toPath).toPath(key);
158
- let index = 0;
159
- let val = object;
160
- while(val !== undefined && val !== null && index < path.length){
161
- val = val[path[index++]];
162
- val = isFunction(val) ? val(resolvePath, configUtils) : val;
163
- }
164
- if (val === undefined) {
165
- return defaultValue;
166
- }
167
- if ((0, _isPlainObject).default(val)) {
168
- return (0, _cloneDeep).cloneDeep(val);
176
+ for (const path of toPaths(key)){
177
+ let index = 0;
178
+ let val = object;
179
+ while(val !== undefined && val !== null && index < path.length){
180
+ val = val[path[index++]];
181
+ let shouldResolveAsFn = isFunction(val) && (path.alpha === undefined || index < path.length - 1);
182
+ val = shouldResolveAsFn ? val(resolvePath, configUtils) : val;
183
+ }
184
+ if (val !== undefined) {
185
+ if (path.alpha !== undefined) {
186
+ let normalized = (0, _pluginUtils).parseColorFormat(val);
187
+ return (0, _withAlphaVariable).withAlphaValue(normalized, path.alpha, (0, _toColorValue).default(normalized));
188
+ }
189
+ if ((0, _isPlainObject).default(val)) {
190
+ return (0, _cloneDeep).cloneDeep(val);
191
+ }
192
+ return val;
193
+ }
169
194
  }
170
- return val;
195
+ return defaultValue;
171
196
  };
172
- resolvePath.theme = resolvePath;
173
- for(let key1 in configUtils){
174
- resolvePath[key1] = configUtils[key1];
175
- }
197
+ Object.assign(resolvePath, {
198
+ theme: resolvePath,
199
+ ...configUtils
200
+ });
176
201
  return Object.keys(object).reduce((resolved, key)=>{
177
- return {
178
- ...resolved,
179
- [key]: isFunction(object[key]) ? object[key](resolvePath, configUtils) : object[key]
180
- };
202
+ resolved[key] = isFunction(object[key]) ? object[key](resolvePath, configUtils) : object[key];
203
+ return resolved;
181
204
  }, {});
182
205
  }
183
206
  function extractPluginConfigs(configs) {
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ exports.splitAtTopLevelOnly = splitAtTopLevelOnly;
6
+ var regex = _interopRequireWildcard(require("../lib/regex"));
7
+ function _getRequireWildcardCache() {
8
+ if (typeof WeakMap !== "function") return null;
9
+ var cache = new WeakMap();
10
+ _getRequireWildcardCache = function() {
11
+ return cache;
12
+ };
13
+ return cache;
14
+ }
15
+ function _interopRequireWildcard(obj) {
16
+ if (obj && obj.__esModule) {
17
+ return obj;
18
+ }
19
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
20
+ return {
21
+ default: obj
22
+ };
23
+ }
24
+ var cache = _getRequireWildcardCache();
25
+ if (cache && cache.has(obj)) {
26
+ return cache.get(obj);
27
+ }
28
+ var newObj = {};
29
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
30
+ for(var key in obj){
31
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
32
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
33
+ if (desc && (desc.get || desc.set)) {
34
+ Object.defineProperty(newObj, key, desc);
35
+ } else {
36
+ newObj[key] = obj[key];
37
+ }
38
+ }
39
+ }
40
+ newObj.default = obj;
41
+ if (cache) {
42
+ cache.set(obj, newObj);
43
+ }
44
+ return newObj;
45
+ }
46
+ function* splitAtTopLevelOnly(input, separator) {
47
+ let SPECIALS = new RegExp(`[(){}\\[\\]${regex.escape(separator)}]`, "g");
48
+ let depth = 0;
49
+ let lastIndex = 0;
50
+ let found = false;
51
+ let separatorIndex = 0;
52
+ let separatorStart = 0;
53
+ let separatorLength = separator.length;
54
+ // Find all paren-like things & character
55
+ // And only split on commas if they're top-level
56
+ for (let match of input.matchAll(SPECIALS)){
57
+ let matchesSeparator = match[0] === separator[separatorIndex];
58
+ let atEndOfSeparator = separatorIndex === separatorLength - 1;
59
+ let matchesFullSeparator = matchesSeparator && atEndOfSeparator;
60
+ if (match[0] === "(") depth++;
61
+ if (match[0] === ")") depth--;
62
+ if (match[0] === "[") depth++;
63
+ if (match[0] === "]") depth--;
64
+ if (match[0] === "{") depth++;
65
+ if (match[0] === "}") depth--;
66
+ if (matchesSeparator && depth === 0) {
67
+ if (separatorStart === 0) {
68
+ separatorStart = match.index;
69
+ }
70
+ separatorIndex++;
71
+ }
72
+ if (matchesFullSeparator && depth === 0) {
73
+ found = true;
74
+ yield input.substring(lastIndex, separatorStart);
75
+ lastIndex = separatorStart + separatorLength;
76
+ }
77
+ if (separatorIndex === separatorLength) {
78
+ separatorIndex = 0;
79
+ separatorStart = 0;
80
+ }
81
+ }
82
+ // Provide the last segment of the string if available
83
+ // Otherwise the whole string since no `char`s were found
84
+ // This mirrors the behavior of string.split()
85
+ if (found) {
86
+ yield input.substring(lastIndex);
87
+ } else {
88
+ yield input;
89
+ }
90
+ }