@smbdy/icons-react 1.0.1 → 1.1.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.
Files changed (73) hide show
  1. package/dist/aave-K32LGE6Y.js +7 -0
  2. package/dist/bnb-DCJ5FXUB.js +7 -0
  3. package/dist/brands-L5PTLZAO.js +6 -0
  4. package/dist/brands-L5PTLZAO.js.map +1 -0
  5. package/dist/brands-ZFN7COP6.cjs +6 -0
  6. package/dist/brands-ZFN7COP6.cjs.map +1 -0
  7. package/dist/brands.js +1 -3
  8. package/dist/chains-AER7LB2F.cjs +6 -0
  9. package/dist/chains-AER7LB2F.cjs.map +1 -0
  10. package/dist/chains-KWHHYIQP.js +6 -0
  11. package/dist/chains-KWHHYIQP.js.map +1 -0
  12. package/dist/chains.js +1 -3
  13. package/dist/{chunk-R2LI45CO.js → chunk-3QBGGX2B.js} +1 -4
  14. package/dist/{chunk-R2LI45CO.js.map → chunk-3QBGGX2B.js.map} +1 -1
  15. package/dist/{chunk-5GKWV4K2.js → chunk-CGCK22HF.js} +1 -4
  16. package/dist/{chunk-5GKWV4K2.js.map → chunk-CGCK22HF.js.map} +1 -1
  17. package/dist/{chunk-C2QAKFGG.js → chunk-DMUNOIF2.js} +1 -4
  18. package/dist/{chunk-C2QAKFGG.js.map → chunk-DMUNOIF2.js.map} +1 -1
  19. package/dist/{chunk-ZKPO5L73.js → chunk-F6KZW5HP.js} +6 -7
  20. package/dist/{chunk-JTV4YTJN.cjs.map → chunk-F6KZW5HP.js.map} +1 -1
  21. package/dist/{chunk-35GWSGWA.js → chunk-FWVJHSO6.js} +1 -4
  22. package/dist/{chunk-35GWSGWA.js.map → chunk-FWVJHSO6.js.map} +1 -1
  23. package/dist/{chunk-JTV4YTJN.cjs → chunk-H4JGJDCF.cjs} +6 -4
  24. package/dist/chunk-H4JGJDCF.cjs.map +1 -0
  25. package/dist/{chunk-WH52PT4Y.js → chunk-JYYQDYRP.js} +1 -4
  26. package/dist/{chunk-WH52PT4Y.js.map → chunk-JYYQDYRP.js.map} +1 -1
  27. package/dist/{chunk-QAWTPM2S.js → chunk-NGMZUDLN.js} +1 -4
  28. package/dist/{chunk-QAWTPM2S.js.map → chunk-NGMZUDLN.js.map} +1 -1
  29. package/dist/{chunk-7P3MIHDC.js → chunk-PZ77ZGR7.js} +1 -4
  30. package/dist/{chunk-7P3MIHDC.js.map → chunk-PZ77ZGR7.js.map} +1 -1
  31. package/dist/{chunk-OVJUO4KZ.js → chunk-TBD6MI4P.js} +1 -4
  32. package/dist/{chunk-OVJUO4KZ.js.map → chunk-TBD6MI4P.js.map} +1 -1
  33. package/dist/{chunk-LMGL65KI.cjs → chunk-WDG7KLLT.cjs} +69 -47
  34. package/dist/chunk-WDG7KLLT.cjs.map +1 -0
  35. package/dist/{chunk-XWYUXPMU.js → chunk-WUKTILCO.js} +72 -52
  36. package/dist/chunk-WUKTILCO.js.map +1 -0
  37. package/dist/{chunk-ICEGTX2E.js → chunk-Y2MK6VUF.js} +1 -4
  38. package/dist/{chunk-ICEGTX2E.js.map → chunk-Y2MK6VUF.js.map} +1 -1
  39. package/dist/compat.cjs +5 -4
  40. package/dist/compat.js +6 -7
  41. package/dist/compat.js.map +1 -1
  42. package/dist/frames.cjs +2 -2
  43. package/dist/frames.js +1 -3
  44. package/dist/{github-fallback-W3AHQ4U6.js → github-fallback-LUYR6NJF.js} +9 -7
  45. package/dist/github-fallback-LUYR6NJF.js.map +1 -0
  46. package/dist/{github-fallback-WEXDJI4H.cjs → github-fallback-ZBK55BLV.cjs} +8 -4
  47. package/dist/github-fallback-ZBK55BLV.cjs.map +1 -0
  48. package/dist/index.cjs +3 -2
  49. package/dist/index.js +5 -6
  50. package/dist/link-XFBO5QDH.js +7 -0
  51. package/dist/pteusde-XLRWLLKT.js +7 -0
  52. package/dist/tokens-7PEFDREU.js +12 -0
  53. package/dist/tokens-7PEFDREU.js.map +1 -0
  54. package/dist/tokens-AYZHIKHK.cjs +12 -0
  55. package/dist/tokens-AYZHIKHK.cjs.map +1 -0
  56. package/dist/tokens.js +6 -8
  57. package/dist/uni-EDTKY5E5.js +7 -0
  58. package/package.json +1 -1
  59. package/dist/aave-4NKY7G5P.js +0 -9
  60. package/dist/bnb-VEXN3I2D.js +0 -9
  61. package/dist/chunk-LMGL65KI.cjs.map +0 -1
  62. package/dist/chunk-XWYUXPMU.js.map +0 -1
  63. package/dist/chunk-ZKPO5L73.js.map +0 -1
  64. package/dist/github-fallback-W3AHQ4U6.js.map +0 -1
  65. package/dist/github-fallback-WEXDJI4H.cjs.map +0 -1
  66. package/dist/link-M5GUQP3F.js +0 -9
  67. package/dist/pteusde-T5QFFBX5.js +0 -9
  68. package/dist/uni-UB66QGDS.js +0 -9
  69. /package/dist/{aave-4NKY7G5P.js.map → aave-K32LGE6Y.js.map} +0 -0
  70. /package/dist/{bnb-VEXN3I2D.js.map → bnb-DCJ5FXUB.js.map} +0 -0
  71. /package/dist/{link-M5GUQP3F.js.map → link-XFBO5QDH.js.map} +0 -0
  72. /package/dist/{pteusde-T5QFFBX5.js.map → pteusde-XLRWLLKT.js.map} +0 -0
  73. /package/dist/{uni-UB66QGDS.js.map → uni-EDTKY5E5.js.map} +0 -0
package/dist/compat.js CHANGED
@@ -1,15 +1,14 @@
1
1
  "use client";
2
-
3
2
  import {
4
3
  Icon
5
- } from "./chunk-XWYUXPMU.js";
6
- import "./chunk-ICEGTX2E.js";
7
- import "./chunk-35GWSGWA.js";
8
- import "./chunk-R2LI45CO.js";
9
- import "./chunk-OVJUO4KZ.js";
4
+ } from "./chunk-WUKTILCO.js";
5
+ import "./chunk-Y2MK6VUF.js";
6
+ import "./chunk-FWVJHSO6.js";
7
+ import "./chunk-3QBGGX2B.js";
8
+ import "./chunk-TBD6MI4P.js";
10
9
  import {
11
10
  FrameWrapper
12
- } from "./chunk-ZKPO5L73.js";
11
+ } from "./chunk-F6KZW5HP.js";
13
12
 
14
13
  // src/compat.ts
15
14
  import { createElement } from "react";
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/compat.ts"],"sourcesContent":["import { createElement } from 'react'\nimport type { ReactNode, SVGProps } from 'react'\nimport { Icon } from './index'\nimport { FrameWrapper } from './frames'\nimport type { IconType } from './types'\n\n// Drop `type` from the inherited SVG attributes so it can't shadow Icon's\n// `type` prop on spread; Web3Icon picks its target type from chainId/brandKey\n// internally.\nexport interface Web3IconProps extends Omit<SVGProps<SVGSVGElement>, 'type'> {\n symbol?: string\n chainId?: number | string\n walletKey?: string\n brandKey?: string\n mono?: boolean\n assetTag?: string\n loader?: ReactNode\n size?: number | string\n}\n\nexport function Web3Icon({\n symbol,\n chainId,\n walletKey,\n brandKey,\n mono,\n assetTag,\n loader,\n size,\n ...props\n}: Web3IconProps) {\n const input = symbol ?? chainId ?? walletKey ?? brandKey\n if (!input) return createElement('span', null, loader ?? null)\n const iconType: IconType | undefined =\n symbol !== undefined\n ? undefined\n : chainId !== undefined\n ? 'chain'\n : brandKey !== undefined\n ? 'brand'\n : walletKey !== undefined\n ? 'brand'\n : undefined\n\n const icon = createElement(Icon, {\n value: input,\n type: iconType,\n mono,\n fallback: loader,\n // Inside a frame, leave size unset so FrameWrapper fills its slot;\n // otherwise the caller's size applies directly.\n size: assetTag ? undefined : size,\n ...props,\n })\n\n if (assetTag) {\n return createElement(\n FrameWrapper,\n {\n frame: assetTag,\n variant: mono ? 'mono' : 'full',\n size,\n },\n icon,\n )\n }\n\n return icon\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA,SAAS,qBAAqB;AAoBvB,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAkB;AAChB,QAAM,QAAQ,UAAU,WAAW,aAAa;AAChD,MAAI,CAAC,MAAO,QAAO,cAAc,QAAQ,MAAM,UAAU,IAAI;AAC7D,QAAM,WACJ,WAAW,SACP,SACA,YAAY,SACV,UACA,aAAa,SACX,UACA,cAAc,SACZ,UACA;AAEZ,QAAM,OAAO,cAAc,MAAM;AAAA,IAC/B,OAAO;AAAA,IACP,MAAM;AAAA,IACN;AAAA,IACA,UAAU;AAAA;AAAA;AAAA,IAGV,MAAM,WAAW,SAAY;AAAA,IAC7B,GAAG;AAAA,EACL,CAAC;AAED,MAAI,UAAU;AACZ,WAAO;AAAA,MACL;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,SAAS,OAAO,SAAS;AAAA,QACzB;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../src/compat.ts"],"sourcesContent":["import { createElement } from 'react'\nimport type { ReactNode, SVGProps } from 'react'\nimport { Icon } from './index'\nimport { FrameWrapper } from './frames'\nimport type { IconType } from './types'\n\n// Drop `type` from the inherited SVG attributes so it can't shadow Icon's\n// `type` prop on spread; Web3Icon picks its target type from chainId/brandKey\n// internally.\nexport interface Web3IconProps extends Omit<SVGProps<SVGSVGElement>, 'type'> {\n symbol?: string\n chainId?: number | string\n walletKey?: string\n brandKey?: string\n mono?: boolean\n assetTag?: string\n loader?: ReactNode\n size?: number | string\n}\n\nexport function Web3Icon({\n symbol,\n chainId,\n walletKey,\n brandKey,\n mono,\n assetTag,\n loader,\n size,\n ...props\n}: Web3IconProps) {\n const input = symbol ?? chainId ?? walletKey ?? brandKey\n if (!input) return createElement('span', null, loader ?? null)\n const iconType: IconType | undefined =\n symbol !== undefined\n ? undefined\n : chainId !== undefined\n ? 'chain'\n : brandKey !== undefined\n ? 'brand'\n : walletKey !== undefined\n ? 'brand'\n : undefined\n\n const icon = createElement(Icon, {\n value: input,\n type: iconType,\n mono,\n fallback: loader,\n // Inside a frame, leave size unset so FrameWrapper fills its slot;\n // otherwise the caller's size applies directly.\n size: assetTag ? undefined : size,\n ...props,\n })\n\n if (assetTag) {\n return createElement(\n FrameWrapper,\n {\n frame: assetTag,\n variant: mono ? 'mono' : 'full',\n size,\n },\n icon,\n )\n }\n\n return icon\n}\n"],"mappings":";;;;;;;;;;;;AAAA,SAAS,qBAAqB;AAoBvB,SAAS,SAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAkB;AAChB,QAAM,QAAQ,UAAU,WAAW,aAAa;AAChD,MAAI,CAAC,MAAO,QAAO,cAAc,QAAQ,MAAM,UAAU,IAAI;AAC7D,QAAM,WACJ,WAAW,SACP,SACA,YAAY,SACV,UACA,aAAa,SACX,UACA,cAAc,SACZ,UACA;AAEZ,QAAM,OAAO,cAAc,MAAM;AAAA,IAC/B,OAAO;AAAA,IACP,MAAM;AAAA,IACN;AAAA,IACA,UAAU;AAAA;AAAA;AAAA,IAGV,MAAM,WAAW,SAAY;AAAA,IAC7B,GAAG;AAAA,EACL,CAAC;AAED,MAAI,UAAU;AACZ,WAAO;AAAA,MACL;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,SAAS,OAAO,SAAS;AAAA,QACzB;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
package/dist/frames.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunkJTV4YTJNcjs = require('./chunk-JTV4YTJN.cjs');
3
+ var _chunkH4JGJDCFcjs = require('./chunk-H4JGJDCF.cjs');
4
4
 
5
5
 
6
- exports.FrameWrapper = _chunkJTV4YTJNcjs.FrameWrapper;
6
+ exports.FrameWrapper = _chunkH4JGJDCFcjs.FrameWrapper;
7
7
  //# sourceMappingURL=frames.cjs.map
package/dist/frames.js CHANGED
@@ -1,8 +1,6 @@
1
- "use client";
2
-
3
1
  import {
4
2
  FrameWrapper
5
- } from "./chunk-ZKPO5L73.js";
3
+ } from "./chunk-F6KZW5HP.js";
6
4
  export {
7
5
  FrameWrapper
8
6
  };
@@ -1,8 +1,6 @@
1
- "use client";
2
-
3
1
  import {
4
2
  useIconConfig
5
- } from "./chunk-ICEGTX2E.js";
3
+ } from "./chunk-Y2MK6VUF.js";
6
4
 
7
5
  // src/github-fallback.tsx
8
6
  import { useEffect, useMemo, useState } from "react";
@@ -98,6 +96,10 @@ var cacheOrder = [];
98
96
  var MAX_CACHE = 200;
99
97
  var NEGATIVE_CACHE_TTL_MS = 6e4;
100
98
  var FETCH_TIMEOUT_MS = 8e3;
99
+ var TIMEOUT_REASON = "bgd-icons:timeout";
100
+ function isTimeout(signal) {
101
+ return signal.aborted && signal.reason === TIMEOUT_REASON;
102
+ }
101
103
  function cacheGet(url) {
102
104
  const entry = svgCache.get(url);
103
105
  if (entry === void 0) return void 0;
@@ -146,7 +148,7 @@ async function fetchSvg(url, signal) {
146
148
  cacheSet(url, text);
147
149
  return text;
148
150
  } catch {
149
- if (!signal.aborted) cacheSet(url, null);
151
+ if (!signal.aborted || isTimeout(signal)) cacheSet(url, null);
150
152
  return null;
151
153
  }
152
154
  }
@@ -196,11 +198,11 @@ function GithubFallback({
196
198
  useEffect(() => {
197
199
  if (currentState.content || currentState.failed) return;
198
200
  const ac = new AbortController();
199
- const timer = setTimeout(() => ac.abort(), FETCH_TIMEOUT_MS);
201
+ const timer = setTimeout(() => ac.abort(TIMEOUT_REASON), FETCH_TIMEOUT_MS);
200
202
  resolveSvg(baseUrl, branch, id, iconType, variant, ac.signal).then(
201
203
  (svgText) => {
202
204
  clearTimeout(timer);
203
- if (ac.signal.aborted) return;
205
+ if (ac.signal.aborted && !isTimeout(ac.signal)) return;
204
206
  setState(() => {
205
207
  if (!svgText) {
206
208
  return { key: requestKey, content: null, failed: true };
@@ -245,4 +247,4 @@ function GithubFallback({
245
247
  export {
246
248
  GithubFallback
247
249
  };
248
- //# sourceMappingURL=github-fallback-W3AHQ4U6.js.map
250
+ //# sourceMappingURL=github-fallback-LUYR6NJF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/github-fallback.tsx","../src/svg-to-react.ts","../src/sanitize-svg.ts","../src/svg-attributes.ts"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react'\nimport type { ReactNode, SVGProps } from 'react'\nimport { resolve } from '@smbdy/icons/resolve'\nimport { useIconConfig } from './icon-provider'\nimport { svgTextToReact } from './svg-to-react'\nimport type { SvgReactContent } from './svg-to-react'\nimport type { IconType } from './types'\n\n// Module-level SVG cache, keyed by URL. null = negative cache (tried & failed).\ninterface CacheEntry {\n value: string | null\n ts: number\n}\n\nconst svgCache = new Map<string, CacheEntry>()\nconst cacheOrder: string[] = []\nconst MAX_CACHE = 200\nconst NEGATIVE_CACHE_TTL_MS = 60_000\nconst FETCH_TIMEOUT_MS = 8_000\n\n// Distinguishes our timeout from an unmount abort: timeouts are real\n// failures (negative-cached, marked failed) while unmount aborts must\n// leave no trace.\nconst TIMEOUT_REASON = 'bgd-icons:timeout'\n\nfunction isTimeout(signal: AbortSignal): boolean {\n return signal.aborted && signal.reason === TIMEOUT_REASON\n}\n\nfunction cacheGet(url: string): string | null | undefined {\n const entry = svgCache.get(url)\n if (entry === undefined) return undefined\n // Successful entries never expire (within LRU window)\n if (entry.value !== null) return entry.value\n // Negative entries expire after TTL\n if (Date.now() - entry.ts > NEGATIVE_CACHE_TTL_MS) {\n svgCache.delete(url)\n const idx = cacheOrder.indexOf(url)\n if (idx !== -1) cacheOrder.splice(idx, 1)\n return undefined\n }\n return null\n}\n\nfunction cacheSet(url: string, value: string | null) {\n if (!svgCache.has(url)) {\n cacheOrder.push(url)\n if (cacheOrder.length > MAX_CACHE) {\n const evict = cacheOrder.shift()!\n svgCache.delete(evict)\n }\n }\n svgCache.set(url, { value, ts: Date.now() })\n}\n\ntype AssetType = 'tokens' | 'chains' | 'brands'\n\nfunction toAssetType(type: IconType): AssetType {\n if (type === 'token') return 'tokens'\n if (type === 'chain') return 'chains'\n return 'brands'\n}\n\nfunction inferType(id: string, explicitType?: IconType): AssetType | null {\n if (explicitType) return toAssetType(explicitType)\n // Ask the resolution module (token-first per ADR-0001) rather than\n // probing the metadata maps per type.\n const hit = resolve(id)\n return hit ? toAssetType(hit.type) : null\n}\n\nfunction buildUrl(\n baseUrl: string,\n branch: string,\n type: AssetType,\n id: string,\n variant: string,\n): string {\n return `${baseUrl}/${branch}/assets/${type}/${id}_${variant}.svg`\n}\n\nasync function fetchSvg(\n url: string,\n signal: AbortSignal,\n): Promise<string | null> {\n const cached = cacheGet(url)\n if (cached !== undefined) return cached\n\n try {\n const res = await fetch(url, { signal })\n if (!res.ok) {\n cacheSet(url, null)\n return null\n }\n const text = await res.text()\n cacheSet(url, text)\n return text\n } catch {\n if (!signal.aborted || isTimeout(signal)) cacheSet(url, null)\n return null\n }\n}\n\nasync function resolveSvg(\n baseUrl: string,\n branch: string,\n id: string,\n explicitType: IconType | undefined,\n variant: string,\n signal: AbortSignal,\n): Promise<string | null> {\n const type = inferType(id, explicitType)\n\n if (type) {\n return fetchSvg(buildUrl(baseUrl, branch, type, id, variant), signal)\n }\n\n // Unknown type — probe all three and keep token-first result ordering.\n const types: AssetType[] = ['tokens', 'chains', 'brands']\n const results = await Promise.all(\n types.map((t) =>\n fetchSvg(buildUrl(baseUrl, branch, t, id, variant), signal),\n ),\n )\n return results.find((result) => result !== null) ?? null\n}\n\nexport interface GithubFallbackProps extends SVGProps<SVGSVGElement> {\n id: string\n iconType?: IconType\n variant: 'full' | 'mono'\n size?: number | string\n fallback?: ReactNode\n}\n\ninterface FallbackState {\n key: string\n content: SvgReactContent | null\n failed: boolean\n}\n\nfunction getCachedContent(\n baseUrl: string,\n branch: string,\n explicitType: IconType | undefined,\n id: string,\n variant: string,\n): SvgReactContent | null {\n const type = inferType(id, explicitType)\n if (!type) return null\n const cached = cacheGet(buildUrl(baseUrl, branch, type, id, variant))\n return typeof cached === 'string' ? svgTextToReact(cached) : null\n}\n\nexport function GithubFallback({\n id,\n iconType,\n variant,\n size = 32,\n fallback,\n ...props\n}: GithubFallbackProps) {\n const { baseUrl, branch } = useIconConfig()\n const requestKey = `${baseUrl}|${branch}|${iconType ?? 'auto'}|${id}|${variant}`\n const cachedContent = useMemo(\n () => getCachedContent(baseUrl, branch, iconType, id, variant),\n [baseUrl, branch, iconType, id, variant],\n )\n const [state, setState] = useState<FallbackState>(() => ({\n key: requestKey,\n content: cachedContent,\n failed: false,\n }))\n const currentState =\n state.key === requestKey\n ? state\n : {\n key: requestKey,\n content: cachedContent,\n failed: false,\n }\n\n useEffect(() => {\n if (currentState.content || currentState.failed) return\n\n const ac = new AbortController()\n const timer = setTimeout(() => ac.abort(TIMEOUT_REASON), FETCH_TIMEOUT_MS)\n\n resolveSvg(baseUrl, branch, id, iconType, variant, ac.signal).then(\n (svgText) => {\n clearTimeout(timer)\n // A timeout is a result (failed), not a cancellation — only an\n // unmount/key-change abort should drop the state update.\n if (ac.signal.aborted && !isTimeout(ac.signal)) return\n setState(() => {\n if (!svgText) {\n return { key: requestKey, content: null, failed: true }\n }\n const content = svgTextToReact(svgText)\n return content\n ? { key: requestKey, content, failed: false }\n : { key: requestKey, content: null, failed: true }\n })\n },\n )\n\n return () => {\n clearTimeout(timer)\n ac.abort()\n }\n }, [\n baseUrl,\n branch,\n currentState.failed,\n currentState.content,\n id,\n requestKey,\n iconType,\n variant,\n ])\n\n if (currentState.failed) return <>{fallback ?? null}</>\n if (!currentState.content) return <>{fallback ?? null}</>\n\n const monoProps = variant === 'mono' ? { fill: 'currentColor' } : {}\n\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox={currentState.content.viewBox}\n role=\"img\"\n aria-label={id}\n {...monoProps}\n {...props}\n >\n {currentState.content.node}\n </svg>\n )\n}\n","import { createElement } from 'react'\nimport type { ReactNode } from 'react'\nimport { sanitizeSvgRoot } from './sanitize-svg'\nimport { styleStringToObject, toReactAttributeName } from './svg-attributes'\n\nexport interface SvgReactContent {\n node: ReactNode\n viewBox: string\n}\n\nfunction svgNodeToReact(node: ChildNode, key: string): ReactNode {\n if (node.nodeType === Node.TEXT_NODE) return node.textContent\n if (node.nodeType !== Node.ELEMENT_NODE) return null\n\n const element = node as Element\n const props: Record<string, unknown> = { key }\n for (const attr of Array.from(element.attributes)) {\n const attrName = toReactAttributeName(attr.name)\n props[attrName] =\n attr.name === 'style' ? styleStringToObject(attr.value) : attr.value\n }\n\n const children = Array.from(element.childNodes)\n .map((child, index) => svgNodeToReact(child, `${key}-${index}`))\n .filter((child) => child !== null)\n\n return createElement(element.tagName, props, ...children)\n}\n\n/**\n * Sanitize an SVG string and convert its children to React nodes in one\n * pass over a single parsed DOM. Returns the converted children and the\n * root's viewBox; the caller renders its own `<svg>` wrapper so it controls\n * sizing and accessibility attributes.\n *\n * Returns null when the input is not a parseable `<svg>` document (or when\n * no DOM is available, e.g. during SSR).\n */\nexport function svgTextToReact(svgText: string): SvgReactContent | null {\n const root = sanitizeSvgRoot(svgText)\n if (!root) return null\n const viewBox = root.getAttribute('viewBox') ?? '0 0 32 32'\n const node = Array.from(root.childNodes)\n .map((child, index) => svgNodeToReact(child, String(index)))\n .filter((child) => child !== null)\n return { node, viewBox }\n}\n","import createDOMPurify from 'dompurify'\nimport type { DOMPurify } from 'dompurify'\n\n// `<use>` and `<script>` are blocked by DOMPurify's SVG profile already\n// (svgDisallowed in the upstream source); listing them here is defense in\n// depth in case a future profile change relaxes that.\nconst FORBID_TAGS = ['script', 'foreignObject', 'text', 'image', 'style']\n\nlet purifierCache: DOMPurify | null = null\n\nfunction getPurifier(): DOMPurify | null {\n if (purifierCache) return purifierCache\n if (typeof window === 'undefined') return null\n const p = createDOMPurify(\n window as unknown as Parameters<typeof createDOMPurify>[0],\n )\n // ALLOWED_URI_REGEXP can't be used to restrict href/xlink:href without also\n // killing geometry attrs like cx/cy/r (DOMPurify applies the URI regex to\n // every non-URI-safe attribute value). A scoped hook on this DOMPurify\n // instance lets us reject non-fragment href values without touching the\n // global DOMPurify state — important for consumers who use DOMPurify\n // elsewhere in their app.\n p.addHook('uponSanitizeAttribute', (_node, ev) => {\n if (ev.attrName === 'href' || ev.attrName === 'xlink:href') {\n const v = typeof ev.attrValue === 'string' ? ev.attrValue : ''\n if (!v.startsWith('#')) ev.keepAttr = false\n }\n })\n purifierCache = p\n return p\n}\n\n// DOMPurify's string-mode sanitize parses input as HTML, which silently\n// drops case-sensitive SVG attributes (viewBox, preserveAspectRatio). Parse\n// with image/svg+xml first and sanitize in place to keep the SVG-namespace\n// context and attribute case. svg-to-react.ts converts the returned root to\n// React nodes from this same DOM — no serialize/re-parse round-trip.\nexport function sanitizeSvgRoot(svgText: string): SVGSVGElement | null {\n if (typeof DOMParser === 'undefined') return null\n const purifier = getPurifier()\n if (!purifier) return null\n const doc = new DOMParser().parseFromString(svgText, 'image/svg+xml')\n const root = doc.documentElement\n if (root.nodeName !== 'svg') return null\n purifier.sanitize(root, {\n USE_PROFILES: { svg: true, svgFilters: true },\n FORBID_TAGS,\n IN_PLACE: true,\n })\n return root as unknown as SVGSVGElement\n}\n\nexport function sanitizeSvg(svgText: string): string {\n const root = sanitizeSvgRoot(svgText)\n if (!root) return ''\n return new XMLSerializer().serializeToString(root)\n}\n","// Single source of truth for converting SVG markup attributes into their\n// React equivalents. Two adapters sit on this interface: the build pipeline\n// (scripts/svg-to-jsx.ts emits JSX strings for generated components) and the\n// runtime network fallback (svg-to-react.ts builds React nodes from fetched\n// SVGs). Sharing the rule guarantees an icon renders identically whether it\n// shipped in the bundle or arrived over the wire.\n\nexport function toReactAttributeName(name: string): string {\n if (name === 'class') return 'className'\n if (name.startsWith('aria-') || name.startsWith('data-')) return name\n return name.replace(/[:-]([a-z])/g, (_, letter: string) =>\n letter.toUpperCase(),\n )\n}\n\nexport function styleStringToObject(style: string): Record<string, string> {\n const result: Record<string, string> = {}\n for (const rule of style.split(';')) {\n const [rawProperty, ...rawValue] = rule.split(':')\n const property = rawProperty?.trim()\n const value = rawValue.join(':').trim()\n if (!property || !value) continue\n const reactProperty = property.replace(/-([a-z])/g, (_, letter: string) =>\n letter.toUpperCase(),\n )\n result[reactProperty] = value\n }\n return result\n}\n"],"mappings":"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","names":[]}
@@ -96,6 +96,10 @@ var cacheOrder = [];
96
96
  var MAX_CACHE = 200;
97
97
  var NEGATIVE_CACHE_TTL_MS = 6e4;
98
98
  var FETCH_TIMEOUT_MS = 8e3;
99
+ var TIMEOUT_REASON = "bgd-icons:timeout";
100
+ function isTimeout(signal) {
101
+ return signal.aborted && signal.reason === TIMEOUT_REASON;
102
+ }
99
103
  function cacheGet(url) {
100
104
  const entry = svgCache.get(url);
101
105
  if (entry === void 0) return void 0;
@@ -144,7 +148,7 @@ async function fetchSvg(url, signal) {
144
148
  cacheSet(url, text);
145
149
  return text;
146
150
  } catch (e) {
147
- if (!signal.aborted) cacheSet(url, null);
151
+ if (!signal.aborted || isTimeout(signal)) cacheSet(url, null);
148
152
  return null;
149
153
  }
150
154
  }
@@ -194,11 +198,11 @@ function GithubFallback({
194
198
  _react.useEffect.call(void 0, () => {
195
199
  if (currentState.content || currentState.failed) return;
196
200
  const ac = new AbortController();
197
- const timer = setTimeout(() => ac.abort(), FETCH_TIMEOUT_MS);
201
+ const timer = setTimeout(() => ac.abort(TIMEOUT_REASON), FETCH_TIMEOUT_MS);
198
202
  resolveSvg(baseUrl, branch, id, iconType, variant, ac.signal).then(
199
203
  (svgText) => {
200
204
  clearTimeout(timer);
201
- if (ac.signal.aborted) return;
205
+ if (ac.signal.aborted && !isTimeout(ac.signal)) return;
202
206
  setState(() => {
203
207
  if (!svgText) {
204
208
  return { key: requestKey, content: null, failed: true };
@@ -243,4 +247,4 @@ function GithubFallback({
243
247
 
244
248
 
245
249
  exports.GithubFallback = GithubFallback;
246
- //# sourceMappingURL=github-fallback-WEXDJI4H.cjs.map
250
+ //# sourceMappingURL=github-fallback-ZBK55BLV.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/icons/icons/packages/react/dist/github-fallback-ZBK55BLV.cjs","../src/github-fallback.tsx","../src/svg-to-react.ts","../src/sanitize-svg.ts","../src/svg-attributes.ts"],"names":[],"mappings":"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","file":"/home/runner/work/icons/icons/packages/react/dist/github-fallback-ZBK55BLV.cjs","sourcesContent":[null,"import { useEffect, useMemo, useState } from 'react'\nimport type { ReactNode, SVGProps } from 'react'\nimport { resolve } from '@smbdy/icons/resolve'\nimport { useIconConfig } from './icon-provider'\nimport { svgTextToReact } from './svg-to-react'\nimport type { SvgReactContent } from './svg-to-react'\nimport type { IconType } from './types'\n\n// Module-level SVG cache, keyed by URL. null = negative cache (tried & failed).\ninterface CacheEntry {\n value: string | null\n ts: number\n}\n\nconst svgCache = new Map<string, CacheEntry>()\nconst cacheOrder: string[] = []\nconst MAX_CACHE = 200\nconst NEGATIVE_CACHE_TTL_MS = 60_000\nconst FETCH_TIMEOUT_MS = 8_000\n\n// Distinguishes our timeout from an unmount abort: timeouts are real\n// failures (negative-cached, marked failed) while unmount aborts must\n// leave no trace.\nconst TIMEOUT_REASON = 'bgd-icons:timeout'\n\nfunction isTimeout(signal: AbortSignal): boolean {\n return signal.aborted && signal.reason === TIMEOUT_REASON\n}\n\nfunction cacheGet(url: string): string | null | undefined {\n const entry = svgCache.get(url)\n if (entry === undefined) return undefined\n // Successful entries never expire (within LRU window)\n if (entry.value !== null) return entry.value\n // Negative entries expire after TTL\n if (Date.now() - entry.ts > NEGATIVE_CACHE_TTL_MS) {\n svgCache.delete(url)\n const idx = cacheOrder.indexOf(url)\n if (idx !== -1) cacheOrder.splice(idx, 1)\n return undefined\n }\n return null\n}\n\nfunction cacheSet(url: string, value: string | null) {\n if (!svgCache.has(url)) {\n cacheOrder.push(url)\n if (cacheOrder.length > MAX_CACHE) {\n const evict = cacheOrder.shift()!\n svgCache.delete(evict)\n }\n }\n svgCache.set(url, { value, ts: Date.now() })\n}\n\ntype AssetType = 'tokens' | 'chains' | 'brands'\n\nfunction toAssetType(type: IconType): AssetType {\n if (type === 'token') return 'tokens'\n if (type === 'chain') return 'chains'\n return 'brands'\n}\n\nfunction inferType(id: string, explicitType?: IconType): AssetType | null {\n if (explicitType) return toAssetType(explicitType)\n // Ask the resolution module (token-first per ADR-0001) rather than\n // probing the metadata maps per type.\n const hit = resolve(id)\n return hit ? toAssetType(hit.type) : null\n}\n\nfunction buildUrl(\n baseUrl: string,\n branch: string,\n type: AssetType,\n id: string,\n variant: string,\n): string {\n return `${baseUrl}/${branch}/assets/${type}/${id}_${variant}.svg`\n}\n\nasync function fetchSvg(\n url: string,\n signal: AbortSignal,\n): Promise<string | null> {\n const cached = cacheGet(url)\n if (cached !== undefined) return cached\n\n try {\n const res = await fetch(url, { signal })\n if (!res.ok) {\n cacheSet(url, null)\n return null\n }\n const text = await res.text()\n cacheSet(url, text)\n return text\n } catch {\n if (!signal.aborted || isTimeout(signal)) cacheSet(url, null)\n return null\n }\n}\n\nasync function resolveSvg(\n baseUrl: string,\n branch: string,\n id: string,\n explicitType: IconType | undefined,\n variant: string,\n signal: AbortSignal,\n): Promise<string | null> {\n const type = inferType(id, explicitType)\n\n if (type) {\n return fetchSvg(buildUrl(baseUrl, branch, type, id, variant), signal)\n }\n\n // Unknown type — probe all three and keep token-first result ordering.\n const types: AssetType[] = ['tokens', 'chains', 'brands']\n const results = await Promise.all(\n types.map((t) =>\n fetchSvg(buildUrl(baseUrl, branch, t, id, variant), signal),\n ),\n )\n return results.find((result) => result !== null) ?? null\n}\n\nexport interface GithubFallbackProps extends SVGProps<SVGSVGElement> {\n id: string\n iconType?: IconType\n variant: 'full' | 'mono'\n size?: number | string\n fallback?: ReactNode\n}\n\ninterface FallbackState {\n key: string\n content: SvgReactContent | null\n failed: boolean\n}\n\nfunction getCachedContent(\n baseUrl: string,\n branch: string,\n explicitType: IconType | undefined,\n id: string,\n variant: string,\n): SvgReactContent | null {\n const type = inferType(id, explicitType)\n if (!type) return null\n const cached = cacheGet(buildUrl(baseUrl, branch, type, id, variant))\n return typeof cached === 'string' ? svgTextToReact(cached) : null\n}\n\nexport function GithubFallback({\n id,\n iconType,\n variant,\n size = 32,\n fallback,\n ...props\n}: GithubFallbackProps) {\n const { baseUrl, branch } = useIconConfig()\n const requestKey = `${baseUrl}|${branch}|${iconType ?? 'auto'}|${id}|${variant}`\n const cachedContent = useMemo(\n () => getCachedContent(baseUrl, branch, iconType, id, variant),\n [baseUrl, branch, iconType, id, variant],\n )\n const [state, setState] = useState<FallbackState>(() => ({\n key: requestKey,\n content: cachedContent,\n failed: false,\n }))\n const currentState =\n state.key === requestKey\n ? state\n : {\n key: requestKey,\n content: cachedContent,\n failed: false,\n }\n\n useEffect(() => {\n if (currentState.content || currentState.failed) return\n\n const ac = new AbortController()\n const timer = setTimeout(() => ac.abort(TIMEOUT_REASON), FETCH_TIMEOUT_MS)\n\n resolveSvg(baseUrl, branch, id, iconType, variant, ac.signal).then(\n (svgText) => {\n clearTimeout(timer)\n // A timeout is a result (failed), not a cancellation — only an\n // unmount/key-change abort should drop the state update.\n if (ac.signal.aborted && !isTimeout(ac.signal)) return\n setState(() => {\n if (!svgText) {\n return { key: requestKey, content: null, failed: true }\n }\n const content = svgTextToReact(svgText)\n return content\n ? { key: requestKey, content, failed: false }\n : { key: requestKey, content: null, failed: true }\n })\n },\n )\n\n return () => {\n clearTimeout(timer)\n ac.abort()\n }\n }, [\n baseUrl,\n branch,\n currentState.failed,\n currentState.content,\n id,\n requestKey,\n iconType,\n variant,\n ])\n\n if (currentState.failed) return <>{fallback ?? null}</>\n if (!currentState.content) return <>{fallback ?? null}</>\n\n const monoProps = variant === 'mono' ? { fill: 'currentColor' } : {}\n\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox={currentState.content.viewBox}\n role=\"img\"\n aria-label={id}\n {...monoProps}\n {...props}\n >\n {currentState.content.node}\n </svg>\n )\n}\n","import { createElement } from 'react'\nimport type { ReactNode } from 'react'\nimport { sanitizeSvgRoot } from './sanitize-svg'\nimport { styleStringToObject, toReactAttributeName } from './svg-attributes'\n\nexport interface SvgReactContent {\n node: ReactNode\n viewBox: string\n}\n\nfunction svgNodeToReact(node: ChildNode, key: string): ReactNode {\n if (node.nodeType === Node.TEXT_NODE) return node.textContent\n if (node.nodeType !== Node.ELEMENT_NODE) return null\n\n const element = node as Element\n const props: Record<string, unknown> = { key }\n for (const attr of Array.from(element.attributes)) {\n const attrName = toReactAttributeName(attr.name)\n props[attrName] =\n attr.name === 'style' ? styleStringToObject(attr.value) : attr.value\n }\n\n const children = Array.from(element.childNodes)\n .map((child, index) => svgNodeToReact(child, `${key}-${index}`))\n .filter((child) => child !== null)\n\n return createElement(element.tagName, props, ...children)\n}\n\n/**\n * Sanitize an SVG string and convert its children to React nodes in one\n * pass over a single parsed DOM. Returns the converted children and the\n * root's viewBox; the caller renders its own `<svg>` wrapper so it controls\n * sizing and accessibility attributes.\n *\n * Returns null when the input is not a parseable `<svg>` document (or when\n * no DOM is available, e.g. during SSR).\n */\nexport function svgTextToReact(svgText: string): SvgReactContent | null {\n const root = sanitizeSvgRoot(svgText)\n if (!root) return null\n const viewBox = root.getAttribute('viewBox') ?? '0 0 32 32'\n const node = Array.from(root.childNodes)\n .map((child, index) => svgNodeToReact(child, String(index)))\n .filter((child) => child !== null)\n return { node, viewBox }\n}\n","import createDOMPurify from 'dompurify'\nimport type { DOMPurify } from 'dompurify'\n\n// `<use>` and `<script>` are blocked by DOMPurify's SVG profile already\n// (svgDisallowed in the upstream source); listing them here is defense in\n// depth in case a future profile change relaxes that.\nconst FORBID_TAGS = ['script', 'foreignObject', 'text', 'image', 'style']\n\nlet purifierCache: DOMPurify | null = null\n\nfunction getPurifier(): DOMPurify | null {\n if (purifierCache) return purifierCache\n if (typeof window === 'undefined') return null\n const p = createDOMPurify(\n window as unknown as Parameters<typeof createDOMPurify>[0],\n )\n // ALLOWED_URI_REGEXP can't be used to restrict href/xlink:href without also\n // killing geometry attrs like cx/cy/r (DOMPurify applies the URI regex to\n // every non-URI-safe attribute value). A scoped hook on this DOMPurify\n // instance lets us reject non-fragment href values without touching the\n // global DOMPurify state — important for consumers who use DOMPurify\n // elsewhere in their app.\n p.addHook('uponSanitizeAttribute', (_node, ev) => {\n if (ev.attrName === 'href' || ev.attrName === 'xlink:href') {\n const v = typeof ev.attrValue === 'string' ? ev.attrValue : ''\n if (!v.startsWith('#')) ev.keepAttr = false\n }\n })\n purifierCache = p\n return p\n}\n\n// DOMPurify's string-mode sanitize parses input as HTML, which silently\n// drops case-sensitive SVG attributes (viewBox, preserveAspectRatio). Parse\n// with image/svg+xml first and sanitize in place to keep the SVG-namespace\n// context and attribute case. svg-to-react.ts converts the returned root to\n// React nodes from this same DOM — no serialize/re-parse round-trip.\nexport function sanitizeSvgRoot(svgText: string): SVGSVGElement | null {\n if (typeof DOMParser === 'undefined') return null\n const purifier = getPurifier()\n if (!purifier) return null\n const doc = new DOMParser().parseFromString(svgText, 'image/svg+xml')\n const root = doc.documentElement\n if (root.nodeName !== 'svg') return null\n purifier.sanitize(root, {\n USE_PROFILES: { svg: true, svgFilters: true },\n FORBID_TAGS,\n IN_PLACE: true,\n })\n return root as unknown as SVGSVGElement\n}\n\nexport function sanitizeSvg(svgText: string): string {\n const root = sanitizeSvgRoot(svgText)\n if (!root) return ''\n return new XMLSerializer().serializeToString(root)\n}\n","// Single source of truth for converting SVG markup attributes into their\n// React equivalents. Two adapters sit on this interface: the build pipeline\n// (scripts/svg-to-jsx.ts emits JSX strings for generated components) and the\n// runtime network fallback (svg-to-react.ts builds React nodes from fetched\n// SVGs). Sharing the rule guarantees an icon renders identically whether it\n// shipped in the bundle or arrived over the wire.\n\nexport function toReactAttributeName(name: string): string {\n if (name === 'class') return 'className'\n if (name.startsWith('aria-') || name.startsWith('data-')) return name\n return name.replace(/[:-]([a-z])/g, (_, letter: string) =>\n letter.toUpperCase(),\n )\n}\n\nexport function styleStringToObject(style: string): Record<string, string> {\n const result: Record<string, string> = {}\n for (const rule of style.split(';')) {\n const [rawProperty, ...rawValue] = rule.split(':')\n const property = rawProperty?.trim()\n const value = rawValue.join(':').trim()\n if (!property || !value) continue\n const reactProperty = property.replace(/-([a-z])/g, (_, letter: string) =>\n letter.toUpperCase(),\n )\n result[reactProperty] = value\n }\n return result\n}\n"]}
package/dist/index.cjs CHANGED
@@ -1,6 +1,7 @@
1
+ "use client";
1
2
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
3
 
3
- var _chunkLMGL65KIcjs = require('./chunk-LMGL65KI.cjs');
4
+ var _chunkWDG7KLLTcjs = require('./chunk-WDG7KLLT.cjs');
4
5
 
5
6
 
6
7
  var _chunkKJL5NVUUcjs = require('./chunk-KJL5NVUU.cjs');
@@ -10,5 +11,5 @@ require('./chunk-KHCWITFW.cjs');
10
11
 
11
12
 
12
13
 
13
- exports.Icon = _chunkLMGL65KIcjs.Icon; exports.IconProvider = _chunkKJL5NVUUcjs.IconProvider;
14
+ exports.Icon = _chunkWDG7KLLTcjs.Icon; exports.IconProvider = _chunkKJL5NVUUcjs.IconProvider;
14
15
  //# sourceMappingURL=index.cjs.map
package/dist/index.js CHANGED
@@ -1,14 +1,13 @@
1
1
  "use client";
2
-
3
2
  import {
4
3
  Icon
5
- } from "./chunk-XWYUXPMU.js";
4
+ } from "./chunk-WUKTILCO.js";
6
5
  import {
7
6
  IconProvider
8
- } from "./chunk-ICEGTX2E.js";
9
- import "./chunk-35GWSGWA.js";
10
- import "./chunk-R2LI45CO.js";
11
- import "./chunk-OVJUO4KZ.js";
7
+ } from "./chunk-Y2MK6VUF.js";
8
+ import "./chunk-FWVJHSO6.js";
9
+ import "./chunk-3QBGGX2B.js";
10
+ import "./chunk-TBD6MI4P.js";
12
11
  export {
13
12
  Icon,
14
13
  IconProvider
@@ -0,0 +1,7 @@
1
+ import {
2
+ LinkIcon
3
+ } from "./chunk-NGMZUDLN.js";
4
+ export {
5
+ LinkIcon
6
+ };
7
+ //# sourceMappingURL=link-XFBO5QDH.js.map
@@ -0,0 +1,7 @@
1
+ import {
2
+ PteusdeIcon
3
+ } from "./chunk-PZ77ZGR7.js";
4
+ export {
5
+ PteusdeIcon
6
+ };
7
+ //# sourceMappingURL=pteusde-XLRWLLKT.js.map
@@ -0,0 +1,12 @@
1
+ // src/generated/lazy/tokens.ts
2
+ var ICON_IMPORTS = {
3
+ "aave": () => import("./aave-K32LGE6Y.js").then((m) => ({ default: m.AaveIcon })),
4
+ "bnb": () => import("./bnb-DCJ5FXUB.js").then((m) => ({ default: m.BnbIcon })),
5
+ "link": () => import("./link-XFBO5QDH.js").then((m) => ({ default: m.LinkIcon })),
6
+ "pteusde": () => import("./pteusde-XLRWLLKT.js").then((m) => ({ default: m.PteusdeIcon })),
7
+ "uni": () => import("./uni-EDTKY5E5.js").then((m) => ({ default: m.UniIcon }))
8
+ };
9
+ export {
10
+ ICON_IMPORTS
11
+ };
12
+ //# sourceMappingURL=tokens-7PEFDREU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/generated/lazy/tokens.ts"],"sourcesContent":["// Auto-generated by scripts/generate.ts - DO NOT EDIT\nimport type { ComponentType } from 'react'\nimport type { IconProps } from '../tokens/index'\n\nexport const ICON_IMPORTS: Record<\n string,\n () => Promise<{ default: ComponentType<IconProps> }>\n> = {\n \"aave\": () => import('../tokens/aave').then((m) => ({ default: m.AaveIcon })),\n \"bnb\": () => import('../tokens/bnb').then((m) => ({ default: m.BnbIcon })),\n \"link\": () => import('../tokens/link').then((m) => ({ default: m.LinkIcon })),\n \"pteusde\": () => import('../tokens/pteusde').then((m) => ({ default: m.PteusdeIcon })),\n \"uni\": () => import('../tokens/uni').then((m) => ({ default: m.UniIcon })),\n}\n"],"mappings":";AAIO,IAAM,eAGT;AAAA,EACF,QAAQ,MAAM,OAAO,oBAAgB,EAAE,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE;AAAA,EAC5E,OAAO,MAAM,OAAO,mBAAe,EAAE,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE;AAAA,EACzE,QAAQ,MAAM,OAAO,oBAAgB,EAAE,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE;AAAA,EAC5E,WAAW,MAAM,OAAO,uBAAmB,EAAE,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE;AAAA,EACrF,OAAO,MAAM,OAAO,mBAAe,EAAE,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE;AAC3E;","names":[]}
@@ -0,0 +1,12 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } }// src/generated/lazy/tokens.ts
2
+ var ICON_IMPORTS = {
3
+ "aave": () => Promise.resolve().then(() => _interopRequireWildcard(require("./aave-EZ44VEFF.cjs"))).then((m) => ({ default: m.AaveIcon })),
4
+ "bnb": () => Promise.resolve().then(() => _interopRequireWildcard(require("./bnb-NS3U5Y5W.cjs"))).then((m) => ({ default: m.BnbIcon })),
5
+ "link": () => Promise.resolve().then(() => _interopRequireWildcard(require("./link-HVLWBKZ5.cjs"))).then((m) => ({ default: m.LinkIcon })),
6
+ "pteusde": () => Promise.resolve().then(() => _interopRequireWildcard(require("./pteusde-ZTEAA2UN.cjs"))).then((m) => ({ default: m.PteusdeIcon })),
7
+ "uni": () => Promise.resolve().then(() => _interopRequireWildcard(require("./uni-LS35CB5G.cjs"))).then((m) => ({ default: m.UniIcon }))
8
+ };
9
+
10
+
11
+ exports.ICON_IMPORTS = ICON_IMPORTS;
12
+ //# sourceMappingURL=tokens-AYZHIKHK.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/icons/icons/packages/react/dist/tokens-AYZHIKHK.cjs","../src/generated/lazy/tokens.ts"],"names":[],"mappings":"AAAA;ACIO,IAAM,aAAA,EAGT;AAAA,EACF,MAAA,EAAQ,CAAA,EAAA,GAAM,4DAAA,CAAO,qBAAgB,GAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAA,GAAA,CAAO,EAAE,OAAA,EAAS,CAAA,CAAE,SAAS,CAAA,CAAE,CAAA;AAAA,EAC5E,KAAA,EAAO,CAAA,EAAA,GAAM,4DAAA,CAAO,oBAAe,GAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAA,GAAA,CAAO,EAAE,OAAA,EAAS,CAAA,CAAE,QAAQ,CAAA,CAAE,CAAA;AAAA,EACzE,MAAA,EAAQ,CAAA,EAAA,GAAM,4DAAA,CAAO,qBAAgB,GAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAA,GAAA,CAAO,EAAE,OAAA,EAAS,CAAA,CAAE,SAAS,CAAA,CAAE,CAAA;AAAA,EAC5E,SAAA,EAAW,CAAA,EAAA,GAAM,4DAAA,CAAO,wBAAmB,GAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAA,GAAA,CAAO,EAAE,OAAA,EAAS,CAAA,CAAE,YAAY,CAAA,CAAE,CAAA;AAAA,EACrF,KAAA,EAAO,CAAA,EAAA,GAAM,4DAAA,CAAO,oBAAe,GAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAA,GAAA,CAAO,EAAE,OAAA,EAAS,CAAA,CAAE,QAAQ,CAAA,CAAE;AAC3E,CAAA;ADLA;AACE;AACF,oCAAC","file":"/home/runner/work/icons/icons/packages/react/dist/tokens-AYZHIKHK.cjs","sourcesContent":[null,"// Auto-generated by scripts/generate.ts - DO NOT EDIT\nimport type { ComponentType } from 'react'\nimport type { IconProps } from '../tokens/index'\n\nexport const ICON_IMPORTS: Record<\n string,\n () => Promise<{ default: ComponentType<IconProps> }>\n> = {\n \"aave\": () => import('../tokens/aave').then((m) => ({ default: m.AaveIcon })),\n \"bnb\": () => import('../tokens/bnb').then((m) => ({ default: m.BnbIcon })),\n \"link\": () => import('../tokens/link').then((m) => ({ default: m.LinkIcon })),\n \"pteusde\": () => import('../tokens/pteusde').then((m) => ({ default: m.PteusdeIcon })),\n \"uni\": () => import('../tokens/uni').then((m) => ({ default: m.UniIcon })),\n}\n"]}
package/dist/tokens.js CHANGED
@@ -1,27 +1,25 @@
1
- "use client";
2
-
3
1
  import {
4
2
  LinkIcon
5
- } from "./chunk-QAWTPM2S.js";
3
+ } from "./chunk-NGMZUDLN.js";
6
4
  import {
7
5
  PteusdeIcon
8
- } from "./chunk-7P3MIHDC.js";
6
+ } from "./chunk-PZ77ZGR7.js";
9
7
  import {
10
8
  UniIcon
11
- } from "./chunk-C2QAKFGG.js";
9
+ } from "./chunk-DMUNOIF2.js";
12
10
  import {
13
11
  BtcIcon,
14
12
  DaiIcon,
15
13
  EthIcon,
16
14
  UsdcIcon,
17
15
  UsdtIcon
18
- } from "./chunk-35GWSGWA.js";
16
+ } from "./chunk-FWVJHSO6.js";
19
17
  import {
20
18
  AaveIcon
21
- } from "./chunk-5GKWV4K2.js";
19
+ } from "./chunk-CGCK22HF.js";
22
20
  import {
23
21
  BnbIcon
24
- } from "./chunk-WH52PT4Y.js";
22
+ } from "./chunk-JYYQDYRP.js";
25
23
  export {
26
24
  AaveIcon,
27
25
  BnbIcon,
@@ -0,0 +1,7 @@
1
+ import {
2
+ UniIcon
3
+ } from "./chunk-DMUNOIF2.js";
4
+ export {
5
+ UniIcon
6
+ };
7
+ //# sourceMappingURL=uni-EDTKY5E5.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smbdy/icons-react",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "Tree-shakeable React icon components for web3 assets",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,9 +0,0 @@
1
- "use client";
2
-
3
- import {
4
- AaveIcon
5
- } from "./chunk-5GKWV4K2.js";
6
- export {
7
- AaveIcon
8
- };
9
- //# sourceMappingURL=aave-4NKY7G5P.js.map
@@ -1,9 +0,0 @@
1
- "use client";
2
-
3
- import {
4
- BnbIcon
5
- } from "./chunk-WH52PT4Y.js";
6
- export {
7
- BnbIcon
8
- };
9
- //# sourceMappingURL=bnb-VEXN3I2D.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/work/icons/icons/packages/react/dist/chunk-LMGL65KI.cjs","../src/index.tsx","../src/generated/eager-map.ts","../src/generated/lazy-map.ts"],"names":["lazy"],"mappings":"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","file":"/home/runner/work/icons/icons/packages/react/dist/chunk-LMGL65KI.cjs","sourcesContent":[null,"import { lazy, Suspense, useEffect, useState } from 'react'\nimport type { ReactNode, SVGProps } from 'react'\nimport { getMeta, getTypedMeta } from '@smbdy/icons'\nimport { resolveOrCandidate } from '@smbdy/icons/resolve'\nimport { EAGER_ICONS } from './generated/eager-map'\nimport { LAZY_ICONS } from './generated/lazy-map'\nimport { useIconConfig } from './icon-provider'\nimport type { IconType } from './types'\n\nexport { IconProvider } from './icon-provider'\nexport type { IconContextValue } from './icon-provider'\n\n// `type` shadows the inherited `SVGProps['type']` HTML attribute, which we\n// never expose anyway. Omitting it makes the prop unambiguously `IconType`.\nexport interface IconProps extends Omit<SVGProps<SVGSVGElement>, 'type'> {\n value: string | number\n type?: IconType\n mono?: boolean\n size?: number | string\n fallback?: ReactNode\n}\n\nlet styleInjected = false\nfunction ensureStyles() {\n if (styleInjected || typeof document === 'undefined') return\n styleInjected = true\n const s = document.createElement('style')\n s.textContent =\n '@keyframes bgd-icon-fade-in{from{opacity:0}to{opacity:1}}' +\n '.bgd-icon-placeholder{transition:opacity 0.3s ease-out}' +\n '@media(prefers-reduced-motion:reduce){.bgd-icon-fade{animation:none;opacity:1}.bgd-icon-placeholder{transition:none}}'\n document.head.appendChild(s)\n}\n\nfunction Placeholder({\n id,\n type,\n size = 32,\n decorative = false,\n}: {\n id: string\n type?: IconType\n size?: number | string\n decorative?: boolean\n}) {\n const meta = type ? getTypedMeta(type, id) : getMeta(id)\n const color = meta?.placeholderColor ?? meta?.brandColor ?? '#ccc'\n const letter = (meta?.symbol ?? id).charAt(0).toUpperCase()\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 32 32\"\n {...(decorative\n ? { 'aria-hidden': true, focusable: false }\n : { role: 'img', 'aria-label': meta?.name ?? id })}\n >\n <circle cx=\"16\" cy=\"16\" r=\"16\" fill={color} opacity={0.25} />\n <text\n x=\"16\"\n y=\"16\"\n dy=\".35em\"\n textAnchor=\"middle\"\n fill={color}\n fontSize=\"14\"\n fontFamily=\"system-ui, sans-serif\"\n fontWeight=\"600\"\n >\n {letter}\n </text>\n </svg>\n )\n}\n\nconst wrapStyle: React.CSSProperties = {\n position: 'relative',\n display: 'inline-flex',\n}\nconst overlayStyle: React.CSSProperties = {\n position: 'absolute',\n inset: 0,\n display: 'inline-flex',\n opacity: 0,\n animation: 'bgd-icon-fade-in 0.3s ease-out forwards',\n}\n\nconst LazyGithubFallback = lazy(() =>\n import('./github-fallback').then((m) => ({ default: m.GithubFallback })),\n)\n\n// Mounts only when the surrounding Suspense boundary resolves — used to\n// learn when the lazy icon is actually on screen.\nfunction NotifyMounted({ onMounted }: { onMounted: () => void }) {\n useEffect(() => {\n onMounted()\n })\n return null\n}\n\ntype LazyIconComponent = (typeof LAZY_ICONS)[string]\n\n// The placeholder is the layout anchor (the lazy icon overlays it), so it\n// must stay mounted — but once the icon has loaded it has to fade out.\n// Mono icons use currentColor with transparent regions; a placeholder left\n// at full opacity peeks through them.\nfunction FadeInLazyIcon({\n Lazy,\n placeholder,\n variant,\n size,\n ...props\n}: Omit<SVGProps<SVGSVGElement>, 'type'> & {\n Lazy: LazyIconComponent\n placeholder: ReactNode\n variant: 'full' | 'mono'\n size?: number | string\n}) {\n const [loaded, setLoaded] = useState(false)\n return (\n <span style={wrapStyle}>\n <span\n className=\"bgd-icon-placeholder\"\n style={{ display: 'inline-flex', opacity: loaded ? 0 : 1 }}\n aria-hidden={loaded || undefined}\n >\n {placeholder}\n </span>\n <Suspense fallback={null}>\n <span className=\"bgd-icon-fade\" style={overlayStyle}>\n <Lazy variant={variant} size={size} {...props} />\n </span>\n <NotifyMounted onMounted={() => setLoaded(true)} />\n </Suspense>\n </span>\n )\n}\n\nexport function Icon({\n value,\n type: explicitType,\n mono = false,\n size,\n fallback,\n ...props\n}: IconProps) {\n const { enableFallback } = useIconConfig()\n const { id, type } = resolveOrCandidate(\n value,\n explicitType ? { type: explicitType } : {},\n )\n const lookupKey = type ? `${type}:${id}` : null\n const placeholderType = type ?? undefined\n const variant: 'full' | 'mono' = mono ? 'mono' : 'full'\n\n const Eager = lookupKey ? EAGER_ICONS[lookupKey] : undefined\n if (Eager) return <Eager variant={variant} size={size} {...props} />\n\n const Lazy = lookupKey ? LAZY_ICONS[lookupKey] : undefined\n if (!Lazy) {\n // Bundlers replace process.env.NODE_ENV and dead-code-eliminate this in production\n if (\n typeof process !== 'undefined' &&\n process.env.NODE_ENV !== 'production'\n ) {\n console.warn(`[bgd-icons] Unknown icon value: \"${value}\"`)\n }\n if (enableFallback) {\n const placeholder = fallback ?? (\n <Placeholder id={id} type={placeholderType} size={size} />\n )\n return (\n <Suspense fallback={placeholder}>\n <LazyGithubFallback\n id={id}\n iconType={placeholderType}\n variant={variant}\n size={size}\n fallback={placeholder}\n {...props}\n />\n </Suspense>\n )\n }\n return (\n <>\n {fallback ?? <Placeholder id={id} type={placeholderType} size={size} />}\n </>\n )\n }\n\n ensureStyles()\n return (\n <FadeInLazyIcon\n // Reset the loaded state when the identity changes\n key={lookupKey}\n Lazy={Lazy}\n placeholder={\n fallback ?? (\n <Placeholder id={id} type={placeholderType} size={size} decorative />\n )\n }\n variant={variant}\n size={size}\n {...props}\n />\n )\n}\n","// Auto-generated by scripts/generate.ts - DO NOT EDIT\nimport type { ComponentType } from 'react'\nimport type { IconProps } from './tokens/index'\n\nimport { BtcIcon } from './tokens/btc'\nimport { DaiIcon } from './tokens/dai'\nimport { EthIcon } from './tokens/eth'\nimport { UsdcIcon } from './tokens/usdc'\nimport { UsdtIcon } from './tokens/usdt'\nimport { EthereumIcon } from './chains/ethereum'\nimport { MetamaskIcon } from './brands/metamask'\n\nexport const EAGER_ICONS: Record<string, ComponentType<IconProps>> = {\n \"token:btc\": BtcIcon,\n \"token:dai\": DaiIcon,\n \"token:eth\": EthIcon,\n \"token:usdc\": UsdcIcon,\n \"token:usdt\": UsdtIcon,\n \"chain:ethereum\": EthereumIcon,\n \"brand:metamask\": MetamaskIcon,\n}\n","// Auto-generated by scripts/generate.ts - DO NOT EDIT\nimport { lazy } from 'react'\nimport type { LazyExoticComponent, ComponentType } from 'react'\nimport type { IconProps } from './tokens/index'\n\ntype LazyIcon = LazyExoticComponent<ComponentType<IconProps>>\n\nexport const LAZY_ICONS: Record<string, LazyIcon> = {\n \"token:aave\": lazy(() => import('./tokens/aave').then((m) => ({ default: m.AaveIcon }))),\n \"token:bnb\": lazy(() => import('./tokens/bnb').then((m) => ({ default: m.BnbIcon }))),\n \"token:link\": lazy(() => import('./tokens/link').then((m) => ({ default: m.LinkIcon }))),\n \"token:pteusde\": lazy(() => import('./tokens/pteusde').then((m) => ({ default: m.PteusdeIcon }))),\n \"token:uni\": lazy(() => import('./tokens/uni').then((m) => ({ default: m.UniIcon }))),\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.tsx","../src/generated/eager-map.ts","../src/generated/lazy-map.ts"],"sourcesContent":["import { lazy, Suspense, useEffect, useState } from 'react'\nimport type { ReactNode, SVGProps } from 'react'\nimport { getMeta, getTypedMeta } from '@smbdy/icons'\nimport { resolveOrCandidate } from '@smbdy/icons/resolve'\nimport { EAGER_ICONS } from './generated/eager-map'\nimport { LAZY_ICONS } from './generated/lazy-map'\nimport { useIconConfig } from './icon-provider'\nimport type { IconType } from './types'\n\nexport { IconProvider } from './icon-provider'\nexport type { IconContextValue } from './icon-provider'\n\n// `type` shadows the inherited `SVGProps['type']` HTML attribute, which we\n// never expose anyway. Omitting it makes the prop unambiguously `IconType`.\nexport interface IconProps extends Omit<SVGProps<SVGSVGElement>, 'type'> {\n value: string | number\n type?: IconType\n mono?: boolean\n size?: number | string\n fallback?: ReactNode\n}\n\nlet styleInjected = false\nfunction ensureStyles() {\n if (styleInjected || typeof document === 'undefined') return\n styleInjected = true\n const s = document.createElement('style')\n s.textContent =\n '@keyframes bgd-icon-fade-in{from{opacity:0}to{opacity:1}}' +\n '.bgd-icon-placeholder{transition:opacity 0.3s ease-out}' +\n '@media(prefers-reduced-motion:reduce){.bgd-icon-fade{animation:none;opacity:1}.bgd-icon-placeholder{transition:none}}'\n document.head.appendChild(s)\n}\n\nfunction Placeholder({\n id,\n type,\n size = 32,\n decorative = false,\n}: {\n id: string\n type?: IconType\n size?: number | string\n decorative?: boolean\n}) {\n const meta = type ? getTypedMeta(type, id) : getMeta(id)\n const color = meta?.placeholderColor ?? meta?.brandColor ?? '#ccc'\n const letter = (meta?.symbol ?? id).charAt(0).toUpperCase()\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 32 32\"\n {...(decorative\n ? { 'aria-hidden': true, focusable: false }\n : { role: 'img', 'aria-label': meta?.name ?? id })}\n >\n <circle cx=\"16\" cy=\"16\" r=\"16\" fill={color} opacity={0.25} />\n <text\n x=\"16\"\n y=\"16\"\n dy=\".35em\"\n textAnchor=\"middle\"\n fill={color}\n fontSize=\"14\"\n fontFamily=\"system-ui, sans-serif\"\n fontWeight=\"600\"\n >\n {letter}\n </text>\n </svg>\n )\n}\n\nconst wrapStyle: React.CSSProperties = {\n position: 'relative',\n display: 'inline-flex',\n}\nconst overlayStyle: React.CSSProperties = {\n position: 'absolute',\n inset: 0,\n display: 'inline-flex',\n opacity: 0,\n animation: 'bgd-icon-fade-in 0.3s ease-out forwards',\n}\n\nconst LazyGithubFallback = lazy(() =>\n import('./github-fallback').then((m) => ({ default: m.GithubFallback })),\n)\n\n// Mounts only when the surrounding Suspense boundary resolves — used to\n// learn when the lazy icon is actually on screen.\nfunction NotifyMounted({ onMounted }: { onMounted: () => void }) {\n useEffect(() => {\n onMounted()\n })\n return null\n}\n\ntype LazyIconComponent = (typeof LAZY_ICONS)[string]\n\n// The placeholder is the layout anchor (the lazy icon overlays it), so it\n// must stay mounted — but once the icon has loaded it has to fade out.\n// Mono icons use currentColor with transparent regions; a placeholder left\n// at full opacity peeks through them.\nfunction FadeInLazyIcon({\n Lazy,\n placeholder,\n variant,\n size,\n ...props\n}: Omit<SVGProps<SVGSVGElement>, 'type'> & {\n Lazy: LazyIconComponent\n placeholder: ReactNode\n variant: 'full' | 'mono'\n size?: number | string\n}) {\n const [loaded, setLoaded] = useState(false)\n return (\n <span style={wrapStyle}>\n <span\n className=\"bgd-icon-placeholder\"\n style={{ display: 'inline-flex', opacity: loaded ? 0 : 1 }}\n aria-hidden={loaded || undefined}\n >\n {placeholder}\n </span>\n <Suspense fallback={null}>\n <span className=\"bgd-icon-fade\" style={overlayStyle}>\n <Lazy variant={variant} size={size} {...props} />\n </span>\n <NotifyMounted onMounted={() => setLoaded(true)} />\n </Suspense>\n </span>\n )\n}\n\nexport function Icon({\n value,\n type: explicitType,\n mono = false,\n size,\n fallback,\n ...props\n}: IconProps) {\n const { enableFallback } = useIconConfig()\n const { id, type } = resolveOrCandidate(\n value,\n explicitType ? { type: explicitType } : {},\n )\n const lookupKey = type ? `${type}:${id}` : null\n const placeholderType = type ?? undefined\n const variant: 'full' | 'mono' = mono ? 'mono' : 'full'\n\n const Eager = lookupKey ? EAGER_ICONS[lookupKey] : undefined\n if (Eager) return <Eager variant={variant} size={size} {...props} />\n\n const Lazy = lookupKey ? LAZY_ICONS[lookupKey] : undefined\n if (!Lazy) {\n // Bundlers replace process.env.NODE_ENV and dead-code-eliminate this in production\n if (\n typeof process !== 'undefined' &&\n process.env.NODE_ENV !== 'production'\n ) {\n console.warn(`[bgd-icons] Unknown icon value: \"${value}\"`)\n }\n if (enableFallback) {\n const placeholder = fallback ?? (\n <Placeholder id={id} type={placeholderType} size={size} />\n )\n return (\n <Suspense fallback={placeholder}>\n <LazyGithubFallback\n id={id}\n iconType={placeholderType}\n variant={variant}\n size={size}\n fallback={placeholder}\n {...props}\n />\n </Suspense>\n )\n }\n return (\n <>\n {fallback ?? <Placeholder id={id} type={placeholderType} size={size} />}\n </>\n )\n }\n\n ensureStyles()\n return (\n <FadeInLazyIcon\n // Reset the loaded state when the identity changes\n key={lookupKey}\n Lazy={Lazy}\n placeholder={\n fallback ?? (\n <Placeholder id={id} type={placeholderType} size={size} decorative />\n )\n }\n variant={variant}\n size={size}\n {...props}\n />\n )\n}\n","// Auto-generated by scripts/generate.ts - DO NOT EDIT\nimport type { ComponentType } from 'react'\nimport type { IconProps } from './tokens/index'\n\nimport { BtcIcon } from './tokens/btc'\nimport { DaiIcon } from './tokens/dai'\nimport { EthIcon } from './tokens/eth'\nimport { UsdcIcon } from './tokens/usdc'\nimport { UsdtIcon } from './tokens/usdt'\nimport { EthereumIcon } from './chains/ethereum'\nimport { MetamaskIcon } from './brands/metamask'\n\nexport const EAGER_ICONS: Record<string, ComponentType<IconProps>> = {\n \"token:btc\": BtcIcon,\n \"token:dai\": DaiIcon,\n \"token:eth\": EthIcon,\n \"token:usdc\": UsdcIcon,\n \"token:usdt\": UsdtIcon,\n \"chain:ethereum\": EthereumIcon,\n \"brand:metamask\": MetamaskIcon,\n}\n","// Auto-generated by scripts/generate.ts - DO NOT EDIT\nimport { lazy } from 'react'\nimport type { LazyExoticComponent, ComponentType } from 'react'\nimport type { IconProps } from './tokens/index'\n\ntype LazyIcon = LazyExoticComponent<ComponentType<IconProps>>\n\nexport const LAZY_ICONS: Record<string, LazyIcon> = {\n \"token:aave\": lazy(() => import('./tokens/aave').then((m) => ({ default: m.AaveIcon }))),\n \"token:bnb\": lazy(() => import('./tokens/bnb').then((m) => ({ default: m.BnbIcon }))),\n \"token:link\": lazy(() => import('./tokens/link').then((m) => ({ default: m.LinkIcon }))),\n \"token:pteusde\": lazy(() => import('./tokens/pteusde').then((m) => ({ default: m.PteusdeIcon }))),\n \"token:uni\": lazy(() => import('./tokens/uni').then((m) => ({ default: m.UniIcon }))),\n}\n"],"mappings":"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","names":["lazy","lazy"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/frames.ts","../src/generated/frames/a.tsx","../src/generated/frames/stk.tsx","../src/generated/frames/stkwa.tsx","../src/generated/frames/wa.tsx"],"sourcesContent":["import { cloneElement, createElement, isValidElement } from 'react'\nimport type { CSSProperties, ReactElement, ReactNode } from 'react'\nimport { AFrame } from './generated/frames/a'\nimport { StkFrame } from './generated/frames/stk'\nimport { StkwaFrame } from './generated/frames/stkwa'\nimport { WaFrame } from './generated/frames/wa'\n\nconst FRAMES: Record<string, typeof AFrame> = {\n a: AFrame,\n stk: StkFrame,\n stkwa: StkwaFrame,\n wa: WaFrame,\n}\n\nexport interface FrameWrapperProps {\n frame: string\n variant?: 'full' | 'mono'\n size?: number | string\n children?: ReactNode\n}\n\nconst wrapperStyle = (size: number | string): CSSProperties => ({\n position: 'relative',\n width: size,\n height: size,\n})\n\nconst innerStyle: CSSProperties = {\n position: 'absolute',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n}\n\nconst iconContainerStyle: CSSProperties = {\n width: '81.25%',\n height: '81.25%',\n}\n\nconst frameStyle = (size: number | string): CSSProperties => ({\n position: 'absolute',\n inset: 0,\n width: size,\n height: size,\n})\n\nexport function FrameWrapper({\n frame,\n variant = 'full',\n size = 32,\n children,\n}: FrameWrapperProps) {\n const FrameSvg = FRAMES[frame]\n if (!FrameSvg) {\n // Bundlers replace process.env.NODE_ENV and dead-code-eliminate this in production\n if (\n typeof process !== 'undefined' &&\n process.env.NODE_ENV !== 'production'\n ) {\n console.warn(\n `[bgd-icons] Unknown frame: \"${frame}\" (known: ${Object.keys(FRAMES).join(', ')}) — rendering the base icon unframed`,\n )\n }\n return createElement('span', null, children)\n }\n\n // The slot is sized to 81.25% of the frame; fill it by default so the base\n // icon doesn't float undersized inside the frame. An explicit `size` on the\n // child always wins.\n const slotChild =\n isValidElement(children) &&\n (children.props as { size?: number | string }).size == null\n ? cloneElement(children as ReactElement<{ size?: number | string }>, {\n size: '100%',\n })\n : children\n\n return createElement(\n 'div',\n { style: wrapperStyle(size) },\n createElement(\n 'div',\n { style: innerStyle },\n createElement('div', { style: iconContainerStyle }, slotChild),\n ),\n createElement(FrameSvg, { variant, style: frameStyle(size), size }),\n )\n}\n","// Auto-generated by scripts/generate.ts - DO NOT EDIT\nimport { forwardRef } from 'react'\nimport type { SVGProps } from 'react'\n\nexport interface FrameIconProps extends SVGProps<SVGSVGElement> {\n variant?: 'full' | 'mono'\n size?: number | string\n}\n\nexport const AFrame = forwardRef<SVGSVGElement, FrameIconProps>(\n ({ variant = 'full', size = 32, ...props }, ref) => {\n if (variant === 'mono') {\n return (\n <svg ref={ref} width={size} height={size} viewBox=\"0 0 32 32\" fill=\"none\" role=\"img\" aria-label=\"A Frame\" {...props}>\n <circle cx=\"16\" cy=\"16\" r=\"15\" stroke=\"currentColor\" strokeWidth=\"2\"/>\n </svg>\n )\n }\n return (\n <svg ref={ref} width={size} height={size} viewBox=\"0 0 32 32\" fill=\"none\" role=\"img\" aria-label=\"A Frame\" {...props}>\n <path stroke=\"#9896ff\" strokeWidth=\"2\" d=\"M16 31c8.284 0 15-6.716 15-15S24.284 1 16 1 1 7.716 1 16s6.716 15 15 15Z\"/>\n </svg>\n )\n }\n)\nAFrame.displayName = 'AFrame'\n","// Auto-generated by scripts/generate.ts - DO NOT EDIT\nimport { forwardRef } from 'react'\nimport type { SVGProps } from 'react'\n\nexport interface FrameIconProps extends SVGProps<SVGSVGElement> {\n variant?: 'full' | 'mono'\n size?: number | string\n}\n\nexport const StkFrame = forwardRef<SVGSVGElement, FrameIconProps>(\n ({ variant = 'full', size = 32, ...props }, ref) => {\n if (variant === 'mono') {\n return (\n <svg ref={ref} width={size} height={size} viewBox=\"0 0 32 32\" fill=\"currentColor\" role=\"img\" aria-label=\"Stk Frame\" {...props}>\n <path fill=\"currentColor\" d=\"M11.35 2.79c1.46-.51 3.02-.81 4.65-.81s3.22.3 4.68.82L21.83.04C21.7.02 21.56 0 21.42 0H10.58c-.12 0-.25.02-.37.04zM3.36 9.96c1.38-2.88 3.71-5.22 6.59-6.6L8.81.6c-.1.08-.21.15-.3.25L.85 8.52c-.09.09-.17.2-.24.3zM30.02 16c0 1.65-.3 3.23-.82 4.7l2.76 1.15c.02-.14.04-.28.04-.42V10.59c0-.11-.02-.22-.03-.33l-2.74 1.13c.51 1.45.8 3 .8 4.62zM23.21.63l-1.14 2.75c2.88 1.39 5.21 3.72 6.58 6.61l2.76-1.14c-.08-.11-.17-.23-.27-.33L23.48.85C23.4.77 23.3.7 23.21.63M1.98 16c0-1.63.29-3.19.81-4.65L.04 10.21c-.02.12-.04.24-.04.37v10.84c0 .13.02.26.04.38l2.75-1.14c-.52-1.46-.81-3.03-.81-4.67zm26.64 6.08a14.07 14.07 0 0 1-6.59 6.56l1.14 2.76c.11-.08.22-.16.32-.26l7.67-7.67c.08-.08.14-.17.21-.26l-2.74-1.14zm-7.99 7.14c-1.45.51-3.01.8-4.63.8s-3.2-.3-4.66-.81l-1.14 2.75c.13.02.25.04.39.04h10.84c.12 0 .23-.02.35-.03l-1.13-2.75zM8.81 31.38l1.14-2.75c-2.87-1.38-5.2-3.7-6.58-6.57L.62 23.2c.08.1.15.2.24.29l7.67 7.67c.09.09.19.16.29.24z\"/>\n </svg>\n )\n }\n return (\n <svg ref={ref} width={size} height={size} viewBox=\"0 0 32 32\" fill=\"none\" role=\"img\" aria-label=\"Stk Frame\" {...props}>\n <path fill=\"#ffb800\" d=\"M11.35 2.79c1.46-.51 3.02-.81 4.65-.81s3.22.3 4.68.82L21.83.04C21.7.02 21.56 0 21.42 0H10.58c-.12 0-.25.02-.37.04zM3.36 9.96c1.38-2.88 3.71-5.22 6.59-6.6L8.81.6c-.1.08-.21.15-.3.25L.85 8.52c-.09.09-.17.2-.24.3zM30.02 16c0 1.65-.3 3.23-.82 4.7l2.76 1.15c.02-.14.04-.28.04-.42V10.59c0-.11-.02-.22-.03-.33l-2.74 1.13c.51 1.45.8 3 .8 4.62zM23.21.63l-1.14 2.75c2.88 1.39 5.21 3.72 6.58 6.61l2.76-1.14c-.08-.11-.17-.23-.27-.33L23.48.85C23.4.77 23.3.7 23.21.63M1.98 16c0-1.63.29-3.19.81-4.65L.04 10.21c-.02.12-.04.24-.04.37v10.84c0 .13.02.26.04.38l2.75-1.14c-.52-1.46-.81-3.03-.81-4.67zm26.64 6.08a14.07 14.07 0 0 1-6.59 6.56l1.14 2.76c.11-.08.22-.16.32-.26l7.67-7.67c.08-.08.14-.17.21-.26l-2.74-1.14zm-7.99 7.14c-1.45.51-3.01.8-4.63.8s-3.2-.3-4.66-.81l-1.14 2.75c.13.02.25.04.39.04h10.84c.12 0 .23-.02.35-.03l-1.13-2.75zM8.81 31.38l1.14-2.75c-2.87-1.38-5.2-3.7-6.58-6.57L.62 23.2c.08.1.15.2.24.29l7.67 7.67c.09.09.19.16.29.24z\"/>\n </svg>\n )\n }\n)\nStkFrame.displayName = 'StkFrame'\n","// Auto-generated by scripts/generate.ts - DO NOT EDIT\nimport { forwardRef } from 'react'\nimport type { SVGProps } from 'react'\n\nexport interface FrameIconProps extends SVGProps<SVGSVGElement> {\n variant?: 'full' | 'mono'\n size?: number | string\n}\n\nexport const StkwaFrame = forwardRef<SVGSVGElement, FrameIconProps>(\n ({ variant = 'full', size = 32, ...props }, ref) => {\n if (variant === 'mono') {\n return (\n <svg ref={ref} width={size} height={size} viewBox=\"0 0 32 32\" fill=\"currentColor\" role=\"img\" aria-label=\"Stkwa Frame\" {...props}>\n <path fill=\"currentColor\" d=\"M11.35 2.79c1.46-.51 3.02-.81 4.65-.81s3.22.3 4.68.82L21.83.04C21.7.02 21.56 0 21.42 0H10.58c-.12 0-.25.02-.37.04zM3.36 9.96c1.38-2.88 3.71-5.22 6.59-6.6L8.81.6c-.1.08-.21.15-.3.25L.85 8.52c-.09.09-.17.2-.24.3zm28.14 1.02v10.13l-1.68-.7c.46-1.45.7-2.93.7-4.41s-.23-2.91-.67-4.34zm.47-.73-2.74 1.13c.51 1.45.8 3 .8 4.62s-.3 3.23-.82 4.7l2.76 1.15c.02-.14.04-.28.04-.42V10.59c0-.11-.02-.22-.03-.33zM23.21.63l-1.14 2.75c2.88 1.39 5.21 3.72 6.58 6.61l2.76-1.14c-.08-.11-.17-.23-.27-.33L23.48.85C23.4.77 23.3.7 23.21.63M1.98 16c0-1.63.29-3.19.81-4.65L.04 10.21c-.02.12-.04.24-.04.37v10.84c0 .13.02.26.04.38l2.75-1.14c-.52-1.46-.81-3.03-.81-4.67zm26.87 6.72 1.66.69-7.15 7.15-.69-1.68a14.6 14.6 0 0 0 6.19-6.16m-.24-.64a14.07 14.07 0 0 1-6.59 6.56l1.14 2.76c.11-.08.22-.16.32-.26l7.67-7.67c.08-.08.14-.17.21-.26l-2.74-1.14zm-17 7.75c1.44.46 2.91.69 4.38.69s2.92-.23 4.35-.68l.68 1.66H10.92l.69-1.67m-.27-.62-1.14 2.75c.13.02.25.04.39.04h10.84c.12 0 .23-.02.35-.03l-1.13-2.75c-1.45.51-3.01.8-4.63.8s-3.2-.3-4.66-.81zM3.13 22.7c1.37 2.63 3.54 4.8 6.18 6.17l-.69 1.67-7.15-7.15 1.67-.69m.23-.64L.62 23.2c.08.1.15.2.24.29l7.67 7.67c.09.09.19.16.29.24l1.14-2.75c-2.87-1.38-5.2-3.7-6.58-6.57z\"/>\n </svg>\n )\n }\n return (\n <svg ref={ref} width={size} height={size} viewBox=\"0 0 32 32\" fill=\"none\" role=\"img\" aria-label=\"Stkwa Frame\" {...props}>\n <path fill=\"#ffb800\" d=\"M11.35 2.79c1.46-.51 3.02-.81 4.65-.81s3.22.3 4.68.82L21.83.04C21.7.02 21.56 0 21.42 0H10.58c-.12 0-.25.02-.37.04zM3.36 9.96c1.38-2.88 3.71-5.22 6.59-6.6L8.81.6c-.1.08-.21.15-.3.25L.85 8.52c-.09.09-.17.2-.24.3z\"/><path fill=\"#9896ff\" d=\"M30.02 16c0 1.65-.3 3.23-.82 4.7l2.76 1.15c.02-.14.04-.28.04-.42V10.59c0-.11-.02-.22-.03-.33l-2.74 1.13c.51 1.45.8 3 .8 4.62z\"/><path fill=\"#ffb800\" d=\"m23.21.63-1.14 2.75c2.88 1.39 5.21 3.72 6.58 6.61l2.76-1.14c-.08-.11-.17-.23-.27-.33L23.48.85C23.4.77 23.3.7 23.21.63M1.98 16c0-1.63.29-3.19.81-4.65L.04 10.21c-.02.12-.04.24-.04.37v10.84c0 .13.02.26.04.38l2.75-1.14c-.52-1.46-.81-3.03-.81-4.67z\"/><path fill=\"#9896ff\" d=\"M28.62 22.08a14.07 14.07 0 0 1-6.59 6.56l1.14 2.76c.11-.08.22-.16.32-.26l7.67-7.67c.08-.08.14-.17.21-.26l-2.74-1.14zm-7.99 7.14c-1.45.51-3.01.8-4.63.8s-3.2-.3-4.66-.81l-1.14 2.75c.13.02.25.04.39.04h10.84c.12 0 .23-.02.35-.03l-1.13-2.75zM8.81 31.38l1.14-2.75c-2.87-1.38-5.2-3.7-6.58-6.57L.62 23.2c.08.1.15.2.24.29l7.67 7.67c.09.09.19.16.29.24z\"/>\n </svg>\n )\n }\n)\nStkwaFrame.displayName = 'StkwaFrame'\n","// Auto-generated by scripts/generate.ts - DO NOT EDIT\nimport { forwardRef } from 'react'\nimport type { SVGProps } from 'react'\n\nexport interface FrameIconProps extends SVGProps<SVGSVGElement> {\n variant?: 'full' | 'mono'\n size?: number | string\n}\n\nexport const WaFrame = forwardRef<SVGSVGElement, FrameIconProps>(\n ({ variant = 'full', size = 32, ...props }, ref) => {\n if (variant === 'mono') {\n return (\n <svg ref={ref} width={size} height={size} viewBox=\"0 0 32 32\" fill=\"currentColor\" role=\"img\" aria-label=\"Wa Frame\" {...props}>\n <path fill=\"currentColor\" fillRule=\"evenodd\" d=\"m31.951 17.257-1.994-.155a14 14 0 0 0 0-2.204l1.994-.155a16 16 0 0 1 0 2.514m-.39-4.994-1.945.466q-.26-1.08-.677-2.087l1.847-.767q.478 1.154.775 2.388M29.644 7.64 27.94 8.686a14 14 0 0 0-1.293-1.778l1.52-1.3a16 16 0 0 1 1.477 2.031m-3.253-3.806-1.3 1.52a14 14 0 0 0-1.777-1.293l1.047-1.704q1.076.661 2.03 1.477m-4.266-2.619-.767 1.848a14 14 0 0 0-2.087-.678l.466-1.945c.822.196 1.62.457 2.388.775M17.257.05l-.155 1.994a14 14 0 0 0-2.204 0L14.743.049a16 16 0 0 1 2.514 0m-4.994.39.466 1.945q-1.08.26-2.087.678l-.767-1.848A16 16 0 0 1 12.263.44M7.64 2.356 8.686 4.06a14 14 0 0 0-1.778 1.293l-1.3-1.52A16 16 0 0 1 7.64 2.356M3.833 5.609l1.52 1.3A14 14 0 0 0 4.06 8.685L2.356 7.639q.661-1.076 1.477-2.03M1.214 9.875l1.848.767a14 14 0 0 0-.678 2.087l-1.945-.466c.196-.822.457-1.62.775-2.388M.05 14.743a16 16 0 0 0 0 2.514l1.994-.155a14 14 0 0 1 0-2.204zm.39 4.994 1.945-.466q.26 1.08.678 2.087l-1.848.767a16 16 0 0 1-.775-2.388m1.917 4.624 1.704-1.047q.579.941 1.293 1.778l-1.52 1.3a16 16 0 0 1-1.477-2.031m3.253 3.806 1.3-1.52q.835.714 1.777 1.293L7.64 29.644a16 16 0 0 1-2.03-1.477m4.266 2.619.767-1.848q1.007.42 2.087.678l-.466 1.945a16 16 0 0 1-2.388-.775m4.868 1.165.155-1.994a14 14 0 0 0 2.204 0l.155 1.994a16 16 0 0 1-2.514 0m4.994-.39-.466-1.945q1.08-.26 2.087-.677l.767 1.847a16 16 0 0 1-2.388.775m4.624-1.917-1.047-1.704q.941-.579 1.778-1.293l1.3 1.52a16 16 0 0 1-2.031 1.477m3.806-3.253-1.52-1.3a14 14 0 0 0 1.293-1.777l1.704 1.047q-.661 1.076-1.477 2.03m2.619-4.266-1.848-.767q.42-1.007.678-2.087l1.945.466a16 16 0 0 1-.775 2.388\" clipRule=\"evenodd\"/>\n </svg>\n )\n }\n return (\n <svg ref={ref} width={size} height={size} viewBox=\"0 0 32 32\" fill=\"none\" role=\"img\" aria-label=\"Wa Frame\" {...props}>\n <path fill=\"#9896ff\" fillRule=\"evenodd\" d=\"m31.951 17.257-1.994-.155a14 14 0 0 0 0-2.204l1.994-.155a16 16 0 0 1 0 2.514m-.39-4.994-1.945.466q-.26-1.08-.677-2.087l1.847-.767q.478 1.154.775 2.388M29.644 7.64 27.94 8.686a14 14 0 0 0-1.293-1.778l1.52-1.3a16 16 0 0 1 1.477 2.031m-3.253-3.806-1.3 1.52a14 14 0 0 0-1.777-1.293l1.047-1.704q1.076.661 2.03 1.477m-4.266-2.619-.767 1.848a14 14 0 0 0-2.087-.678l.466-1.945c.822.196 1.62.457 2.388.775M17.257.05l-.155 1.994a14 14 0 0 0-2.204 0L14.743.049a16 16 0 0 1 2.514 0m-4.994.39.466 1.945q-1.08.26-2.087.678l-.767-1.848A16 16 0 0 1 12.263.44M7.64 2.356 8.686 4.06a14 14 0 0 0-1.778 1.293l-1.3-1.52A16 16 0 0 1 7.64 2.356M3.833 5.609l1.52 1.3A14 14 0 0 0 4.06 8.685L2.356 7.639q.661-1.076 1.477-2.03M1.214 9.875l1.848.767a14 14 0 0 0-.678 2.087l-1.945-.466c.196-.822.457-1.62.775-2.388M.05 14.743a16 16 0 0 0 0 2.514l1.994-.155a14 14 0 0 1 0-2.204zm.39 4.994 1.945-.466q.26 1.08.678 2.087l-1.848.767a16 16 0 0 1-.775-2.388m1.917 4.624 1.704-1.047q.579.941 1.293 1.778l-1.52 1.3a16 16 0 0 1-1.477-2.031m3.253 3.806 1.3-1.52q.835.714 1.777 1.293L7.64 29.644a16 16 0 0 1-2.03-1.477m4.266 2.619.767-1.848q1.007.42 2.087.678l-.466 1.945a16 16 0 0 1-2.388-.775m4.868 1.165.155-1.994a14 14 0 0 0 2.204 0l.155 1.994a16 16 0 0 1-2.514 0m4.994-.39-.466-1.945q1.08-.26 2.087-.677l.767 1.847a16 16 0 0 1-2.388.775m4.624-1.917-1.047-1.704q.941-.579 1.778-1.293l1.3 1.52a16 16 0 0 1-2.031 1.477m3.806-3.253-1.52-1.3a14 14 0 0 0 1.293-1.777l1.704 1.047q-.661 1.076-1.477 2.03m2.619-4.266-1.848-.767q.42-1.007.678-2.087l1.945.466a16 16 0 0 1-.775 2.388\" clipRule=\"evenodd\"/>\n </svg>\n )\n }\n)\nWaFrame.displayName = 'WaFrame'\n"],"mappings":"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","names":["forwardRef","jsx","forwardRef","jsx","forwardRef","jsx"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/github-fallback.tsx","../src/svg-to-react.ts","../src/sanitize-svg.ts","../src/svg-attributes.ts"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react'\nimport type { ReactNode, SVGProps } from 'react'\nimport { resolve } from '@smbdy/icons/resolve'\nimport { useIconConfig } from './icon-provider'\nimport { svgTextToReact } from './svg-to-react'\nimport type { SvgReactContent } from './svg-to-react'\nimport type { IconType } from './types'\n\n// Module-level SVG cache, keyed by URL. null = negative cache (tried & failed).\ninterface CacheEntry {\n value: string | null\n ts: number\n}\n\nconst svgCache = new Map<string, CacheEntry>()\nconst cacheOrder: string[] = []\nconst MAX_CACHE = 200\nconst NEGATIVE_CACHE_TTL_MS = 60_000\nconst FETCH_TIMEOUT_MS = 8_000\n\nfunction cacheGet(url: string): string | null | undefined {\n const entry = svgCache.get(url)\n if (entry === undefined) return undefined\n // Successful entries never expire (within LRU window)\n if (entry.value !== null) return entry.value\n // Negative entries expire after TTL\n if (Date.now() - entry.ts > NEGATIVE_CACHE_TTL_MS) {\n svgCache.delete(url)\n const idx = cacheOrder.indexOf(url)\n if (idx !== -1) cacheOrder.splice(idx, 1)\n return undefined\n }\n return null\n}\n\nfunction cacheSet(url: string, value: string | null) {\n if (!svgCache.has(url)) {\n cacheOrder.push(url)\n if (cacheOrder.length > MAX_CACHE) {\n const evict = cacheOrder.shift()!\n svgCache.delete(evict)\n }\n }\n svgCache.set(url, { value, ts: Date.now() })\n}\n\ntype AssetType = 'tokens' | 'chains' | 'brands'\n\nfunction toAssetType(type: IconType): AssetType {\n if (type === 'token') return 'tokens'\n if (type === 'chain') return 'chains'\n return 'brands'\n}\n\nfunction inferType(id: string, explicitType?: IconType): AssetType | null {\n if (explicitType) return toAssetType(explicitType)\n // Ask the resolution module (token-first per ADR-0001) rather than\n // probing the metadata maps per type.\n const hit = resolve(id)\n return hit ? toAssetType(hit.type) : null\n}\n\nfunction buildUrl(\n baseUrl: string,\n branch: string,\n type: AssetType,\n id: string,\n variant: string,\n): string {\n return `${baseUrl}/${branch}/assets/${type}/${id}_${variant}.svg`\n}\n\nasync function fetchSvg(\n url: string,\n signal: AbortSignal,\n): Promise<string | null> {\n const cached = cacheGet(url)\n if (cached !== undefined) return cached\n\n try {\n const res = await fetch(url, { signal })\n if (!res.ok) {\n cacheSet(url, null)\n return null\n }\n const text = await res.text()\n cacheSet(url, text)\n return text\n } catch {\n if (!signal.aborted) cacheSet(url, null)\n return null\n }\n}\n\nasync function resolveSvg(\n baseUrl: string,\n branch: string,\n id: string,\n explicitType: IconType | undefined,\n variant: string,\n signal: AbortSignal,\n): Promise<string | null> {\n const type = inferType(id, explicitType)\n\n if (type) {\n return fetchSvg(buildUrl(baseUrl, branch, type, id, variant), signal)\n }\n\n // Unknown type — probe all three and keep token-first result ordering.\n const types: AssetType[] = ['tokens', 'chains', 'brands']\n const results = await Promise.all(\n types.map((t) =>\n fetchSvg(buildUrl(baseUrl, branch, t, id, variant), signal),\n ),\n )\n return results.find((result) => result !== null) ?? null\n}\n\nexport interface GithubFallbackProps extends SVGProps<SVGSVGElement> {\n id: string\n iconType?: IconType\n variant: 'full' | 'mono'\n size?: number | string\n fallback?: ReactNode\n}\n\ninterface FallbackState {\n key: string\n content: SvgReactContent | null\n failed: boolean\n}\n\nfunction getCachedContent(\n baseUrl: string,\n branch: string,\n explicitType: IconType | undefined,\n id: string,\n variant: string,\n): SvgReactContent | null {\n const type = inferType(id, explicitType)\n if (!type) return null\n const cached = cacheGet(buildUrl(baseUrl, branch, type, id, variant))\n return typeof cached === 'string' ? svgTextToReact(cached) : null\n}\n\nexport function GithubFallback({\n id,\n iconType,\n variant,\n size = 32,\n fallback,\n ...props\n}: GithubFallbackProps) {\n const { baseUrl, branch } = useIconConfig()\n const requestKey = `${baseUrl}|${branch}|${iconType ?? 'auto'}|${id}|${variant}`\n const cachedContent = useMemo(\n () => getCachedContent(baseUrl, branch, iconType, id, variant),\n [baseUrl, branch, iconType, id, variant],\n )\n const [state, setState] = useState<FallbackState>(() => ({\n key: requestKey,\n content: cachedContent,\n failed: false,\n }))\n const currentState =\n state.key === requestKey\n ? state\n : {\n key: requestKey,\n content: cachedContent,\n failed: false,\n }\n\n useEffect(() => {\n if (currentState.content || currentState.failed) return\n\n const ac = new AbortController()\n const timer = setTimeout(() => ac.abort(), FETCH_TIMEOUT_MS)\n\n resolveSvg(baseUrl, branch, id, iconType, variant, ac.signal).then(\n (svgText) => {\n clearTimeout(timer)\n if (ac.signal.aborted) return\n setState(() => {\n if (!svgText) {\n return { key: requestKey, content: null, failed: true }\n }\n const content = svgTextToReact(svgText)\n return content\n ? { key: requestKey, content, failed: false }\n : { key: requestKey, content: null, failed: true }\n })\n },\n )\n\n return () => {\n clearTimeout(timer)\n ac.abort()\n }\n }, [\n baseUrl,\n branch,\n currentState.failed,\n currentState.content,\n id,\n requestKey,\n iconType,\n variant,\n ])\n\n if (currentState.failed) return <>{fallback ?? null}</>\n if (!currentState.content) return <>{fallback ?? null}</>\n\n const monoProps = variant === 'mono' ? { fill: 'currentColor' } : {}\n\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox={currentState.content.viewBox}\n role=\"img\"\n aria-label={id}\n {...monoProps}\n {...props}\n >\n {currentState.content.node}\n </svg>\n )\n}\n","import { createElement } from 'react'\nimport type { ReactNode } from 'react'\nimport { sanitizeSvgRoot } from './sanitize-svg'\nimport { styleStringToObject, toReactAttributeName } from './svg-attributes'\n\nexport interface SvgReactContent {\n node: ReactNode\n viewBox: string\n}\n\nfunction svgNodeToReact(node: ChildNode, key: string): ReactNode {\n if (node.nodeType === Node.TEXT_NODE) return node.textContent\n if (node.nodeType !== Node.ELEMENT_NODE) return null\n\n const element = node as Element\n const props: Record<string, unknown> = { key }\n for (const attr of Array.from(element.attributes)) {\n const attrName = toReactAttributeName(attr.name)\n props[attrName] =\n attr.name === 'style' ? styleStringToObject(attr.value) : attr.value\n }\n\n const children = Array.from(element.childNodes)\n .map((child, index) => svgNodeToReact(child, `${key}-${index}`))\n .filter((child) => child !== null)\n\n return createElement(element.tagName, props, ...children)\n}\n\n/**\n * Sanitize an SVG string and convert its children to React nodes in one\n * pass over a single parsed DOM. Returns the converted children and the\n * root's viewBox; the caller renders its own `<svg>` wrapper so it controls\n * sizing and accessibility attributes.\n *\n * Returns null when the input is not a parseable `<svg>` document (or when\n * no DOM is available, e.g. during SSR).\n */\nexport function svgTextToReact(svgText: string): SvgReactContent | null {\n const root = sanitizeSvgRoot(svgText)\n if (!root) return null\n const viewBox = root.getAttribute('viewBox') ?? '0 0 32 32'\n const node = Array.from(root.childNodes)\n .map((child, index) => svgNodeToReact(child, String(index)))\n .filter((child) => child !== null)\n return { node, viewBox }\n}\n","import createDOMPurify from 'dompurify'\nimport type { DOMPurify } from 'dompurify'\n\n// `<use>` and `<script>` are blocked by DOMPurify's SVG profile already\n// (svgDisallowed in the upstream source); listing them here is defense in\n// depth in case a future profile change relaxes that.\nconst FORBID_TAGS = ['script', 'foreignObject', 'text', 'image', 'style']\n\nlet purifierCache: DOMPurify | null = null\n\nfunction getPurifier(): DOMPurify | null {\n if (purifierCache) return purifierCache\n if (typeof window === 'undefined') return null\n const p = createDOMPurify(\n window as unknown as Parameters<typeof createDOMPurify>[0],\n )\n // ALLOWED_URI_REGEXP can't be used to restrict href/xlink:href without also\n // killing geometry attrs like cx/cy/r (DOMPurify applies the URI regex to\n // every non-URI-safe attribute value). A scoped hook on this DOMPurify\n // instance lets us reject non-fragment href values without touching the\n // global DOMPurify state — important for consumers who use DOMPurify\n // elsewhere in their app.\n p.addHook('uponSanitizeAttribute', (_node, ev) => {\n if (ev.attrName === 'href' || ev.attrName === 'xlink:href') {\n const v = typeof ev.attrValue === 'string' ? ev.attrValue : ''\n if (!v.startsWith('#')) ev.keepAttr = false\n }\n })\n purifierCache = p\n return p\n}\n\n// DOMPurify's string-mode sanitize parses input as HTML, which silently\n// drops case-sensitive SVG attributes (viewBox, preserveAspectRatio). Parse\n// with image/svg+xml first and sanitize in place to keep the SVG-namespace\n// context and attribute case. svg-to-react.ts converts the returned root to\n// React nodes from this same DOM — no serialize/re-parse round-trip.\nexport function sanitizeSvgRoot(svgText: string): SVGSVGElement | null {\n if (typeof DOMParser === 'undefined') return null\n const purifier = getPurifier()\n if (!purifier) return null\n const doc = new DOMParser().parseFromString(svgText, 'image/svg+xml')\n const root = doc.documentElement\n if (root.nodeName !== 'svg') return null\n purifier.sanitize(root, {\n USE_PROFILES: { svg: true, svgFilters: true },\n FORBID_TAGS,\n IN_PLACE: true,\n })\n return root as unknown as SVGSVGElement\n}\n\nexport function sanitizeSvg(svgText: string): string {\n const root = sanitizeSvgRoot(svgText)\n if (!root) return ''\n return new XMLSerializer().serializeToString(root)\n}\n","// Single source of truth for converting SVG markup attributes into their\n// React equivalents. Two adapters sit on this interface: the build pipeline\n// (scripts/svg-to-jsx.ts emits JSX strings for generated components) and the\n// runtime network fallback (svg-to-react.ts builds React nodes from fetched\n// SVGs). Sharing the rule guarantees an icon renders identically whether it\n// shipped in the bundle or arrived over the wire.\n\nexport function toReactAttributeName(name: string): string {\n if (name === 'class') return 'className'\n if (name.startsWith('aria-') || name.startsWith('data-')) return name\n return name.replace(/[:-]([a-z])/g, (_, letter: string) =>\n letter.toUpperCase(),\n )\n}\n\nexport function styleStringToObject(style: string): Record<string, string> {\n const result: Record<string, string> = {}\n for (const rule of style.split(';')) {\n const [rawProperty, ...rawValue] = rule.split(':')\n const property = rawProperty?.trim()\n const value = rawValue.join(':').trim()\n if (!property || !value) continue\n const reactProperty = property.replace(/-([a-z])/g, (_, letter: string) =>\n letter.toUpperCase(),\n )\n result[reactProperty] = value\n }\n return result\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/work/icons/icons/packages/react/dist/github-fallback-WEXDJI4H.cjs","../src/github-fallback.tsx","../src/svg-to-react.ts","../src/sanitize-svg.ts","../src/svg-attributes.ts"],"names":[],"mappings":"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","file":"/home/runner/work/icons/icons/packages/react/dist/github-fallback-WEXDJI4H.cjs","sourcesContent":[null,"import { useEffect, useMemo, useState } from 'react'\nimport type { ReactNode, SVGProps } from 'react'\nimport { resolve } from '@smbdy/icons/resolve'\nimport { useIconConfig } from './icon-provider'\nimport { svgTextToReact } from './svg-to-react'\nimport type { SvgReactContent } from './svg-to-react'\nimport type { IconType } from './types'\n\n// Module-level SVG cache, keyed by URL. null = negative cache (tried & failed).\ninterface CacheEntry {\n value: string | null\n ts: number\n}\n\nconst svgCache = new Map<string, CacheEntry>()\nconst cacheOrder: string[] = []\nconst MAX_CACHE = 200\nconst NEGATIVE_CACHE_TTL_MS = 60_000\nconst FETCH_TIMEOUT_MS = 8_000\n\nfunction cacheGet(url: string): string | null | undefined {\n const entry = svgCache.get(url)\n if (entry === undefined) return undefined\n // Successful entries never expire (within LRU window)\n if (entry.value !== null) return entry.value\n // Negative entries expire after TTL\n if (Date.now() - entry.ts > NEGATIVE_CACHE_TTL_MS) {\n svgCache.delete(url)\n const idx = cacheOrder.indexOf(url)\n if (idx !== -1) cacheOrder.splice(idx, 1)\n return undefined\n }\n return null\n}\n\nfunction cacheSet(url: string, value: string | null) {\n if (!svgCache.has(url)) {\n cacheOrder.push(url)\n if (cacheOrder.length > MAX_CACHE) {\n const evict = cacheOrder.shift()!\n svgCache.delete(evict)\n }\n }\n svgCache.set(url, { value, ts: Date.now() })\n}\n\ntype AssetType = 'tokens' | 'chains' | 'brands'\n\nfunction toAssetType(type: IconType): AssetType {\n if (type === 'token') return 'tokens'\n if (type === 'chain') return 'chains'\n return 'brands'\n}\n\nfunction inferType(id: string, explicitType?: IconType): AssetType | null {\n if (explicitType) return toAssetType(explicitType)\n // Ask the resolution module (token-first per ADR-0001) rather than\n // probing the metadata maps per type.\n const hit = resolve(id)\n return hit ? toAssetType(hit.type) : null\n}\n\nfunction buildUrl(\n baseUrl: string,\n branch: string,\n type: AssetType,\n id: string,\n variant: string,\n): string {\n return `${baseUrl}/${branch}/assets/${type}/${id}_${variant}.svg`\n}\n\nasync function fetchSvg(\n url: string,\n signal: AbortSignal,\n): Promise<string | null> {\n const cached = cacheGet(url)\n if (cached !== undefined) return cached\n\n try {\n const res = await fetch(url, { signal })\n if (!res.ok) {\n cacheSet(url, null)\n return null\n }\n const text = await res.text()\n cacheSet(url, text)\n return text\n } catch {\n if (!signal.aborted) cacheSet(url, null)\n return null\n }\n}\n\nasync function resolveSvg(\n baseUrl: string,\n branch: string,\n id: string,\n explicitType: IconType | undefined,\n variant: string,\n signal: AbortSignal,\n): Promise<string | null> {\n const type = inferType(id, explicitType)\n\n if (type) {\n return fetchSvg(buildUrl(baseUrl, branch, type, id, variant), signal)\n }\n\n // Unknown type — probe all three and keep token-first result ordering.\n const types: AssetType[] = ['tokens', 'chains', 'brands']\n const results = await Promise.all(\n types.map((t) =>\n fetchSvg(buildUrl(baseUrl, branch, t, id, variant), signal),\n ),\n )\n return results.find((result) => result !== null) ?? null\n}\n\nexport interface GithubFallbackProps extends SVGProps<SVGSVGElement> {\n id: string\n iconType?: IconType\n variant: 'full' | 'mono'\n size?: number | string\n fallback?: ReactNode\n}\n\ninterface FallbackState {\n key: string\n content: SvgReactContent | null\n failed: boolean\n}\n\nfunction getCachedContent(\n baseUrl: string,\n branch: string,\n explicitType: IconType | undefined,\n id: string,\n variant: string,\n): SvgReactContent | null {\n const type = inferType(id, explicitType)\n if (!type) return null\n const cached = cacheGet(buildUrl(baseUrl, branch, type, id, variant))\n return typeof cached === 'string' ? svgTextToReact(cached) : null\n}\n\nexport function GithubFallback({\n id,\n iconType,\n variant,\n size = 32,\n fallback,\n ...props\n}: GithubFallbackProps) {\n const { baseUrl, branch } = useIconConfig()\n const requestKey = `${baseUrl}|${branch}|${iconType ?? 'auto'}|${id}|${variant}`\n const cachedContent = useMemo(\n () => getCachedContent(baseUrl, branch, iconType, id, variant),\n [baseUrl, branch, iconType, id, variant],\n )\n const [state, setState] = useState<FallbackState>(() => ({\n key: requestKey,\n content: cachedContent,\n failed: false,\n }))\n const currentState =\n state.key === requestKey\n ? state\n : {\n key: requestKey,\n content: cachedContent,\n failed: false,\n }\n\n useEffect(() => {\n if (currentState.content || currentState.failed) return\n\n const ac = new AbortController()\n const timer = setTimeout(() => ac.abort(), FETCH_TIMEOUT_MS)\n\n resolveSvg(baseUrl, branch, id, iconType, variant, ac.signal).then(\n (svgText) => {\n clearTimeout(timer)\n if (ac.signal.aborted) return\n setState(() => {\n if (!svgText) {\n return { key: requestKey, content: null, failed: true }\n }\n const content = svgTextToReact(svgText)\n return content\n ? { key: requestKey, content, failed: false }\n : { key: requestKey, content: null, failed: true }\n })\n },\n )\n\n return () => {\n clearTimeout(timer)\n ac.abort()\n }\n }, [\n baseUrl,\n branch,\n currentState.failed,\n currentState.content,\n id,\n requestKey,\n iconType,\n variant,\n ])\n\n if (currentState.failed) return <>{fallback ?? null}</>\n if (!currentState.content) return <>{fallback ?? null}</>\n\n const monoProps = variant === 'mono' ? { fill: 'currentColor' } : {}\n\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox={currentState.content.viewBox}\n role=\"img\"\n aria-label={id}\n {...monoProps}\n {...props}\n >\n {currentState.content.node}\n </svg>\n )\n}\n","import { createElement } from 'react'\nimport type { ReactNode } from 'react'\nimport { sanitizeSvgRoot } from './sanitize-svg'\nimport { styleStringToObject, toReactAttributeName } from './svg-attributes'\n\nexport interface SvgReactContent {\n node: ReactNode\n viewBox: string\n}\n\nfunction svgNodeToReact(node: ChildNode, key: string): ReactNode {\n if (node.nodeType === Node.TEXT_NODE) return node.textContent\n if (node.nodeType !== Node.ELEMENT_NODE) return null\n\n const element = node as Element\n const props: Record<string, unknown> = { key }\n for (const attr of Array.from(element.attributes)) {\n const attrName = toReactAttributeName(attr.name)\n props[attrName] =\n attr.name === 'style' ? styleStringToObject(attr.value) : attr.value\n }\n\n const children = Array.from(element.childNodes)\n .map((child, index) => svgNodeToReact(child, `${key}-${index}`))\n .filter((child) => child !== null)\n\n return createElement(element.tagName, props, ...children)\n}\n\n/**\n * Sanitize an SVG string and convert its children to React nodes in one\n * pass over a single parsed DOM. Returns the converted children and the\n * root's viewBox; the caller renders its own `<svg>` wrapper so it controls\n * sizing and accessibility attributes.\n *\n * Returns null when the input is not a parseable `<svg>` document (or when\n * no DOM is available, e.g. during SSR).\n */\nexport function svgTextToReact(svgText: string): SvgReactContent | null {\n const root = sanitizeSvgRoot(svgText)\n if (!root) return null\n const viewBox = root.getAttribute('viewBox') ?? '0 0 32 32'\n const node = Array.from(root.childNodes)\n .map((child, index) => svgNodeToReact(child, String(index)))\n .filter((child) => child !== null)\n return { node, viewBox }\n}\n","import createDOMPurify from 'dompurify'\nimport type { DOMPurify } from 'dompurify'\n\n// `<use>` and `<script>` are blocked by DOMPurify's SVG profile already\n// (svgDisallowed in the upstream source); listing them here is defense in\n// depth in case a future profile change relaxes that.\nconst FORBID_TAGS = ['script', 'foreignObject', 'text', 'image', 'style']\n\nlet purifierCache: DOMPurify | null = null\n\nfunction getPurifier(): DOMPurify | null {\n if (purifierCache) return purifierCache\n if (typeof window === 'undefined') return null\n const p = createDOMPurify(\n window as unknown as Parameters<typeof createDOMPurify>[0],\n )\n // ALLOWED_URI_REGEXP can't be used to restrict href/xlink:href without also\n // killing geometry attrs like cx/cy/r (DOMPurify applies the URI regex to\n // every non-URI-safe attribute value). A scoped hook on this DOMPurify\n // instance lets us reject non-fragment href values without touching the\n // global DOMPurify state — important for consumers who use DOMPurify\n // elsewhere in their app.\n p.addHook('uponSanitizeAttribute', (_node, ev) => {\n if (ev.attrName === 'href' || ev.attrName === 'xlink:href') {\n const v = typeof ev.attrValue === 'string' ? ev.attrValue : ''\n if (!v.startsWith('#')) ev.keepAttr = false\n }\n })\n purifierCache = p\n return p\n}\n\n// DOMPurify's string-mode sanitize parses input as HTML, which silently\n// drops case-sensitive SVG attributes (viewBox, preserveAspectRatio). Parse\n// with image/svg+xml first and sanitize in place to keep the SVG-namespace\n// context and attribute case. svg-to-react.ts converts the returned root to\n// React nodes from this same DOM — no serialize/re-parse round-trip.\nexport function sanitizeSvgRoot(svgText: string): SVGSVGElement | null {\n if (typeof DOMParser === 'undefined') return null\n const purifier = getPurifier()\n if (!purifier) return null\n const doc = new DOMParser().parseFromString(svgText, 'image/svg+xml')\n const root = doc.documentElement\n if (root.nodeName !== 'svg') return null\n purifier.sanitize(root, {\n USE_PROFILES: { svg: true, svgFilters: true },\n FORBID_TAGS,\n IN_PLACE: true,\n })\n return root as unknown as SVGSVGElement\n}\n\nexport function sanitizeSvg(svgText: string): string {\n const root = sanitizeSvgRoot(svgText)\n if (!root) return ''\n return new XMLSerializer().serializeToString(root)\n}\n","// Single source of truth for converting SVG markup attributes into their\n// React equivalents. Two adapters sit on this interface: the build pipeline\n// (scripts/svg-to-jsx.ts emits JSX strings for generated components) and the\n// runtime network fallback (svg-to-react.ts builds React nodes from fetched\n// SVGs). Sharing the rule guarantees an icon renders identically whether it\n// shipped in the bundle or arrived over the wire.\n\nexport function toReactAttributeName(name: string): string {\n if (name === 'class') return 'className'\n if (name.startsWith('aria-') || name.startsWith('data-')) return name\n return name.replace(/[:-]([a-z])/g, (_, letter: string) =>\n letter.toUpperCase(),\n )\n}\n\nexport function styleStringToObject(style: string): Record<string, string> {\n const result: Record<string, string> = {}\n for (const rule of style.split(';')) {\n const [rawProperty, ...rawValue] = rule.split(':')\n const property = rawProperty?.trim()\n const value = rawValue.join(':').trim()\n if (!property || !value) continue\n const reactProperty = property.replace(/-([a-z])/g, (_, letter: string) =>\n letter.toUpperCase(),\n )\n result[reactProperty] = value\n }\n return result\n}\n"]}