viconic-react-icons 1.4.1 â 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 +61 -35
- 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
|
@@ -1,21 +1,27 @@
|
|
|
1
|
-
# Viconic React Icons
|
|
1
|
+
ïŧŋ# Viconic React Icons
|
|
2
2
|
|
|
3
|
-

|
|
4
|
-

|
|
3
|
+
[](https://www.npmjs.com/package/viconic-react-icons)
|
|
4
|
+
[](https://github.com/noname21024/copyicons-backend)
|
|
5
|
+
[](https://bundlephobia.com/package/viconic-react-icons)
|
|
5
6
|
|
|
6
7
|
The official React component wrapper for [Viconic](https://viconic.dev), a modern, hyper-fast, CDN-powered icon system.
|
|
7
8
|
|
|
8
|
-
`viconic-react-icons` gives you access to over 200,000+ open-source, pixel-perfect icons grouped in customizable collections. The icons are loaded dynamically from our Smart CDN at runtime, meaning your React bundle stays incredibly lightweight regardless of how many icons you use.
|
|
9
|
+
`viconic-react-icons` gives you access to over **200,000+ open-source, pixel-perfect icons** grouped in customizable collections. The icons are loaded dynamically from our Smart CDN at runtime, meaning your React bundle stays incredibly lightweight regardless of how many icons you use.
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
- ðŠķ **Zero-Bundle Bloat**: SVGs are fetched magically via our CDN and injected directly into the DOM.
|
|
12
|
-
- ðĻ **Fully Customizable**: Compatible with Tailwind CSS and standard inline styles. Inherits color natively via `currentColor`.
|
|
13
|
-
- ⥠**Smart Caching**: LocalStorage and Memory caching so icons appear instantly on repeated renders.
|
|
14
|
-
- ð§ **Kit Support**: Use your custom icon kit with `initViconic()` â supports multiple kits.
|
|
15
|
-
- ðĨïļ **SSR Ready**: Fully supports Next.js, Vite, and other Server-Side Rendering frameworks.
|
|
16
|
-
- ð **TypeScript Support**: Includes built-in types for easy autocompletion.
|
|
11
|
+
---
|
|
17
12
|
|
|
18
|
-
##
|
|
13
|
+
## ð Highlights
|
|
14
|
+
|
|
15
|
+
* ðŠķ **Zero-Bundle Bloat**: SVGs are fetched magically via our CDN and injected directly into the DOM.
|
|
16
|
+
* ⥠**Smart Caching**: LocalStorage and Memory caching so icons appear instantly on repeated renders. Event-driven icon injection for ultra-fast, progressive rendering.
|
|
17
|
+
* ïŋ―ïŋ― **Fully Customizable**: Compatible with Tailwind CSS and standard inline styles. Inherits color natively via `currentColor`.
|
|
18
|
+
* ð§ **Kit Support**: Use your custom icon kit with `initViconic()` â supports multiple kits and user-uploaded SVGs simultaneously.
|
|
19
|
+
* ðĨïļ **SSR Ready**: Fully supports Next.js, Vite, Remix, and other Server-Side Rendering frameworks.
|
|
20
|
+
* ð **TypeScript Support**: Includes built-in types for easy autocompletion.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## ðĶ Installation
|
|
19
25
|
|
|
20
26
|
```bash
|
|
21
27
|
npm install viconic-react-icons
|
|
@@ -25,7 +31,11 @@ yarn add viconic-react-icons
|
|
|
25
31
|
pnpm add viconic-react-icons
|
|
26
32
|
```
|
|
27
33
|
|
|
28
|
-
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## ð Quick Start
|
|
37
|
+
|
|
38
|
+
### 1. System Icons (200k+ Free Icons)
|
|
29
39
|
|
|
30
40
|
Import the `ViconicIcon` component and pass the unique `name` identifier corresponding to your icon of choice from [viconic.dev](https://viconic.dev).
|
|
31
41
|
|
|
@@ -37,7 +47,7 @@ function App() {
|
|
|
37
47
|
<div style={{ display: "flex", gap: "10px" }}>
|
|
38
48
|
{/* Basic Usage */}
|
|
39
49
|
<ViconicIcon name="h2:0" />
|
|
40
|
-
|
|
50
|
+
|
|
41
51
|
{/* With Tailwind CSS */}
|
|
42
52
|
<ViconicIcon name="lucide:home" className="w-8 h-8 text-blue-500" />
|
|
43
53
|
|
|
@@ -48,17 +58,17 @@ function App() {
|
|
|
48
58
|
}
|
|
49
59
|
```
|
|
50
60
|
|
|
51
|
-
|
|
61
|
+
### 2. Custom Kits & Uploaded Icons
|
|
52
62
|
|
|
53
|
-
Use icons from your own kit created at [viconic.dev](https://viconic.dev):
|
|
63
|
+
Use icons from your own customized kit (including your own SVG uploads) created at [viconic.dev](https://viconic.dev):
|
|
54
64
|
|
|
55
65
|
```jsx
|
|
56
66
|
import { initViconic, ViconicIcon } from "viconic-react-icons";
|
|
57
67
|
|
|
58
|
-
// Initialize your kit â call once at app startup (e.g., in main.jsx or
|
|
68
|
+
// Initialize your kit â call once at app startup (e.g., in main.jsx or _app.tsx)
|
|
59
69
|
initViconic({ kitId: "your-kit-uuid-here" });
|
|
60
70
|
|
|
61
|
-
// You can load multiple kits!
|
|
71
|
+
// You can load multiple kits at the same time!
|
|
62
72
|
initViconic({ kitId: "another-kit-uuid" });
|
|
63
73
|
|
|
64
74
|
function App() {
|
|
@@ -66,21 +76,23 @@ function App() {
|
|
|
66
76
|
<div style={{ display: "flex", gap: "10px" }}>
|
|
67
77
|
{/* Kit icon using @prefix/name format */}
|
|
68
78
|
<ViconicIcon name="@myprefix/home" />
|
|
69
|
-
|
|
70
|
-
{/*
|
|
71
|
-
<ViconicIcon name="myprefix
|
|
72
|
-
|
|
79
|
+
|
|
80
|
+
{/* User uploaded icon format */}
|
|
81
|
+
<ViconicIcon name="@myprefix/my-custom-logo" size="48px" />
|
|
82
|
+
|
|
73
83
|
{/* Mix kit icons with system icons */}
|
|
74
|
-
<ViconicIcon name="lucide:star" />
|
|
84
|
+
<ViconicIcon name="lucide:star" color="#FFD700" />
|
|
75
85
|
</div>
|
|
76
86
|
);
|
|
77
87
|
}
|
|
78
88
|
```
|
|
79
89
|
|
|
80
|
-
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## ðïļ Props
|
|
81
93
|
|
|
82
94
|
| Prop | Type | Default | Description |
|
|
83
|
-
|
|
|
95
|
+
| :--- | :--- | :--- | :--- |
|
|
84
96
|
| `name` | `string` | `undefined` | **Required.** The unique icon ID (e.g. `lucide:activity`, `@prefix/name`). |
|
|
85
97
|
| `size` | `string \| number` | `undefined` | Icon size as CSS value (e.g. `"24px"`, `"2rem"`). |
|
|
86
98
|
| `color` | `string` | `undefined` | Icon color as CSS value (e.g. `"red"`, `"#333"`). |
|
|
@@ -88,32 +100,46 @@ function App() {
|
|
|
88
100
|
| `style` | `React.CSSProperties` | `{}` | Inline CSS styling. |
|
|
89
101
|
| `...props` | `HTMLAttributes` | | Spread standard HTML attributes (e.g. `onClick`, `title`). |
|
|
90
102
|
|
|
91
|
-
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## ð ïļ API Reference
|
|
92
106
|
|
|
93
107
|
### `initViconic(options)`
|
|
94
108
|
|
|
95
|
-
Inject a kit's loader script into `<head>`. Call once per kit at app startup.
|
|
109
|
+
Inject a kit's smart loader script into `<head>`. Call once per kit at app startup.
|
|
96
110
|
|
|
97
111
|
| Option | Type | Default | Description |
|
|
98
|
-
|
|
|
112
|
+
| :--- | :--- | :--- | :--- |
|
|
99
113
|
| `kitId` | `string` | â | **Required.** UUID of your Viconic Kit. |
|
|
100
114
|
| `cdnBase` | `string` | `"cdn.viconic.dev"` | Custom CDN domain. |
|
|
115
|
+
| `version` | `string` | `undefined` | Cache-bust version. **Update this every time you add/remove icons in your kit.** |
|
|
101
116
|
|
|
102
117
|
```jsx
|
|
103
118
|
// In your main.jsx or App.jsx
|
|
104
119
|
import { initViconic } from "viconic-react-icons";
|
|
105
120
|
|
|
106
|
-
|
|
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" });
|
|
107
124
|
```
|
|
108
125
|
|
|
109
|
-
|
|
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
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## ð§ Architecture
|
|
134
|
+
|
|
135
|
+
This package is a high-performance React wrapper around `<viconic-icon>` Web Components. The included smart loader script dynamically monitors the DOM using a lightweight `MutationObserver` and rapidly replaces `<viconic-icon>` elements with actual raw `<svg>` code.
|
|
110
136
|
|
|
111
|
-
|
|
137
|
+
When using kits, `initViconic()` injects the kit's loader from CDN, which leverages **chunked batch fetching**, **event-driven rendering**, and **parallel processing**.
|
|
112
138
|
|
|
113
|
-
|
|
139
|
+
Because we fetch SVGs in parallel and cache them heavily via LocalStorage across user sessions, your frontend performance score will skyrocket compared to packing large icon sets directly into your JS chunks.
|
|
114
140
|
|
|
115
|
-
|
|
141
|
+
---
|
|
116
142
|
|
|
117
|
-
## License
|
|
143
|
+
## ð License
|
|
118
144
|
|
|
119
|
-
This project is licensed under the MIT License. Icon licenses depend on the specific icon families you
|
|
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);
|