viconic-react-icons 1.5.5 → 1.5.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.
- package/dist/index.js +41 -129
- package/dist/index.mjs +41 -129
- package/package.json +1 -1
- package/src/index.jsx +69 -195
package/dist/index.js
CHANGED
|
@@ -1992,8 +1992,7 @@ var import_react = __toESM(require("react"));
|
|
|
1992
1992
|
if (c && c.d && Date.now() - c.t < TTL) {
|
|
1993
1993
|
for (const n in c.d) {
|
|
1994
1994
|
if (!Object.prototype.hasOwnProperty.call(c.d, n)) continue;
|
|
1995
|
-
|
|
1996
|
-
if (!W.icons[n]) W.icons[n] = svg;
|
|
1995
|
+
if (!W.icons[n]) W.icons[n] = c.d[n];
|
|
1997
1996
|
}
|
|
1998
1997
|
}
|
|
1999
1998
|
} catch (e) {
|
|
@@ -2003,85 +2002,16 @@ var import_react = __toESM(require("react"));
|
|
|
2003
2002
|
}
|
|
2004
2003
|
})();
|
|
2005
2004
|
var _initializedKits = /* @__PURE__ */ new Set();
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
}
|
|
2014
|
-
var _kitMissQueues = {};
|
|
2015
|
-
var _kitMissTimers = {};
|
|
2016
|
-
var _kitQueued = {};
|
|
2017
|
-
function _resolveRegistry(prefix) {
|
|
2018
|
-
if (_kitRegistry[prefix]) return _kitRegistry[prefix];
|
|
2019
|
-
const kits = window.CopyIconsKit || {};
|
|
2020
|
-
for (const kId in kits) {
|
|
2021
|
-
const kit = kits[kId];
|
|
2022
|
-
if (kit.config && kit.config.prefix === prefix) {
|
|
2023
|
-
const entry = { kitId: kId, api: kit.config.api || "https://api.viconic.dev" };
|
|
2024
|
-
_kitRegistry[prefix] = entry;
|
|
2025
|
-
return entry;
|
|
2026
|
-
}
|
|
2027
|
-
}
|
|
2028
|
-
return null;
|
|
2029
|
-
}
|
|
2030
|
-
function _flushPendingMisses(prefix) {
|
|
2031
|
-
const pending = _pendingMisses[prefix];
|
|
2032
|
-
if (!pending || !pending.size) return;
|
|
2033
|
-
const entry = _resolveRegistry(prefix);
|
|
2034
|
-
if (!entry) return;
|
|
2035
|
-
delete _pendingMisses[prefix];
|
|
2036
|
-
pending.forEach((name) => _dispatchBatchFetch(prefix, name, entry));
|
|
2037
|
-
}
|
|
2038
|
-
function _dispatchBatchFetch(prefix, iconBaseName, entry) {
|
|
2039
|
-
const { kitId, api } = entry;
|
|
2040
|
-
if (!_kitQueued[kitId]) _kitQueued[kitId] = /* @__PURE__ */ new Set();
|
|
2041
|
-
if (_kitQueued[kitId].has(iconBaseName)) return;
|
|
2042
|
-
_kitQueued[kitId].add(iconBaseName);
|
|
2043
|
-
if (!_kitMissQueues[kitId]) _kitMissQueues[kitId] = /* @__PURE__ */ new Set();
|
|
2044
|
-
_kitMissQueues[kitId].add(iconBaseName);
|
|
2045
|
-
if (_kitMissTimers[kitId]) return;
|
|
2046
|
-
_kitMissTimers[kitId] = setTimeout(() => {
|
|
2047
|
-
delete _kitMissTimers[kitId];
|
|
2048
|
-
const names = [..._kitMissQueues[kitId] || []];
|
|
2049
|
-
delete _kitMissQueues[kitId];
|
|
2050
|
-
if (!names.length) return;
|
|
2051
|
-
fetch(`${api}/api/v1/kits/${kitId}/icons/?icons=${names.join(",")}`).then((r) => r.ok ? r.json() : null).then((bj) => {
|
|
2052
|
-
if (!bj || !bj.icons) return;
|
|
2053
|
-
const W = window.__viconic = window.__viconic || {};
|
|
2054
|
-
W.icons = W.icons || {};
|
|
2055
|
-
for (const n in bj.icons) {
|
|
2056
|
-
if (!Object.prototype.hasOwnProperty.call(bj.icons, n)) continue;
|
|
2057
|
-
const d = bj.icons[n];
|
|
2058
|
-
const svg = d.svg || "";
|
|
2059
|
-
if (!svg || !svg.includes("<")) continue;
|
|
2060
|
-
W.icons[`@${prefix}/${n}`] = svg;
|
|
2061
|
-
W.icons[`${prefix}:${n}`] = svg;
|
|
2062
|
-
W.icons[`${prefix}/${n}`] = svg;
|
|
2063
|
-
W.icons[n] = W.icons[n] || svg;
|
|
2064
|
-
}
|
|
2065
|
-
try {
|
|
2066
|
-
document.dispatchEvent(new CustomEvent("viconic:ready", { detail: { prefix, kitId } }));
|
|
2067
|
-
} catch (e) {
|
|
2068
|
-
}
|
|
2069
|
-
}).catch(() => {
|
|
2070
|
-
});
|
|
2071
|
-
}, 150);
|
|
2072
|
-
}
|
|
2073
|
-
function _queueKitMiss(prefix, iconBaseName) {
|
|
2074
|
-
if (typeof window === "undefined") return;
|
|
2075
|
-
const entry = _resolveRegistry(prefix);
|
|
2076
|
-
if (entry) {
|
|
2077
|
-
_dispatchBatchFetch(prefix, iconBaseName, entry);
|
|
2078
|
-
} else {
|
|
2079
|
-
if (!_pendingMisses[prefix]) _pendingMisses[prefix] = /* @__PURE__ */ new Set();
|
|
2080
|
-
_pendingMisses[prefix].add(iconBaseName);
|
|
2081
|
-
}
|
|
2005
|
+
function _isQueued(kitId, iconName) {
|
|
2006
|
+
if (typeof window === "undefined") return false;
|
|
2007
|
+
const q = window.__viconicQueued = window.__viconicQueued || {};
|
|
2008
|
+
const k = kitId + ":" + iconName;
|
|
2009
|
+
if (q[k]) return true;
|
|
2010
|
+
q[k] = 1;
|
|
2011
|
+
return false;
|
|
2082
2012
|
}
|
|
2083
2013
|
function initViconic(options = {}) {
|
|
2084
|
-
const { kitId, cdnBase = "cdn.viconic.dev", version
|
|
2014
|
+
const { kitId, cdnBase = "cdn.viconic.dev", version } = options;
|
|
2085
2015
|
if (typeof window === "undefined") return;
|
|
2086
2016
|
if (!kitId) {
|
|
2087
2017
|
console.warn("[Viconic] initViconic requires a kitId");
|
|
@@ -2089,31 +2019,14 @@ function initViconic(options = {}) {
|
|
|
2089
2019
|
}
|
|
2090
2020
|
if (_initializedKits.has(kitId)) return;
|
|
2091
2021
|
_initializedKits.add(kitId);
|
|
2092
|
-
if (explicitPrefix) {
|
|
2093
|
-
_kitRegistry[explicitPrefix] = { kitId, api };
|
|
2094
|
-
}
|
|
2095
|
-
if (typeof window !== "undefined") {
|
|
2096
|
-
window.__viconicKitIds = window.__viconicKitIds || {};
|
|
2097
|
-
window.__viconicKitIds[kitId] = { api };
|
|
2098
|
-
}
|
|
2099
2022
|
const scriptId = `viconic-kit-${kitId}`;
|
|
2100
2023
|
if (document.getElementById(scriptId)) return;
|
|
2101
2024
|
const script = document.createElement("script");
|
|
2102
2025
|
script.id = scriptId;
|
|
2103
2026
|
let url = `https://${cdnBase}/kits/${kitId}/loader.js`;
|
|
2104
2027
|
if (version) {
|
|
2105
|
-
|
|
2106
|
-
url += `?v=${vQuery}`;
|
|
2028
|
+
url += `?v=${version === "dev" ? Date.now() : version}`;
|
|
2107
2029
|
}
|
|
2108
|
-
script.onload = () => {
|
|
2109
|
-
const kits = window.CopyIconsKit || {};
|
|
2110
|
-
const kit = kits[kitId];
|
|
2111
|
-
if (kit && kit.config && kit.config.prefix) {
|
|
2112
|
-
const pfx = kit.config.prefix;
|
|
2113
|
-
_kitRegistry[pfx] = { kitId, api: kit.config.api || api };
|
|
2114
|
-
_flushPendingMisses(pfx);
|
|
2115
|
-
}
|
|
2116
|
-
};
|
|
2117
2030
|
script.src = url;
|
|
2118
2031
|
script.async = true;
|
|
2119
2032
|
document.head.appendChild(script);
|
|
@@ -2134,51 +2047,50 @@ var ViconicIcon = ({ name, className, style, size, color, ...props }) => {
|
|
|
2134
2047
|
function isInjected() {
|
|
2135
2048
|
return el.classList.contains("vi-ok") || el.classList.contains("svg-loaded");
|
|
2136
2049
|
}
|
|
2137
|
-
|
|
2050
|
+
function tryInjectFromCache() {
|
|
2051
|
+
if (isInjected()) return false;
|
|
2138
2052
|
const W = window.__viconic;
|
|
2139
|
-
if (W
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2053
|
+
if (!W || !W.icons) return false;
|
|
2054
|
+
const baseName = prefixMatch ? prefixMatch[2] : null;
|
|
2055
|
+
const svg = baseName && W.icons[baseName] || name && W.icons[name] || null;
|
|
2056
|
+
if (svg) {
|
|
2057
|
+
el.innerHTML = svg;
|
|
2058
|
+
el.classList.add("vi-ok", "svg-loaded");
|
|
2059
|
+
return true;
|
|
2146
2060
|
}
|
|
2061
|
+
return false;
|
|
2147
2062
|
}
|
|
2148
|
-
if (
|
|
2063
|
+
if (tryInjectFromCache()) return;
|
|
2064
|
+
if (!isKitIcon) {
|
|
2149
2065
|
if (window.CopyIcons && window.CopyIcons.forceProcess) {
|
|
2150
2066
|
window.CopyIcons.forceProcess(el);
|
|
2067
|
+
} else if (el._u) {
|
|
2068
|
+
el._u();
|
|
2151
2069
|
}
|
|
2152
2070
|
}
|
|
2153
|
-
if (!isInjected() && !isKitIcon && el._u) {
|
|
2154
|
-
el._u();
|
|
2155
|
-
}
|
|
2156
2071
|
if (isInjected()) return;
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2072
|
+
if (isKitIcon && prefixMatch) {
|
|
2073
|
+
const kitId = (() => {
|
|
2074
|
+
const kits = window.CopyIconsKit || {};
|
|
2075
|
+
for (const kId in kits) {
|
|
2076
|
+
if (kits[kId].config && kits[kId].config.prefix === prefixMatch[1]) return kId;
|
|
2077
|
+
}
|
|
2078
|
+
return prefixMatch[1];
|
|
2079
|
+
})();
|
|
2080
|
+
if (!_isQueued(kitId, prefixMatch[2])) {
|
|
2081
|
+
if (el._u) {
|
|
2082
|
+
el._u();
|
|
2167
2083
|
}
|
|
2168
|
-
}
|
|
2169
|
-
if (!isKitIcon && el._u) el._u();
|
|
2170
|
-
if (!isKitIcon && window.CopyIcons && window.CopyIcons.forceProcess) {
|
|
2171
|
-
window.CopyIcons.forceProcess(el);
|
|
2172
2084
|
}
|
|
2173
2085
|
}
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
_queueKitMiss(prefix, iconBaseName);
|
|
2086
|
+
function onReady() {
|
|
2087
|
+
if (tryInjectFromCache()) {
|
|
2088
|
+
document.removeEventListener("viconic:ready", onReady);
|
|
2089
|
+
}
|
|
2179
2090
|
}
|
|
2091
|
+
document.addEventListener("viconic:ready", onReady);
|
|
2180
2092
|
return () => {
|
|
2181
|
-
document.removeEventListener("viconic:ready",
|
|
2093
|
+
document.removeEventListener("viconic:ready", onReady);
|
|
2182
2094
|
};
|
|
2183
2095
|
}, [name, className, size, color, style]);
|
|
2184
2096
|
const combinedStyle = {
|
package/dist/index.mjs
CHANGED
|
@@ -1957,8 +1957,7 @@ import React, { useEffect, useRef } from "react";
|
|
|
1957
1957
|
if (c && c.d && Date.now() - c.t < TTL) {
|
|
1958
1958
|
for (const n in c.d) {
|
|
1959
1959
|
if (!Object.prototype.hasOwnProperty.call(c.d, n)) continue;
|
|
1960
|
-
|
|
1961
|
-
if (!W.icons[n]) W.icons[n] = svg;
|
|
1960
|
+
if (!W.icons[n]) W.icons[n] = c.d[n];
|
|
1962
1961
|
}
|
|
1963
1962
|
}
|
|
1964
1963
|
} catch (e) {
|
|
@@ -1968,85 +1967,16 @@ import React, { useEffect, useRef } from "react";
|
|
|
1968
1967
|
}
|
|
1969
1968
|
})();
|
|
1970
1969
|
var _initializedKits = /* @__PURE__ */ new Set();
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
}
|
|
1979
|
-
var _kitMissQueues = {};
|
|
1980
|
-
var _kitMissTimers = {};
|
|
1981
|
-
var _kitQueued = {};
|
|
1982
|
-
function _resolveRegistry(prefix) {
|
|
1983
|
-
if (_kitRegistry[prefix]) return _kitRegistry[prefix];
|
|
1984
|
-
const kits = window.CopyIconsKit || {};
|
|
1985
|
-
for (const kId in kits) {
|
|
1986
|
-
const kit = kits[kId];
|
|
1987
|
-
if (kit.config && kit.config.prefix === prefix) {
|
|
1988
|
-
const entry = { kitId: kId, api: kit.config.api || "https://api.viconic.dev" };
|
|
1989
|
-
_kitRegistry[prefix] = entry;
|
|
1990
|
-
return entry;
|
|
1991
|
-
}
|
|
1992
|
-
}
|
|
1993
|
-
return null;
|
|
1994
|
-
}
|
|
1995
|
-
function _flushPendingMisses(prefix) {
|
|
1996
|
-
const pending = _pendingMisses[prefix];
|
|
1997
|
-
if (!pending || !pending.size) return;
|
|
1998
|
-
const entry = _resolveRegistry(prefix);
|
|
1999
|
-
if (!entry) return;
|
|
2000
|
-
delete _pendingMisses[prefix];
|
|
2001
|
-
pending.forEach((name) => _dispatchBatchFetch(prefix, name, entry));
|
|
2002
|
-
}
|
|
2003
|
-
function _dispatchBatchFetch(prefix, iconBaseName, entry) {
|
|
2004
|
-
const { kitId, api } = entry;
|
|
2005
|
-
if (!_kitQueued[kitId]) _kitQueued[kitId] = /* @__PURE__ */ new Set();
|
|
2006
|
-
if (_kitQueued[kitId].has(iconBaseName)) return;
|
|
2007
|
-
_kitQueued[kitId].add(iconBaseName);
|
|
2008
|
-
if (!_kitMissQueues[kitId]) _kitMissQueues[kitId] = /* @__PURE__ */ new Set();
|
|
2009
|
-
_kitMissQueues[kitId].add(iconBaseName);
|
|
2010
|
-
if (_kitMissTimers[kitId]) return;
|
|
2011
|
-
_kitMissTimers[kitId] = setTimeout(() => {
|
|
2012
|
-
delete _kitMissTimers[kitId];
|
|
2013
|
-
const names = [..._kitMissQueues[kitId] || []];
|
|
2014
|
-
delete _kitMissQueues[kitId];
|
|
2015
|
-
if (!names.length) return;
|
|
2016
|
-
fetch(`${api}/api/v1/kits/${kitId}/icons/?icons=${names.join(",")}`).then((r) => r.ok ? r.json() : null).then((bj) => {
|
|
2017
|
-
if (!bj || !bj.icons) return;
|
|
2018
|
-
const W = window.__viconic = window.__viconic || {};
|
|
2019
|
-
W.icons = W.icons || {};
|
|
2020
|
-
for (const n in bj.icons) {
|
|
2021
|
-
if (!Object.prototype.hasOwnProperty.call(bj.icons, n)) continue;
|
|
2022
|
-
const d = bj.icons[n];
|
|
2023
|
-
const svg = d.svg || "";
|
|
2024
|
-
if (!svg || !svg.includes("<")) continue;
|
|
2025
|
-
W.icons[`@${prefix}/${n}`] = svg;
|
|
2026
|
-
W.icons[`${prefix}:${n}`] = svg;
|
|
2027
|
-
W.icons[`${prefix}/${n}`] = svg;
|
|
2028
|
-
W.icons[n] = W.icons[n] || svg;
|
|
2029
|
-
}
|
|
2030
|
-
try {
|
|
2031
|
-
document.dispatchEvent(new CustomEvent("viconic:ready", { detail: { prefix, kitId } }));
|
|
2032
|
-
} catch (e) {
|
|
2033
|
-
}
|
|
2034
|
-
}).catch(() => {
|
|
2035
|
-
});
|
|
2036
|
-
}, 150);
|
|
2037
|
-
}
|
|
2038
|
-
function _queueKitMiss(prefix, iconBaseName) {
|
|
2039
|
-
if (typeof window === "undefined") return;
|
|
2040
|
-
const entry = _resolveRegistry(prefix);
|
|
2041
|
-
if (entry) {
|
|
2042
|
-
_dispatchBatchFetch(prefix, iconBaseName, entry);
|
|
2043
|
-
} else {
|
|
2044
|
-
if (!_pendingMisses[prefix]) _pendingMisses[prefix] = /* @__PURE__ */ new Set();
|
|
2045
|
-
_pendingMisses[prefix].add(iconBaseName);
|
|
2046
|
-
}
|
|
1970
|
+
function _isQueued(kitId, iconName) {
|
|
1971
|
+
if (typeof window === "undefined") return false;
|
|
1972
|
+
const q = window.__viconicQueued = window.__viconicQueued || {};
|
|
1973
|
+
const k = kitId + ":" + iconName;
|
|
1974
|
+
if (q[k]) return true;
|
|
1975
|
+
q[k] = 1;
|
|
1976
|
+
return false;
|
|
2047
1977
|
}
|
|
2048
1978
|
function initViconic(options = {}) {
|
|
2049
|
-
const { kitId, cdnBase = "cdn.viconic.dev", version
|
|
1979
|
+
const { kitId, cdnBase = "cdn.viconic.dev", version } = options;
|
|
2050
1980
|
if (typeof window === "undefined") return;
|
|
2051
1981
|
if (!kitId) {
|
|
2052
1982
|
console.warn("[Viconic] initViconic requires a kitId");
|
|
@@ -2054,31 +1984,14 @@ function initViconic(options = {}) {
|
|
|
2054
1984
|
}
|
|
2055
1985
|
if (_initializedKits.has(kitId)) return;
|
|
2056
1986
|
_initializedKits.add(kitId);
|
|
2057
|
-
if (explicitPrefix) {
|
|
2058
|
-
_kitRegistry[explicitPrefix] = { kitId, api };
|
|
2059
|
-
}
|
|
2060
|
-
if (typeof window !== "undefined") {
|
|
2061
|
-
window.__viconicKitIds = window.__viconicKitIds || {};
|
|
2062
|
-
window.__viconicKitIds[kitId] = { api };
|
|
2063
|
-
}
|
|
2064
1987
|
const scriptId = `viconic-kit-${kitId}`;
|
|
2065
1988
|
if (document.getElementById(scriptId)) return;
|
|
2066
1989
|
const script = document.createElement("script");
|
|
2067
1990
|
script.id = scriptId;
|
|
2068
1991
|
let url = `https://${cdnBase}/kits/${kitId}/loader.js`;
|
|
2069
1992
|
if (version) {
|
|
2070
|
-
|
|
2071
|
-
url += `?v=${vQuery}`;
|
|
1993
|
+
url += `?v=${version === "dev" ? Date.now() : version}`;
|
|
2072
1994
|
}
|
|
2073
|
-
script.onload = () => {
|
|
2074
|
-
const kits = window.CopyIconsKit || {};
|
|
2075
|
-
const kit = kits[kitId];
|
|
2076
|
-
if (kit && kit.config && kit.config.prefix) {
|
|
2077
|
-
const pfx = kit.config.prefix;
|
|
2078
|
-
_kitRegistry[pfx] = { kitId, api: kit.config.api || api };
|
|
2079
|
-
_flushPendingMisses(pfx);
|
|
2080
|
-
}
|
|
2081
|
-
};
|
|
2082
1995
|
script.src = url;
|
|
2083
1996
|
script.async = true;
|
|
2084
1997
|
document.head.appendChild(script);
|
|
@@ -2099,51 +2012,50 @@ var ViconicIcon = ({ name, className, style, size, color, ...props }) => {
|
|
|
2099
2012
|
function isInjected() {
|
|
2100
2013
|
return el.classList.contains("vi-ok") || el.classList.contains("svg-loaded");
|
|
2101
2014
|
}
|
|
2102
|
-
|
|
2015
|
+
function tryInjectFromCache() {
|
|
2016
|
+
if (isInjected()) return false;
|
|
2103
2017
|
const W = window.__viconic;
|
|
2104
|
-
if (W
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2018
|
+
if (!W || !W.icons) return false;
|
|
2019
|
+
const baseName = prefixMatch ? prefixMatch[2] : null;
|
|
2020
|
+
const svg = baseName && W.icons[baseName] || name && W.icons[name] || null;
|
|
2021
|
+
if (svg) {
|
|
2022
|
+
el.innerHTML = svg;
|
|
2023
|
+
el.classList.add("vi-ok", "svg-loaded");
|
|
2024
|
+
return true;
|
|
2111
2025
|
}
|
|
2026
|
+
return false;
|
|
2112
2027
|
}
|
|
2113
|
-
if (
|
|
2028
|
+
if (tryInjectFromCache()) return;
|
|
2029
|
+
if (!isKitIcon) {
|
|
2114
2030
|
if (window.CopyIcons && window.CopyIcons.forceProcess) {
|
|
2115
2031
|
window.CopyIcons.forceProcess(el);
|
|
2032
|
+
} else if (el._u) {
|
|
2033
|
+
el._u();
|
|
2116
2034
|
}
|
|
2117
2035
|
}
|
|
2118
|
-
if (!isInjected() && !isKitIcon && el._u) {
|
|
2119
|
-
el._u();
|
|
2120
|
-
}
|
|
2121
2036
|
if (isInjected()) return;
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2037
|
+
if (isKitIcon && prefixMatch) {
|
|
2038
|
+
const kitId = (() => {
|
|
2039
|
+
const kits = window.CopyIconsKit || {};
|
|
2040
|
+
for (const kId in kits) {
|
|
2041
|
+
if (kits[kId].config && kits[kId].config.prefix === prefixMatch[1]) return kId;
|
|
2042
|
+
}
|
|
2043
|
+
return prefixMatch[1];
|
|
2044
|
+
})();
|
|
2045
|
+
if (!_isQueued(kitId, prefixMatch[2])) {
|
|
2046
|
+
if (el._u) {
|
|
2047
|
+
el._u();
|
|
2132
2048
|
}
|
|
2133
|
-
}
|
|
2134
|
-
if (!isKitIcon && el._u) el._u();
|
|
2135
|
-
if (!isKitIcon && window.CopyIcons && window.CopyIcons.forceProcess) {
|
|
2136
|
-
window.CopyIcons.forceProcess(el);
|
|
2137
2049
|
}
|
|
2138
2050
|
}
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
_queueKitMiss(prefix, iconBaseName);
|
|
2051
|
+
function onReady() {
|
|
2052
|
+
if (tryInjectFromCache()) {
|
|
2053
|
+
document.removeEventListener("viconic:ready", onReady);
|
|
2054
|
+
}
|
|
2144
2055
|
}
|
|
2056
|
+
document.addEventListener("viconic:ready", onReady);
|
|
2145
2057
|
return () => {
|
|
2146
|
-
document.removeEventListener("viconic:ready",
|
|
2058
|
+
document.removeEventListener("viconic:ready", onReady);
|
|
2147
2059
|
};
|
|
2148
2060
|
}, [name, className, size, color, style]);
|
|
2149
2061
|
const combinedStyle = {
|
package/package.json
CHANGED
package/src/index.jsx
CHANGED
|
@@ -3,32 +3,27 @@ import './copyicons-smart-loader.js';
|
|
|
3
3
|
|
|
4
4
|
// ============================================
|
|
5
5
|
// PRE-LOAD KIT CACHE SYNCHRONOUSLY AT MODULE LEVEL
|
|
6
|
-
// Same architecture as kit loader: read localStorage before any render
|
|
7
|
-
// so icons are available instantly when components mount.
|
|
8
6
|
// ============================================
|
|
9
7
|
(function _preloadKitCache() {
|
|
10
8
|
if (typeof window === 'undefined' || typeof localStorage === 'undefined') return;
|
|
11
9
|
try {
|
|
12
10
|
const W = (window.__viconic = window.__viconic || {});
|
|
13
11
|
W.icons = W.icons || {};
|
|
14
|
-
const TTL = 3 * 24 * 60 * 60 * 1000;
|
|
12
|
+
const TTL = 3 * 24 * 60 * 60 * 1000;
|
|
15
13
|
for (let i = 0; i < localStorage.length; i++) {
|
|
16
14
|
const key = localStorage.key(i);
|
|
17
15
|
if (!key || !key.startsWith('viconic:')) continue;
|
|
18
16
|
try {
|
|
19
17
|
const c = JSON.parse(localStorage.getItem(key));
|
|
20
18
|
if (c && c.d && Date.now() - c.t < TTL) {
|
|
21
|
-
// Register all icon name variants into W.icons
|
|
22
19
|
for (const n in c.d) {
|
|
23
20
|
if (!Object.prototype.hasOwnProperty.call(c.d, n)) continue;
|
|
24
|
-
|
|
25
|
-
// Store by plain name so _u() can find it regardless of prefix
|
|
26
|
-
if (!W.icons[n]) W.icons[n] = svg;
|
|
21
|
+
if (!W.icons[n]) W.icons[n] = c.d[n];
|
|
27
22
|
}
|
|
28
23
|
}
|
|
29
|
-
} catch (e) {
|
|
24
|
+
} catch (e) {}
|
|
30
25
|
}
|
|
31
|
-
} catch (e) {
|
|
26
|
+
} catch (e) {}
|
|
32
27
|
})();
|
|
33
28
|
|
|
34
29
|
// ============================================
|
|
@@ -37,169 +32,58 @@ import './copyicons-smart-loader.js';
|
|
|
37
32
|
const _initializedKits = new Set();
|
|
38
33
|
|
|
39
34
|
// ============================================
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
// and by viconic:ready event handler.
|
|
35
|
+
// Window-level dedup set: survives HMR module reloads and Strict Mode remounts.
|
|
36
|
+
// Keyed by iconKey = "kitId:iconName". Cleared after loader fires viconic:ready.
|
|
43
37
|
// ============================================
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
// This is the main trigger for flushing pending misses when loader.js
|
|
52
|
-
// completes its first batch fetch (which happens after script.onload).
|
|
53
|
-
if (typeof document !== 'undefined') {
|
|
54
|
-
document.addEventListener('viconic:ready', (e) => {
|
|
55
|
-
const prefix = e && e.detail && e.detail.prefix;
|
|
56
|
-
if (prefix) _flushPendingMisses(prefix);
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// ============================================
|
|
61
|
-
// DEBOUNCED BATCH FETCH for missing kit icons
|
|
62
|
-
// ============================================
|
|
63
|
-
const _kitMissQueues = {}; // kitId -> Set of icon names
|
|
64
|
-
const _kitMissTimers = {}; // kitId -> timer handle
|
|
65
|
-
const _kitQueued = {}; // kitId -> Set of icon names already queued (prevents Strict Mode double-queue)
|
|
66
|
-
|
|
67
|
-
function _resolveRegistry(prefix) {
|
|
68
|
-
if (_kitRegistry[prefix]) return _kitRegistry[prefix];
|
|
69
|
-
// Fallback: check CopyIconsKit
|
|
70
|
-
const kits = window.CopyIconsKit || {};
|
|
71
|
-
for (const kId in kits) {
|
|
72
|
-
const kit = kits[kId];
|
|
73
|
-
if (kit.config && kit.config.prefix === prefix) {
|
|
74
|
-
const entry = { kitId: kId, api: kit.config.api || 'https://api.viconic.dev' };
|
|
75
|
-
_kitRegistry[prefix] = entry;
|
|
76
|
-
return entry;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return null;
|
|
38
|
+
function _isQueued(kitId, iconName) {
|
|
39
|
+
if (typeof window === 'undefined') return false;
|
|
40
|
+
const q = (window.__viconicQueued = window.__viconicQueued || {});
|
|
41
|
+
const k = kitId + ':' + iconName;
|
|
42
|
+
if (q[k]) return true;
|
|
43
|
+
q[k] = 1;
|
|
44
|
+
return false;
|
|
80
45
|
}
|
|
81
46
|
|
|
82
|
-
function
|
|
83
|
-
const pending = _pendingMisses[prefix];
|
|
84
|
-
if (!pending || !pending.size) return;
|
|
85
|
-
const entry = _resolveRegistry(prefix);
|
|
86
|
-
if (!entry) return;
|
|
87
|
-
delete _pendingMisses[prefix];
|
|
88
|
-
pending.forEach(name => _dispatchBatchFetch(prefix, name, entry));
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function _dispatchBatchFetch(prefix, iconBaseName, entry) {
|
|
92
|
-
const { kitId, api } = entry;
|
|
93
|
-
// Skip if already queued — prevents React Strict Mode double-invoke from making 2 requests
|
|
94
|
-
if (!_kitQueued[kitId]) _kitQueued[kitId] = new Set();
|
|
95
|
-
if (_kitQueued[kitId].has(iconBaseName)) return;
|
|
96
|
-
_kitQueued[kitId].add(iconBaseName);
|
|
97
|
-
if (!_kitMissQueues[kitId]) _kitMissQueues[kitId] = new Set();
|
|
98
|
-
_kitMissQueues[kitId].add(iconBaseName);
|
|
99
|
-
if (_kitMissTimers[kitId]) return; // already scheduled, will pick up new additions
|
|
100
|
-
// 150ms debounce: collect all icons across the full React render cycle
|
|
101
|
-
_kitMissTimers[kitId] = setTimeout(() => {
|
|
102
|
-
delete _kitMissTimers[kitId];
|
|
103
|
-
const names = [...(_kitMissQueues[kitId] || [])];
|
|
104
|
-
delete _kitMissQueues[kitId];
|
|
105
|
-
if (!names.length) return;
|
|
106
|
-
fetch(`${api}/api/v1/kits/${kitId}/icons/?icons=${names.join(',')}`)
|
|
107
|
-
.then(r => r.ok ? r.json() : null)
|
|
108
|
-
.then(bj => {
|
|
109
|
-
if (!bj || !bj.icons) return;
|
|
110
|
-
const W = (window.__viconic = window.__viconic || {});
|
|
111
|
-
W.icons = W.icons || {};
|
|
112
|
-
for (const n in bj.icons) {
|
|
113
|
-
if (!Object.prototype.hasOwnProperty.call(bj.icons, n)) continue;
|
|
114
|
-
const d = bj.icons[n];
|
|
115
|
-
const svg = d.svg || '';
|
|
116
|
-
if (!svg || !svg.includes('<')) continue;
|
|
117
|
-
W.icons[`@${prefix}/${n}`] = svg;
|
|
118
|
-
W.icons[`${prefix}:${n}`] = svg;
|
|
119
|
-
W.icons[`${prefix}/${n}`] = svg;
|
|
120
|
-
W.icons[n] = W.icons[n] || svg;
|
|
121
|
-
}
|
|
122
|
-
try { document.dispatchEvent(new CustomEvent('viconic:ready', { detail: { prefix, kitId } })); } catch(e) {}
|
|
123
|
-
})
|
|
124
|
-
.catch(() => {});
|
|
125
|
-
}, 150);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function _queueKitMiss(prefix, iconBaseName) {
|
|
47
|
+
function _clearQueued(kitId) {
|
|
129
48
|
if (typeof window === 'undefined') return;
|
|
130
|
-
const
|
|
131
|
-
if (
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
if (!_pendingMisses[prefix]) _pendingMisses[prefix] = new Set();
|
|
136
|
-
_pendingMisses[prefix].add(iconBaseName);
|
|
49
|
+
const q = window.__viconicQueued;
|
|
50
|
+
if (!q) return;
|
|
51
|
+
const prefix = kitId + ':';
|
|
52
|
+
for (const k in q) {
|
|
53
|
+
if (k.startsWith(prefix)) delete q[k];
|
|
137
54
|
}
|
|
138
55
|
}
|
|
139
56
|
|
|
140
57
|
/**
|
|
141
58
|
* Initialize a Viconic Kit in your React app.
|
|
142
59
|
* Injects the kit's loader.js script into <head>.
|
|
143
|
-
* Supports multiple kits — call once per kit.
|
|
144
60
|
*
|
|
145
61
|
* @param {Object} options
|
|
146
62
|
* @param {string} options.kitId - UUID of the Kit (required)
|
|
147
63
|
* @param {string} [options.cdnBase] - Custom CDN domain (default: cdn.viconic.dev)
|
|
148
|
-
*
|
|
149
|
-
* @example
|
|
150
|
-
* import { initViconic } from 'viconic-react-icons';
|
|
151
|
-
*
|
|
152
|
-
* initViconic({ kitId: '387a6161-cb39-411f-8f13-29a5813e4efd' });
|
|
153
|
-
* // Multiple kits:
|
|
154
|
-
* initViconic({ kitId: 'another-kit-uuid', version: '1.0' });
|
|
64
|
+
* @param {string} [options.version] - Version string for cache busting
|
|
155
65
|
*/
|
|
156
66
|
export function initViconic(options = {}) {
|
|
157
|
-
const { kitId, cdnBase = 'cdn.viconic.dev', version
|
|
158
|
-
if (typeof window === 'undefined') return;
|
|
67
|
+
const { kitId, cdnBase = 'cdn.viconic.dev', version } = options;
|
|
68
|
+
if (typeof window === 'undefined') return;
|
|
159
69
|
if (!kitId) {
|
|
160
70
|
console.warn('[Viconic] initViconic requires a kitId');
|
|
161
71
|
return;
|
|
162
72
|
}
|
|
163
|
-
if (_initializedKits.has(kitId)) return;
|
|
73
|
+
if (_initializedKits.has(kitId)) return;
|
|
164
74
|
_initializedKits.add(kitId);
|
|
165
75
|
|
|
166
|
-
// Register synchronously so _queueKitMiss can find kitId immediately,
|
|
167
|
-
// even before the async loader.js script has loaded and populated CopyIconsKit.
|
|
168
|
-
// If prefix is not known yet, we'll also register once CopyIconsKit fires.
|
|
169
|
-
if (explicitPrefix) {
|
|
170
|
-
_kitRegistry[explicitPrefix] = { kitId, api };
|
|
171
|
-
}
|
|
172
|
-
// Also register by kitId so we can backfill prefix once loader fires
|
|
173
|
-
if (typeof window !== 'undefined') {
|
|
174
|
-
window.__viconicKitIds = window.__viconicKitIds || {};
|
|
175
|
-
window.__viconicKitIds[kitId] = { api };
|
|
176
|
-
}
|
|
177
|
-
|
|
178
76
|
const scriptId = `viconic-kit-${kitId}`;
|
|
179
|
-
if (document.getElementById(scriptId)) return;
|
|
77
|
+
if (document.getElementById(scriptId)) return;
|
|
180
78
|
|
|
181
79
|
const script = document.createElement('script');
|
|
182
80
|
script.id = scriptId;
|
|
183
81
|
|
|
184
|
-
// Add cache busting for development or specific version updates
|
|
185
82
|
let url = `https://${cdnBase}/kits/${kitId}/loader.js`;
|
|
186
83
|
if (version) {
|
|
187
|
-
|
|
188
|
-
url += `?v=${vQuery}`;
|
|
84
|
+
url += `?v=${version === 'dev' ? Date.now() : version}`;
|
|
189
85
|
}
|
|
190
86
|
|
|
191
|
-
// Once loader.js runs and registers CopyIconsKit, backfill _kitRegistry and flush pending misses
|
|
192
|
-
script.onload = () => {
|
|
193
|
-
const kits = window.CopyIconsKit || {};
|
|
194
|
-
const kit = kits[kitId];
|
|
195
|
-
if (kit && kit.config && kit.config.prefix) {
|
|
196
|
-
const pfx = kit.config.prefix;
|
|
197
|
-
_kitRegistry[pfx] = { kitId, api: kit.config.api || api };
|
|
198
|
-
// Flush any misses buffered before the loader was ready
|
|
199
|
-
_flushPendingMisses(pfx);
|
|
200
|
-
}
|
|
201
|
-
};
|
|
202
|
-
|
|
203
87
|
script.src = url;
|
|
204
88
|
script.async = true;
|
|
205
89
|
document.head.appendChild(script);
|
|
@@ -207,11 +91,7 @@ export function initViconic(options = {}) {
|
|
|
207
91
|
|
|
208
92
|
/**
|
|
209
93
|
* ViconicIcon — React component for rendering Viconic icons.
|
|
210
|
-
*
|
|
211
|
-
* Works with both:
|
|
212
|
-
* - System icons: <ViconicIcon name="lucide:home" />
|
|
213
|
-
* - Kit icons: <ViconicIcon name="@myprefix/home" /> (after initViconic)
|
|
214
|
-
*
|
|
94
|
+
*
|
|
215
95
|
* @param {string} name - Icon identifier (e.g., "lucide:home", "@prefix/name")
|
|
216
96
|
* @param {string} [className] - CSS class names
|
|
217
97
|
* @param {object} [style] - Inline styles
|
|
@@ -226,7 +106,6 @@ export const ViconicIcon = ({ name, className, style, size, color, ...props }) =
|
|
|
226
106
|
const el = iconRef.current;
|
|
227
107
|
if (!el) return;
|
|
228
108
|
|
|
229
|
-
// --- FIX DOM REUSE (Reconciliation) ---
|
|
230
109
|
if (prevNameRef.current !== name) {
|
|
231
110
|
el.innerHTML = '';
|
|
232
111
|
el.classList.remove('vi-ok', 'svg-loaded', 'vi-mono', 'ci-multicolor');
|
|
@@ -240,78 +119,73 @@ export const ViconicIcon = ({ name, className, style, size, color, ...props }) =
|
|
|
240
119
|
return el.classList.contains('vi-ok') || el.classList.contains('svg-loaded');
|
|
241
120
|
}
|
|
242
121
|
|
|
243
|
-
|
|
244
|
-
|
|
122
|
+
function tryInjectFromCache() {
|
|
123
|
+
if (isInjected()) return false;
|
|
245
124
|
const W = window.__viconic;
|
|
246
|
-
if (W
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
}
|
|
125
|
+
if (!W || !W.icons) return false;
|
|
126
|
+
const baseName = prefixMatch ? prefixMatch[2] : null;
|
|
127
|
+
const svg = (baseName && W.icons[baseName])
|
|
128
|
+
|| (name && W.icons[name])
|
|
129
|
+
|| null;
|
|
130
|
+
if (svg) {
|
|
131
|
+
el.innerHTML = svg;
|
|
132
|
+
el.classList.add('vi-ok', 'svg-loaded');
|
|
133
|
+
return true;
|
|
256
134
|
}
|
|
135
|
+
return false;
|
|
257
136
|
}
|
|
258
137
|
|
|
259
|
-
//
|
|
260
|
-
if (
|
|
138
|
+
// PATH 1: Already in W.icons (from localStorage preload or prior fetch)
|
|
139
|
+
if (tryInjectFromCache()) return;
|
|
140
|
+
|
|
141
|
+
// PATH 2: System icons — delegate to smart loader
|
|
142
|
+
if (!isKitIcon) {
|
|
261
143
|
if (window.CopyIcons && window.CopyIcons.forceProcess) {
|
|
262
144
|
window.CopyIcons.forceProcess(el);
|
|
145
|
+
} else if (el._u) {
|
|
146
|
+
el._u();
|
|
263
147
|
}
|
|
264
148
|
}
|
|
265
149
|
|
|
266
|
-
// --- PATH 3: Custom element _u() call (kit loader registered element, system icons only) ---
|
|
267
|
-
if (!isInjected() && !isKitIcon && el._u) {
|
|
268
|
-
el._u();
|
|
269
|
-
}
|
|
270
|
-
|
|
271
150
|
if (isInjected()) return;
|
|
272
151
|
|
|
273
|
-
//
|
|
274
|
-
//
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
const
|
|
280
|
-
const
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
152
|
+
// PATH 3: Kit icons — let loader.js handle batching via el._u()
|
|
153
|
+
// el._u() notifies the loader element to queue this icon.
|
|
154
|
+
// Loader already has its own debounced batch queue.
|
|
155
|
+
// Use window-level dedup to prevent Strict Mode / HMR double-calls.
|
|
156
|
+
if (isKitIcon && prefixMatch) {
|
|
157
|
+
const kitId = (() => {
|
|
158
|
+
const kits = window.CopyIconsKit || {};
|
|
159
|
+
for (const kId in kits) {
|
|
160
|
+
if (kits[kId].config && kits[kId].config.prefix === prefixMatch[1]) return kId;
|
|
161
|
+
}
|
|
162
|
+
return prefixMatch[1]; // fallback to prefix as key
|
|
163
|
+
})();
|
|
164
|
+
|
|
165
|
+
if (!_isQueued(kitId, prefixMatch[2])) {
|
|
166
|
+
if (el._u) {
|
|
167
|
+
el._u();
|
|
287
168
|
}
|
|
288
|
-
}
|
|
289
|
-
if (!isKitIcon && el._u) el._u();
|
|
290
|
-
if (!isKitIcon && window.CopyIcons && window.CopyIcons.forceProcess) {
|
|
291
|
-
window.CopyIcons.forceProcess(el);
|
|
292
169
|
}
|
|
293
170
|
}
|
|
294
171
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
if (!isInjected() && isKitIcon && prefixMatch) {
|
|
301
|
-
const prefix = prefixMatch[1];
|
|
302
|
-
const iconBaseName = prefixMatch[2];
|
|
303
|
-
_queueKitMiss(prefix, iconBaseName);
|
|
172
|
+
// PATH 4: Listen for viconic:ready to inject when loader finishes fetching
|
|
173
|
+
function onReady() {
|
|
174
|
+
if (tryInjectFromCache()) {
|
|
175
|
+
document.removeEventListener('viconic:ready', onReady);
|
|
176
|
+
}
|
|
304
177
|
}
|
|
178
|
+
document.addEventListener('viconic:ready', onReady);
|
|
305
179
|
|
|
306
180
|
return () => {
|
|
307
|
-
document.removeEventListener('viconic:ready',
|
|
181
|
+
document.removeEventListener('viconic:ready', onReady);
|
|
308
182
|
};
|
|
309
183
|
}, [name, className, size, color, style]);
|
|
310
184
|
|
|
311
185
|
const combinedStyle = {
|
|
312
186
|
...(size ? { fontSize: size } : {}),
|
|
313
187
|
...(color ? { color: color } : {}),
|
|
314
|
-
...style
|
|
188
|
+
...style,
|
|
315
189
|
};
|
|
316
190
|
|
|
317
191
|
return (
|