@modul-es/icons 0.2.5 → 0.2.7

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 (2) hide show
  1. package/dist/Icon.js +57 -27
  2. package/package.json +1 -1
package/dist/Icon.js CHANGED
@@ -47,11 +47,21 @@ var SIZE_MAP = {
47
47
  lg: 32,
48
48
  xl: 40
49
49
  };
50
+ var svgCache = new Map();
51
+ var failedUrls = new Set();
52
+ function buildUrl(set, iconKey, color, stroke) {
53
+ var params = new URLSearchParams();
54
+ if (color !== 'currentColor') {
55
+ var colorValue = (0, colors_1.resolveColor)(color).replace('#', '');
56
+ params.set('color', colorValue);
57
+ }
58
+ if (stroke)
59
+ params.set('stroke', stroke);
60
+ return "https://modul.es/api/icons/".concat(set, "/").concat(iconKey, ".svg").concat(params.toString() ? "?".concat(params.toString()) : '');
61
+ }
50
62
  function Icon(_a) {
51
63
  var _this = this;
52
64
  var name = _a.name, _b = _a.color, color = _b === void 0 ? 'currentColor' : _b, stroke = _a.stroke, style = _a.style, _c = _a.set, set = _c === void 0 ? 'huge' : _c, className = _a.className, _d = _a.size, size = _d === void 0 ? 'md' : _d;
53
- var _e = (0, react_1.useState)(null), svgContent = _e[0], setSvgContent = _e[1];
54
- var _f = (0, react_1.useState)(false), error = _f[0], setError = _f[1];
55
65
  var iconKey = (0, react_1.useMemo)(function () {
56
66
  var iconName = name.replace('.svg', '');
57
67
  if (set === 'phosphor' && (style === 'thin' || style === 'light' || style === 'bold' || style === 'fill' || style === 'duotone')) {
@@ -70,47 +80,67 @@ function Icon(_a) {
70
80
  }
71
81
  return iconName;
72
82
  }, [name, set, style]);
83
+ var url = (0, react_1.useMemo)(function () { return buildUrl(set, iconKey, color, stroke); }, [set, iconKey, color, stroke]);
84
+ var _e = (0, react_1.useState)(function () { var _a; return (_a = svgCache.get(url)) !== null && _a !== void 0 ? _a : null; }), svgContent = _e[0], setSvgContent = _e[1];
85
+ var _f = (0, react_1.useState)(function () { return failedUrls.has(url); }), error = _f[0], setError = _f[1];
86
+ var _g = (0, react_1.useState)(url), currentUrl = _g[0], setCurrentUrl = _g[1];
87
+ if (currentUrl !== url) {
88
+ setCurrentUrl(url);
89
+ var cached = svgCache.get(url);
90
+ if (cached) {
91
+ setSvgContent(cached);
92
+ setError(false);
93
+ }
94
+ else if (failedUrls.has(url)) {
95
+ setSvgContent(null);
96
+ setError(true);
97
+ }
98
+ else {
99
+ setSvgContent(null);
100
+ setError(false);
101
+ }
102
+ }
73
103
  (0, react_1.useEffect)(function () {
104
+ if (svgCache.has(url) || failedUrls.has(url))
105
+ return;
106
+ var cancelled = false;
74
107
  var loadSvg = function () { return __awaiter(_this, void 0, void 0, function () {
75
- var params, colorValue, url, response, svg, _a;
108
+ var response, svg, _a;
76
109
  return __generator(this, function (_b) {
77
110
  switch (_b.label) {
78
111
  case 0:
79
- setError(false);
80
- _b.label = 1;
81
- case 1:
82
- _b.trys.push([1, 6, , 7]);
83
- params = new URLSearchParams();
84
- if (color !== 'currentColor') {
85
- colorValue = (0, colors_1.resolveColor)(color).replace('#', '');
86
- params.set('color', colorValue);
87
- }
88
- if (stroke)
89
- params.set('stroke', stroke);
90
- url = "https://modul.es/api/icons/".concat(set, "/").concat(iconKey, ".svg").concat(params.toString() ? "?".concat(params.toString()) : '');
112
+ _b.trys.push([0, 5, , 6]);
91
113
  return [4 /*yield*/, fetch(url, { mode: 'cors' })];
92
- case 2:
114
+ case 1:
93
115
  response = _b.sent();
94
- if (!response.ok) return [3 /*break*/, 4];
116
+ if (cancelled)
117
+ return [2 /*return*/];
118
+ if (!response.ok) return [3 /*break*/, 3];
95
119
  return [4 /*yield*/, response.text()];
96
- case 3:
120
+ case 2:
97
121
  svg = _b.sent();
122
+ svgCache.set(url, svg);
98
123
  setSvgContent(svg);
99
- return [3 /*break*/, 5];
100
- case 4:
124
+ return [3 /*break*/, 4];
125
+ case 3:
126
+ failedUrls.add(url);
101
127
  setError(true);
102
- _b.label = 5;
103
- case 5: return [3 /*break*/, 7];
104
- case 6:
128
+ _b.label = 4;
129
+ case 4: return [3 /*break*/, 6];
130
+ case 5:
105
131
  _a = _b.sent();
106
- setError(true);
107
- return [3 /*break*/, 7];
108
- case 7: return [2 /*return*/];
132
+ if (!cancelled) {
133
+ failedUrls.add(url);
134
+ setError(true);
135
+ }
136
+ return [3 /*break*/, 6];
137
+ case 6: return [2 /*return*/];
109
138
  }
110
139
  });
111
140
  }); };
112
141
  loadSvg();
113
- }, [color, stroke, set, iconKey]);
142
+ return function () { cancelled = true; };
143
+ }, [url]);
114
144
  var processedSvg = (0, react_1.useMemo)(function () {
115
145
  if (!svgContent)
116
146
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modul-es/icons",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "Icon component system",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",