viconic-react-icons 1.4.2 → 1.5.0
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.
- package/README.md +10 -3
- package/dist/index.js +51 -10
- package/dist/index.mjs +51 -10
- package/package.json +1 -1
- package/src/index.jsx +59 -12
package/README.md
CHANGED
|
@@ -112,15 +112,22 @@ Inject a kit's smart loader script into `<head>`. Call once per kit at app start
|
|
|
112
112
|
| :--- | :--- | :--- | :--- |
|
|
113
113
|
| `kitId` | `string` | — | **Required.** UUID of your Viconic Kit. |
|
|
114
114
|
| `cdnBase` | `string` | `"cdn.viconic.dev"` | Custom CDN domain. |
|
|
115
|
-
| `version` | `string` | `undefined` |
|
|
115
|
+
| `version` | `string` | `undefined` | Cache-bust version. **Update this every time you add/remove icons in your kit.** |
|
|
116
116
|
|
|
117
117
|
```jsx
|
|
118
118
|
// In your main.jsx or App.jsx
|
|
119
119
|
import { initViconic } from "viconic-react-icons";
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
// Copy the exact snippet from the "Usage & Setup" tab in your Kit Editor
|
|
122
|
+
// It already includes the correct version timestamp for your kit.
|
|
123
|
+
initViconic({ kitId: "387a6161-cb39-411f-8f13-29a5813e4efd", version: "1774867419" });
|
|
122
124
|
```
|
|
123
125
|
|
|
126
|
+
> **⚠️ Important — Cache Busting:**
|
|
127
|
+
> Every time you update your kit on [viconic.dev](https://viconic.dev) (add/remove icons, click **"Update Kit"**), you must update the `version` value in `initViconic()` to the new timestamp shown in the **Usage & Setup** tab.
|
|
128
|
+
> This ensures your users always load the latest kit instead of a stale cached version.
|
|
129
|
+
> The **Usage & Setup** tab always shows the ready-to-copy snippet with the current version pre-filled.
|
|
130
|
+
|
|
124
131
|
---
|
|
125
132
|
|
|
126
133
|
## 🧠 Architecture
|
|
@@ -135,4 +142,4 @@ Because we fetch SVGs in parallel and cache them heavily via LocalStorage across
|
|
|
135
142
|
|
|
136
143
|
## 📄 License
|
|
137
144
|
|
|
138
|
-
This project is licensed under the MIT License. Icon licenses depend on the specific icon families you use.
|
|
145
|
+
This project is licensed under the MIT License. Icon licenses depend on the specific icon families you use.
|
package/dist/index.js
CHANGED
|
@@ -2003,6 +2003,54 @@ var import_react = __toESM(require("react"));
|
|
|
2003
2003
|
}
|
|
2004
2004
|
})();
|
|
2005
2005
|
var _initializedKits = /* @__PURE__ */ new Set();
|
|
2006
|
+
var _kitMissQueues = {};
|
|
2007
|
+
var _kitMissTimers = {};
|
|
2008
|
+
function _queueKitMiss(prefix, iconBaseName) {
|
|
2009
|
+
if (typeof window === "undefined") return;
|
|
2010
|
+
const kits = window.CopyIconsKit || {};
|
|
2011
|
+
let kitId = null;
|
|
2012
|
+
for (const kId in kits) {
|
|
2013
|
+
const kit = kits[kId];
|
|
2014
|
+
if (kit.config && kit.config.prefix === prefix) {
|
|
2015
|
+
kitId = kId;
|
|
2016
|
+
break;
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
if (!kitId) return;
|
|
2020
|
+
if (!_kitMissQueues[kitId]) _kitMissQueues[kitId] = /* @__PURE__ */ new Set();
|
|
2021
|
+
_kitMissQueues[kitId].add(iconBaseName);
|
|
2022
|
+
if (_kitMissTimers[kitId]) return;
|
|
2023
|
+
_kitMissTimers[kitId] = setTimeout(() => {
|
|
2024
|
+
delete _kitMissTimers[kitId];
|
|
2025
|
+
const names = [..._kitMissQueues[kitId] || []];
|
|
2026
|
+
delete _kitMissQueues[kitId];
|
|
2027
|
+
if (!names.length) return;
|
|
2028
|
+
const kit = (window.CopyIconsKit || {})[kitId];
|
|
2029
|
+
if (!kit || !kit.config) return;
|
|
2030
|
+
const api = kit.config.api || "https://api.viconic.dev";
|
|
2031
|
+
fetch(`${api}/api/v1/kits/${kitId}/icons/?icons=${names.join(",")}`).then((r) => r.ok ? r.json() : null).then((bj) => {
|
|
2032
|
+
if (!bj || !bj.icons) return;
|
|
2033
|
+
const W = window.__viconic = window.__viconic || {};
|
|
2034
|
+
W.icons = W.icons || {};
|
|
2035
|
+
const pfx = kit.config.prefix;
|
|
2036
|
+
for (const n in bj.icons) {
|
|
2037
|
+
if (!Object.prototype.hasOwnProperty.call(bj.icons, n)) continue;
|
|
2038
|
+
const d = bj.icons[n];
|
|
2039
|
+
const svg = d.svg || "";
|
|
2040
|
+
if (!svg || !svg.includes("<")) continue;
|
|
2041
|
+
W.icons[`@${pfx}/${n}`] = svg;
|
|
2042
|
+
W.icons[`${pfx}:${n}`] = svg;
|
|
2043
|
+
W.icons[`${pfx}/${n}`] = svg;
|
|
2044
|
+
W.icons[n] = W.icons[n] || svg;
|
|
2045
|
+
}
|
|
2046
|
+
try {
|
|
2047
|
+
document.dispatchEvent(new CustomEvent("viconic:ready", { detail: { prefix: pfx, kitId } }));
|
|
2048
|
+
} catch (e) {
|
|
2049
|
+
}
|
|
2050
|
+
}).catch(() => {
|
|
2051
|
+
});
|
|
2052
|
+
}, 0);
|
|
2053
|
+
}
|
|
2006
2054
|
function initViconic(options = {}) {
|
|
2007
2055
|
const { kitId, cdnBase = "cdn.viconic.dev", version } = options;
|
|
2008
2056
|
if (typeof window === "undefined") return;
|
|
@@ -2084,17 +2132,10 @@ var ViconicIcon = ({ name, className, style, size, color, ...props }) => {
|
|
|
2084
2132
|
tryInjectFromEvent();
|
|
2085
2133
|
if (!isInjected() && isKitIcon && prefixMatch) {
|
|
2086
2134
|
const prefix = prefixMatch[1];
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
const kit = window.CopyIconsKit[kId];
|
|
2090
|
-
if (kit.config && kit.config.prefix === prefix && typeof kit.reload === "function") {
|
|
2091
|
-
kit.reload();
|
|
2092
|
-
break;
|
|
2093
|
-
}
|
|
2094
|
-
}
|
|
2095
|
-
}
|
|
2135
|
+
const iconBaseName = prefixMatch[2];
|
|
2136
|
+
_queueKitMiss(prefix, iconBaseName);
|
|
2096
2137
|
}
|
|
2097
|
-
},
|
|
2138
|
+
}, 50);
|
|
2098
2139
|
return () => {
|
|
2099
2140
|
document.removeEventListener("viconic:ready", tryInjectFromEvent);
|
|
2100
2141
|
clearTimeout(fallbackTimer);
|
package/dist/index.mjs
CHANGED
|
@@ -1968,6 +1968,54 @@ import React, { useEffect, useRef } from "react";
|
|
|
1968
1968
|
}
|
|
1969
1969
|
})();
|
|
1970
1970
|
var _initializedKits = /* @__PURE__ */ new Set();
|
|
1971
|
+
var _kitMissQueues = {};
|
|
1972
|
+
var _kitMissTimers = {};
|
|
1973
|
+
function _queueKitMiss(prefix, iconBaseName) {
|
|
1974
|
+
if (typeof window === "undefined") return;
|
|
1975
|
+
const kits = window.CopyIconsKit || {};
|
|
1976
|
+
let kitId = null;
|
|
1977
|
+
for (const kId in kits) {
|
|
1978
|
+
const kit = kits[kId];
|
|
1979
|
+
if (kit.config && kit.config.prefix === prefix) {
|
|
1980
|
+
kitId = kId;
|
|
1981
|
+
break;
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1984
|
+
if (!kitId) return;
|
|
1985
|
+
if (!_kitMissQueues[kitId]) _kitMissQueues[kitId] = /* @__PURE__ */ new Set();
|
|
1986
|
+
_kitMissQueues[kitId].add(iconBaseName);
|
|
1987
|
+
if (_kitMissTimers[kitId]) return;
|
|
1988
|
+
_kitMissTimers[kitId] = setTimeout(() => {
|
|
1989
|
+
delete _kitMissTimers[kitId];
|
|
1990
|
+
const names = [..._kitMissQueues[kitId] || []];
|
|
1991
|
+
delete _kitMissQueues[kitId];
|
|
1992
|
+
if (!names.length) return;
|
|
1993
|
+
const kit = (window.CopyIconsKit || {})[kitId];
|
|
1994
|
+
if (!kit || !kit.config) return;
|
|
1995
|
+
const api = kit.config.api || "https://api.viconic.dev";
|
|
1996
|
+
fetch(`${api}/api/v1/kits/${kitId}/icons/?icons=${names.join(",")}`).then((r) => r.ok ? r.json() : null).then((bj) => {
|
|
1997
|
+
if (!bj || !bj.icons) return;
|
|
1998
|
+
const W = window.__viconic = window.__viconic || {};
|
|
1999
|
+
W.icons = W.icons || {};
|
|
2000
|
+
const pfx = kit.config.prefix;
|
|
2001
|
+
for (const n in bj.icons) {
|
|
2002
|
+
if (!Object.prototype.hasOwnProperty.call(bj.icons, n)) continue;
|
|
2003
|
+
const d = bj.icons[n];
|
|
2004
|
+
const svg = d.svg || "";
|
|
2005
|
+
if (!svg || !svg.includes("<")) continue;
|
|
2006
|
+
W.icons[`@${pfx}/${n}`] = svg;
|
|
2007
|
+
W.icons[`${pfx}:${n}`] = svg;
|
|
2008
|
+
W.icons[`${pfx}/${n}`] = svg;
|
|
2009
|
+
W.icons[n] = W.icons[n] || svg;
|
|
2010
|
+
}
|
|
2011
|
+
try {
|
|
2012
|
+
document.dispatchEvent(new CustomEvent("viconic:ready", { detail: { prefix: pfx, kitId } }));
|
|
2013
|
+
} catch (e) {
|
|
2014
|
+
}
|
|
2015
|
+
}).catch(() => {
|
|
2016
|
+
});
|
|
2017
|
+
}, 0);
|
|
2018
|
+
}
|
|
1971
2019
|
function initViconic(options = {}) {
|
|
1972
2020
|
const { kitId, cdnBase = "cdn.viconic.dev", version } = options;
|
|
1973
2021
|
if (typeof window === "undefined") return;
|
|
@@ -2049,17 +2097,10 @@ var ViconicIcon = ({ name, className, style, size, color, ...props }) => {
|
|
|
2049
2097
|
tryInjectFromEvent();
|
|
2050
2098
|
if (!isInjected() && isKitIcon && prefixMatch) {
|
|
2051
2099
|
const prefix = prefixMatch[1];
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
const kit = window.CopyIconsKit[kId];
|
|
2055
|
-
if (kit.config && kit.config.prefix === prefix && typeof kit.reload === "function") {
|
|
2056
|
-
kit.reload();
|
|
2057
|
-
break;
|
|
2058
|
-
}
|
|
2059
|
-
}
|
|
2060
|
-
}
|
|
2100
|
+
const iconBaseName = prefixMatch[2];
|
|
2101
|
+
_queueKitMiss(prefix, iconBaseName);
|
|
2061
2102
|
}
|
|
2062
|
-
},
|
|
2103
|
+
}, 50);
|
|
2063
2104
|
return () => {
|
|
2064
2105
|
document.removeEventListener("viconic:ready", tryInjectFromEvent);
|
|
2065
2106
|
clearTimeout(fallbackTimer);
|
package/package.json
CHANGED
package/src/index.jsx
CHANGED
|
@@ -36,6 +36,60 @@ import './copyicons-smart-loader.js';
|
|
|
36
36
|
// ============================================
|
|
37
37
|
const _initializedKits = new Set();
|
|
38
38
|
|
|
39
|
+
// ============================================
|
|
40
|
+
// DEBOUNCED BATCH FETCH for missing kit icons
|
|
41
|
+
// All ViconicIcon mounts queue their miss here;
|
|
42
|
+
// a single setTimeout(0) fires ONE batch request
|
|
43
|
+
// per kit instead of N individual kit.reload() calls.
|
|
44
|
+
// ============================================
|
|
45
|
+
const _kitMissQueues = {}; // kitId -> Set of icon names
|
|
46
|
+
const _kitMissTimers = {}; // kitId -> timer handle
|
|
47
|
+
|
|
48
|
+
function _queueKitMiss(prefix, iconBaseName) {
|
|
49
|
+
if (typeof window === 'undefined') return;
|
|
50
|
+
// Find kit by prefix
|
|
51
|
+
const kits = window.CopyIconsKit || {};
|
|
52
|
+
let kitId = null;
|
|
53
|
+
for (const kId in kits) {
|
|
54
|
+
const kit = kits[kId];
|
|
55
|
+
if (kit.config && kit.config.prefix === prefix) { kitId = kId; break; }
|
|
56
|
+
}
|
|
57
|
+
if (!kitId) return;
|
|
58
|
+
if (!_kitMissQueues[kitId]) _kitMissQueues[kitId] = new Set();
|
|
59
|
+
_kitMissQueues[kitId].add(iconBaseName);
|
|
60
|
+
if (_kitMissTimers[kitId]) return; // already scheduled
|
|
61
|
+
_kitMissTimers[kitId] = setTimeout(() => {
|
|
62
|
+
delete _kitMissTimers[kitId];
|
|
63
|
+
const names = [...(_kitMissQueues[kitId] || [])];
|
|
64
|
+
delete _kitMissQueues[kitId];
|
|
65
|
+
if (!names.length) return;
|
|
66
|
+
const kit = (window.CopyIconsKit || {})[kitId];
|
|
67
|
+
if (!kit || !kit.config) return;
|
|
68
|
+
const api = kit.config.api || 'https://api.viconic.dev';
|
|
69
|
+
fetch(`${api}/api/v1/kits/${kitId}/icons/?icons=${names.join(',')}`)
|
|
70
|
+
.then(r => r.ok ? r.json() : null)
|
|
71
|
+
.then(bj => {
|
|
72
|
+
if (!bj || !bj.icons) return;
|
|
73
|
+
const W = (window.__viconic = window.__viconic || {});
|
|
74
|
+
W.icons = W.icons || {};
|
|
75
|
+
const pfx = kit.config.prefix;
|
|
76
|
+
for (const n in bj.icons) {
|
|
77
|
+
if (!Object.prototype.hasOwnProperty.call(bj.icons, n)) continue;
|
|
78
|
+
const d = bj.icons[n];
|
|
79
|
+
const svg = d.svg || '';
|
|
80
|
+
if (!svg || !svg.includes('<')) continue;
|
|
81
|
+
W.icons[`@${pfx}/${n}`] = svg;
|
|
82
|
+
W.icons[`${pfx}:${n}`] = svg;
|
|
83
|
+
W.icons[`${pfx}/${n}`] = svg;
|
|
84
|
+
W.icons[n] = W.icons[n] || svg;
|
|
85
|
+
}
|
|
86
|
+
// Fire viconic:ready so all waiting ViconicIcon components inject
|
|
87
|
+
try { document.dispatchEvent(new CustomEvent('viconic:ready', { detail: { prefix: pfx, kitId } })); } catch(e) {}
|
|
88
|
+
})
|
|
89
|
+
.catch(() => {});
|
|
90
|
+
}, 0); // setTimeout(0): collect ALL icon misses from current render cycle
|
|
91
|
+
}
|
|
92
|
+
|
|
39
93
|
/**
|
|
40
94
|
* Initialize a Viconic Kit in your React app.
|
|
41
95
|
* Injects the kit's loader.js script into <head>.
|
|
@@ -169,24 +223,17 @@ export const ViconicIcon = ({ name, className, style, size, color, ...props }) =
|
|
|
169
223
|
|
|
170
224
|
document.addEventListener('viconic:ready', tryInjectFromEvent);
|
|
171
225
|
|
|
172
|
-
// --- PATH 5: Short-deadline fallback (
|
|
226
|
+
// --- PATH 5: Short-deadline fallback (50ms) — queue a batch fetch for all missing kit icons ---
|
|
173
227
|
const fallbackTimer = setTimeout(() => {
|
|
174
228
|
if (isInjected()) return;
|
|
175
229
|
tryInjectFromEvent();
|
|
176
|
-
// If still not loaded after 500ms, trigger kit reload once
|
|
177
230
|
if (!isInjected() && isKitIcon && prefixMatch) {
|
|
178
231
|
const prefix = prefixMatch[1];
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (kit.config && kit.config.prefix === prefix && typeof kit.reload === 'function') {
|
|
183
|
-
kit.reload();
|
|
184
|
-
break;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
232
|
+
const iconBaseName = prefixMatch[2];
|
|
233
|
+
// Use batch queue instead of kit.reload() to avoid N separate API calls
|
|
234
|
+
_queueKitMiss(prefix, iconBaseName);
|
|
188
235
|
}
|
|
189
|
-
},
|
|
236
|
+
}, 50);
|
|
190
237
|
|
|
191
238
|
return () => {
|
|
192
239
|
document.removeEventListener('viconic:ready', tryInjectFromEvent);
|