@ai-matrx/icons 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.1 — 2026-08-29
4
+
5
+ - `getIconWithColorAndSize`: a hex color rendered a literal `null` token in the
6
+ className (the faithful-port quirk recorded at 0.1.0); hex colors now color
7
+ via inline style — the behavior the code's own comment always described —
8
+ and the class list never contains `null`.
9
+ - `IconResolver`'s load effect now cancels on unmount / icon change: a slow
10
+ dynamic import can no longer set state on a dead effect or clobber a newer
11
+ icon's resolution.
12
+ - All module-level mutable state moved to `globalThis` `Symbol.for` slots
13
+ (`ai-matrx.icons.svg-registry`, `.custom-icon-cache`, `.dynamic-icon-cache`):
14
+ with dual ESM/CJS unsplit bundles, per-module state silently splits across
15
+ loader graphs — a host's `registerSvgIcons` call could be invisible to a
16
+ consumer resolving through the other graph.
17
+
3
18
  ## 0.1.0 — 2026-08-28
4
19
 
5
20
  - Created the package, ported verbatim from the Matrx frontend icon system
package/dist/index.cjs CHANGED
@@ -236,7 +236,16 @@ var CUSTOM_ICON_SOURCES = {
236
236
  FcBusiness: "fc",
237
237
  FcSignature: "fc"
238
238
  };
239
- var customIconCache = {};
239
+ var CUSTOM_CACHE_SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.icons.custom-icon-cache");
240
+ var customIconCache = (() => {
241
+ const holder = globalThis;
242
+ let cache = holder[CUSTOM_CACHE_SLOT];
243
+ if (!cache) {
244
+ cache = {};
245
+ holder[CUSTOM_CACHE_SLOT] = cache;
246
+ }
247
+ return cache;
248
+ })();
240
249
  function isCustomIconName(name) {
241
250
  return Object.prototype.hasOwnProperty.call(CUSTOM_ICON_SOURCES, name);
242
251
  }
@@ -267,7 +276,16 @@ async function loadCustomIcon(name) {
267
276
  }
268
277
 
269
278
  // src/svg-registry.ts
270
- var svgIconRegistry = {};
279
+ var SVG_REGISTRY_SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.icons.svg-registry");
280
+ var svgIconRegistry = (() => {
281
+ const holder = globalThis;
282
+ let reg = holder[SVG_REGISTRY_SLOT];
283
+ if (!reg) {
284
+ reg = {};
285
+ holder[SVG_REGISTRY_SLOT] = reg;
286
+ }
287
+ return reg;
288
+ })();
271
289
  var SVG_PREFIX = "svg:";
272
290
  function registerSvgIcons(map) {
273
291
  for (const [rawId, path] of Object.entries(map)) {
@@ -360,7 +378,16 @@ function cn(...values) {
360
378
 
361
379
  // src/resolver.tsx
362
380
  var import_jsx_runtime = require("react/jsx-runtime");
363
- var dynamicIconCache = {};
381
+ var DYNAMIC_CACHE_SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.icons.dynamic-icon-cache");
382
+ var dynamicIconCache = (() => {
383
+ const holder = globalThis;
384
+ let cache = holder[DYNAMIC_CACHE_SLOT];
385
+ if (!cache) {
386
+ cache = {};
387
+ holder[DYNAMIC_CACHE_SLOT] = cache;
388
+ }
389
+ return cache;
390
+ })();
364
391
  function getCuratedIconIdsForPicker() {
365
392
  const set = /* @__PURE__ */ new Set();
366
393
  for (const k of Object.keys(staticLucideIconMap)) {
@@ -414,6 +441,7 @@ var IconResolver = ({
414
441
  const [DynamicIcon2, setDynamicIcon] = (0, import_react.useState)(null);
415
442
  const [isLoading, setIsLoading] = (0, import_react.useState)(false);
416
443
  (0, import_react.useEffect)(() => {
444
+ let cancelled = false;
417
445
  const loadIcon = async () => {
418
446
  if (!iconName) {
419
447
  setDynamicIcon(null);
@@ -443,6 +471,7 @@ var IconResolver = ({
443
471
  if (isCustomIconName(iconName)) {
444
472
  setIsLoading(true);
445
473
  const loaded = await loadCustomIcon(iconName);
474
+ if (cancelled) return;
446
475
  if (loaded) {
447
476
  setDynamicIcon(() => loaded);
448
477
  } else {
@@ -454,6 +483,7 @@ var IconResolver = ({
454
483
  setIsLoading(true);
455
484
  try {
456
485
  const iconModule = await import("lucide-react");
486
+ if (cancelled) return;
457
487
  const exported = iconModule[iconName];
458
488
  if (isLucideModuleIconExport(iconName, exported)) {
459
489
  const IconComponent2 = exported;
@@ -463,13 +493,17 @@ var IconResolver = ({
463
493
  setDynamicIcon(() => staticLucideIconMap[fallbackIcon] || import_lucide_react.Zap);
464
494
  }
465
495
  } catch (error) {
496
+ if (cancelled) return;
466
497
  console.warn(`Failed to load icon: ${iconName}`, error);
467
498
  setDynamicIcon(() => staticLucideIconMap[fallbackIcon] || import_lucide_react.Zap);
468
499
  } finally {
469
- setIsLoading(false);
500
+ if (!cancelled) setIsLoading(false);
470
501
  }
471
502
  };
472
503
  loadIcon();
504
+ return () => {
505
+ cancelled = true;
506
+ };
473
507
  }, [iconName, fallbackIcon]);
474
508
  if (svgSrc) {
475
509
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -554,7 +588,13 @@ var getTextColorClass = (color) => {
554
588
  var getIconWithColorAndSize = (iconName, color = "gray", size = 4) => {
555
589
  const IconComponent = getIconComponent(iconName);
556
590
  const colorClass = getTextColorClass(color);
557
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconComponent, { className: `h-${size} w-${size} ${colorClass}` });
591
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
592
+ IconComponent,
593
+ {
594
+ className: cn(`h-${size} w-${size}`, colorClass),
595
+ ...colorClass === null ? { style: { color } } : {}
596
+ }
597
+ );
558
598
  };
559
599
  var DynamicIcon = ({
560
600
  name,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/static-icons.ts","../src/custom-icons.ts","../src/svg-registry.ts","../src/lucide-name-normalize.ts","../src/lucide-module-icon.ts","../src/resolver.tsx","../src/cn.ts"],"sourcesContent":["export type { IconComponentType, IconRenderProps } from \"./types\";\nexport {\n staticLucideIconMap,\n extendStaticIcons,\n} from \"./static-icons\";\nexport {\n isCustomIconName,\n listCustomIconNames,\n loadCustomIcon,\n} from \"./custom-icons\";\nexport {\n registerSvgIcons,\n parseSvgIconPath,\n isSvgIconValue,\n listSvgIconValues,\n} from \"./svg-registry\";\nexport {\n extractLucideJsxIconName,\n kebabCaseToLucidePascalCase,\n collectLucideIconNameCandidates,\n} from \"./lucide-name-normalize\";\nexport { isLucideModuleIconExport } from \"./lucide-module-icon\";\nexport {\n default as IconResolver,\n type IconResolverProps,\n DynamicIcon,\n type DynamicIconProps,\n getIconComponent,\n renderIcon,\n getCuratedIconIdsForPicker,\n isIconRegisteredSync,\n isRegisteredOrLucideIconName,\n isHexColor,\n getTextColorClass,\n getIconWithColorAndSize,\n} from \"./resolver\";\n","// Statically import commonly used Lucide icons to reduce bundle size.\n// This curated hot set is the product: a hit here renders synchronously,\n// with zero dynamic-import latency and no fallback flash.\nimport {\n Zap,\n Home,\n User,\n Settings,\n Search,\n Bell,\n Menu,\n X,\n ChevronDown,\n ChevronUp,\n ChevronLeft,\n ChevronRight,\n Plus,\n Minus,\n Edit,\n Trash,\n Check,\n AlertCircle,\n Info,\n HelpCircle,\n Eye,\n EyeOff,\n Copy,\n Download,\n Upload,\n Save,\n MoreVertical,\n MoreHorizontal,\n Filter,\n SortAsc,\n SortDesc,\n Calendar,\n Clock,\n Mail,\n Phone,\n MapPin,\n Link,\n ExternalLink,\n File,\n Folder,\n Image,\n Video,\n Music,\n FileText,\n Database,\n Cloud,\n Server,\n Code,\n Terminal,\n Globe,\n Lock,\n Unlock,\n Shield,\n Key,\n LogIn,\n LogOut,\n UserPlus,\n Users,\n Star,\n Heart,\n Bookmark,\n Share,\n Send,\n MessageSquare,\n MessageCircle,\n Hash,\n AtSign,\n Paperclip,\n Mic,\n Volume2,\n Play,\n Pause,\n SkipForward,\n SkipBack,\n RefreshCw,\n RotateCw,\n Loader,\n Loader2,\n Circle,\n Square,\n Triangle,\n Hexagon,\n Package,\n Box,\n Archive,\n Inbox,\n Layers,\n Layout,\n Grid,\n List,\n Columns,\n Sidebar,\n Maximize,\n Minimize,\n ZoomIn,\n ZoomOut,\n Move,\n Scissors,\n Clipboard,\n PieChart,\n BarChart,\n TrendingUp,\n TrendingDown,\n Activity,\n Cpu,\n HardDrive,\n Wifi,\n WifiOff,\n Bluetooth,\n Battery,\n BatteryCharging,\n Power,\n Sun,\n Moon,\n CloudRain,\n Droplet,\n Wind,\n Tag,\n Tags,\n Flag,\n Award,\n Gift,\n ShoppingCart,\n CreditCard,\n DollarSign,\n Percent,\n Target,\n Crosshair,\n Navigation,\n Compass,\n Map,\n Smile,\n Frown,\n Meh,\n ThumbsUp,\n ThumbsDown,\n} from \"lucide-react\";\nimport type { IconComponentType } from \"./types\";\n\nexport { Zap as fallbackZapIcon };\n\n// Statically imported Lucide icons map (commonly used icons for optimal bundle size)\n// Exported so callers can spread it as a scope without importing the full lucide namespace.\nexport const staticLucideIconMap: Record<string, IconComponentType> = {\n Zap,\n Home,\n User,\n Settings,\n Search,\n Bell,\n Menu,\n X,\n ChevronDown,\n ChevronUp,\n ChevronLeft,\n ChevronRight,\n Plus,\n Minus,\n Edit,\n Trash,\n Check,\n AlertCircle,\n Info,\n HelpCircle,\n Eye,\n EyeOff,\n Copy,\n Download,\n Upload,\n Save,\n MoreVertical,\n MoreHorizontal,\n Filter,\n SortAsc,\n SortDesc,\n Calendar,\n Clock,\n Mail,\n Phone,\n MapPin,\n Link,\n ExternalLink,\n File,\n Folder,\n Image,\n Video,\n Music,\n FileText,\n Database,\n Cloud,\n Server,\n Code,\n Terminal,\n Globe,\n Lock,\n Unlock,\n Shield,\n Key,\n LogIn,\n LogOut,\n UserPlus,\n Users,\n Star,\n Heart,\n Bookmark,\n Share,\n Send,\n MessageSquare,\n MessageCircle,\n Hash,\n AtSign,\n Paperclip,\n Mic,\n Volume2,\n Play,\n Pause,\n SkipForward,\n SkipBack,\n RefreshCw,\n RotateCw,\n Loader,\n Loader2,\n Circle,\n Square,\n Triangle,\n Hexagon,\n Package,\n Box,\n Archive,\n Inbox,\n Layers,\n Layout,\n Grid,\n List,\n Columns,\n Sidebar,\n Maximize,\n Minimize,\n ZoomIn,\n ZoomOut,\n Move,\n Scissors,\n Clipboard,\n PieChart,\n BarChart,\n TrendingUp,\n TrendingDown,\n Activity,\n Cpu,\n HardDrive,\n Wifi,\n WifiOff,\n Bluetooth,\n Battery,\n BatteryCharging,\n Power,\n Sun,\n Moon,\n CloudRain,\n Droplet,\n Wind,\n Tag,\n Tags,\n Flag,\n Award,\n Gift,\n ShoppingCart,\n CreditCard,\n DollarSign,\n Percent,\n Target,\n Crosshair,\n Navigation,\n Compass,\n Map,\n Smile,\n Frown,\n Meh,\n ThumbsUp,\n ThumbsDown,\n};\n\n/**\n * Extend the static (synchronous, zero-latency) icon map with host-supplied\n * components — extra statically imported Lucide icons a host uses on hot paths,\n * or any component matching {@link IconComponentType}. Merges in place; later\n * registrations override earlier entries of the same name.\n */\nexport function extendStaticIcons(map: Record<string, IconComponentType>): void {\n Object.assign(staticLucideIconMap, map);\n}\n","/**\n * Curated brand/custom icon names served from the OPTIONAL `react-icons` peer.\n *\n * Coupling inversion vs. the original (which statically imported react-icons):\n * `react-icons` is an optional peerDependency, so these are lazy-imported on first\n * use and cached at module level. When the host has not installed `react-icons`,\n * loading degrades to null and the resolver renders the fallback icon instead —\n * no install-time or import-time failure.\n */\nimport type { IconComponentType } from \"./types\";\n\n/** name → react-icons subpackage the export lives in. */\nconst CUSTOM_ICON_SOURCES: Record<string, \"fc\" | \"fa6\"> = {\n FaBrave: \"fa6\",\n FcGoogle: \"fc\",\n FcBrokenLink: \"fc\",\n FcFilm: \"fc\",\n FcDownload: \"fc\",\n FcBiotech: \"fc\",\n FcElectronics: \"fc\",\n FcGraduationCap: \"fc\",\n FcLibrary: \"fc\",\n FcMusic: \"fc\",\n FcParallelTasks: \"fc\",\n FcSalesPerformance: \"fc\",\n FcCalendar: \"fc\",\n FcDocument: \"fc\",\n FcEngineering: \"fc\",\n FcDataProtection: \"fc\",\n FcAssistant: \"fc\",\n FcSms: \"fc\",\n FcTodoList: \"fc\",\n FcWikipedia: \"fc\",\n FcCommandLine: \"fc\",\n FcConferenceCall: \"fc\",\n FcManager: \"fc\",\n FcAreaChart: \"fc\",\n FcMultipleInputs: \"fc\",\n FcShipped: \"fc\",\n FcBusinessContact: \"fc\",\n FcAlphabeticalSortingAz: \"fc\",\n FcAlphabeticalSortingZa: \"fc\",\n FcFeedback: \"fc\",\n FcBusiness: \"fc\",\n FcSignature: \"fc\",\n};\n\n/** Cache for lazily loaded custom icons (also the sync-lookup source once loaded). */\nexport const customIconCache: Record<string, IconComponentType> = {};\n\n/** True when `name` is one of the curated custom (react-icons) ids. */\nexport function isCustomIconName(name: string): boolean {\n return Object.prototype.hasOwnProperty.call(CUSTOM_ICON_SOURCES, name);\n}\n\n/** The curated custom icon ids (known without loading react-icons). */\nexport function listCustomIconNames(): string[] {\n return Object.keys(CUSTOM_ICON_SOURCES);\n}\n\n/**\n * Lazy-load a curated custom icon from the optional `react-icons` peer.\n * Returns null for unknown names, a missing export, or when `react-icons`\n * is not installed — the caller degrades to the fallback icon.\n */\nexport async function loadCustomIcon(\n name: string,\n): Promise<IconComponentType | null> {\n const cached = customIconCache[name];\n if (cached) {\n return cached;\n }\n const source = CUSTOM_ICON_SOURCES[name];\n if (!source) {\n return null;\n }\n try {\n const mod: Record<string, unknown> =\n source === \"fc\"\n ? await import(\"react-icons/fc\")\n : await import(\"react-icons/fa6\");\n const exported = mod[name];\n if (typeof exported !== \"function\") {\n return null;\n }\n const IconComponent = exported as IconComponentType;\n customIconCache[name] = IconComponent;\n return IconComponent;\n } catch {\n // react-icons not installed (optional peer) — degrade to the fallback icon.\n return null;\n }\n}\n","/**\n * Injectable registry for host-owned SVG assets. Stored icon ids use the form\n * `svg:<path-without-leading-slash-and-without-extension>` e.g. `svg:icons/Home`\n * → whatever URL the host registered for the id `icons/Home` (typically `/icons/Home.svg`).\n *\n * The package ships EMPTY — the host application registers its own asset paths once at\n * startup via {@link registerSvgIcons}. An unregistered `svg:` value resolves to null\n * and the resolver falls back exactly as it does for an unknown Lucide name.\n */\nconst svgIconRegistry: Record<string, string> = {};\n\nconst SVG_PREFIX = \"svg:\";\n\n/**\n * Register (or override) `svg:` icon ids → asset URLs. Merges into the module-level\n * registry, so multiple calls compose. Ids are stored without the `svg:` prefix.\n */\nexport function registerSvgIcons(map: Record<string, string>): void {\n for (const [rawId, path] of Object.entries(map)) {\n const id = rawId.startsWith(SVG_PREFIX)\n ? rawId.slice(SVG_PREFIX.length).replace(/^\\/+/, \"\")\n : rawId.replace(/^\\/+/, \"\");\n if (id && path) {\n svgIconRegistry[id] = path;\n }\n }\n}\n\n/** The registered asset URL for a `svg:…` icon value, or null when not a registered svg icon. */\nexport function parseSvgIconPath(value: string): string | null {\n if (!value.startsWith(SVG_PREFIX)) {\n return null;\n }\n const id = value.slice(SVG_PREFIX.length).replace(/^\\/+/, \"\");\n const path = svgIconRegistry[id];\n return path ?? null;\n}\n\n/** True if `value` is a `svg:…` id with a registered asset path. */\nexport function isSvgIconValue(value: string | null | undefined): boolean {\n if (!value || !value.startsWith(SVG_PREFIX)) {\n return false;\n }\n const id = value.slice(SVG_PREFIX.length).replace(/^\\/+/, \"\");\n return Boolean(svgIconRegistry[id]);\n}\n\n/** Every registered svg icon value, `svg:` prefix included (for pickers/galleries). */\nexport function listSvgIconValues(): string[] {\n return Object.keys(svgIconRegistry).map((id) => `${SVG_PREFIX}${id}`);\n}\n","/**\n * Lucide.dev lists icons in kebab-case (e.g. `alarm-clock`); the React package\n * exports PascalCase (`AlarmClock`). Normalize pasted / typed names into candidates\n * to validate against `lucide-react` exports.\n */\n\n/**\n * If the user pasted Lucide's JSX snippet (e.g. `'<BugPlay />'` or `<AlignCenterHorizontal />`),\n * return the component name only. Otherwise return null.\n *\n * Supports optional outer quotes and optional attributes before the closing `/>`.\n */\nexport function extractLucideJsxIconName(raw: string): string | null {\n let s = raw.trim();\n if (!s) return null;\n if (\n (s.startsWith(\"'\") && s.endsWith(\"'\") && s.length >= 2) ||\n (s.startsWith('\"') && s.endsWith('\"') && s.length >= 2)\n ) {\n s = s.slice(1, -1).trim();\n }\n const m = s.match(/^<\\s*([A-Za-z][A-Za-z0-9]*)(?:\\s[^>]*)?\\s*\\/\\s*>$/);\n return m?.[1] ?? null;\n}\n\n/** `alarm-clock` → `AlarmClock`, `a-arrow-down` → `AArrowDown` */\nexport function kebabCaseToLucidePascalCase(raw: string): string {\n const s = raw.trim();\n if (!s.includes(\"-\")) {\n return s;\n }\n return s\n .split(\"-\")\n .filter(Boolean)\n .map((seg) => seg.charAt(0).toUpperCase() + seg.slice(1).toLowerCase())\n .join(\"\");\n}\n\n/**\n * Ordered unique candidates: exact input, first-letter fix, kebab → Pascal variants.\n * Skip Lucide heuristics for `svg:…` asset values (caller should pass only those as `[trimmed]`).\n */\nexport function collectLucideIconNameCandidates(raw: string): string[] {\n const t = raw.trim();\n if (!t) {\n return [];\n }\n\n const out: string[] = [];\n const push = (s: string) => {\n if (s && !out.includes(s)) {\n out.push(s);\n }\n };\n\n push(t);\n\n if (t[0] === t[0]!.toLowerCase()) {\n push(t.charAt(0).toUpperCase() + t.slice(1));\n }\n\n if (t.includes(\"-\")) {\n push(kebabCaseToLucidePascalCase(t));\n const lower = t.toLowerCase();\n if (lower !== t) {\n push(kebabCaseToLucidePascalCase(lower));\n }\n }\n\n return out;\n}\n","/**\n * lucide-react namespaced exports: icons are ForwardRef/Memo objects in current builds,\n * not plain functions. Only createLucideIcon and default are non-icon exports we skip.\n */\nconst LUCIDE_NAMESPACE_DENYLIST = new Set([\"default\", \"createLucideIcon\"]);\n\n/**\n * True if `exported` is the value of a Lucide icon entry for `name` in `import * as Lucide`.\n * Does not mean the icon exists in the static resolver map — only that the lucide-react\n * module exposes this name as a renderable component type.\n */\nexport function isLucideModuleIconExport(\n name: string,\n exported: unknown,\n): boolean {\n if (!name || LUCIDE_NAMESPACE_DENYLIST.has(name)) return false;\n if (exported == null) return false;\n if (typeof exported === \"function\") return true;\n if (typeof exported === \"object\" && \"$$typeof\" in (exported as object)) {\n return true;\n }\n return false;\n}\n","\"use client\";\n\nimport React, { useState, useEffect } from \"react\";\nimport { cn } from \"./cn\";\nimport {\n staticLucideIconMap,\n fallbackZapIcon as Zap,\n} from \"./static-icons\";\nimport {\n customIconCache,\n isCustomIconName,\n listCustomIconNames,\n loadCustomIcon,\n} from \"./custom-icons\";\nimport { isLucideModuleIconExport } from \"./lucide-module-icon\";\nimport {\n isSvgIconValue,\n listSvgIconValues,\n parseSvgIconPath,\n} from \"./svg-registry\";\nimport type { IconComponentType, IconRenderProps } from \"./types\";\n\n// Cache for dynamically loaded icons to prevent re-importing\nconst dynamicIconCache: Record<string, IconComponentType> = {};\n\n/**\n * Finite list for a curated icon gallery: every statically bundled Lucide name,\n * curated custom ids (react-icons), and all registered `svg:…` assets.\n */\nexport function getCuratedIconIdsForPicker(): string[] {\n const set = new Set<string>();\n for (const k of Object.keys(staticLucideIconMap)) {\n set.add(k);\n }\n for (const k of listCustomIconNames()) {\n set.add(k);\n }\n for (const id of listSvgIconValues()) {\n set.add(id);\n }\n return Array.from(set).sort((a, b) =>\n a.localeCompare(b, undefined, { sensitivity: \"base\" }),\n );\n}\n\n/**\n * True if this exact name maps to a known icon (static Lucide, curated custom id, or\n * previously resolved dynamic Lucide cached under this key).\n *\n * Does not import lucide-react — use with {@link isRegisteredOrLucideIconName} for full checks.\n */\nexport function isIconRegisteredSync(\n iconName: string | null | undefined,\n): boolean {\n if (!iconName || iconName.trim() === \"\") {\n return false;\n }\n const name = iconName;\n if (isCustomIconName(name)) return true;\n if (staticLucideIconMap[name]) return true;\n return Boolean(dynamicIconCache[name]);\n}\n\n/**\n * True if `iconName` is a real icon id: custom/static/cached, a registered `svg:…`\n * asset, or a Lucide export that is a renderable component (not the fallback Zap).\n *\n * Prefer this over truthiness on {@link getIconComponent}, which always returns a component.\n */\nexport async function isRegisteredOrLucideIconName(\n iconName: string | null | undefined,\n): Promise<boolean> {\n if (!iconName || iconName.trim() === \"\") {\n return false;\n }\n if (isSvgIconValue(iconName)) {\n return true;\n }\n if (isIconRegisteredSync(iconName)) {\n return true;\n }\n try {\n const iconModule = await import(\"lucide-react\");\n const Exported = iconModule[iconName as keyof typeof iconModule];\n return isLucideModuleIconExport(iconName, Exported);\n } catch {\n return false;\n }\n}\n\n/**\n * HOW TO ADD MORE STATIC ICONS:\n *\n * The curated hot set ships in the package (src/static-icons.ts). A host that\n * frequently renders an icon outside the set keeps it zero-latency by statically\n * importing it and registering it once at startup:\n *\n * import { YourIcon } from \"lucide-react\";\n * import { extendStaticIcons } from \"@ai-matrx/icons\";\n * extendStaticIcons({ YourIcon });\n */\n\nexport interface IconResolverProps {\n iconName: string | null;\n className?: string | undefined;\n size?: number | undefined;\n fallbackIcon?: string | undefined;\n style?: React.CSSProperties | undefined;\n}\n\n/**\n * IconResolver - A unified component for resolving and rendering icons by name\n * Uses hybrid approach: static imports for common icons, dynamic imports for others\n * Supports all lucide-react icons, curated custom icons (optional react-icons peer),\n * and registered `svg:…` public assets.\n */\nconst IconResolver: React.FC<IconResolverProps> = ({\n iconName,\n className = \"h-4 w-4\",\n size,\n fallbackIcon = \"Zap\",\n style,\n}) => {\n const svgSrc = iconName ? parseSvgIconPath(iconName) : null;\n const [DynamicIcon, setDynamicIcon] = useState<IconComponentType | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n\n useEffect(() => {\n const loadIcon = async () => {\n if (!iconName) {\n setDynamicIcon(null);\n setIsLoading(false);\n return;\n }\n\n if (parseSvgIconPath(iconName)) {\n setDynamicIcon(null);\n setIsLoading(false);\n return;\n }\n\n // Check custom icons first (already-loaded cache hit is synchronous)\n const cachedCustom = customIconCache[iconName];\n if (cachedCustom) {\n setDynamicIcon(() => cachedCustom);\n return;\n }\n\n // Check statically imported Lucide icons\n const staticIcon = staticLucideIconMap[iconName];\n if (staticIcon) {\n setDynamicIcon(() => staticIcon);\n return;\n }\n\n // Check if already cached\n const cachedDynamic = dynamicIconCache[iconName];\n if (cachedDynamic) {\n setDynamicIcon(() => cachedDynamic);\n return;\n }\n\n // Curated custom icon: lazy-import the optional react-icons peer;\n // degrade to the fallback icon when it is absent.\n if (isCustomIconName(iconName)) {\n setIsLoading(true);\n const loaded = await loadCustomIcon(iconName);\n if (loaded) {\n setDynamicIcon(() => loaded);\n } else {\n setDynamicIcon(() => staticLucideIconMap[fallbackIcon] || Zap);\n }\n setIsLoading(false);\n return;\n }\n\n // Dynamically import from lucide-react\n setIsLoading(true);\n try {\n const iconModule = await import(\"lucide-react\");\n const exported: unknown = iconModule[iconName as keyof typeof iconModule];\n\n if (isLucideModuleIconExport(iconName, exported)) {\n const IconComponent = exported as IconComponentType;\n dynamicIconCache[iconName] = IconComponent;\n setDynamicIcon(() => IconComponent);\n } else {\n // Icon not found, use fallback\n setDynamicIcon(() => staticLucideIconMap[fallbackIcon] || Zap);\n }\n } catch (error) {\n console.warn(`Failed to load icon: ${iconName}`, error);\n setDynamicIcon(() => staticLucideIconMap[fallbackIcon] || Zap);\n } finally {\n setIsLoading(false);\n }\n };\n\n loadIcon();\n }, [iconName, fallbackIcon]);\n\n if (svgSrc) {\n return (\n <img\n src={svgSrc}\n alt=\"\"\n className={cn(\"object-contain shrink-0\", className)}\n width={size}\n height={size}\n style={style}\n />\n );\n }\n\n // Get the icon component to render\n const IconComponent = DynamicIcon || staticLucideIconMap[fallbackIcon] || Zap;\n\n // Build exact-optional props (never pass an explicit undefined through)\n const iconProps: IconRenderProps = {\n ...(className !== undefined ? { className } : {}),\n ...(size !== undefined ? { size } : {}),\n ...(style !== undefined ? { style } : {}),\n };\n\n // Show fallback while loading dynamic icons (seamless experience)\n if (isLoading && !DynamicIcon) {\n const FallbackIcon = staticLucideIconMap[fallbackIcon] || Zap;\n return <FallbackIcon {...iconProps} />;\n }\n\n return <IconComponent {...iconProps} />;\n};\n\nexport default IconResolver;\n\n/**\n * Synchronous utility function for getting icon components directly\n * Only works with statically imported icons plus already-loaded custom/dynamic icons.\n * For dynamic Lucide icons not in the static map, use the IconResolver component instead\n *\n * **Always returns a component** (default/fallback Zap when unknown). Do not use the return\n * value to infer whether `iconName` exists — use {@link isIconRegisteredSync} or\n * {@link isRegisteredOrLucideIconName} instead.\n */\nexport const getIconComponent = (\n iconName: string | null | undefined,\n fallbackIcon: string = \"Zap\",\n): IconComponentType => {\n if (!iconName) {\n return staticLucideIconMap[fallbackIcon] || Zap;\n }\n\n // First check custom icons (loaded lazily; a hit means it is already cached)\n const custom = customIconCache[iconName];\n if (custom) {\n return custom;\n }\n\n // Then check statically imported Lucide icons\n const staticIcon = staticLucideIconMap[iconName];\n if (staticIcon) {\n return staticIcon;\n }\n\n // Check dynamic cache\n const dynamic = dynamicIconCache[iconName];\n if (dynamic) {\n return dynamic;\n }\n\n // Fallback to default icon\n return staticLucideIconMap[fallbackIcon] || Zap;\n};\n\n/**\n * Renders an icon element directly with optional props\n * This is the preferred method for rendering icons in JSX\n */\nexport const renderIcon = (\n iconName: string | null | undefined,\n props?: IconRenderProps,\n fallbackIcon: string = \"Zap\",\n) => {\n const IconComponent = getIconComponent(iconName, fallbackIcon);\n return <IconComponent {...props} />;\n};\n\n/**\n * Utility to detect if a string is a hex color code\n */\nexport const isHexColor = (color: string): boolean => {\n return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(color);\n};\n\nexport const getTextColorClass = (color?: string) => {\n if (!color) return \"text-gray-600 dark:text-gray-400\";\n\n // If it's a hex color, return null (we'll use inline styles instead)\n if (isHexColor(color)) return null;\n\n const colorMap: Record<string, string> = {\n gray: \"text-gray-600 dark:text-gray-400\",\n rose: \"text-rose-600 dark:text-rose-400\",\n blue: \"text-blue-600 dark:text-blue-400\",\n amber: \"text-amber-600 dark:text-amber-400\",\n cyan: \"text-cyan-600 dark:text-cyan-400\",\n emerald: \"text-emerald-600 dark:text-emerald-400\",\n fuchsia: \"text-fuchsia-600 dark:text-fuchsia-400\",\n green: \"text-green-600 dark:text-green-400\",\n indigo: \"text-indigo-600 dark:text-indigo-400\",\n lime: \"text-lime-600 dark:text-lime-400\",\n neutral: \"text-neutral-600 dark:text-neutral-400\",\n orange: \"text-orange-600 dark:text-orange-400\",\n pink: \"text-pink-600 dark:text-pink-400\",\n purple: \"text-purple-600 dark:text-purple-400\",\n red: \"text-red-600 dark:text-red-400\",\n sky: \"text-sky-600 dark:text-sky-400\",\n slate: \"text-slate-600 dark:text-slate-400\",\n stone: \"text-stone-600 dark:text-stone-400\",\n teal: \"text-teal-600 dark:text-teal-400\",\n violet: \"text-violet-600 dark:text-violet-400\",\n yellow: \"text-yellow-600 dark:text-yellow-400\",\n zinc: \"text-zinc-600 dark:text-zinc-400\",\n };\n\n return colorMap[color.toLowerCase()] || \"text-gray-600 dark:text-gray-400\";\n};\n\n/**\n * Utility function for rendering an icon with color and size\n * Note: This is synchronous and only works with statically imported icons\n * For dynamic icons, use the DynamicIcon component instead\n */\nexport const getIconWithColorAndSize = (\n iconName: string | null,\n color: string = \"gray\",\n size: number = 4,\n) => {\n const IconComponent = getIconComponent(iconName);\n const colorClass = getTextColorClass(color);\n return <IconComponent className={`h-${size} w-${size} ${colorClass}`} />;\n};\n\n/**\n * Simple Icon component for direct usage with color and size support\n * Uses IconResolver internally to support both static and dynamic icons\n *\n * Supports both Tailwind color names (e.g., \"blue\", \"red\", \"zinc\") and hex colors (e.g., \"#ff0000\", \"#666\")\n */\nexport interface DynamicIconProps {\n name: string | null;\n color?: string | undefined;\n size?: number | undefined;\n className?: string | undefined;\n fallbackIcon?: string | undefined;\n}\n\nexport const DynamicIcon: React.FC<DynamicIconProps> = ({\n name,\n color = \"gray\",\n size = 4,\n className,\n fallbackIcon = \"Zap\",\n}) => {\n const isHex = color && isHexColor(color);\n const colorClass = isHex ? null : getTextColorClass(color);\n const sizeClass = `h-${size} w-${size}`;\n\n // Build className: always include size, include colorClass if not hex, include custom className\n const combinedClassName = [sizeClass, !isHex && colorClass, className]\n .filter(Boolean)\n .join(\" \")\n .trim();\n\n // If hex color, apply as inline style\n const style = isHex ? { color } : undefined;\n\n return (\n <IconResolver\n iconName={name}\n className={combinedClassName}\n fallbackIcon={fallbackIcon}\n style={style}\n />\n );\n};\n","/**\n * Minimal className join — the only piece of `cn` this package needs.\n * No tailwind-merge / clsx dependency by design: callers pass literal strings.\n */\nexport function cn(\n ...values: Array<string | null | undefined | false>\n): string {\n return values.filter(Boolean).join(\" \").trim();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACGA,0BAyIO;AAOA,IAAM,sBAAyD;AAAA,EACpE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AA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","names":["DynamicIcon","IconComponent"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/static-icons.ts","../src/custom-icons.ts","../src/svg-registry.ts","../src/lucide-name-normalize.ts","../src/lucide-module-icon.ts","../src/resolver.tsx","../src/cn.ts"],"sourcesContent":["export type { IconComponentType, IconRenderProps } from \"./types\";\nexport {\n staticLucideIconMap,\n extendStaticIcons,\n} from \"./static-icons\";\nexport {\n isCustomIconName,\n listCustomIconNames,\n loadCustomIcon,\n} from \"./custom-icons\";\nexport {\n registerSvgIcons,\n parseSvgIconPath,\n isSvgIconValue,\n listSvgIconValues,\n} from \"./svg-registry\";\nexport {\n extractLucideJsxIconName,\n kebabCaseToLucidePascalCase,\n collectLucideIconNameCandidates,\n} from \"./lucide-name-normalize\";\nexport { isLucideModuleIconExport } from \"./lucide-module-icon\";\nexport {\n default as IconResolver,\n type IconResolverProps,\n DynamicIcon,\n type DynamicIconProps,\n getIconComponent,\n renderIcon,\n getCuratedIconIdsForPicker,\n isIconRegisteredSync,\n isRegisteredOrLucideIconName,\n isHexColor,\n getTextColorClass,\n getIconWithColorAndSize,\n} from \"./resolver\";\n","// Statically import commonly used Lucide icons to reduce bundle size.\n// This curated hot set is the product: a hit here renders synchronously,\n// with zero dynamic-import latency and no fallback flash.\nimport {\n Zap,\n Home,\n User,\n Settings,\n Search,\n Bell,\n Menu,\n X,\n ChevronDown,\n ChevronUp,\n ChevronLeft,\n ChevronRight,\n Plus,\n Minus,\n Edit,\n Trash,\n Check,\n AlertCircle,\n Info,\n HelpCircle,\n Eye,\n EyeOff,\n Copy,\n Download,\n Upload,\n Save,\n MoreVertical,\n MoreHorizontal,\n Filter,\n SortAsc,\n SortDesc,\n Calendar,\n Clock,\n Mail,\n Phone,\n MapPin,\n Link,\n ExternalLink,\n File,\n Folder,\n Image,\n Video,\n Music,\n FileText,\n Database,\n Cloud,\n Server,\n Code,\n Terminal,\n Globe,\n Lock,\n Unlock,\n Shield,\n Key,\n LogIn,\n LogOut,\n UserPlus,\n Users,\n Star,\n Heart,\n Bookmark,\n Share,\n Send,\n MessageSquare,\n MessageCircle,\n Hash,\n AtSign,\n Paperclip,\n Mic,\n Volume2,\n Play,\n Pause,\n SkipForward,\n SkipBack,\n RefreshCw,\n RotateCw,\n Loader,\n Loader2,\n Circle,\n Square,\n Triangle,\n Hexagon,\n Package,\n Box,\n Archive,\n Inbox,\n Layers,\n Layout,\n Grid,\n List,\n Columns,\n Sidebar,\n Maximize,\n Minimize,\n ZoomIn,\n ZoomOut,\n Move,\n Scissors,\n Clipboard,\n PieChart,\n BarChart,\n TrendingUp,\n TrendingDown,\n Activity,\n Cpu,\n HardDrive,\n Wifi,\n WifiOff,\n Bluetooth,\n Battery,\n BatteryCharging,\n Power,\n Sun,\n Moon,\n CloudRain,\n Droplet,\n Wind,\n Tag,\n Tags,\n Flag,\n Award,\n Gift,\n ShoppingCart,\n CreditCard,\n DollarSign,\n Percent,\n Target,\n Crosshair,\n Navigation,\n Compass,\n Map,\n Smile,\n Frown,\n Meh,\n ThumbsUp,\n ThumbsDown,\n} from \"lucide-react\";\nimport type { IconComponentType } from \"./types\";\n\nexport { Zap as fallbackZapIcon };\n\n// Statically imported Lucide icons map (commonly used icons for optimal bundle size)\n// Exported so callers can spread it as a scope without importing the full lucide namespace.\nexport const staticLucideIconMap: Record<string, IconComponentType> = {\n Zap,\n Home,\n User,\n Settings,\n Search,\n Bell,\n Menu,\n X,\n ChevronDown,\n ChevronUp,\n ChevronLeft,\n ChevronRight,\n Plus,\n Minus,\n Edit,\n Trash,\n Check,\n AlertCircle,\n Info,\n HelpCircle,\n Eye,\n EyeOff,\n Copy,\n Download,\n Upload,\n Save,\n MoreVertical,\n MoreHorizontal,\n Filter,\n SortAsc,\n SortDesc,\n Calendar,\n Clock,\n Mail,\n Phone,\n MapPin,\n Link,\n ExternalLink,\n File,\n Folder,\n Image,\n Video,\n Music,\n FileText,\n Database,\n Cloud,\n Server,\n Code,\n Terminal,\n Globe,\n Lock,\n Unlock,\n Shield,\n Key,\n LogIn,\n LogOut,\n UserPlus,\n Users,\n Star,\n Heart,\n Bookmark,\n Share,\n Send,\n MessageSquare,\n MessageCircle,\n Hash,\n AtSign,\n Paperclip,\n Mic,\n Volume2,\n Play,\n Pause,\n SkipForward,\n SkipBack,\n RefreshCw,\n RotateCw,\n Loader,\n Loader2,\n Circle,\n Square,\n Triangle,\n Hexagon,\n Package,\n Box,\n Archive,\n Inbox,\n Layers,\n Layout,\n Grid,\n List,\n Columns,\n Sidebar,\n Maximize,\n Minimize,\n ZoomIn,\n ZoomOut,\n Move,\n Scissors,\n Clipboard,\n PieChart,\n BarChart,\n TrendingUp,\n TrendingDown,\n Activity,\n Cpu,\n HardDrive,\n Wifi,\n WifiOff,\n Bluetooth,\n Battery,\n BatteryCharging,\n Power,\n Sun,\n Moon,\n CloudRain,\n Droplet,\n Wind,\n Tag,\n Tags,\n Flag,\n Award,\n Gift,\n ShoppingCart,\n CreditCard,\n DollarSign,\n Percent,\n Target,\n Crosshair,\n Navigation,\n Compass,\n Map,\n Smile,\n Frown,\n Meh,\n ThumbsUp,\n ThumbsDown,\n};\n\n/**\n * Extend the static (synchronous, zero-latency) icon map with host-supplied\n * components — extra statically imported Lucide icons a host uses on hot paths,\n * or any component matching {@link IconComponentType}. Merges in place; later\n * registrations override earlier entries of the same name.\n */\nexport function extendStaticIcons(map: Record<string, IconComponentType>): void {\n Object.assign(staticLucideIconMap, map);\n}\n","/**\n * Curated brand/custom icon names served from the OPTIONAL `react-icons` peer.\n *\n * Coupling inversion vs. the original (which statically imported react-icons):\n * `react-icons` is an optional peerDependency, so these are lazy-imported on first\n * use and cached at module level. When the host has not installed `react-icons`,\n * loading degrades to null and the resolver renders the fallback icon instead —\n * no install-time or import-time failure.\n */\nimport type { IconComponentType } from \"./types\";\n\n/** name → react-icons subpackage the export lives in. */\nconst CUSTOM_ICON_SOURCES: Record<string, \"fc\" | \"fa6\"> = {\n FaBrave: \"fa6\",\n FcGoogle: \"fc\",\n FcBrokenLink: \"fc\",\n FcFilm: \"fc\",\n FcDownload: \"fc\",\n FcBiotech: \"fc\",\n FcElectronics: \"fc\",\n FcGraduationCap: \"fc\",\n FcLibrary: \"fc\",\n FcMusic: \"fc\",\n FcParallelTasks: \"fc\",\n FcSalesPerformance: \"fc\",\n FcCalendar: \"fc\",\n FcDocument: \"fc\",\n FcEngineering: \"fc\",\n FcDataProtection: \"fc\",\n FcAssistant: \"fc\",\n FcSms: \"fc\",\n FcTodoList: \"fc\",\n FcWikipedia: \"fc\",\n FcCommandLine: \"fc\",\n FcConferenceCall: \"fc\",\n FcManager: \"fc\",\n FcAreaChart: \"fc\",\n FcMultipleInputs: \"fc\",\n FcShipped: \"fc\",\n FcBusinessContact: \"fc\",\n FcAlphabeticalSortingAz: \"fc\",\n FcAlphabeticalSortingZa: \"fc\",\n FcFeedback: \"fc\",\n FcBusiness: \"fc\",\n FcSignature: \"fc\",\n};\n\n/**\n * Cache for lazily loaded custom icons (also the sync-lookup source once\n * loaded). Lives on a globalThis Symbol.for slot, NOT module state — dual\n * ESM/CJS unsplit bundles each instantiate their own module graph, and a\n * module-level cache would load the same icon once per graph and let a\n * sync lookup miss what the other graph already loaded. Never \"clean this up\".\n */\nconst CUSTOM_CACHE_SLOT = Symbol.for(\"ai-matrx.icons.custom-icon-cache\");\nexport const customIconCache: Record<string, IconComponentType> = (() => {\n const holder = globalThis as Record<\n symbol,\n Record<string, IconComponentType> | undefined\n >;\n let cache = holder[CUSTOM_CACHE_SLOT];\n if (!cache) {\n cache = {};\n holder[CUSTOM_CACHE_SLOT] = cache;\n }\n return cache;\n})();\n\n/** True when `name` is one of the curated custom (react-icons) ids. */\nexport function isCustomIconName(name: string): boolean {\n return Object.prototype.hasOwnProperty.call(CUSTOM_ICON_SOURCES, name);\n}\n\n/** The curated custom icon ids (known without loading react-icons). */\nexport function listCustomIconNames(): string[] {\n return Object.keys(CUSTOM_ICON_SOURCES);\n}\n\n/**\n * Lazy-load a curated custom icon from the optional `react-icons` peer.\n * Returns null for unknown names, a missing export, or when `react-icons`\n * is not installed — the caller degrades to the fallback icon.\n */\nexport async function loadCustomIcon(\n name: string,\n): Promise<IconComponentType | null> {\n const cached = customIconCache[name];\n if (cached) {\n return cached;\n }\n const source = CUSTOM_ICON_SOURCES[name];\n if (!source) {\n return null;\n }\n try {\n const mod: Record<string, unknown> =\n source === \"fc\"\n ? await import(\"react-icons/fc\")\n : await import(\"react-icons/fa6\");\n const exported = mod[name];\n if (typeof exported !== \"function\") {\n return null;\n }\n const IconComponent = exported as IconComponentType;\n customIconCache[name] = IconComponent;\n return IconComponent;\n } catch {\n // react-icons not installed (optional peer) — degrade to the fallback icon.\n return null;\n }\n}\n","/**\n * Injectable registry for host-owned SVG assets. Stored icon ids use the form\n * `svg:<path-without-leading-slash-and-without-extension>` e.g. `svg:icons/Home`\n * → whatever URL the host registered for the id `icons/Home` (typically `/icons/Home.svg`).\n *\n * The package ships EMPTY — the host application registers its own asset paths once at\n * startup via {@link registerSvgIcons}. An unregistered `svg:` value resolves to null\n * and the resolver falls back exactly as it does for an unknown Lucide name.\n */\n// The registry lives on a globalThis Symbol.for slot, NOT module state: with\n// dual ESM/CJS unsplit bundles each loader graph instantiates its own module,\n// and a module-level map would silently split the host's registrations from\n// a consumer resolving through the other graph. Never \"clean this up\".\nconst SVG_REGISTRY_SLOT = Symbol.for(\"ai-matrx.icons.svg-registry\");\nconst svgIconRegistry: Record<string, string> = (() => {\n const holder = globalThis as Record<symbol, Record<string, string> | undefined>;\n let reg = holder[SVG_REGISTRY_SLOT];\n if (!reg) {\n reg = {};\n holder[SVG_REGISTRY_SLOT] = reg;\n }\n return reg;\n})();\n\nconst SVG_PREFIX = \"svg:\";\n\n/**\n * Register (or override) `svg:` icon ids → asset URLs. Merges into the module-level\n * registry, so multiple calls compose. Ids are stored without the `svg:` prefix.\n */\nexport function registerSvgIcons(map: Record<string, string>): void {\n for (const [rawId, path] of Object.entries(map)) {\n const id = rawId.startsWith(SVG_PREFIX)\n ? rawId.slice(SVG_PREFIX.length).replace(/^\\/+/, \"\")\n : rawId.replace(/^\\/+/, \"\");\n if (id && path) {\n svgIconRegistry[id] = path;\n }\n }\n}\n\n/** The registered asset URL for a `svg:…` icon value, or null when not a registered svg icon. */\nexport function parseSvgIconPath(value: string): string | null {\n if (!value.startsWith(SVG_PREFIX)) {\n return null;\n }\n const id = value.slice(SVG_PREFIX.length).replace(/^\\/+/, \"\");\n const path = svgIconRegistry[id];\n return path ?? null;\n}\n\n/** True if `value` is a `svg:…` id with a registered asset path. */\nexport function isSvgIconValue(value: string | null | undefined): boolean {\n if (!value || !value.startsWith(SVG_PREFIX)) {\n return false;\n }\n const id = value.slice(SVG_PREFIX.length).replace(/^\\/+/, \"\");\n return Boolean(svgIconRegistry[id]);\n}\n\n/** Every registered svg icon value, `svg:` prefix included (for pickers/galleries). */\nexport function listSvgIconValues(): string[] {\n return Object.keys(svgIconRegistry).map((id) => `${SVG_PREFIX}${id}`);\n}\n","/**\n * Lucide.dev lists icons in kebab-case (e.g. `alarm-clock`); the React package\n * exports PascalCase (`AlarmClock`). Normalize pasted / typed names into candidates\n * to validate against `lucide-react` exports.\n */\n\n/**\n * If the user pasted Lucide's JSX snippet (e.g. `'<BugPlay />'` or `<AlignCenterHorizontal />`),\n * return the component name only. Otherwise return null.\n *\n * Supports optional outer quotes and optional attributes before the closing `/>`.\n */\nexport function extractLucideJsxIconName(raw: string): string | null {\n let s = raw.trim();\n if (!s) return null;\n if (\n (s.startsWith(\"'\") && s.endsWith(\"'\") && s.length >= 2) ||\n (s.startsWith('\"') && s.endsWith('\"') && s.length >= 2)\n ) {\n s = s.slice(1, -1).trim();\n }\n const m = s.match(/^<\\s*([A-Za-z][A-Za-z0-9]*)(?:\\s[^>]*)?\\s*\\/\\s*>$/);\n return m?.[1] ?? null;\n}\n\n/** `alarm-clock` → `AlarmClock`, `a-arrow-down` → `AArrowDown` */\nexport function kebabCaseToLucidePascalCase(raw: string): string {\n const s = raw.trim();\n if (!s.includes(\"-\")) {\n return s;\n }\n return s\n .split(\"-\")\n .filter(Boolean)\n .map((seg) => seg.charAt(0).toUpperCase() + seg.slice(1).toLowerCase())\n .join(\"\");\n}\n\n/**\n * Ordered unique candidates: exact input, first-letter fix, kebab → Pascal variants.\n * Skip Lucide heuristics for `svg:…` asset values (caller should pass only those as `[trimmed]`).\n */\nexport function collectLucideIconNameCandidates(raw: string): string[] {\n const t = raw.trim();\n if (!t) {\n return [];\n }\n\n const out: string[] = [];\n const push = (s: string) => {\n if (s && !out.includes(s)) {\n out.push(s);\n }\n };\n\n push(t);\n\n if (t[0] === t[0]!.toLowerCase()) {\n push(t.charAt(0).toUpperCase() + t.slice(1));\n }\n\n if (t.includes(\"-\")) {\n push(kebabCaseToLucidePascalCase(t));\n const lower = t.toLowerCase();\n if (lower !== t) {\n push(kebabCaseToLucidePascalCase(lower));\n }\n }\n\n return out;\n}\n","/**\n * lucide-react namespaced exports: icons are ForwardRef/Memo objects in current builds,\n * not plain functions. Only createLucideIcon and default are non-icon exports we skip.\n */\nconst LUCIDE_NAMESPACE_DENYLIST = new Set([\"default\", \"createLucideIcon\"]);\n\n/**\n * True if `exported` is the value of a Lucide icon entry for `name` in `import * as Lucide`.\n * Does not mean the icon exists in the static resolver map — only that the lucide-react\n * module exposes this name as a renderable component type.\n */\nexport function isLucideModuleIconExport(\n name: string,\n exported: unknown,\n): boolean {\n if (!name || LUCIDE_NAMESPACE_DENYLIST.has(name)) return false;\n if (exported == null) return false;\n if (typeof exported === \"function\") return true;\n if (typeof exported === \"object\" && \"$$typeof\" in (exported as object)) {\n return true;\n }\n return false;\n}\n","\"use client\";\n\nimport React, { useState, useEffect } from \"react\";\nimport { cn } from \"./cn\";\nimport {\n staticLucideIconMap,\n fallbackZapIcon as Zap,\n} from \"./static-icons\";\nimport {\n customIconCache,\n isCustomIconName,\n listCustomIconNames,\n loadCustomIcon,\n} from \"./custom-icons\";\nimport { isLucideModuleIconExport } from \"./lucide-module-icon\";\nimport {\n isSvgIconValue,\n listSvgIconValues,\n parseSvgIconPath,\n} from \"./svg-registry\";\nimport type { IconComponentType, IconRenderProps } from \"./types\";\n\n// Cache for dynamically loaded icons to prevent re-importing. Lives on a\n// globalThis Symbol.for slot, NOT module state — dual ESM/CJS unsplit bundles\n// each instantiate their own module graph, and a per-graph cache would\n// re-import icons the other graph already resolved. Never \"clean this up\".\nconst DYNAMIC_CACHE_SLOT = Symbol.for(\"ai-matrx.icons.dynamic-icon-cache\");\nconst dynamicIconCache: Record<string, IconComponentType> = (() => {\n const holder = globalThis as Record<\n symbol,\n Record<string, IconComponentType> | undefined\n >;\n let cache = holder[DYNAMIC_CACHE_SLOT];\n if (!cache) {\n cache = {};\n holder[DYNAMIC_CACHE_SLOT] = cache;\n }\n return cache;\n})();\n\n/**\n * Finite list for a curated icon gallery: every statically bundled Lucide name,\n * curated custom ids (react-icons), and all registered `svg:…` assets.\n */\nexport function getCuratedIconIdsForPicker(): string[] {\n const set = new Set<string>();\n for (const k of Object.keys(staticLucideIconMap)) {\n set.add(k);\n }\n for (const k of listCustomIconNames()) {\n set.add(k);\n }\n for (const id of listSvgIconValues()) {\n set.add(id);\n }\n return Array.from(set).sort((a, b) =>\n a.localeCompare(b, undefined, { sensitivity: \"base\" }),\n );\n}\n\n/**\n * True if this exact name maps to a known icon (static Lucide, curated custom id, or\n * previously resolved dynamic Lucide cached under this key).\n *\n * Does not import lucide-react — use with {@link isRegisteredOrLucideIconName} for full checks.\n */\nexport function isIconRegisteredSync(\n iconName: string | null | undefined,\n): boolean {\n if (!iconName || iconName.trim() === \"\") {\n return false;\n }\n const name = iconName;\n if (isCustomIconName(name)) return true;\n if (staticLucideIconMap[name]) return true;\n return Boolean(dynamicIconCache[name]);\n}\n\n/**\n * True if `iconName` is a real icon id: custom/static/cached, a registered `svg:…`\n * asset, or a Lucide export that is a renderable component (not the fallback Zap).\n *\n * Prefer this over truthiness on {@link getIconComponent}, which always returns a component.\n */\nexport async function isRegisteredOrLucideIconName(\n iconName: string | null | undefined,\n): Promise<boolean> {\n if (!iconName || iconName.trim() === \"\") {\n return false;\n }\n if (isSvgIconValue(iconName)) {\n return true;\n }\n if (isIconRegisteredSync(iconName)) {\n return true;\n }\n try {\n const iconModule = await import(\"lucide-react\");\n const Exported = iconModule[iconName as keyof typeof iconModule];\n return isLucideModuleIconExport(iconName, Exported);\n } catch {\n return false;\n }\n}\n\n/**\n * HOW TO ADD MORE STATIC ICONS:\n *\n * The curated hot set ships in the package (src/static-icons.ts). A host that\n * frequently renders an icon outside the set keeps it zero-latency by statically\n * importing it and registering it once at startup:\n *\n * import { YourIcon } from \"lucide-react\";\n * import { extendStaticIcons } from \"@ai-matrx/icons\";\n * extendStaticIcons({ YourIcon });\n */\n\nexport interface IconResolverProps {\n iconName: string | null;\n className?: string | undefined;\n size?: number | undefined;\n fallbackIcon?: string | undefined;\n style?: React.CSSProperties | undefined;\n}\n\n/**\n * IconResolver - A unified component for resolving and rendering icons by name\n * Uses hybrid approach: static imports for common icons, dynamic imports for others\n * Supports all lucide-react icons, curated custom icons (optional react-icons peer),\n * and registered `svg:…` public assets.\n */\nconst IconResolver: React.FC<IconResolverProps> = ({\n iconName,\n className = \"h-4 w-4\",\n size,\n fallbackIcon = \"Zap\",\n style,\n}) => {\n const svgSrc = iconName ? parseSvgIconPath(iconName) : null;\n const [DynamicIcon, setDynamicIcon] = useState<IconComponentType | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n\n useEffect(() => {\n let cancelled = false;\n const loadIcon = async () => {\n if (!iconName) {\n setDynamicIcon(null);\n setIsLoading(false);\n return;\n }\n\n if (parseSvgIconPath(iconName)) {\n setDynamicIcon(null);\n setIsLoading(false);\n return;\n }\n\n // Check custom icons first (already-loaded cache hit is synchronous)\n const cachedCustom = customIconCache[iconName];\n if (cachedCustom) {\n setDynamicIcon(() => cachedCustom);\n return;\n }\n\n // Check statically imported Lucide icons\n const staticIcon = staticLucideIconMap[iconName];\n if (staticIcon) {\n setDynamicIcon(() => staticIcon);\n return;\n }\n\n // Check if already cached\n const cachedDynamic = dynamicIconCache[iconName];\n if (cachedDynamic) {\n setDynamicIcon(() => cachedDynamic);\n return;\n }\n\n // Curated custom icon: lazy-import the optional react-icons peer;\n // degrade to the fallback icon when it is absent.\n if (isCustomIconName(iconName)) {\n setIsLoading(true);\n const loaded = await loadCustomIcon(iconName);\n if (cancelled) return;\n if (loaded) {\n setDynamicIcon(() => loaded);\n } else {\n setDynamicIcon(() => staticLucideIconMap[fallbackIcon] || Zap);\n }\n setIsLoading(false);\n return;\n }\n\n // Dynamically import from lucide-react\n setIsLoading(true);\n try {\n const iconModule = await import(\"lucide-react\");\n if (cancelled) return;\n const exported: unknown = iconModule[iconName as keyof typeof iconModule];\n\n if (isLucideModuleIconExport(iconName, exported)) {\n const IconComponent = exported as IconComponentType;\n dynamicIconCache[iconName] = IconComponent;\n setDynamicIcon(() => IconComponent);\n } else {\n // Icon not found, use fallback\n setDynamicIcon(() => staticLucideIconMap[fallbackIcon] || Zap);\n }\n } catch (error) {\n if (cancelled) return;\n console.warn(`Failed to load icon: ${iconName}`, error);\n setDynamicIcon(() => staticLucideIconMap[fallbackIcon] || Zap);\n } finally {\n if (!cancelled) setIsLoading(false);\n }\n };\n\n loadIcon();\n // Cancellation: without it, a slow dynamic import resolving after unmount\n // (or after iconName changed) called setState on a dead/stale effect.\n return () => {\n cancelled = true;\n };\n }, [iconName, fallbackIcon]);\n\n if (svgSrc) {\n return (\n <img\n src={svgSrc}\n alt=\"\"\n className={cn(\"object-contain shrink-0\", className)}\n width={size}\n height={size}\n style={style}\n />\n );\n }\n\n // Get the icon component to render\n const IconComponent = DynamicIcon || staticLucideIconMap[fallbackIcon] || Zap;\n\n // Build exact-optional props (never pass an explicit undefined through)\n const iconProps: IconRenderProps = {\n ...(className !== undefined ? { className } : {}),\n ...(size !== undefined ? { size } : {}),\n ...(style !== undefined ? { style } : {}),\n };\n\n // Show fallback while loading dynamic icons (seamless experience)\n if (isLoading && !DynamicIcon) {\n const FallbackIcon = staticLucideIconMap[fallbackIcon] || Zap;\n return <FallbackIcon {...iconProps} />;\n }\n\n return <IconComponent {...iconProps} />;\n};\n\nexport default IconResolver;\n\n/**\n * Synchronous utility function for getting icon components directly\n * Only works with statically imported icons plus already-loaded custom/dynamic icons.\n * For dynamic Lucide icons not in the static map, use the IconResolver component instead\n *\n * **Always returns a component** (default/fallback Zap when unknown). Do not use the return\n * value to infer whether `iconName` exists — use {@link isIconRegisteredSync} or\n * {@link isRegisteredOrLucideIconName} instead.\n */\nexport const getIconComponent = (\n iconName: string | null | undefined,\n fallbackIcon: string = \"Zap\",\n): IconComponentType => {\n if (!iconName) {\n return staticLucideIconMap[fallbackIcon] || Zap;\n }\n\n // First check custom icons (loaded lazily; a hit means it is already cached)\n const custom = customIconCache[iconName];\n if (custom) {\n return custom;\n }\n\n // Then check statically imported Lucide icons\n const staticIcon = staticLucideIconMap[iconName];\n if (staticIcon) {\n return staticIcon;\n }\n\n // Check dynamic cache\n const dynamic = dynamicIconCache[iconName];\n if (dynamic) {\n return dynamic;\n }\n\n // Fallback to default icon\n return staticLucideIconMap[fallbackIcon] || Zap;\n};\n\n/**\n * Renders an icon element directly with optional props\n * This is the preferred method for rendering icons in JSX\n */\nexport const renderIcon = (\n iconName: string | null | undefined,\n props?: IconRenderProps,\n fallbackIcon: string = \"Zap\",\n) => {\n const IconComponent = getIconComponent(iconName, fallbackIcon);\n return <IconComponent {...props} />;\n};\n\n/**\n * Utility to detect if a string is a hex color code\n */\nexport const isHexColor = (color: string): boolean => {\n return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(color);\n};\n\nexport const getTextColorClass = (color?: string) => {\n if (!color) return \"text-gray-600 dark:text-gray-400\";\n\n // If it's a hex color, return null (we'll use inline styles instead)\n if (isHexColor(color)) return null;\n\n const colorMap: Record<string, string> = {\n gray: \"text-gray-600 dark:text-gray-400\",\n rose: \"text-rose-600 dark:text-rose-400\",\n blue: \"text-blue-600 dark:text-blue-400\",\n amber: \"text-amber-600 dark:text-amber-400\",\n cyan: \"text-cyan-600 dark:text-cyan-400\",\n emerald: \"text-emerald-600 dark:text-emerald-400\",\n fuchsia: \"text-fuchsia-600 dark:text-fuchsia-400\",\n green: \"text-green-600 dark:text-green-400\",\n indigo: \"text-indigo-600 dark:text-indigo-400\",\n lime: \"text-lime-600 dark:text-lime-400\",\n neutral: \"text-neutral-600 dark:text-neutral-400\",\n orange: \"text-orange-600 dark:text-orange-400\",\n pink: \"text-pink-600 dark:text-pink-400\",\n purple: \"text-purple-600 dark:text-purple-400\",\n red: \"text-red-600 dark:text-red-400\",\n sky: \"text-sky-600 dark:text-sky-400\",\n slate: \"text-slate-600 dark:text-slate-400\",\n stone: \"text-stone-600 dark:text-stone-400\",\n teal: \"text-teal-600 dark:text-teal-400\",\n violet: \"text-violet-600 dark:text-violet-400\",\n yellow: \"text-yellow-600 dark:text-yellow-400\",\n zinc: \"text-zinc-600 dark:text-zinc-400\",\n };\n\n return colorMap[color.toLowerCase()] || \"text-gray-600 dark:text-gray-400\";\n};\n\n/**\n * Utility function for rendering an icon with color and size\n * Note: This is synchronous and only works with statically imported icons\n * For dynamic icons, use the DynamicIcon component instead\n */\nexport const getIconWithColorAndSize = (\n iconName: string | null,\n color: string = \"gray\",\n size: number = 4,\n) => {\n const IconComponent = getIconComponent(iconName);\n const colorClass = getTextColorClass(color);\n // Hex colors have no Tailwind class (getTextColorClass returns null) —\n // they color via inline style. The original interpolated the null into the\n // className as a literal \"null\" token; fixed in 0.1.1.\n return (\n <IconComponent\n className={cn(`h-${size} w-${size}`, colorClass)}\n {...(colorClass === null ? { style: { color } } : {})}\n />\n );\n};\n\n/**\n * Simple Icon component for direct usage with color and size support\n * Uses IconResolver internally to support both static and dynamic icons\n *\n * Supports both Tailwind color names (e.g., \"blue\", \"red\", \"zinc\") and hex colors (e.g., \"#ff0000\", \"#666\")\n */\nexport interface DynamicIconProps {\n name: string | null;\n color?: string | undefined;\n size?: number | undefined;\n className?: string | undefined;\n fallbackIcon?: string | undefined;\n}\n\nexport const DynamicIcon: React.FC<DynamicIconProps> = ({\n name,\n color = \"gray\",\n size = 4,\n className,\n fallbackIcon = \"Zap\",\n}) => {\n const isHex = color && isHexColor(color);\n const colorClass = isHex ? null : getTextColorClass(color);\n const sizeClass = `h-${size} w-${size}`;\n\n // Build className: always include size, include colorClass if not hex, include custom className\n const combinedClassName = [sizeClass, !isHex && colorClass, className]\n .filter(Boolean)\n .join(\" \")\n .trim();\n\n // If hex color, apply as inline style\n const style = isHex ? { color } : undefined;\n\n return (\n <IconResolver\n iconName={name}\n className={combinedClassName}\n fallbackIcon={fallbackIcon}\n style={style}\n />\n );\n};\n","/**\n * Minimal className join — the only piece of `cn` this package needs.\n * No tailwind-merge / clsx dependency by design: callers pass literal strings.\n */\nexport function cn(\n ...values: Array<string | null | undefined | false>\n): string {\n return values.filter(Boolean).join(\" \").trim();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACGA,0BAyIO;AAOA,IAAM,sBAAyD;AAAA,EACpE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AA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","names":["DynamicIcon","IconComponent"]}
package/dist/index.js CHANGED
@@ -316,7 +316,16 @@ var CUSTOM_ICON_SOURCES = {
316
316
  FcBusiness: "fc",
317
317
  FcSignature: "fc"
318
318
  };
319
- var customIconCache = {};
319
+ var CUSTOM_CACHE_SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.icons.custom-icon-cache");
320
+ var customIconCache = (() => {
321
+ const holder = globalThis;
322
+ let cache = holder[CUSTOM_CACHE_SLOT];
323
+ if (!cache) {
324
+ cache = {};
325
+ holder[CUSTOM_CACHE_SLOT] = cache;
326
+ }
327
+ return cache;
328
+ })();
320
329
  function isCustomIconName(name) {
321
330
  return Object.prototype.hasOwnProperty.call(CUSTOM_ICON_SOURCES, name);
322
331
  }
@@ -347,7 +356,16 @@ async function loadCustomIcon(name) {
347
356
  }
348
357
 
349
358
  // src/svg-registry.ts
350
- var svgIconRegistry = {};
359
+ var SVG_REGISTRY_SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.icons.svg-registry");
360
+ var svgIconRegistry = (() => {
361
+ const holder = globalThis;
362
+ let reg = holder[SVG_REGISTRY_SLOT];
363
+ if (!reg) {
364
+ reg = {};
365
+ holder[SVG_REGISTRY_SLOT] = reg;
366
+ }
367
+ return reg;
368
+ })();
351
369
  var SVG_PREFIX = "svg:";
352
370
  function registerSvgIcons(map) {
353
371
  for (const [rawId, path] of Object.entries(map)) {
@@ -440,7 +458,16 @@ function cn(...values) {
440
458
 
441
459
  // src/resolver.tsx
442
460
  import { jsx } from "react/jsx-runtime";
443
- var dynamicIconCache = {};
461
+ var DYNAMIC_CACHE_SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.icons.dynamic-icon-cache");
462
+ var dynamicIconCache = (() => {
463
+ const holder = globalThis;
464
+ let cache = holder[DYNAMIC_CACHE_SLOT];
465
+ if (!cache) {
466
+ cache = {};
467
+ holder[DYNAMIC_CACHE_SLOT] = cache;
468
+ }
469
+ return cache;
470
+ })();
444
471
  function getCuratedIconIdsForPicker() {
445
472
  const set = /* @__PURE__ */ new Set();
446
473
  for (const k of Object.keys(staticLucideIconMap)) {
@@ -494,6 +521,7 @@ var IconResolver = ({
494
521
  const [DynamicIcon2, setDynamicIcon] = useState(null);
495
522
  const [isLoading, setIsLoading] = useState(false);
496
523
  useEffect(() => {
524
+ let cancelled = false;
497
525
  const loadIcon = async () => {
498
526
  if (!iconName) {
499
527
  setDynamicIcon(null);
@@ -523,6 +551,7 @@ var IconResolver = ({
523
551
  if (isCustomIconName(iconName)) {
524
552
  setIsLoading(true);
525
553
  const loaded = await loadCustomIcon(iconName);
554
+ if (cancelled) return;
526
555
  if (loaded) {
527
556
  setDynamicIcon(() => loaded);
528
557
  } else {
@@ -534,6 +563,7 @@ var IconResolver = ({
534
563
  setIsLoading(true);
535
564
  try {
536
565
  const iconModule = await import("lucide-react");
566
+ if (cancelled) return;
537
567
  const exported = iconModule[iconName];
538
568
  if (isLucideModuleIconExport(iconName, exported)) {
539
569
  const IconComponent2 = exported;
@@ -543,13 +573,17 @@ var IconResolver = ({
543
573
  setDynamicIcon(() => staticLucideIconMap[fallbackIcon] || Zap);
544
574
  }
545
575
  } catch (error) {
576
+ if (cancelled) return;
546
577
  console.warn(`Failed to load icon: ${iconName}`, error);
547
578
  setDynamicIcon(() => staticLucideIconMap[fallbackIcon] || Zap);
548
579
  } finally {
549
- setIsLoading(false);
580
+ if (!cancelled) setIsLoading(false);
550
581
  }
551
582
  };
552
583
  loadIcon();
584
+ return () => {
585
+ cancelled = true;
586
+ };
553
587
  }, [iconName, fallbackIcon]);
554
588
  if (svgSrc) {
555
589
  return /* @__PURE__ */ jsx(
@@ -634,7 +668,13 @@ var getTextColorClass = (color) => {
634
668
  var getIconWithColorAndSize = (iconName, color = "gray", size = 4) => {
635
669
  const IconComponent = getIconComponent(iconName);
636
670
  const colorClass = getTextColorClass(color);
637
- return /* @__PURE__ */ jsx(IconComponent, { className: `h-${size} w-${size} ${colorClass}` });
671
+ return /* @__PURE__ */ jsx(
672
+ IconComponent,
673
+ {
674
+ className: cn(`h-${size} w-${size}`, colorClass),
675
+ ...colorClass === null ? { style: { color } } : {}
676
+ }
677
+ );
638
678
  };
639
679
  var DynamicIcon = ({
640
680
  name,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/static-icons.ts","../src/custom-icons.ts","../src/svg-registry.ts","../src/lucide-name-normalize.ts","../src/lucide-module-icon.ts","../src/resolver.tsx","../src/cn.ts"],"sourcesContent":["// Statically import commonly used Lucide icons to reduce bundle size.\n// This curated hot set is the product: a hit here renders synchronously,\n// with zero dynamic-import latency and no fallback flash.\nimport {\n Zap,\n Home,\n User,\n Settings,\n Search,\n Bell,\n Menu,\n X,\n ChevronDown,\n ChevronUp,\n ChevronLeft,\n ChevronRight,\n Plus,\n Minus,\n Edit,\n Trash,\n Check,\n AlertCircle,\n Info,\n HelpCircle,\n Eye,\n EyeOff,\n Copy,\n Download,\n Upload,\n Save,\n MoreVertical,\n MoreHorizontal,\n Filter,\n SortAsc,\n SortDesc,\n Calendar,\n Clock,\n Mail,\n Phone,\n MapPin,\n Link,\n ExternalLink,\n File,\n Folder,\n Image,\n Video,\n Music,\n FileText,\n Database,\n Cloud,\n Server,\n Code,\n Terminal,\n Globe,\n Lock,\n Unlock,\n Shield,\n Key,\n LogIn,\n LogOut,\n UserPlus,\n Users,\n Star,\n Heart,\n Bookmark,\n Share,\n Send,\n MessageSquare,\n MessageCircle,\n Hash,\n AtSign,\n Paperclip,\n Mic,\n Volume2,\n Play,\n Pause,\n SkipForward,\n SkipBack,\n RefreshCw,\n RotateCw,\n Loader,\n Loader2,\n Circle,\n Square,\n Triangle,\n Hexagon,\n Package,\n Box,\n Archive,\n Inbox,\n Layers,\n Layout,\n Grid,\n List,\n Columns,\n Sidebar,\n Maximize,\n Minimize,\n ZoomIn,\n ZoomOut,\n Move,\n Scissors,\n Clipboard,\n PieChart,\n BarChart,\n TrendingUp,\n TrendingDown,\n Activity,\n Cpu,\n HardDrive,\n Wifi,\n WifiOff,\n Bluetooth,\n Battery,\n BatteryCharging,\n Power,\n Sun,\n Moon,\n CloudRain,\n Droplet,\n Wind,\n Tag,\n Tags,\n Flag,\n Award,\n Gift,\n ShoppingCart,\n CreditCard,\n DollarSign,\n Percent,\n Target,\n Crosshair,\n Navigation,\n Compass,\n Map,\n Smile,\n Frown,\n Meh,\n ThumbsUp,\n ThumbsDown,\n} from \"lucide-react\";\nimport type { IconComponentType } from \"./types\";\n\nexport { Zap as fallbackZapIcon };\n\n// Statically imported Lucide icons map (commonly used icons for optimal bundle size)\n// Exported so callers can spread it as a scope without importing the full lucide namespace.\nexport const staticLucideIconMap: Record<string, IconComponentType> = {\n Zap,\n Home,\n User,\n Settings,\n Search,\n Bell,\n Menu,\n X,\n ChevronDown,\n ChevronUp,\n ChevronLeft,\n ChevronRight,\n Plus,\n Minus,\n Edit,\n Trash,\n Check,\n AlertCircle,\n Info,\n HelpCircle,\n Eye,\n EyeOff,\n Copy,\n Download,\n Upload,\n Save,\n MoreVertical,\n MoreHorizontal,\n Filter,\n SortAsc,\n SortDesc,\n Calendar,\n Clock,\n Mail,\n Phone,\n MapPin,\n Link,\n ExternalLink,\n File,\n Folder,\n Image,\n Video,\n Music,\n FileText,\n Database,\n Cloud,\n Server,\n Code,\n Terminal,\n Globe,\n Lock,\n Unlock,\n Shield,\n Key,\n LogIn,\n LogOut,\n UserPlus,\n Users,\n Star,\n Heart,\n Bookmark,\n Share,\n Send,\n MessageSquare,\n MessageCircle,\n Hash,\n AtSign,\n Paperclip,\n Mic,\n Volume2,\n Play,\n Pause,\n SkipForward,\n SkipBack,\n RefreshCw,\n RotateCw,\n Loader,\n Loader2,\n Circle,\n Square,\n Triangle,\n Hexagon,\n Package,\n Box,\n Archive,\n Inbox,\n Layers,\n Layout,\n Grid,\n List,\n Columns,\n Sidebar,\n Maximize,\n Minimize,\n ZoomIn,\n ZoomOut,\n Move,\n Scissors,\n Clipboard,\n PieChart,\n BarChart,\n TrendingUp,\n TrendingDown,\n Activity,\n Cpu,\n HardDrive,\n Wifi,\n WifiOff,\n Bluetooth,\n Battery,\n BatteryCharging,\n Power,\n Sun,\n Moon,\n CloudRain,\n Droplet,\n Wind,\n Tag,\n Tags,\n Flag,\n Award,\n Gift,\n ShoppingCart,\n CreditCard,\n DollarSign,\n Percent,\n Target,\n Crosshair,\n Navigation,\n Compass,\n Map,\n Smile,\n Frown,\n Meh,\n ThumbsUp,\n ThumbsDown,\n};\n\n/**\n * Extend the static (synchronous, zero-latency) icon map with host-supplied\n * components — extra statically imported Lucide icons a host uses on hot paths,\n * or any component matching {@link IconComponentType}. Merges in place; later\n * registrations override earlier entries of the same name.\n */\nexport function extendStaticIcons(map: Record<string, IconComponentType>): void {\n Object.assign(staticLucideIconMap, map);\n}\n","/**\n * Curated brand/custom icon names served from the OPTIONAL `react-icons` peer.\n *\n * Coupling inversion vs. the original (which statically imported react-icons):\n * `react-icons` is an optional peerDependency, so these are lazy-imported on first\n * use and cached at module level. When the host has not installed `react-icons`,\n * loading degrades to null and the resolver renders the fallback icon instead —\n * no install-time or import-time failure.\n */\nimport type { IconComponentType } from \"./types\";\n\n/** name → react-icons subpackage the export lives in. */\nconst CUSTOM_ICON_SOURCES: Record<string, \"fc\" | \"fa6\"> = {\n FaBrave: \"fa6\",\n FcGoogle: \"fc\",\n FcBrokenLink: \"fc\",\n FcFilm: \"fc\",\n FcDownload: \"fc\",\n FcBiotech: \"fc\",\n FcElectronics: \"fc\",\n FcGraduationCap: \"fc\",\n FcLibrary: \"fc\",\n FcMusic: \"fc\",\n FcParallelTasks: \"fc\",\n FcSalesPerformance: \"fc\",\n FcCalendar: \"fc\",\n FcDocument: \"fc\",\n FcEngineering: \"fc\",\n FcDataProtection: \"fc\",\n FcAssistant: \"fc\",\n FcSms: \"fc\",\n FcTodoList: \"fc\",\n FcWikipedia: \"fc\",\n FcCommandLine: \"fc\",\n FcConferenceCall: \"fc\",\n FcManager: \"fc\",\n FcAreaChart: \"fc\",\n FcMultipleInputs: \"fc\",\n FcShipped: \"fc\",\n FcBusinessContact: \"fc\",\n FcAlphabeticalSortingAz: \"fc\",\n FcAlphabeticalSortingZa: \"fc\",\n FcFeedback: \"fc\",\n FcBusiness: \"fc\",\n FcSignature: \"fc\",\n};\n\n/** Cache for lazily loaded custom icons (also the sync-lookup source once loaded). */\nexport const customIconCache: Record<string, IconComponentType> = {};\n\n/** True when `name` is one of the curated custom (react-icons) ids. */\nexport function isCustomIconName(name: string): boolean {\n return Object.prototype.hasOwnProperty.call(CUSTOM_ICON_SOURCES, name);\n}\n\n/** The curated custom icon ids (known without loading react-icons). */\nexport function listCustomIconNames(): string[] {\n return Object.keys(CUSTOM_ICON_SOURCES);\n}\n\n/**\n * Lazy-load a curated custom icon from the optional `react-icons` peer.\n * Returns null for unknown names, a missing export, or when `react-icons`\n * is not installed — the caller degrades to the fallback icon.\n */\nexport async function loadCustomIcon(\n name: string,\n): Promise<IconComponentType | null> {\n const cached = customIconCache[name];\n if (cached) {\n return cached;\n }\n const source = CUSTOM_ICON_SOURCES[name];\n if (!source) {\n return null;\n }\n try {\n const mod: Record<string, unknown> =\n source === \"fc\"\n ? await import(\"react-icons/fc\")\n : await import(\"react-icons/fa6\");\n const exported = mod[name];\n if (typeof exported !== \"function\") {\n return null;\n }\n const IconComponent = exported as IconComponentType;\n customIconCache[name] = IconComponent;\n return IconComponent;\n } catch {\n // react-icons not installed (optional peer) — degrade to the fallback icon.\n return null;\n }\n}\n","/**\n * Injectable registry for host-owned SVG assets. Stored icon ids use the form\n * `svg:<path-without-leading-slash-and-without-extension>` e.g. `svg:icons/Home`\n * → whatever URL the host registered for the id `icons/Home` (typically `/icons/Home.svg`).\n *\n * The package ships EMPTY — the host application registers its own asset paths once at\n * startup via {@link registerSvgIcons}. An unregistered `svg:` value resolves to null\n * and the resolver falls back exactly as it does for an unknown Lucide name.\n */\nconst svgIconRegistry: Record<string, string> = {};\n\nconst SVG_PREFIX = \"svg:\";\n\n/**\n * Register (or override) `svg:` icon ids → asset URLs. Merges into the module-level\n * registry, so multiple calls compose. Ids are stored without the `svg:` prefix.\n */\nexport function registerSvgIcons(map: Record<string, string>): void {\n for (const [rawId, path] of Object.entries(map)) {\n const id = rawId.startsWith(SVG_PREFIX)\n ? rawId.slice(SVG_PREFIX.length).replace(/^\\/+/, \"\")\n : rawId.replace(/^\\/+/, \"\");\n if (id && path) {\n svgIconRegistry[id] = path;\n }\n }\n}\n\n/** The registered asset URL for a `svg:…` icon value, or null when not a registered svg icon. */\nexport function parseSvgIconPath(value: string): string | null {\n if (!value.startsWith(SVG_PREFIX)) {\n return null;\n }\n const id = value.slice(SVG_PREFIX.length).replace(/^\\/+/, \"\");\n const path = svgIconRegistry[id];\n return path ?? null;\n}\n\n/** True if `value` is a `svg:…` id with a registered asset path. */\nexport function isSvgIconValue(value: string | null | undefined): boolean {\n if (!value || !value.startsWith(SVG_PREFIX)) {\n return false;\n }\n const id = value.slice(SVG_PREFIX.length).replace(/^\\/+/, \"\");\n return Boolean(svgIconRegistry[id]);\n}\n\n/** Every registered svg icon value, `svg:` prefix included (for pickers/galleries). */\nexport function listSvgIconValues(): string[] {\n return Object.keys(svgIconRegistry).map((id) => `${SVG_PREFIX}${id}`);\n}\n","/**\n * Lucide.dev lists icons in kebab-case (e.g. `alarm-clock`); the React package\n * exports PascalCase (`AlarmClock`). Normalize pasted / typed names into candidates\n * to validate against `lucide-react` exports.\n */\n\n/**\n * If the user pasted Lucide's JSX snippet (e.g. `'<BugPlay />'` or `<AlignCenterHorizontal />`),\n * return the component name only. Otherwise return null.\n *\n * Supports optional outer quotes and optional attributes before the closing `/>`.\n */\nexport function extractLucideJsxIconName(raw: string): string | null {\n let s = raw.trim();\n if (!s) return null;\n if (\n (s.startsWith(\"'\") && s.endsWith(\"'\") && s.length >= 2) ||\n (s.startsWith('\"') && s.endsWith('\"') && s.length >= 2)\n ) {\n s = s.slice(1, -1).trim();\n }\n const m = s.match(/^<\\s*([A-Za-z][A-Za-z0-9]*)(?:\\s[^>]*)?\\s*\\/\\s*>$/);\n return m?.[1] ?? null;\n}\n\n/** `alarm-clock` → `AlarmClock`, `a-arrow-down` → `AArrowDown` */\nexport function kebabCaseToLucidePascalCase(raw: string): string {\n const s = raw.trim();\n if (!s.includes(\"-\")) {\n return s;\n }\n return s\n .split(\"-\")\n .filter(Boolean)\n .map((seg) => seg.charAt(0).toUpperCase() + seg.slice(1).toLowerCase())\n .join(\"\");\n}\n\n/**\n * Ordered unique candidates: exact input, first-letter fix, kebab → Pascal variants.\n * Skip Lucide heuristics for `svg:…` asset values (caller should pass only those as `[trimmed]`).\n */\nexport function collectLucideIconNameCandidates(raw: string): string[] {\n const t = raw.trim();\n if (!t) {\n return [];\n }\n\n const out: string[] = [];\n const push = (s: string) => {\n if (s && !out.includes(s)) {\n out.push(s);\n }\n };\n\n push(t);\n\n if (t[0] === t[0]!.toLowerCase()) {\n push(t.charAt(0).toUpperCase() + t.slice(1));\n }\n\n if (t.includes(\"-\")) {\n push(kebabCaseToLucidePascalCase(t));\n const lower = t.toLowerCase();\n if (lower !== t) {\n push(kebabCaseToLucidePascalCase(lower));\n }\n }\n\n return out;\n}\n","/**\n * lucide-react namespaced exports: icons are ForwardRef/Memo objects in current builds,\n * not plain functions. Only createLucideIcon and default are non-icon exports we skip.\n */\nconst LUCIDE_NAMESPACE_DENYLIST = new Set([\"default\", \"createLucideIcon\"]);\n\n/**\n * True if `exported` is the value of a Lucide icon entry for `name` in `import * as Lucide`.\n * Does not mean the icon exists in the static resolver map — only that the lucide-react\n * module exposes this name as a renderable component type.\n */\nexport function isLucideModuleIconExport(\n name: string,\n exported: unknown,\n): boolean {\n if (!name || LUCIDE_NAMESPACE_DENYLIST.has(name)) return false;\n if (exported == null) return false;\n if (typeof exported === \"function\") return true;\n if (typeof exported === \"object\" && \"$$typeof\" in (exported as object)) {\n return true;\n }\n return false;\n}\n","\"use client\";\n\nimport React, { useState, useEffect } from \"react\";\nimport { cn } from \"./cn\";\nimport {\n staticLucideIconMap,\n fallbackZapIcon as Zap,\n} from \"./static-icons\";\nimport {\n customIconCache,\n isCustomIconName,\n listCustomIconNames,\n loadCustomIcon,\n} from \"./custom-icons\";\nimport { isLucideModuleIconExport } from \"./lucide-module-icon\";\nimport {\n isSvgIconValue,\n listSvgIconValues,\n parseSvgIconPath,\n} from \"./svg-registry\";\nimport type { IconComponentType, IconRenderProps } from \"./types\";\n\n// Cache for dynamically loaded icons to prevent re-importing\nconst dynamicIconCache: Record<string, IconComponentType> = {};\n\n/**\n * Finite list for a curated icon gallery: every statically bundled Lucide name,\n * curated custom ids (react-icons), and all registered `svg:…` assets.\n */\nexport function getCuratedIconIdsForPicker(): string[] {\n const set = new Set<string>();\n for (const k of Object.keys(staticLucideIconMap)) {\n set.add(k);\n }\n for (const k of listCustomIconNames()) {\n set.add(k);\n }\n for (const id of listSvgIconValues()) {\n set.add(id);\n }\n return Array.from(set).sort((a, b) =>\n a.localeCompare(b, undefined, { sensitivity: \"base\" }),\n );\n}\n\n/**\n * True if this exact name maps to a known icon (static Lucide, curated custom id, or\n * previously resolved dynamic Lucide cached under this key).\n *\n * Does not import lucide-react — use with {@link isRegisteredOrLucideIconName} for full checks.\n */\nexport function isIconRegisteredSync(\n iconName: string | null | undefined,\n): boolean {\n if (!iconName || iconName.trim() === \"\") {\n return false;\n }\n const name = iconName;\n if (isCustomIconName(name)) return true;\n if (staticLucideIconMap[name]) return true;\n return Boolean(dynamicIconCache[name]);\n}\n\n/**\n * True if `iconName` is a real icon id: custom/static/cached, a registered `svg:…`\n * asset, or a Lucide export that is a renderable component (not the fallback Zap).\n *\n * Prefer this over truthiness on {@link getIconComponent}, which always returns a component.\n */\nexport async function isRegisteredOrLucideIconName(\n iconName: string | null | undefined,\n): Promise<boolean> {\n if (!iconName || iconName.trim() === \"\") {\n return false;\n }\n if (isSvgIconValue(iconName)) {\n return true;\n }\n if (isIconRegisteredSync(iconName)) {\n return true;\n }\n try {\n const iconModule = await import(\"lucide-react\");\n const Exported = iconModule[iconName as keyof typeof iconModule];\n return isLucideModuleIconExport(iconName, Exported);\n } catch {\n return false;\n }\n}\n\n/**\n * HOW TO ADD MORE STATIC ICONS:\n *\n * The curated hot set ships in the package (src/static-icons.ts). A host that\n * frequently renders an icon outside the set keeps it zero-latency by statically\n * importing it and registering it once at startup:\n *\n * import { YourIcon } from \"lucide-react\";\n * import { extendStaticIcons } from \"@ai-matrx/icons\";\n * extendStaticIcons({ YourIcon });\n */\n\nexport interface IconResolverProps {\n iconName: string | null;\n className?: string | undefined;\n size?: number | undefined;\n fallbackIcon?: string | undefined;\n style?: React.CSSProperties | undefined;\n}\n\n/**\n * IconResolver - A unified component for resolving and rendering icons by name\n * Uses hybrid approach: static imports for common icons, dynamic imports for others\n * Supports all lucide-react icons, curated custom icons (optional react-icons peer),\n * and registered `svg:…` public assets.\n */\nconst IconResolver: React.FC<IconResolverProps> = ({\n iconName,\n className = \"h-4 w-4\",\n size,\n fallbackIcon = \"Zap\",\n style,\n}) => {\n const svgSrc = iconName ? parseSvgIconPath(iconName) : null;\n const [DynamicIcon, setDynamicIcon] = useState<IconComponentType | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n\n useEffect(() => {\n const loadIcon = async () => {\n if (!iconName) {\n setDynamicIcon(null);\n setIsLoading(false);\n return;\n }\n\n if (parseSvgIconPath(iconName)) {\n setDynamicIcon(null);\n setIsLoading(false);\n return;\n }\n\n // Check custom icons first (already-loaded cache hit is synchronous)\n const cachedCustom = customIconCache[iconName];\n if (cachedCustom) {\n setDynamicIcon(() => cachedCustom);\n return;\n }\n\n // Check statically imported Lucide icons\n const staticIcon = staticLucideIconMap[iconName];\n if (staticIcon) {\n setDynamicIcon(() => staticIcon);\n return;\n }\n\n // Check if already cached\n const cachedDynamic = dynamicIconCache[iconName];\n if (cachedDynamic) {\n setDynamicIcon(() => cachedDynamic);\n return;\n }\n\n // Curated custom icon: lazy-import the optional react-icons peer;\n // degrade to the fallback icon when it is absent.\n if (isCustomIconName(iconName)) {\n setIsLoading(true);\n const loaded = await loadCustomIcon(iconName);\n if (loaded) {\n setDynamicIcon(() => loaded);\n } else {\n setDynamicIcon(() => staticLucideIconMap[fallbackIcon] || Zap);\n }\n setIsLoading(false);\n return;\n }\n\n // Dynamically import from lucide-react\n setIsLoading(true);\n try {\n const iconModule = await import(\"lucide-react\");\n const exported: unknown = iconModule[iconName as keyof typeof iconModule];\n\n if (isLucideModuleIconExport(iconName, exported)) {\n const IconComponent = exported as IconComponentType;\n dynamicIconCache[iconName] = IconComponent;\n setDynamicIcon(() => IconComponent);\n } else {\n // Icon not found, use fallback\n setDynamicIcon(() => staticLucideIconMap[fallbackIcon] || Zap);\n }\n } catch (error) {\n console.warn(`Failed to load icon: ${iconName}`, error);\n setDynamicIcon(() => staticLucideIconMap[fallbackIcon] || Zap);\n } finally {\n setIsLoading(false);\n }\n };\n\n loadIcon();\n }, [iconName, fallbackIcon]);\n\n if (svgSrc) {\n return (\n <img\n src={svgSrc}\n alt=\"\"\n className={cn(\"object-contain shrink-0\", className)}\n width={size}\n height={size}\n style={style}\n />\n );\n }\n\n // Get the icon component to render\n const IconComponent = DynamicIcon || staticLucideIconMap[fallbackIcon] || Zap;\n\n // Build exact-optional props (never pass an explicit undefined through)\n const iconProps: IconRenderProps = {\n ...(className !== undefined ? { className } : {}),\n ...(size !== undefined ? { size } : {}),\n ...(style !== undefined ? { style } : {}),\n };\n\n // Show fallback while loading dynamic icons (seamless experience)\n if (isLoading && !DynamicIcon) {\n const FallbackIcon = staticLucideIconMap[fallbackIcon] || Zap;\n return <FallbackIcon {...iconProps} />;\n }\n\n return <IconComponent {...iconProps} />;\n};\n\nexport default IconResolver;\n\n/**\n * Synchronous utility function for getting icon components directly\n * Only works with statically imported icons plus already-loaded custom/dynamic icons.\n * For dynamic Lucide icons not in the static map, use the IconResolver component instead\n *\n * **Always returns a component** (default/fallback Zap when unknown). Do not use the return\n * value to infer whether `iconName` exists — use {@link isIconRegisteredSync} or\n * {@link isRegisteredOrLucideIconName} instead.\n */\nexport const getIconComponent = (\n iconName: string | null | undefined,\n fallbackIcon: string = \"Zap\",\n): IconComponentType => {\n if (!iconName) {\n return staticLucideIconMap[fallbackIcon] || Zap;\n }\n\n // First check custom icons (loaded lazily; a hit means it is already cached)\n const custom = customIconCache[iconName];\n if (custom) {\n return custom;\n }\n\n // Then check statically imported Lucide icons\n const staticIcon = staticLucideIconMap[iconName];\n if (staticIcon) {\n return staticIcon;\n }\n\n // Check dynamic cache\n const dynamic = dynamicIconCache[iconName];\n if (dynamic) {\n return dynamic;\n }\n\n // Fallback to default icon\n return staticLucideIconMap[fallbackIcon] || Zap;\n};\n\n/**\n * Renders an icon element directly with optional props\n * This is the preferred method for rendering icons in JSX\n */\nexport const renderIcon = (\n iconName: string | null | undefined,\n props?: IconRenderProps,\n fallbackIcon: string = \"Zap\",\n) => {\n const IconComponent = getIconComponent(iconName, fallbackIcon);\n return <IconComponent {...props} />;\n};\n\n/**\n * Utility to detect if a string is a hex color code\n */\nexport const isHexColor = (color: string): boolean => {\n return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(color);\n};\n\nexport const getTextColorClass = (color?: string) => {\n if (!color) return \"text-gray-600 dark:text-gray-400\";\n\n // If it's a hex color, return null (we'll use inline styles instead)\n if (isHexColor(color)) return null;\n\n const colorMap: Record<string, string> = {\n gray: \"text-gray-600 dark:text-gray-400\",\n rose: \"text-rose-600 dark:text-rose-400\",\n blue: \"text-blue-600 dark:text-blue-400\",\n amber: \"text-amber-600 dark:text-amber-400\",\n cyan: \"text-cyan-600 dark:text-cyan-400\",\n emerald: \"text-emerald-600 dark:text-emerald-400\",\n fuchsia: \"text-fuchsia-600 dark:text-fuchsia-400\",\n green: \"text-green-600 dark:text-green-400\",\n indigo: \"text-indigo-600 dark:text-indigo-400\",\n lime: \"text-lime-600 dark:text-lime-400\",\n neutral: \"text-neutral-600 dark:text-neutral-400\",\n orange: \"text-orange-600 dark:text-orange-400\",\n pink: \"text-pink-600 dark:text-pink-400\",\n purple: \"text-purple-600 dark:text-purple-400\",\n red: \"text-red-600 dark:text-red-400\",\n sky: \"text-sky-600 dark:text-sky-400\",\n slate: \"text-slate-600 dark:text-slate-400\",\n stone: \"text-stone-600 dark:text-stone-400\",\n teal: \"text-teal-600 dark:text-teal-400\",\n violet: \"text-violet-600 dark:text-violet-400\",\n yellow: \"text-yellow-600 dark:text-yellow-400\",\n zinc: \"text-zinc-600 dark:text-zinc-400\",\n };\n\n return colorMap[color.toLowerCase()] || \"text-gray-600 dark:text-gray-400\";\n};\n\n/**\n * Utility function for rendering an icon with color and size\n * Note: This is synchronous and only works with statically imported icons\n * For dynamic icons, use the DynamicIcon component instead\n */\nexport const getIconWithColorAndSize = (\n iconName: string | null,\n color: string = \"gray\",\n size: number = 4,\n) => {\n const IconComponent = getIconComponent(iconName);\n const colorClass = getTextColorClass(color);\n return <IconComponent className={`h-${size} w-${size} ${colorClass}`} />;\n};\n\n/**\n * Simple Icon component for direct usage with color and size support\n * Uses IconResolver internally to support both static and dynamic icons\n *\n * Supports both Tailwind color names (e.g., \"blue\", \"red\", \"zinc\") and hex colors (e.g., \"#ff0000\", \"#666\")\n */\nexport interface DynamicIconProps {\n name: string | null;\n color?: string | undefined;\n size?: number | undefined;\n className?: string | undefined;\n fallbackIcon?: string | undefined;\n}\n\nexport const DynamicIcon: React.FC<DynamicIconProps> = ({\n name,\n color = \"gray\",\n size = 4,\n className,\n fallbackIcon = \"Zap\",\n}) => {\n const isHex = color && isHexColor(color);\n const colorClass = isHex ? null : getTextColorClass(color);\n const sizeClass = `h-${size} w-${size}`;\n\n // Build className: always include size, include colorClass if not hex, include custom className\n const combinedClassName = [sizeClass, !isHex && colorClass, className]\n .filter(Boolean)\n .join(\" \")\n .trim();\n\n // If hex color, apply as inline style\n const style = isHex ? { color } : undefined;\n\n return (\n <IconResolver\n iconName={name}\n className={combinedClassName}\n fallbackIcon={fallbackIcon}\n style={style}\n />\n );\n};\n","/**\n * Minimal className join — the only piece of `cn` this package needs.\n * No tailwind-merge / clsx dependency by design: callers pass literal strings.\n */\nexport function cn(\n ...values: Array<string | null | undefined | false>\n): string {\n return values.filter(Boolean).join(\" \").trim();\n}\n"],"mappings":";;;AAGA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAOA,IAAM,sBAAyD;AAAA,EACpE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAQO,SAAS,kBAAkB,KAA8C;AAC9E,SAAO,OAAO,qBAAqB,GAAG;AACxC;;;AC1RA,IAAM,sBAAoD;AAAA,EACxD,SAAS;AAAA,EACT,UAAU;AAAA,EACV,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,SAAS;AAAA,EACT,iBAAiB;AAAA,EACjB,oBAAoB;AAAA,EACpB,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,WAAW;AAAA,EACX,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,WAAW;AAAA,EACX,mBAAmB;AAAA,EACnB,yBAAyB;AAAA,EACzB,yBAAyB;AAAA,EACzB,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,aAAa;AACf;AAGO,IAAM,kBAAqD,CAAC;AAG5D,SAAS,iBAAiB,MAAuB;AACtD,SAAO,OAAO,UAAU,eAAe,KAAK,qBAAqB,IAAI;AACvE;AAGO,SAAS,sBAAgC;AAC9C,SAAO,OAAO,KAAK,mBAAmB;AACxC;AAOA,eAAsB,eACpB,MACmC;AACnC,QAAM,SAAS,gBAAgB,IAAI;AACnC,MAAI,QAAQ;AACV,WAAO;AAAA,EACT;AACA,QAAM,SAAS,oBAAoB,IAAI;AACvC,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,MACJ,WAAW,OACP,MAAM,OAAO,gBAAgB,IAC7B,MAAM,OAAO,iBAAiB;AACpC,UAAM,WAAW,IAAI,IAAI;AACzB,QAAI,OAAO,aAAa,YAAY;AAClC,aAAO;AAAA,IACT;AACA,UAAM,gBAAgB;AACtB,oBAAgB,IAAI,IAAI;AACxB,WAAO;AAAA,EACT,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;;;ACnFA,IAAM,kBAA0C,CAAC;AAEjD,IAAM,aAAa;AAMZ,SAAS,iBAAiB,KAAmC;AAClE,aAAW,CAAC,OAAO,IAAI,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC/C,UAAM,KAAK,MAAM,WAAW,UAAU,IAClC,MAAM,MAAM,WAAW,MAAM,EAAE,QAAQ,QAAQ,EAAE,IACjD,MAAM,QAAQ,QAAQ,EAAE;AAC5B,QAAI,MAAM,MAAM;AACd,sBAAgB,EAAE,IAAI;AAAA,IACxB;AAAA,EACF;AACF;AAGO,SAAS,iBAAiB,OAA8B;AAC7D,MAAI,CAAC,MAAM,WAAW,UAAU,GAAG;AACjC,WAAO;AAAA,EACT;AACA,QAAM,KAAK,MAAM,MAAM,WAAW,MAAM,EAAE,QAAQ,QAAQ,EAAE;AAC5D,QAAM,OAAO,gBAAgB,EAAE;AAC/B,SAAO,QAAQ;AACjB;AAGO,SAAS,eAAe,OAA2C;AACxE,MAAI,CAAC,SAAS,CAAC,MAAM,WAAW,UAAU,GAAG;AAC3C,WAAO;AAAA,EACT;AACA,QAAM,KAAK,MAAM,MAAM,WAAW,MAAM,EAAE,QAAQ,QAAQ,EAAE;AAC5D,SAAO,QAAQ,gBAAgB,EAAE,CAAC;AACpC;AAGO,SAAS,oBAA8B;AAC5C,SAAO,OAAO,KAAK,eAAe,EAAE,IAAI,CAAC,OAAO,GAAG,UAAU,GAAG,EAAE,EAAE;AACtE;;;ACtCO,SAAS,yBAAyB,KAA4B;AACnE,MAAI,IAAI,IAAI,KAAK;AACjB,MAAI,CAAC,EAAG,QAAO;AACf,MACG,EAAE,WAAW,GAAG,KAAK,EAAE,SAAS,GAAG,KAAK,EAAE,UAAU,KACpD,EAAE,WAAW,GAAG,KAAK,EAAE,SAAS,GAAG,KAAK,EAAE,UAAU,GACrD;AACA,QAAI,EAAE,MAAM,GAAG,EAAE,EAAE,KAAK;AAAA,EAC1B;AACA,QAAM,IAAI,EAAE,MAAM,mDAAmD;AACrE,SAAO,IAAI,CAAC,KAAK;AACnB;AAGO,SAAS,4BAA4B,KAAqB;AAC/D,QAAM,IAAI,IAAI,KAAK;AACnB,MAAI,CAAC,EAAE,SAAS,GAAG,GAAG;AACpB,WAAO;AAAA,EACT;AACA,SAAO,EACJ,MAAM,GAAG,EACT,OAAO,OAAO,EACd,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC,EAAE,YAAY,CAAC,EACrE,KAAK,EAAE;AACZ;AAMO,SAAS,gCAAgC,KAAuB;AACrE,QAAM,IAAI,IAAI,KAAK;AACnB,MAAI,CAAC,GAAG;AACN,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,MAAgB,CAAC;AACvB,QAAM,OAAO,CAAC,MAAc;AAC1B,QAAI,KAAK,CAAC,IAAI,SAAS,CAAC,GAAG;AACzB,UAAI,KAAK,CAAC;AAAA,IACZ;AAAA,EACF;AAEA,OAAK,CAAC;AAEN,MAAI,EAAE,CAAC,MAAM,EAAE,CAAC,EAAG,YAAY,GAAG;AAChC,SAAK,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,EAAE,MAAM,CAAC,CAAC;AAAA,EAC7C;AAEA,MAAI,EAAE,SAAS,GAAG,GAAG;AACnB,SAAK,4BAA4B,CAAC,CAAC;AACnC,UAAM,QAAQ,EAAE,YAAY;AAC5B,QAAI,UAAU,GAAG;AACf,WAAK,4BAA4B,KAAK,CAAC;AAAA,IACzC;AAAA,EACF;AAEA,SAAO;AACT;;;AClEA,IAAM,4BAA4B,oBAAI,IAAI,CAAC,WAAW,kBAAkB,CAAC;AAOlE,SAAS,yBACd,MACA,UACS;AACT,MAAI,CAAC,QAAQ,0BAA0B,IAAI,IAAI,EAAG,QAAO;AACzD,MAAI,YAAY,KAAM,QAAO;AAC7B,MAAI,OAAO,aAAa,WAAY,QAAO;AAC3C,MAAI,OAAO,aAAa,YAAY,cAAe,UAAqB;AACtE,WAAO;AAAA,EACT;AACA,SAAO;AACT;;;ACpBA,SAAgB,UAAU,iBAAiB;;;ACEpC,SAAS,MACX,QACK;AACR,SAAO,OAAO,OAAO,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK;AAC/C;;;ADmMM;AApLN,IAAM,mBAAsD,CAAC;AAMtD,SAAS,6BAAuC;AACrD,QAAM,MAAM,oBAAI,IAAY;AAC5B,aAAW,KAAK,OAAO,KAAK,mBAAmB,GAAG;AAChD,QAAI,IAAI,CAAC;AAAA,EACX;AACA,aAAW,KAAK,oBAAoB,GAAG;AACrC,QAAI,IAAI,CAAC;AAAA,EACX;AACA,aAAW,MAAM,kBAAkB,GAAG;AACpC,QAAI,IAAI,EAAE;AAAA,EACZ;AACA,SAAO,MAAM,KAAK,GAAG,EAAE;AAAA,IAAK,CAAC,GAAG,MAC9B,EAAE,cAAc,GAAG,QAAW,EAAE,aAAa,OAAO,CAAC;AAAA,EACvD;AACF;AAQO,SAAS,qBACd,UACS;AACT,MAAI,CAAC,YAAY,SAAS,KAAK,MAAM,IAAI;AACvC,WAAO;AAAA,EACT;AACA,QAAM,OAAO;AACb,MAAI,iBAAiB,IAAI,EAAG,QAAO;AACnC,MAAI,oBAAoB,IAAI,EAAG,QAAO;AACtC,SAAO,QAAQ,iBAAiB,IAAI,CAAC;AACvC;AAQA,eAAsB,6BACpB,UACkB;AAClB,MAAI,CAAC,YAAY,SAAS,KAAK,MAAM,IAAI;AACvC,WAAO;AAAA,EACT;AACA,MAAI,eAAe,QAAQ,GAAG;AAC5B,WAAO;AAAA,EACT;AACA,MAAI,qBAAqB,QAAQ,GAAG;AAClC,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,aAAa,MAAM,OAAO,cAAc;AAC9C,UAAM,WAAW,WAAW,QAAmC;AAC/D,WAAO,yBAAyB,UAAU,QAAQ;AAAA,EACpD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AA4BA,IAAM,eAA4C,CAAC;AAAA,EACjD;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA,eAAe;AAAA,EACf;AACF,MAAM;AACJ,QAAM,SAAS,WAAW,iBAAiB,QAAQ,IAAI;AACvD,QAAM,CAACA,cAAa,cAAc,IAAI,SAAmC,IAAI;AAC7E,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAEhD,YAAU,MAAM;AACd,UAAM,WAAW,YAAY;AAC3B,UAAI,CAAC,UAAU;AACb,uBAAe,IAAI;AACnB,qBAAa,KAAK;AAClB;AAAA,MACF;AAEA,UAAI,iBAAiB,QAAQ,GAAG;AAC9B,uBAAe,IAAI;AACnB,qBAAa,KAAK;AAClB;AAAA,MACF;AAGA,YAAM,eAAe,gBAAgB,QAAQ;AAC7C,UAAI,cAAc;AAChB,uBAAe,MAAM,YAAY;AACjC;AAAA,MACF;AAGA,YAAM,aAAa,oBAAoB,QAAQ;AAC/C,UAAI,YAAY;AACd,uBAAe,MAAM,UAAU;AAC/B;AAAA,MACF;AAGA,YAAM,gBAAgB,iBAAiB,QAAQ;AAC/C,UAAI,eAAe;AACjB,uBAAe,MAAM,aAAa;AAClC;AAAA,MACF;AAIA,UAAI,iBAAiB,QAAQ,GAAG;AAC9B,qBAAa,IAAI;AACjB,cAAM,SAAS,MAAM,eAAe,QAAQ;AAC5C,YAAI,QAAQ;AACV,yBAAe,MAAM,MAAM;AAAA,QAC7B,OAAO;AACL,yBAAe,MAAM,oBAAoB,YAAY,KAAK,GAAG;AAAA,QAC/D;AACA,qBAAa,KAAK;AAClB;AAAA,MACF;AAGA,mBAAa,IAAI;AACjB,UAAI;AACF,cAAM,aAAa,MAAM,OAAO,cAAc;AAC9C,cAAM,WAAoB,WAAW,QAAmC;AAExE,YAAI,yBAAyB,UAAU,QAAQ,GAAG;AAChD,gBAAMC,iBAAgB;AACtB,2BAAiB,QAAQ,IAAIA;AAC7B,yBAAe,MAAMA,cAAa;AAAA,QACpC,OAAO;AAEL,yBAAe,MAAM,oBAAoB,YAAY,KAAK,GAAG;AAAA,QAC/D;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,KAAK,wBAAwB,QAAQ,IAAI,KAAK;AACtD,uBAAe,MAAM,oBAAoB,YAAY,KAAK,GAAG;AAAA,MAC/D,UAAE;AACA,qBAAa,KAAK;AAAA,MACpB;AAAA,IACF;AAEA,aAAS;AAAA,EACX,GAAG,CAAC,UAAU,YAAY,CAAC;AAE3B,MAAI,QAAQ;AACV,WACE;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,KAAI;AAAA,QACJ,WAAW,GAAG,2BAA2B,SAAS;AAAA,QAClD,OAAO;AAAA,QACP,QAAQ;AAAA,QACR;AAAA;AAAA,IACF;AAAA,EAEJ;AAGA,QAAM,gBAAgBD,gBAAe,oBAAoB,YAAY,KAAK;AAG1E,QAAM,YAA6B;AAAA,IACjC,GAAI,cAAc,SAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IAC/C,GAAI,SAAS,SAAY,EAAE,KAAK,IAAI,CAAC;AAAA,IACrC,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC;AAAA,EACzC;AAGA,MAAI,aAAa,CAACA,cAAa;AAC7B,UAAM,eAAe,oBAAoB,YAAY,KAAK;AAC1D,WAAO,oBAAC,gBAAc,GAAG,WAAW;AAAA,EACtC;AAEA,SAAO,oBAAC,iBAAe,GAAG,WAAW;AACvC;AAEA,IAAO,mBAAQ;AAWR,IAAM,mBAAmB,CAC9B,UACA,eAAuB,UACD;AACtB,MAAI,CAAC,UAAU;AACb,WAAO,oBAAoB,YAAY,KAAK;AAAA,EAC9C;AAGA,QAAM,SAAS,gBAAgB,QAAQ;AACvC,MAAI,QAAQ;AACV,WAAO;AAAA,EACT;AAGA,QAAM,aAAa,oBAAoB,QAAQ;AAC/C,MAAI,YAAY;AACd,WAAO;AAAA,EACT;AAGA,QAAM,UAAU,iBAAiB,QAAQ;AACzC,MAAI,SAAS;AACX,WAAO;AAAA,EACT;AAGA,SAAO,oBAAoB,YAAY,KAAK;AAC9C;AAMO,IAAM,aAAa,CACxB,UACA,OACA,eAAuB,UACpB;AACH,QAAM,gBAAgB,iBAAiB,UAAU,YAAY;AAC7D,SAAO,oBAAC,iBAAe,GAAG,OAAO;AACnC;AAKO,IAAM,aAAa,CAAC,UAA2B;AACpD,SAAO,qCAAqC,KAAK,KAAK;AACxD;AAEO,IAAM,oBAAoB,CAAC,UAAmB;AACnD,MAAI,CAAC,MAAO,QAAO;AAGnB,MAAI,WAAW,KAAK,EAAG,QAAO;AAE9B,QAAM,WAAmC;AAAA,IACvC,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,IACT,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,KAAK;AAAA,IACL,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAEA,SAAO,SAAS,MAAM,YAAY,CAAC,KAAK;AAC1C;AAOO,IAAM,0BAA0B,CACrC,UACA,QAAgB,QAChB,OAAe,MACZ;AACH,QAAM,gBAAgB,iBAAiB,QAAQ;AAC/C,QAAM,aAAa,kBAAkB,KAAK;AAC1C,SAAO,oBAAC,iBAAc,WAAW,KAAK,IAAI,MAAM,IAAI,IAAI,UAAU,IAAI;AACxE;AAgBO,IAAM,cAA0C,CAAC;AAAA,EACtD;AAAA,EACA,QAAQ;AAAA,EACR,OAAO;AAAA,EACP;AAAA,EACA,eAAe;AACjB,MAAM;AACJ,QAAM,QAAQ,SAAS,WAAW,KAAK;AACvC,QAAM,aAAa,QAAQ,OAAO,kBAAkB,KAAK;AACzD,QAAM,YAAY,KAAK,IAAI,MAAM,IAAI;AAGrC,QAAM,oBAAoB,CAAC,WAAW,CAAC,SAAS,YAAY,SAAS,EAClE,OAAO,OAAO,EACd,KAAK,GAAG,EACR,KAAK;AAGR,QAAM,QAAQ,QAAQ,EAAE,MAAM,IAAI;AAElC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV,WAAW;AAAA,MACX;AAAA,MACA;AAAA;AAAA,EACF;AAEJ;","names":["DynamicIcon","IconComponent"]}
1
+ {"version":3,"sources":["../src/static-icons.ts","../src/custom-icons.ts","../src/svg-registry.ts","../src/lucide-name-normalize.ts","../src/lucide-module-icon.ts","../src/resolver.tsx","../src/cn.ts"],"sourcesContent":["// Statically import commonly used Lucide icons to reduce bundle size.\n// This curated hot set is the product: a hit here renders synchronously,\n// with zero dynamic-import latency and no fallback flash.\nimport {\n Zap,\n Home,\n User,\n Settings,\n Search,\n Bell,\n Menu,\n X,\n ChevronDown,\n ChevronUp,\n ChevronLeft,\n ChevronRight,\n Plus,\n Minus,\n Edit,\n Trash,\n Check,\n AlertCircle,\n Info,\n HelpCircle,\n Eye,\n EyeOff,\n Copy,\n Download,\n Upload,\n Save,\n MoreVertical,\n MoreHorizontal,\n Filter,\n SortAsc,\n SortDesc,\n Calendar,\n Clock,\n Mail,\n Phone,\n MapPin,\n Link,\n ExternalLink,\n File,\n Folder,\n Image,\n Video,\n Music,\n FileText,\n Database,\n Cloud,\n Server,\n Code,\n Terminal,\n Globe,\n Lock,\n Unlock,\n Shield,\n Key,\n LogIn,\n LogOut,\n UserPlus,\n Users,\n Star,\n Heart,\n Bookmark,\n Share,\n Send,\n MessageSquare,\n MessageCircle,\n Hash,\n AtSign,\n Paperclip,\n Mic,\n Volume2,\n Play,\n Pause,\n SkipForward,\n SkipBack,\n RefreshCw,\n RotateCw,\n Loader,\n Loader2,\n Circle,\n Square,\n Triangle,\n Hexagon,\n Package,\n Box,\n Archive,\n Inbox,\n Layers,\n Layout,\n Grid,\n List,\n Columns,\n Sidebar,\n Maximize,\n Minimize,\n ZoomIn,\n ZoomOut,\n Move,\n Scissors,\n Clipboard,\n PieChart,\n BarChart,\n TrendingUp,\n TrendingDown,\n Activity,\n Cpu,\n HardDrive,\n Wifi,\n WifiOff,\n Bluetooth,\n Battery,\n BatteryCharging,\n Power,\n Sun,\n Moon,\n CloudRain,\n Droplet,\n Wind,\n Tag,\n Tags,\n Flag,\n Award,\n Gift,\n ShoppingCart,\n CreditCard,\n DollarSign,\n Percent,\n Target,\n Crosshair,\n Navigation,\n Compass,\n Map,\n Smile,\n Frown,\n Meh,\n ThumbsUp,\n ThumbsDown,\n} from \"lucide-react\";\nimport type { IconComponentType } from \"./types\";\n\nexport { Zap as fallbackZapIcon };\n\n// Statically imported Lucide icons map (commonly used icons for optimal bundle size)\n// Exported so callers can spread it as a scope without importing the full lucide namespace.\nexport const staticLucideIconMap: Record<string, IconComponentType> = {\n Zap,\n Home,\n User,\n Settings,\n Search,\n Bell,\n Menu,\n X,\n ChevronDown,\n ChevronUp,\n ChevronLeft,\n ChevronRight,\n Plus,\n Minus,\n Edit,\n Trash,\n Check,\n AlertCircle,\n Info,\n HelpCircle,\n Eye,\n EyeOff,\n Copy,\n Download,\n Upload,\n Save,\n MoreVertical,\n MoreHorizontal,\n Filter,\n SortAsc,\n SortDesc,\n Calendar,\n Clock,\n Mail,\n Phone,\n MapPin,\n Link,\n ExternalLink,\n File,\n Folder,\n Image,\n Video,\n Music,\n FileText,\n Database,\n Cloud,\n Server,\n Code,\n Terminal,\n Globe,\n Lock,\n Unlock,\n Shield,\n Key,\n LogIn,\n LogOut,\n UserPlus,\n Users,\n Star,\n Heart,\n Bookmark,\n Share,\n Send,\n MessageSquare,\n MessageCircle,\n Hash,\n AtSign,\n Paperclip,\n Mic,\n Volume2,\n Play,\n Pause,\n SkipForward,\n SkipBack,\n RefreshCw,\n RotateCw,\n Loader,\n Loader2,\n Circle,\n Square,\n Triangle,\n Hexagon,\n Package,\n Box,\n Archive,\n Inbox,\n Layers,\n Layout,\n Grid,\n List,\n Columns,\n Sidebar,\n Maximize,\n Minimize,\n ZoomIn,\n ZoomOut,\n Move,\n Scissors,\n Clipboard,\n PieChart,\n BarChart,\n TrendingUp,\n TrendingDown,\n Activity,\n Cpu,\n HardDrive,\n Wifi,\n WifiOff,\n Bluetooth,\n Battery,\n BatteryCharging,\n Power,\n Sun,\n Moon,\n CloudRain,\n Droplet,\n Wind,\n Tag,\n Tags,\n Flag,\n Award,\n Gift,\n ShoppingCart,\n CreditCard,\n DollarSign,\n Percent,\n Target,\n Crosshair,\n Navigation,\n Compass,\n Map,\n Smile,\n Frown,\n Meh,\n ThumbsUp,\n ThumbsDown,\n};\n\n/**\n * Extend the static (synchronous, zero-latency) icon map with host-supplied\n * components — extra statically imported Lucide icons a host uses on hot paths,\n * or any component matching {@link IconComponentType}. Merges in place; later\n * registrations override earlier entries of the same name.\n */\nexport function extendStaticIcons(map: Record<string, IconComponentType>): void {\n Object.assign(staticLucideIconMap, map);\n}\n","/**\n * Curated brand/custom icon names served from the OPTIONAL `react-icons` peer.\n *\n * Coupling inversion vs. the original (which statically imported react-icons):\n * `react-icons` is an optional peerDependency, so these are lazy-imported on first\n * use and cached at module level. When the host has not installed `react-icons`,\n * loading degrades to null and the resolver renders the fallback icon instead —\n * no install-time or import-time failure.\n */\nimport type { IconComponentType } from \"./types\";\n\n/** name → react-icons subpackage the export lives in. */\nconst CUSTOM_ICON_SOURCES: Record<string, \"fc\" | \"fa6\"> = {\n FaBrave: \"fa6\",\n FcGoogle: \"fc\",\n FcBrokenLink: \"fc\",\n FcFilm: \"fc\",\n FcDownload: \"fc\",\n FcBiotech: \"fc\",\n FcElectronics: \"fc\",\n FcGraduationCap: \"fc\",\n FcLibrary: \"fc\",\n FcMusic: \"fc\",\n FcParallelTasks: \"fc\",\n FcSalesPerformance: \"fc\",\n FcCalendar: \"fc\",\n FcDocument: \"fc\",\n FcEngineering: \"fc\",\n FcDataProtection: \"fc\",\n FcAssistant: \"fc\",\n FcSms: \"fc\",\n FcTodoList: \"fc\",\n FcWikipedia: \"fc\",\n FcCommandLine: \"fc\",\n FcConferenceCall: \"fc\",\n FcManager: \"fc\",\n FcAreaChart: \"fc\",\n FcMultipleInputs: \"fc\",\n FcShipped: \"fc\",\n FcBusinessContact: \"fc\",\n FcAlphabeticalSortingAz: \"fc\",\n FcAlphabeticalSortingZa: \"fc\",\n FcFeedback: \"fc\",\n FcBusiness: \"fc\",\n FcSignature: \"fc\",\n};\n\n/**\n * Cache for lazily loaded custom icons (also the sync-lookup source once\n * loaded). Lives on a globalThis Symbol.for slot, NOT module state — dual\n * ESM/CJS unsplit bundles each instantiate their own module graph, and a\n * module-level cache would load the same icon once per graph and let a\n * sync lookup miss what the other graph already loaded. Never \"clean this up\".\n */\nconst CUSTOM_CACHE_SLOT = Symbol.for(\"ai-matrx.icons.custom-icon-cache\");\nexport const customIconCache: Record<string, IconComponentType> = (() => {\n const holder = globalThis as Record<\n symbol,\n Record<string, IconComponentType> | undefined\n >;\n let cache = holder[CUSTOM_CACHE_SLOT];\n if (!cache) {\n cache = {};\n holder[CUSTOM_CACHE_SLOT] = cache;\n }\n return cache;\n})();\n\n/** True when `name` is one of the curated custom (react-icons) ids. */\nexport function isCustomIconName(name: string): boolean {\n return Object.prototype.hasOwnProperty.call(CUSTOM_ICON_SOURCES, name);\n}\n\n/** The curated custom icon ids (known without loading react-icons). */\nexport function listCustomIconNames(): string[] {\n return Object.keys(CUSTOM_ICON_SOURCES);\n}\n\n/**\n * Lazy-load a curated custom icon from the optional `react-icons` peer.\n * Returns null for unknown names, a missing export, or when `react-icons`\n * is not installed — the caller degrades to the fallback icon.\n */\nexport async function loadCustomIcon(\n name: string,\n): Promise<IconComponentType | null> {\n const cached = customIconCache[name];\n if (cached) {\n return cached;\n }\n const source = CUSTOM_ICON_SOURCES[name];\n if (!source) {\n return null;\n }\n try {\n const mod: Record<string, unknown> =\n source === \"fc\"\n ? await import(\"react-icons/fc\")\n : await import(\"react-icons/fa6\");\n const exported = mod[name];\n if (typeof exported !== \"function\") {\n return null;\n }\n const IconComponent = exported as IconComponentType;\n customIconCache[name] = IconComponent;\n return IconComponent;\n } catch {\n // react-icons not installed (optional peer) — degrade to the fallback icon.\n return null;\n }\n}\n","/**\n * Injectable registry for host-owned SVG assets. Stored icon ids use the form\n * `svg:<path-without-leading-slash-and-without-extension>` e.g. `svg:icons/Home`\n * → whatever URL the host registered for the id `icons/Home` (typically `/icons/Home.svg`).\n *\n * The package ships EMPTY — the host application registers its own asset paths once at\n * startup via {@link registerSvgIcons}. An unregistered `svg:` value resolves to null\n * and the resolver falls back exactly as it does for an unknown Lucide name.\n */\n// The registry lives on a globalThis Symbol.for slot, NOT module state: with\n// dual ESM/CJS unsplit bundles each loader graph instantiates its own module,\n// and a module-level map would silently split the host's registrations from\n// a consumer resolving through the other graph. Never \"clean this up\".\nconst SVG_REGISTRY_SLOT = Symbol.for(\"ai-matrx.icons.svg-registry\");\nconst svgIconRegistry: Record<string, string> = (() => {\n const holder = globalThis as Record<symbol, Record<string, string> | undefined>;\n let reg = holder[SVG_REGISTRY_SLOT];\n if (!reg) {\n reg = {};\n holder[SVG_REGISTRY_SLOT] = reg;\n }\n return reg;\n})();\n\nconst SVG_PREFIX = \"svg:\";\n\n/**\n * Register (or override) `svg:` icon ids → asset URLs. Merges into the module-level\n * registry, so multiple calls compose. Ids are stored without the `svg:` prefix.\n */\nexport function registerSvgIcons(map: Record<string, string>): void {\n for (const [rawId, path] of Object.entries(map)) {\n const id = rawId.startsWith(SVG_PREFIX)\n ? rawId.slice(SVG_PREFIX.length).replace(/^\\/+/, \"\")\n : rawId.replace(/^\\/+/, \"\");\n if (id && path) {\n svgIconRegistry[id] = path;\n }\n }\n}\n\n/** The registered asset URL for a `svg:…` icon value, or null when not a registered svg icon. */\nexport function parseSvgIconPath(value: string): string | null {\n if (!value.startsWith(SVG_PREFIX)) {\n return null;\n }\n const id = value.slice(SVG_PREFIX.length).replace(/^\\/+/, \"\");\n const path = svgIconRegistry[id];\n return path ?? null;\n}\n\n/** True if `value` is a `svg:…` id with a registered asset path. */\nexport function isSvgIconValue(value: string | null | undefined): boolean {\n if (!value || !value.startsWith(SVG_PREFIX)) {\n return false;\n }\n const id = value.slice(SVG_PREFIX.length).replace(/^\\/+/, \"\");\n return Boolean(svgIconRegistry[id]);\n}\n\n/** Every registered svg icon value, `svg:` prefix included (for pickers/galleries). */\nexport function listSvgIconValues(): string[] {\n return Object.keys(svgIconRegistry).map((id) => `${SVG_PREFIX}${id}`);\n}\n","/**\n * Lucide.dev lists icons in kebab-case (e.g. `alarm-clock`); the React package\n * exports PascalCase (`AlarmClock`). Normalize pasted / typed names into candidates\n * to validate against `lucide-react` exports.\n */\n\n/**\n * If the user pasted Lucide's JSX snippet (e.g. `'<BugPlay />'` or `<AlignCenterHorizontal />`),\n * return the component name only. Otherwise return null.\n *\n * Supports optional outer quotes and optional attributes before the closing `/>`.\n */\nexport function extractLucideJsxIconName(raw: string): string | null {\n let s = raw.trim();\n if (!s) return null;\n if (\n (s.startsWith(\"'\") && s.endsWith(\"'\") && s.length >= 2) ||\n (s.startsWith('\"') && s.endsWith('\"') && s.length >= 2)\n ) {\n s = s.slice(1, -1).trim();\n }\n const m = s.match(/^<\\s*([A-Za-z][A-Za-z0-9]*)(?:\\s[^>]*)?\\s*\\/\\s*>$/);\n return m?.[1] ?? null;\n}\n\n/** `alarm-clock` → `AlarmClock`, `a-arrow-down` → `AArrowDown` */\nexport function kebabCaseToLucidePascalCase(raw: string): string {\n const s = raw.trim();\n if (!s.includes(\"-\")) {\n return s;\n }\n return s\n .split(\"-\")\n .filter(Boolean)\n .map((seg) => seg.charAt(0).toUpperCase() + seg.slice(1).toLowerCase())\n .join(\"\");\n}\n\n/**\n * Ordered unique candidates: exact input, first-letter fix, kebab → Pascal variants.\n * Skip Lucide heuristics for `svg:…` asset values (caller should pass only those as `[trimmed]`).\n */\nexport function collectLucideIconNameCandidates(raw: string): string[] {\n const t = raw.trim();\n if (!t) {\n return [];\n }\n\n const out: string[] = [];\n const push = (s: string) => {\n if (s && !out.includes(s)) {\n out.push(s);\n }\n };\n\n push(t);\n\n if (t[0] === t[0]!.toLowerCase()) {\n push(t.charAt(0).toUpperCase() + t.slice(1));\n }\n\n if (t.includes(\"-\")) {\n push(kebabCaseToLucidePascalCase(t));\n const lower = t.toLowerCase();\n if (lower !== t) {\n push(kebabCaseToLucidePascalCase(lower));\n }\n }\n\n return out;\n}\n","/**\n * lucide-react namespaced exports: icons are ForwardRef/Memo objects in current builds,\n * not plain functions. Only createLucideIcon and default are non-icon exports we skip.\n */\nconst LUCIDE_NAMESPACE_DENYLIST = new Set([\"default\", \"createLucideIcon\"]);\n\n/**\n * True if `exported` is the value of a Lucide icon entry for `name` in `import * as Lucide`.\n * Does not mean the icon exists in the static resolver map — only that the lucide-react\n * module exposes this name as a renderable component type.\n */\nexport function isLucideModuleIconExport(\n name: string,\n exported: unknown,\n): boolean {\n if (!name || LUCIDE_NAMESPACE_DENYLIST.has(name)) return false;\n if (exported == null) return false;\n if (typeof exported === \"function\") return true;\n if (typeof exported === \"object\" && \"$$typeof\" in (exported as object)) {\n return true;\n }\n return false;\n}\n","\"use client\";\n\nimport React, { useState, useEffect } from \"react\";\nimport { cn } from \"./cn\";\nimport {\n staticLucideIconMap,\n fallbackZapIcon as Zap,\n} from \"./static-icons\";\nimport {\n customIconCache,\n isCustomIconName,\n listCustomIconNames,\n loadCustomIcon,\n} from \"./custom-icons\";\nimport { isLucideModuleIconExport } from \"./lucide-module-icon\";\nimport {\n isSvgIconValue,\n listSvgIconValues,\n parseSvgIconPath,\n} from \"./svg-registry\";\nimport type { IconComponentType, IconRenderProps } from \"./types\";\n\n// Cache for dynamically loaded icons to prevent re-importing. Lives on a\n// globalThis Symbol.for slot, NOT module state — dual ESM/CJS unsplit bundles\n// each instantiate their own module graph, and a per-graph cache would\n// re-import icons the other graph already resolved. Never \"clean this up\".\nconst DYNAMIC_CACHE_SLOT = Symbol.for(\"ai-matrx.icons.dynamic-icon-cache\");\nconst dynamicIconCache: Record<string, IconComponentType> = (() => {\n const holder = globalThis as Record<\n symbol,\n Record<string, IconComponentType> | undefined\n >;\n let cache = holder[DYNAMIC_CACHE_SLOT];\n if (!cache) {\n cache = {};\n holder[DYNAMIC_CACHE_SLOT] = cache;\n }\n return cache;\n})();\n\n/**\n * Finite list for a curated icon gallery: every statically bundled Lucide name,\n * curated custom ids (react-icons), and all registered `svg:…` assets.\n */\nexport function getCuratedIconIdsForPicker(): string[] {\n const set = new Set<string>();\n for (const k of Object.keys(staticLucideIconMap)) {\n set.add(k);\n }\n for (const k of listCustomIconNames()) {\n set.add(k);\n }\n for (const id of listSvgIconValues()) {\n set.add(id);\n }\n return Array.from(set).sort((a, b) =>\n a.localeCompare(b, undefined, { sensitivity: \"base\" }),\n );\n}\n\n/**\n * True if this exact name maps to a known icon (static Lucide, curated custom id, or\n * previously resolved dynamic Lucide cached under this key).\n *\n * Does not import lucide-react — use with {@link isRegisteredOrLucideIconName} for full checks.\n */\nexport function isIconRegisteredSync(\n iconName: string | null | undefined,\n): boolean {\n if (!iconName || iconName.trim() === \"\") {\n return false;\n }\n const name = iconName;\n if (isCustomIconName(name)) return true;\n if (staticLucideIconMap[name]) return true;\n return Boolean(dynamicIconCache[name]);\n}\n\n/**\n * True if `iconName` is a real icon id: custom/static/cached, a registered `svg:…`\n * asset, or a Lucide export that is a renderable component (not the fallback Zap).\n *\n * Prefer this over truthiness on {@link getIconComponent}, which always returns a component.\n */\nexport async function isRegisteredOrLucideIconName(\n iconName: string | null | undefined,\n): Promise<boolean> {\n if (!iconName || iconName.trim() === \"\") {\n return false;\n }\n if (isSvgIconValue(iconName)) {\n return true;\n }\n if (isIconRegisteredSync(iconName)) {\n return true;\n }\n try {\n const iconModule = await import(\"lucide-react\");\n const Exported = iconModule[iconName as keyof typeof iconModule];\n return isLucideModuleIconExport(iconName, Exported);\n } catch {\n return false;\n }\n}\n\n/**\n * HOW TO ADD MORE STATIC ICONS:\n *\n * The curated hot set ships in the package (src/static-icons.ts). A host that\n * frequently renders an icon outside the set keeps it zero-latency by statically\n * importing it and registering it once at startup:\n *\n * import { YourIcon } from \"lucide-react\";\n * import { extendStaticIcons } from \"@ai-matrx/icons\";\n * extendStaticIcons({ YourIcon });\n */\n\nexport interface IconResolverProps {\n iconName: string | null;\n className?: string | undefined;\n size?: number | undefined;\n fallbackIcon?: string | undefined;\n style?: React.CSSProperties | undefined;\n}\n\n/**\n * IconResolver - A unified component for resolving and rendering icons by name\n * Uses hybrid approach: static imports for common icons, dynamic imports for others\n * Supports all lucide-react icons, curated custom icons (optional react-icons peer),\n * and registered `svg:…` public assets.\n */\nconst IconResolver: React.FC<IconResolverProps> = ({\n iconName,\n className = \"h-4 w-4\",\n size,\n fallbackIcon = \"Zap\",\n style,\n}) => {\n const svgSrc = iconName ? parseSvgIconPath(iconName) : null;\n const [DynamicIcon, setDynamicIcon] = useState<IconComponentType | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n\n useEffect(() => {\n let cancelled = false;\n const loadIcon = async () => {\n if (!iconName) {\n setDynamicIcon(null);\n setIsLoading(false);\n return;\n }\n\n if (parseSvgIconPath(iconName)) {\n setDynamicIcon(null);\n setIsLoading(false);\n return;\n }\n\n // Check custom icons first (already-loaded cache hit is synchronous)\n const cachedCustom = customIconCache[iconName];\n if (cachedCustom) {\n setDynamicIcon(() => cachedCustom);\n return;\n }\n\n // Check statically imported Lucide icons\n const staticIcon = staticLucideIconMap[iconName];\n if (staticIcon) {\n setDynamicIcon(() => staticIcon);\n return;\n }\n\n // Check if already cached\n const cachedDynamic = dynamicIconCache[iconName];\n if (cachedDynamic) {\n setDynamicIcon(() => cachedDynamic);\n return;\n }\n\n // Curated custom icon: lazy-import the optional react-icons peer;\n // degrade to the fallback icon when it is absent.\n if (isCustomIconName(iconName)) {\n setIsLoading(true);\n const loaded = await loadCustomIcon(iconName);\n if (cancelled) return;\n if (loaded) {\n setDynamicIcon(() => loaded);\n } else {\n setDynamicIcon(() => staticLucideIconMap[fallbackIcon] || Zap);\n }\n setIsLoading(false);\n return;\n }\n\n // Dynamically import from lucide-react\n setIsLoading(true);\n try {\n const iconModule = await import(\"lucide-react\");\n if (cancelled) return;\n const exported: unknown = iconModule[iconName as keyof typeof iconModule];\n\n if (isLucideModuleIconExport(iconName, exported)) {\n const IconComponent = exported as IconComponentType;\n dynamicIconCache[iconName] = IconComponent;\n setDynamicIcon(() => IconComponent);\n } else {\n // Icon not found, use fallback\n setDynamicIcon(() => staticLucideIconMap[fallbackIcon] || Zap);\n }\n } catch (error) {\n if (cancelled) return;\n console.warn(`Failed to load icon: ${iconName}`, error);\n setDynamicIcon(() => staticLucideIconMap[fallbackIcon] || Zap);\n } finally {\n if (!cancelled) setIsLoading(false);\n }\n };\n\n loadIcon();\n // Cancellation: without it, a slow dynamic import resolving after unmount\n // (or after iconName changed) called setState on a dead/stale effect.\n return () => {\n cancelled = true;\n };\n }, [iconName, fallbackIcon]);\n\n if (svgSrc) {\n return (\n <img\n src={svgSrc}\n alt=\"\"\n className={cn(\"object-contain shrink-0\", className)}\n width={size}\n height={size}\n style={style}\n />\n );\n }\n\n // Get the icon component to render\n const IconComponent = DynamicIcon || staticLucideIconMap[fallbackIcon] || Zap;\n\n // Build exact-optional props (never pass an explicit undefined through)\n const iconProps: IconRenderProps = {\n ...(className !== undefined ? { className } : {}),\n ...(size !== undefined ? { size } : {}),\n ...(style !== undefined ? { style } : {}),\n };\n\n // Show fallback while loading dynamic icons (seamless experience)\n if (isLoading && !DynamicIcon) {\n const FallbackIcon = staticLucideIconMap[fallbackIcon] || Zap;\n return <FallbackIcon {...iconProps} />;\n }\n\n return <IconComponent {...iconProps} />;\n};\n\nexport default IconResolver;\n\n/**\n * Synchronous utility function for getting icon components directly\n * Only works with statically imported icons plus already-loaded custom/dynamic icons.\n * For dynamic Lucide icons not in the static map, use the IconResolver component instead\n *\n * **Always returns a component** (default/fallback Zap when unknown). Do not use the return\n * value to infer whether `iconName` exists — use {@link isIconRegisteredSync} or\n * {@link isRegisteredOrLucideIconName} instead.\n */\nexport const getIconComponent = (\n iconName: string | null | undefined,\n fallbackIcon: string = \"Zap\",\n): IconComponentType => {\n if (!iconName) {\n return staticLucideIconMap[fallbackIcon] || Zap;\n }\n\n // First check custom icons (loaded lazily; a hit means it is already cached)\n const custom = customIconCache[iconName];\n if (custom) {\n return custom;\n }\n\n // Then check statically imported Lucide icons\n const staticIcon = staticLucideIconMap[iconName];\n if (staticIcon) {\n return staticIcon;\n }\n\n // Check dynamic cache\n const dynamic = dynamicIconCache[iconName];\n if (dynamic) {\n return dynamic;\n }\n\n // Fallback to default icon\n return staticLucideIconMap[fallbackIcon] || Zap;\n};\n\n/**\n * Renders an icon element directly with optional props\n * This is the preferred method for rendering icons in JSX\n */\nexport const renderIcon = (\n iconName: string | null | undefined,\n props?: IconRenderProps,\n fallbackIcon: string = \"Zap\",\n) => {\n const IconComponent = getIconComponent(iconName, fallbackIcon);\n return <IconComponent {...props} />;\n};\n\n/**\n * Utility to detect if a string is a hex color code\n */\nexport const isHexColor = (color: string): boolean => {\n return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(color);\n};\n\nexport const getTextColorClass = (color?: string) => {\n if (!color) return \"text-gray-600 dark:text-gray-400\";\n\n // If it's a hex color, return null (we'll use inline styles instead)\n if (isHexColor(color)) return null;\n\n const colorMap: Record<string, string> = {\n gray: \"text-gray-600 dark:text-gray-400\",\n rose: \"text-rose-600 dark:text-rose-400\",\n blue: \"text-blue-600 dark:text-blue-400\",\n amber: \"text-amber-600 dark:text-amber-400\",\n cyan: \"text-cyan-600 dark:text-cyan-400\",\n emerald: \"text-emerald-600 dark:text-emerald-400\",\n fuchsia: \"text-fuchsia-600 dark:text-fuchsia-400\",\n green: \"text-green-600 dark:text-green-400\",\n indigo: \"text-indigo-600 dark:text-indigo-400\",\n lime: \"text-lime-600 dark:text-lime-400\",\n neutral: \"text-neutral-600 dark:text-neutral-400\",\n orange: \"text-orange-600 dark:text-orange-400\",\n pink: \"text-pink-600 dark:text-pink-400\",\n purple: \"text-purple-600 dark:text-purple-400\",\n red: \"text-red-600 dark:text-red-400\",\n sky: \"text-sky-600 dark:text-sky-400\",\n slate: \"text-slate-600 dark:text-slate-400\",\n stone: \"text-stone-600 dark:text-stone-400\",\n teal: \"text-teal-600 dark:text-teal-400\",\n violet: \"text-violet-600 dark:text-violet-400\",\n yellow: \"text-yellow-600 dark:text-yellow-400\",\n zinc: \"text-zinc-600 dark:text-zinc-400\",\n };\n\n return colorMap[color.toLowerCase()] || \"text-gray-600 dark:text-gray-400\";\n};\n\n/**\n * Utility function for rendering an icon with color and size\n * Note: This is synchronous and only works with statically imported icons\n * For dynamic icons, use the DynamicIcon component instead\n */\nexport const getIconWithColorAndSize = (\n iconName: string | null,\n color: string = \"gray\",\n size: number = 4,\n) => {\n const IconComponent = getIconComponent(iconName);\n const colorClass = getTextColorClass(color);\n // Hex colors have no Tailwind class (getTextColorClass returns null) —\n // they color via inline style. The original interpolated the null into the\n // className as a literal \"null\" token; fixed in 0.1.1.\n return (\n <IconComponent\n className={cn(`h-${size} w-${size}`, colorClass)}\n {...(colorClass === null ? { style: { color } } : {})}\n />\n );\n};\n\n/**\n * Simple Icon component for direct usage with color and size support\n * Uses IconResolver internally to support both static and dynamic icons\n *\n * Supports both Tailwind color names (e.g., \"blue\", \"red\", \"zinc\") and hex colors (e.g., \"#ff0000\", \"#666\")\n */\nexport interface DynamicIconProps {\n name: string | null;\n color?: string | undefined;\n size?: number | undefined;\n className?: string | undefined;\n fallbackIcon?: string | undefined;\n}\n\nexport const DynamicIcon: React.FC<DynamicIconProps> = ({\n name,\n color = \"gray\",\n size = 4,\n className,\n fallbackIcon = \"Zap\",\n}) => {\n const isHex = color && isHexColor(color);\n const colorClass = isHex ? null : getTextColorClass(color);\n const sizeClass = `h-${size} w-${size}`;\n\n // Build className: always include size, include colorClass if not hex, include custom className\n const combinedClassName = [sizeClass, !isHex && colorClass, className]\n .filter(Boolean)\n .join(\" \")\n .trim();\n\n // If hex color, apply as inline style\n const style = isHex ? { color } : undefined;\n\n return (\n <IconResolver\n iconName={name}\n className={combinedClassName}\n fallbackIcon={fallbackIcon}\n style={style}\n />\n );\n};\n","/**\n * Minimal className join — the only piece of `cn` this package needs.\n * No tailwind-merge / clsx dependency by design: callers pass literal strings.\n */\nexport function cn(\n ...values: Array<string | null | undefined | false>\n): string {\n return values.filter(Boolean).join(\" \").trim();\n}\n"],"mappings":";;;AAGA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAOA,IAAM,sBAAyD;AAAA,EACpE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA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","names":["DynamicIcon","IconComponent"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/icons",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "The AI Matrx icon resolver: turn any icon NAME into a rendered component — a curated static map of ~140 hot Lucide icons for zero-latency hits, a validated dynamic import for the rest of the Lucide catalog, a module-level cache, kebab/PascalCase name normalization, an injectable svg: public-asset registry, and a fallback icon while loading.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",