icons.mjs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import { getIconData } from '../icon-set/get-icon.mjs';
  2. import { defaultIconProps } from '../icon/defaults.mjs';
  3. import { getCommonCSSRules, generateItemCSSRules, generateItemContent } from './common.mjs';
  4. import { formatCSS } from './format.mjs';
  5. import '../icon/merge.mjs';
  6. import '../icon/transformations.mjs';
  7. import '../icon-set/tree.mjs';
  8. import '../svg/html.mjs';
  9. import '../svg/size.mjs';
  10. import '../svg/url.mjs';
  11. import '../icon/square.mjs';
  12. import '../svg/build.mjs';
  13. import '../customisations/defaults.mjs';
  14. import '../svg/defs.mjs';
  15. const commonSelector = ".icon--{prefix}";
  16. const iconSelector = ".icon--{prefix}--{name}";
  17. const contentSelector = ".icon--{prefix}--{name}::after";
  18. const defaultSelectors = {
  19. commonSelector,
  20. iconSelector,
  21. overrideSelector: commonSelector + iconSelector
  22. };
  23. function getIconsCSSData(iconSet, names, options = {}) {
  24. const css = [];
  25. const errors = [];
  26. const palette = options.color ? true : void 0;
  27. let mode = options.mode || typeof palette === "boolean" && (palette ? "background" : "mask");
  28. if (!mode) {
  29. for (let i = 0; i < names.length; i++) {
  30. const name = names[i];
  31. const icon = getIconData(iconSet, name);
  32. if (icon) {
  33. const body = options.customise ? options.customise(icon.body, name) : icon.body;
  34. mode = body.includes("currentColor") ? "mask" : "background";
  35. break;
  36. }
  37. }
  38. if (!mode) {
  39. mode = "mask";
  40. errors.push(
  41. "/* cannot detect icon mode: not set in options and icon set is missing info, rendering as " + mode + " */"
  42. );
  43. }
  44. }
  45. let varName = options.varName;
  46. if (varName === void 0 && mode === "mask") {
  47. varName = "svg";
  48. }
  49. const newOptions = {
  50. ...options,
  51. // Override mode and varName
  52. mode,
  53. varName
  54. };
  55. const { commonSelector: commonSelector2, iconSelector: iconSelector2, overrideSelector } = newOptions.iconSelector ? newOptions : defaultSelectors;
  56. const iconSelectorWithPrefix = iconSelector2.replace(
  57. /{prefix}/g,
  58. iconSet.prefix
  59. );
  60. const commonRules = {
  61. ...options.rules,
  62. ...getCommonCSSRules(newOptions)
  63. };
  64. const hasCommonRules = commonSelector2 && commonSelector2 !== iconSelector2;
  65. const commonSelectors = /* @__PURE__ */ new Set();
  66. if (hasCommonRules) {
  67. css.push({
  68. selector: commonSelector2.replace(/{prefix}/g, iconSet.prefix),
  69. rules: commonRules
  70. });
  71. }
  72. for (let i = 0; i < names.length; i++) {
  73. const name = names[i];
  74. const iconData = getIconData(iconSet, name);
  75. if (!iconData) {
  76. errors.push("/* Could not find icon: " + name + " */");
  77. continue;
  78. }
  79. const body = options.customise ? options.customise(iconData.body, name) : iconData.body;
  80. const rules = generateItemCSSRules(
  81. {
  82. ...defaultIconProps,
  83. ...iconData,
  84. body
  85. },
  86. newOptions
  87. );
  88. let requiresOverride = false;
  89. if (hasCommonRules && overrideSelector) {
  90. for (const key in rules) {
  91. if (key in commonRules) {
  92. requiresOverride = true;
  93. }
  94. }
  95. }
  96. const selector = (requiresOverride && overrideSelector ? overrideSelector.replace(/{prefix}/g, iconSet.prefix) : iconSelectorWithPrefix).replace(/{name}/g, name);
  97. css.push({
  98. selector,
  99. rules
  100. });
  101. if (!hasCommonRules) {
  102. commonSelectors.add(selector);
  103. }
  104. }
  105. const result = {
  106. css,
  107. errors
  108. };
  109. if (!hasCommonRules && commonSelectors.size) {
  110. const selector = Array.from(commonSelectors).join(
  111. newOptions.format === "compressed" ? "," : ", "
  112. );
  113. result.common = {
  114. selector,
  115. rules: commonRules
  116. };
  117. }
  118. return result;
  119. }
  120. function getIconsCSS(iconSet, names, options = {}) {
  121. const { css, errors, common } = getIconsCSSData(iconSet, names, options);
  122. if (common) {
  123. if (css.length === 1 && css[0].selector === common.selector) {
  124. css[0].rules = {
  125. // Common first, override later
  126. ...common.rules,
  127. ...css[0].rules
  128. };
  129. } else {
  130. css.unshift(common);
  131. }
  132. }
  133. return formatCSS(css, options.format) + (errors.length ? "\n" + errors.join("\n") + "\n" : "");
  134. }
  135. function getIconsContentCSS(iconSet, names, options) {
  136. const errors = [];
  137. const css = [];
  138. const iconSelectorWithPrefix = (options.iconSelector ?? contentSelector).replace(/{prefix}/g, iconSet.prefix);
  139. for (let i = 0; i < names.length; i++) {
  140. const name = names[i];
  141. const iconData = getIconData(iconSet, name);
  142. if (!iconData) {
  143. errors.push("/* Could not find icon: " + name + " */");
  144. continue;
  145. }
  146. const body = options.customise ? options.customise(iconData.body, name) : iconData.body;
  147. const content = generateItemContent(
  148. {
  149. ...defaultIconProps,
  150. ...iconData,
  151. body
  152. },
  153. options
  154. );
  155. const selector = iconSelectorWithPrefix.replace(/{name}/g, name);
  156. css.push({
  157. selector,
  158. rules: {
  159. ...options.rules,
  160. content
  161. }
  162. });
  163. }
  164. return formatCSS(css, options.format) + (errors.length ? "\n" + errors.join("\n") + "\n" : "");
  165. }
  166. export { getIconsCSS, getIconsCSSData, getIconsContentCSS };