pluginUtils.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. function _export(target, all) {
  6. for(var name in all)Object.defineProperty(target, name, {
  7. enumerable: true,
  8. get: all[name]
  9. });
  10. }
  11. _export(exports, {
  12. updateAllClasses: function() {
  13. return updateAllClasses;
  14. },
  15. asValue: function() {
  16. return asValue;
  17. },
  18. parseColorFormat: function() {
  19. return parseColorFormat;
  20. },
  21. asColor: function() {
  22. return asColor;
  23. },
  24. asLookupValue: function() {
  25. return asLookupValue;
  26. },
  27. typeMap: function() {
  28. return typeMap;
  29. },
  30. coerceValue: function() {
  31. return coerceValue;
  32. },
  33. getMatchingTypes: function() {
  34. return getMatchingTypes;
  35. }
  36. });
  37. const _escapeCommas = /*#__PURE__*/ _interop_require_default(require("./escapeCommas"));
  38. const _withAlphaVariable = require("./withAlphaVariable");
  39. const _dataTypes = require("./dataTypes");
  40. const _negateValue = /*#__PURE__*/ _interop_require_default(require("./negateValue"));
  41. const _validateFormalSyntax = require("./validateFormalSyntax");
  42. const _featureFlags = require("../featureFlags.js");
  43. function _interop_require_default(obj) {
  44. return obj && obj.__esModule ? obj : {
  45. default: obj
  46. };
  47. }
  48. function updateAllClasses(selectors, updateClass) {
  49. selectors.walkClasses((sel)=>{
  50. sel.value = updateClass(sel.value);
  51. if (sel.raws && sel.raws.value) {
  52. sel.raws.value = (0, _escapeCommas.default)(sel.raws.value);
  53. }
  54. });
  55. }
  56. function resolveArbitraryValue(modifier, validate) {
  57. if (!isArbitraryValue(modifier)) {
  58. return undefined;
  59. }
  60. let value = modifier.slice(1, -1);
  61. if (!validate(value)) {
  62. return undefined;
  63. }
  64. return (0, _dataTypes.normalize)(value);
  65. }
  66. function asNegativeValue(modifier, lookup = {}, validate) {
  67. let positiveValue = lookup[modifier];
  68. if (positiveValue !== undefined) {
  69. return (0, _negateValue.default)(positiveValue);
  70. }
  71. if (isArbitraryValue(modifier)) {
  72. let resolved = resolveArbitraryValue(modifier, validate);
  73. if (resolved === undefined) {
  74. return undefined;
  75. }
  76. return (0, _negateValue.default)(resolved);
  77. }
  78. }
  79. function asValue(modifier, options = {}, { validate =()=>true } = {}) {
  80. var _options_values;
  81. let value = (_options_values = options.values) === null || _options_values === void 0 ? void 0 : _options_values[modifier];
  82. if (value !== undefined) {
  83. return value;
  84. }
  85. if (options.supportsNegativeValues && modifier.startsWith("-")) {
  86. return asNegativeValue(modifier.slice(1), options.values, validate);
  87. }
  88. return resolveArbitraryValue(modifier, validate);
  89. }
  90. function isArbitraryValue(input) {
  91. return input.startsWith("[") && input.endsWith("]");
  92. }
  93. function splitUtilityModifier(modifier) {
  94. let slashIdx = modifier.lastIndexOf("/");
  95. // If the `/` is inside an arbitrary, we want to find the previous one if any
  96. // This logic probably isn't perfect but it should work for most cases
  97. let arbitraryStartIdx = modifier.lastIndexOf("[", slashIdx);
  98. let arbitraryEndIdx = modifier.indexOf("]", slashIdx);
  99. let isNextToArbitrary = modifier[slashIdx - 1] === "]" || modifier[slashIdx + 1] === "[";
  100. // Backtrack to the previous `/` if the one we found was inside an arbitrary
  101. if (!isNextToArbitrary) {
  102. if (arbitraryStartIdx !== -1 && arbitraryEndIdx !== -1) {
  103. if (arbitraryStartIdx < slashIdx && slashIdx < arbitraryEndIdx) {
  104. slashIdx = modifier.lastIndexOf("/", arbitraryStartIdx);
  105. }
  106. }
  107. }
  108. if (slashIdx === -1 || slashIdx === modifier.length - 1) {
  109. return [
  110. modifier,
  111. undefined
  112. ];
  113. }
  114. let arbitrary = isArbitraryValue(modifier);
  115. // The modifier could be of the form `[foo]/[bar]`
  116. // We want to handle this case properly
  117. // without affecting `[foo/bar]`
  118. if (arbitrary && !modifier.includes("]/[")) {
  119. return [
  120. modifier,
  121. undefined
  122. ];
  123. }
  124. return [
  125. modifier.slice(0, slashIdx),
  126. modifier.slice(slashIdx + 1)
  127. ];
  128. }
  129. function parseColorFormat(value) {
  130. if (typeof value === "string" && value.includes("<alpha-value>")) {
  131. let oldValue = value;
  132. return ({ opacityValue =1 })=>oldValue.replace(/<alpha-value>/g, opacityValue);
  133. }
  134. return value;
  135. }
  136. function unwrapArbitraryModifier(modifier) {
  137. return (0, _dataTypes.normalize)(modifier.slice(1, -1));
  138. }
  139. function asColor(modifier, options = {}, { tailwindConfig ={} } = {}) {
  140. var _options_values;
  141. if (((_options_values = options.values) === null || _options_values === void 0 ? void 0 : _options_values[modifier]) !== undefined) {
  142. var _options_values1;
  143. return parseColorFormat((_options_values1 = options.values) === null || _options_values1 === void 0 ? void 0 : _options_values1[modifier]);
  144. }
  145. // TODO: Hoist this up to getMatchingTypes or something
  146. // We do this here because we need the alpha value (if any)
  147. let [color, alpha] = splitUtilityModifier(modifier);
  148. if (alpha !== undefined) {
  149. var _options_values2, _tailwindConfig_theme, _tailwindConfig_theme_opacity;
  150. var _options_values_color;
  151. let normalizedColor = (_options_values_color = (_options_values2 = options.values) === null || _options_values2 === void 0 ? void 0 : _options_values2[color]) !== null && _options_values_color !== void 0 ? _options_values_color : isArbitraryValue(color) ? color.slice(1, -1) : undefined;
  152. if (normalizedColor === undefined) {
  153. return undefined;
  154. }
  155. normalizedColor = parseColorFormat(normalizedColor);
  156. if (isArbitraryValue(alpha)) {
  157. return (0, _withAlphaVariable.withAlphaValue)(normalizedColor, unwrapArbitraryModifier(alpha));
  158. }
  159. if (((_tailwindConfig_theme = tailwindConfig.theme) === null || _tailwindConfig_theme === void 0 ? void 0 : (_tailwindConfig_theme_opacity = _tailwindConfig_theme.opacity) === null || _tailwindConfig_theme_opacity === void 0 ? void 0 : _tailwindConfig_theme_opacity[alpha]) === undefined) {
  160. return undefined;
  161. }
  162. return (0, _withAlphaVariable.withAlphaValue)(normalizedColor, tailwindConfig.theme.opacity[alpha]);
  163. }
  164. return asValue(modifier, options, {
  165. validate: _dataTypes.color
  166. });
  167. }
  168. function asLookupValue(modifier, options = {}) {
  169. var _options_values;
  170. return (_options_values = options.values) === null || _options_values === void 0 ? void 0 : _options_values[modifier];
  171. }
  172. function guess(validate) {
  173. return (modifier, options)=>{
  174. return asValue(modifier, options, {
  175. validate
  176. });
  177. };
  178. }
  179. let typeMap = {
  180. any: asValue,
  181. color: asColor,
  182. url: guess(_dataTypes.url),
  183. image: guess(_dataTypes.image),
  184. length: guess(_dataTypes.length),
  185. percentage: guess(_dataTypes.percentage),
  186. position: guess(_dataTypes.position),
  187. lookup: asLookupValue,
  188. "generic-name": guess(_dataTypes.genericName),
  189. "family-name": guess(_dataTypes.familyName),
  190. number: guess(_dataTypes.number),
  191. "line-width": guess(_dataTypes.lineWidth),
  192. "absolute-size": guess(_dataTypes.absoluteSize),
  193. "relative-size": guess(_dataTypes.relativeSize),
  194. shadow: guess(_dataTypes.shadow),
  195. size: guess(_validateFormalSyntax.backgroundSize)
  196. };
  197. let supportedTypes = Object.keys(typeMap);
  198. function splitAtFirst(input, delim) {
  199. let idx = input.indexOf(delim);
  200. if (idx === -1) return [
  201. undefined,
  202. input
  203. ];
  204. return [
  205. input.slice(0, idx),
  206. input.slice(idx + 1)
  207. ];
  208. }
  209. function coerceValue(types, modifier, options, tailwindConfig) {
  210. if (options.values && modifier in options.values) {
  211. for (let { type } of types !== null && types !== void 0 ? types : []){
  212. let result = typeMap[type](modifier, options, {
  213. tailwindConfig
  214. });
  215. if (result === undefined) {
  216. continue;
  217. }
  218. return [
  219. result,
  220. type,
  221. null
  222. ];
  223. }
  224. }
  225. if (isArbitraryValue(modifier)) {
  226. let arbitraryValue = modifier.slice(1, -1);
  227. let [explicitType, value] = splitAtFirst(arbitraryValue, ":");
  228. // It could be that this resolves to `url(https` which is not a valid
  229. // identifier. We currently only support "simple" words with dashes or
  230. // underscores. E.g.: family-name
  231. if (!/^[\w-_]+$/g.test(explicitType)) {
  232. value = arbitraryValue;
  233. } else if (explicitType !== undefined && !supportedTypes.includes(explicitType)) {
  234. return [];
  235. }
  236. if (value.length > 0 && supportedTypes.includes(explicitType)) {
  237. return [
  238. asValue(`[${value}]`, options),
  239. explicitType,
  240. null
  241. ];
  242. }
  243. }
  244. let matches = getMatchingTypes(types, modifier, options, tailwindConfig);
  245. // Find first matching type
  246. for (let match of matches){
  247. return match;
  248. }
  249. return [];
  250. }
  251. function* getMatchingTypes(types, rawModifier, options, tailwindConfig) {
  252. let modifiersEnabled = (0, _featureFlags.flagEnabled)(tailwindConfig, "generalizedModifiers");
  253. let [modifier, utilityModifier] = splitUtilityModifier(rawModifier);
  254. let canUseUtilityModifier = modifiersEnabled && options.modifiers != null && (options.modifiers === "any" || typeof options.modifiers === "object" && (utilityModifier && isArbitraryValue(utilityModifier) || utilityModifier in options.modifiers));
  255. if (!canUseUtilityModifier) {
  256. modifier = rawModifier;
  257. utilityModifier = undefined;
  258. }
  259. if (utilityModifier !== undefined && modifier === "") {
  260. modifier = "DEFAULT";
  261. }
  262. // Check the full value first
  263. // TODO: Move to asValue… somehow
  264. if (utilityModifier !== undefined) {
  265. if (typeof options.modifiers === "object") {
  266. var _options_modifiers;
  267. var _options_modifiers_utilityModifier;
  268. let configValue = (_options_modifiers_utilityModifier = (_options_modifiers = options.modifiers) === null || _options_modifiers === void 0 ? void 0 : _options_modifiers[utilityModifier]) !== null && _options_modifiers_utilityModifier !== void 0 ? _options_modifiers_utilityModifier : null;
  269. if (configValue !== null) {
  270. utilityModifier = configValue;
  271. } else if (isArbitraryValue(utilityModifier)) {
  272. utilityModifier = unwrapArbitraryModifier(utilityModifier);
  273. }
  274. }
  275. }
  276. for (let { type } of types !== null && types !== void 0 ? types : []){
  277. let result = typeMap[type](modifier, options, {
  278. tailwindConfig
  279. });
  280. if (result === undefined) {
  281. continue;
  282. }
  283. yield [
  284. result,
  285. type,
  286. utilityModifier !== null && utilityModifier !== void 0 ? utilityModifier : null
  287. ];
  288. }
  289. }