{"version":3,"file":"DynamicIcon.mjs","sources":["../../src/DynamicIcon.ts"],"sourcesContent":["import { createElement, forwardRef, memo, useEffect, useState } from 'react';\nimport type { JSX } from 'react';\nimport { IconNode, YCloudIcon, YCloudIconsProps } from './types';\nimport dynamicIconImports from './dynamicIconImports';\nimport Icon from './Icon';\n\nexport type DynamicIconModule = { default: YCloudIcon; __iconNode: IconNode };\n\nexport type IconName = keyof typeof dynamicIconImports;\n\nexport const iconNames = Object.keys(dynamicIconImports) as Array<IconName>;\n\ninterface DynamicIconComponentProps extends YCloudIconsProps {\n  name: IconName;\n  fallback?: () => JSX.Element | null;\n}\n\nasync function getIconNode(name: IconName) {\n  if (!(name in dynamicIconImports)) {\n    throw new Error('[ycloud-react]: Name in YCloud DynamicIcon not found');\n  }\n\n  // TODO: Replace this with a generic iconNode package.\n  const icon = (await dynamicIconImports[name]()) as DynamicIconModule;\n\n  return icon.__iconNode;\n}\n\n/**\n * Dynamic YCloud icon component\n *\n * @component Icon\n * @param {object} props\n * @param {string} props.color - The color of the icon\n * @param {number} props.size - The size of the icon\n * @param {number} props.strokeWidth - The stroke width of the icon\n * @param {boolean} props.absoluteStrokeWidth - Whether to use absolute stroke width\n * @param {string} props.className - The class name of the icon\n * @param {IconNode} props.children - The children of the icon\n * @param {IconNode} props.iconNode - The icon node of the icon\n *\n * @returns {ForwardRefExoticComponent} YCloudIcon\n */\nconst DynamicIcon = forwardRef<SVGSVGElement, DynamicIconComponentProps>(\n  ({ name, fallback: Fallback, ...props }, ref) => {\n    const [iconNode, setIconNode] = useState<IconNode>();\n\n    useEffect(() => {\n      let cancelled = false;\n\n      getIconNode(name)\n        .then((node) => {\n          if (!cancelled) {\n            setIconNode(node);\n          }\n        })\n        .catch((error) => {\n          if (!cancelled) {\n            console.error(error);\n          }\n        });\n\n      return () => {\n        cancelled = true;\n      };\n    }, [name]);\n\n    if (iconNode == null) {\n      if (Fallback == null) {\n        return null;\n      }\n\n      return createElement(Fallback);\n    }\n\n    return createElement(Icon, {\n      ref,\n      ...props,\n      iconNode,\n    });\n  },\n);\n\nDynamicIcon.displayName = 'DynamicIcon';\n\n// Memoize DynamicIcon to prevent unnecessary re-renders\n// Only re-render when name or other props change\nexport default memo(DynamicIcon);\n"],"names":[],"mappings":";;;;;;;;;;;;AAUO;AAOP;AACE;AACE;AAAsE;AAIxE;AAEA;AACF;AAiBA;AAAoB;AAEhB;AAEA;AACE;AAEA;AAEI;AACE;AAAgB;AAClB;AAGA;AACE;AAAmB;AACrB;AAGJ;AACE;AAAY;AACd;AAGF;AACE;AACE;AAAO;AAGT;AAA6B;AAG/B;AAA2B;AACzB;AACG;AACH;AACD;AAEL;AAEA;AAIA;;"}