viconic-react-icons 1.1.5 → 1.1.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 CHANGED
@@ -45,7 +45,7 @@ var import_react = __toESM(require("react"));
45
45
  }
46
46
  if (typeof document !== "undefined") {
47
47
  const style = document.createElement("style");
48
- style.textContent = ":where(viconic-icon) { display: inline-flex; align-items: center; justify-content: center; width: 1em; height: 1em; font-size: inherit; line-height: 1; } :where(viconic-icon):not(.ci-multicolor) svg { width: 100%; height: 100%; display: block; fill: currentColor; } :where(viconic-icon).ci-multicolor svg { width: 100%; height: 100%; display: block; }";
48
+ style.textContent = ":where(viconic-icon) { display: inline-flex; align-items: center; justify-content: center; width: 1em; height: 1em; font-size: inherit; line-height: 1; } :where(viconic-icon):not(.ci-multicolor) svg { width: 100%; height: 100%; display: block; fill: currentColor; } :where(viconic-icon).ci-multicolor svg { width: 100%; height: 100%; display: block; } viconic-icon:not(.vi-ok):not(.svg-loaded) { animation: none !important; background: none !important; }";
49
49
  if (document.head.firstChild) {
50
50
  document.head.insertBefore(style, document.head.firstChild);
51
51
  } else {
@@ -2003,9 +2003,15 @@ function initViconic(options = {}) {
2003
2003
  }
2004
2004
  var ViconicIcon = ({ name, className, style, size, color, ...props }) => {
2005
2005
  const iconRef = (0, import_react.useRef)(null);
2006
+ const prevNameRef = (0, import_react.useRef)(name);
2006
2007
  (0, import_react.useEffect)(() => {
2007
2008
  const el = iconRef.current;
2008
2009
  if (!el) return;
2010
+ if (prevNameRef.current !== name) {
2011
+ el.innerHTML = "";
2012
+ el.classList.remove("vi-ok", "svg-loaded", "vi-mono", "ci-multicolor");
2013
+ prevNameRef.current = name;
2014
+ }
2009
2015
  const isKitIcon = name && name.startsWith("@");
2010
2016
  if (window.CopyIcons && window.CopyIcons.forceProcess && !isKitIcon) {
2011
2017
  window.CopyIcons.forceProcess(el);
@@ -2013,7 +2019,8 @@ var ViconicIcon = ({ name, className, style, size, color, ...props }) => {
2013
2019
  const isLoaded = el.classList.contains("vi-ok") || el.classList.contains("svg-loaded");
2014
2020
  if (isLoaded) return;
2015
2021
  let retries = 0;
2016
- const maxRetries = 50;
2022
+ const maxRetries = 100;
2023
+ let hasTriggeredReload = false;
2017
2024
  const timer = setInterval(() => {
2018
2025
  retries++;
2019
2026
  if (el.classList.contains("vi-ok") || el.classList.contains("svg-loaded")) {
@@ -2024,6 +2031,20 @@ var ViconicIcon = ({ name, className, style, size, color, ...props }) => {
2024
2031
  if (window.CopyIcons && window.CopyIcons.forceProcess && !isKitIcon) {
2025
2032
  window.CopyIcons.forceProcess(el);
2026
2033
  }
2034
+ if (isKitIcon && !hasTriggeredReload && retries === 10) {
2035
+ hasTriggeredReload = true;
2036
+ const prefixMatch = name.match(/^@([^\/]+)/);
2037
+ if (prefixMatch && window.CopyIconsKit) {
2038
+ const prefix = prefixMatch[1];
2039
+ for (const kitId in window.CopyIconsKit) {
2040
+ const kit = window.CopyIconsKit[kitId];
2041
+ if (kit.config && kit.config.prefix === prefix && typeof kit.reload === "function") {
2042
+ kit.reload();
2043
+ break;
2044
+ }
2045
+ }
2046
+ }
2047
+ }
2027
2048
  if (retries >= maxRetries) clearInterval(timer);
2028
2049
  }, 100);
2029
2050
  return () => clearInterval(timer);
package/dist/index.mjs CHANGED
@@ -10,7 +10,7 @@ import React, { useEffect, useRef } from "react";
10
10
  }
11
11
  if (typeof document !== "undefined") {
12
12
  const style = document.createElement("style");
13
- style.textContent = ":where(viconic-icon) { display: inline-flex; align-items: center; justify-content: center; width: 1em; height: 1em; font-size: inherit; line-height: 1; } :where(viconic-icon):not(.ci-multicolor) svg { width: 100%; height: 100%; display: block; fill: currentColor; } :where(viconic-icon).ci-multicolor svg { width: 100%; height: 100%; display: block; }";
13
+ style.textContent = ":where(viconic-icon) { display: inline-flex; align-items: center; justify-content: center; width: 1em; height: 1em; font-size: inherit; line-height: 1; } :where(viconic-icon):not(.ci-multicolor) svg { width: 100%; height: 100%; display: block; fill: currentColor; } :where(viconic-icon).ci-multicolor svg { width: 100%; height: 100%; display: block; } viconic-icon:not(.vi-ok):not(.svg-loaded) { animation: none !important; background: none !important; }";
14
14
  if (document.head.firstChild) {
15
15
  document.head.insertBefore(style, document.head.firstChild);
16
16
  } else {
@@ -1968,9 +1968,15 @@ function initViconic(options = {}) {
1968
1968
  }
1969
1969
  var ViconicIcon = ({ name, className, style, size, color, ...props }) => {
1970
1970
  const iconRef = useRef(null);
1971
+ const prevNameRef = useRef(name);
1971
1972
  useEffect(() => {
1972
1973
  const el = iconRef.current;
1973
1974
  if (!el) return;
1975
+ if (prevNameRef.current !== name) {
1976
+ el.innerHTML = "";
1977
+ el.classList.remove("vi-ok", "svg-loaded", "vi-mono", "ci-multicolor");
1978
+ prevNameRef.current = name;
1979
+ }
1974
1980
  const isKitIcon = name && name.startsWith("@");
1975
1981
  if (window.CopyIcons && window.CopyIcons.forceProcess && !isKitIcon) {
1976
1982
  window.CopyIcons.forceProcess(el);
@@ -1978,7 +1984,8 @@ var ViconicIcon = ({ name, className, style, size, color, ...props }) => {
1978
1984
  const isLoaded = el.classList.contains("vi-ok") || el.classList.contains("svg-loaded");
1979
1985
  if (isLoaded) return;
1980
1986
  let retries = 0;
1981
- const maxRetries = 50;
1987
+ const maxRetries = 100;
1988
+ let hasTriggeredReload = false;
1982
1989
  const timer = setInterval(() => {
1983
1990
  retries++;
1984
1991
  if (el.classList.contains("vi-ok") || el.classList.contains("svg-loaded")) {
@@ -1989,6 +1996,20 @@ var ViconicIcon = ({ name, className, style, size, color, ...props }) => {
1989
1996
  if (window.CopyIcons && window.CopyIcons.forceProcess && !isKitIcon) {
1990
1997
  window.CopyIcons.forceProcess(el);
1991
1998
  }
1999
+ if (isKitIcon && !hasTriggeredReload && retries === 10) {
2000
+ hasTriggeredReload = true;
2001
+ const prefixMatch = name.match(/^@([^\/]+)/);
2002
+ if (prefixMatch && window.CopyIconsKit) {
2003
+ const prefix = prefixMatch[1];
2004
+ for (const kitId in window.CopyIconsKit) {
2005
+ const kit = window.CopyIconsKit[kitId];
2006
+ if (kit.config && kit.config.prefix === prefix && typeof kit.reload === "function") {
2007
+ kit.reload();
2008
+ break;
2009
+ }
2010
+ }
2011
+ }
2012
+ }
1992
2013
  if (retries >= maxRetries) clearInterval(timer);
1993
2014
  }, 100);
1994
2015
  return () => clearInterval(timer);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "viconic-react-icons",
3
- "version": "1.1.5",
3
+ "version": "1.1.7",
4
4
  "description": "Viconic Smart Icons loader for React — supports Kit and 200k+ system icons",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -34,7 +34,7 @@
34
34
  if (typeof document !== 'undefined') {
35
35
  const style = document.createElement('style');
36
36
  // Use :where() to set specificity to 0, so user styles can easily override without !important
37
- style.textContent = ':where(viconic-icon) { display: inline-flex; align-items: center; justify-content: center; width: 1em; height: 1em; font-size: inherit; line-height: 1; } :where(viconic-icon):not(.ci-multicolor) svg { width: 100%; height: 100%; display: block; fill: currentColor; } :where(viconic-icon).ci-multicolor svg { width: 100%; height: 100%; display: block; }';
37
+ style.textContent = ':where(viconic-icon) { display: inline-flex; align-items: center; justify-content: center; width: 1em; height: 1em; font-size: inherit; line-height: 1; } :where(viconic-icon):not(.ci-multicolor) svg { width: 100%; height: 100%; display: block; fill: currentColor; } :where(viconic-icon).ci-multicolor svg { width: 100%; height: 100%; display: block; } viconic-icon:not(.vi-ok):not(.svg-loaded) { animation: none !important; background: none !important; }';
38
38
  if (document.head.firstChild) {
39
39
  document.head.insertBefore(style, document.head.firstChild);
40
40
  } else {
package/src/index.jsx CHANGED
@@ -65,11 +65,21 @@ export function initViconic(options = {}) {
65
65
  */
66
66
  export const ViconicIcon = ({ name, className, style, size, color, ...props }) => {
67
67
  const iconRef = useRef(null);
68
+ const prevNameRef = useRef(name);
68
69
 
69
70
  useEffect(() => {
70
71
  const el = iconRef.current;
71
72
  if (!el) return;
72
73
 
74
+ // --- FIX DOM REUSE (Reconciliation) ---
75
+ // React reuses DOM nodes. If `name` changes, we must wipe the old state
76
+ // because the DOM node might still have 'svg-loaded' or 'vi-ok'.
77
+ if (prevNameRef.current !== name) {
78
+ el.innerHTML = '';
79
+ el.classList.remove('vi-ok', 'svg-loaded', 'vi-mono', 'ci-multicolor');
80
+ prevNameRef.current = name;
81
+ }
82
+
73
83
  // Path 1: Smart loader (system icons with prefix:name format)
74
84
  const isKitIcon = name && name.startsWith('@');
75
85
  if (window.CopyIcons && window.CopyIcons.forceProcess && !isKitIcon) {
@@ -83,7 +93,9 @@ export const ViconicIcon = ({ name, className, style, size, color, ...props }) =
83
93
  if (isLoaded) return;
84
94
 
85
95
  let retries = 0;
86
- const maxRetries = 50; // 50 × 100ms = 5 seconds max
96
+ const maxRetries = 100; // 100 × 100ms = 10 seconds max
97
+ let hasTriggeredReload = false;
98
+
87
99
  const timer = setInterval(() => {
88
100
  retries++;
89
101
  if (el.classList.contains('vi-ok') || el.classList.contains('svg-loaded')) {
@@ -96,6 +108,25 @@ export const ViconicIcon = ({ name, className, style, size, color, ...props }) =
96
108
  if (window.CopyIcons && window.CopyIcons.forceProcess && !isKitIcon) {
97
109
  window.CopyIcons.forceProcess(el);
98
110
  }
111
+
112
+ // HMR / Missing Kit Icon Fallback:
113
+ // If it's a kit icon and hasn't loaded after 1 second, it might be newly added
114
+ // in the Viconic Dashboard. We trigger a background reload of the kit.
115
+ if (isKitIcon && !hasTriggeredReload && retries === 10) {
116
+ hasTriggeredReload = true;
117
+ const prefixMatch = name.match(/^@([^\/]+)/);
118
+ if (prefixMatch && window.CopyIconsKit) {
119
+ const prefix = prefixMatch[1];
120
+ for (const kitId in window.CopyIconsKit) {
121
+ const kit = window.CopyIconsKit[kitId];
122
+ if (kit.config && kit.config.prefix === prefix && typeof kit.reload === 'function') {
123
+ kit.reload();
124
+ break;
125
+ }
126
+ }
127
+ }
128
+ }
129
+
99
130
  if (retries >= maxRetries) clearInterval(timer);
100
131
  }, 100);
101
132