{"version":3,"file":"Icon.cjs","names":[],"sources":["../../src/icons/Icon.tsx"],"sourcesContent":["import { createElement, type ReactNode, type SVGProps } from \"react\";\nimport type { LucideIcon } from \"lucide-react\";\n\nimport type { IconName } from \"./generated/icon-name\";\nimport { useIconContext } from \"./icon-context\";\nimport { normalizeIconName } from \"./normalize-icon-name\";\nimport { iconStatus } from \"./shard-cache\";\nimport { useIcon } from \"./use-icon\";\nimport { isDevBuild } from \"../utils/dev-mode\";\n\ninterface IconBaseProps extends Omit<SVGProps<SVGSVGElement>, \"ref\" | \"name\"> {\n    /** Width and height in px. Defaults to the provider's value, then lucide's `24`. */\n    size?: number | string;\n    /** Stroke width. Defaults to the provider's value, then lucide's `2`. */\n    strokeWidth?: number;\n    /**\n     * Rendered while the icon's shard is in flight, and for a slug that does not\n     * exist at all. Defaults to nothing.\n     *\n     * Pass a same-sized placeholder when the surrounding layout would otherwise\n     * shift. Note that a slug already in the registry or the cache never renders\n     * this — it resolves during render.\n     */\n    fallback?: ReactNode;\n    /**\n     * Clean up `name` before looking it up. Default `true`.\n     *\n     * A stored `icon_code` arrives dirty — `shopping_cart`, `\" Save\"`, a slug\n     * lucide deprecated two releases ago — and normalizing is what makes those\n     * render instead of falling back. `false` asks for a strict lookup, for the\n     * case where you want an unexpected spelling to be visible rather than\n     * quietly repaired.\n     *\n     * Ignored when the icon is passed as a component.\n     */\n    normalize?: boolean;\n}\n\n/**\n * Address the icon by slug — the reason this component exists.\n *\n * The slug is typed as the union of every name lucide ships, so a typo is a\n * compile error, while still accepting a plain `string` for the case that\n * motivates the whole module: a name arriving from an API, a CMS or a config\n * table.\n */\ninterface IconByNameProps extends IconBaseProps {\n    name: IconName | (string & {});\n    icon?: never;\n}\n\n/**\n * Address the icon by component, for a call site that already imported it.\n *\n * No lookup, no registry, no shard: the component is rendered as passed. It is\n * there so a screen mixing literal icons with data-driven ones can keep using one\n * component instead of alternating between `<Icon name>` and `<Wrench />`, which\n * is what makes the shared `size`/`strokeWidth` defaults apply to both.\n */\ninterface IconByComponentProps extends IconBaseProps {\n    icon: LucideIcon;\n    name?: never;\n}\n\nexport type IconProps = IconByNameProps | IconByComponentProps;\n\n/**\n * Render a lucide icon by slug.\n *\n * All ~2000 lucide icons are addressable, without the cost that makes\n * `lucide-react`'s own `DynamicIcon` unusable: its icon map holds a dynamic\n * `import()` per icon, so a bundler has to emit ~2000 chunk boundaries and the\n * browser floods with requests. Here a slug the app wrote as a literal is\n * resolved from a static registry, and a slug only known at runtime pulls a\n * single shard covering every icon sharing its initial letter.\n *\n * An unknown slug renders `fallback` (nothing, by default) and warns in dev only\n * — it never throws, because a bad name from an API must not take down the tree.\n *\n * `name` is normalized before the lookup, so a stored `icon_code` renders whether\n * it was written `shopping_cart`, `\" Save\"` or under a slug lucide has since\n * deprecated. Pass `normalize={false}` for a strict lookup.\n *\n * @example\n * <Icon name=\"save\" size={18} />\n * <Icon name={row.iconSlug} fallback={<span className=\"skeleton\" />} />\n * <Icon icon={Wrench} size={18} />\n */\nexport function Icon({\n    name,\n    icon,\n    size,\n    strokeWidth,\n    fallback = null,\n    normalize = true,\n    ...rest\n}: IconProps): ReactNode {\n    const context = useIconContext();\n    const slug = name === undefined ? undefined : normalize ? normalizeIconName(name) : name;\n    const fromSlug = useIcon(slug);\n    const resolved = icon ?? fromSlug;\n\n    if (!resolved) {\n        if (isDevBuild() && name !== undefined && slug !== undefined) {\n            if (iconStatus(slug) === \"missing\") warnUnknownIcon(name);\n        }\n        return fallback;\n    }\n\n    return createElement(resolved, {\n        size: size ?? context?.size,\n        strokeWidth: strokeWidth ?? context?.strokeWidth,\n        ...rest,\n    });\n}\n\nconst warnedSlugs = new Set<string>();\n\n/**\n * Warn once per unknown slug.\n *\n * Once, because `<Icon>` re-renders and a warning per render would bury the\n * console; the set is never cleared, since a slug that does not exist will not\n * start existing within the life of the page.\n *\n * Reports the name **as written**, not the normalized slug: the reader is the\n * developer who typed it, and `\"CircleAlert\"` is a far more useful thing to see in\n * the console than the `\"circlealert\"` it normalizes to.\n *\n * @param name - The slug that resolved to nothing, as passed.\n */\nfunction warnUnknownIcon(name: string): void {\n    if (warnedSlugs.has(name)) return;\n    warnedSlugs.add(name);\n    console.warn(\n        `[tempest-react-sdk] <Icon name=\"${name}\" /> — no such lucide icon. ` +\n            `Slugs are kebab-case (\"circle-alert\", not \"CircleAlert\"); check against \\`iconNames\\`.`,\n    );\n}\n"],"mappings":"kMAwFA,SAAgB,EAAK,CACjB,OACA,OACA,OACA,cACA,WAAW,KACX,YAAY,GACZ,GAAG,GACkB,CACrB,IAAM,EAAU,EAAA,eAAe,EACzB,EAAO,IAAS,IAAA,GAAY,IAAA,GAAY,EAAY,EAAA,kBAAkB,CAAI,EAAI,EAC9E,EAAW,EAAA,QAAQ,CAAI,EACvB,EAAW,GAAQ,EASzB,OAPK,GAOL,EAAO,EAAA,cAAA,CAAc,EAAU,CAC3B,KAAM,GAAQ,GAAS,KACvB,YAAa,GAAe,GAAS,YACrC,GAAG,CACP,CAAC,GAVO,EAAA,WAAW,GAAK,IAAS,IAAA,IAAa,IAAS,IAAA,IAC3C,EAAA,WAAW,CAAI,IAAM,WAAW,EAAgB,CAAI,EAErD,EAQf,CAEA,IAAM,EAAc,IAAI,IAexB,SAAS,EAAgB,EAAoB,CACrC,EAAY,IAAI,CAAI,IACxB,EAAY,IAAI,CAAI,EACpB,QAAQ,KACJ,mCAAmC,EAAK,mHAE5C,EACJ"}