ngx-com 0.0.15 → 0.0.17

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, inject, input, computed, ViewEncapsulation, ChangeDetectionStrategy, Component, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER } from '@angular/core';
2
+ import { Injectable, InjectionToken, inject, input, computed, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
  import * as i1 from 'lucide-angular';
4
4
  import { LucideAngularModule } from 'lucide-angular';
5
5
  import { cva } from 'class-variance-authority';
@@ -28,6 +28,58 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
28
28
  args: [{ providedIn: 'root' }]
29
29
  }] });
30
30
 
31
+ /**
32
+ * Token injected by `ComIcon` to trigger icon registration factories.
33
+ *
34
+ * Each `provideComIcons()` call adds a `multi` provider whose factory
35
+ * registers icons into the singleton `ComIconRegistry`. The token itself
36
+ * is never read — its purpose is to force Angular's DI to run the factories.
37
+ */
38
+ const COM_ICON_REGISTRAR = new InjectionToken('ComIconRegistrar');
39
+ /**
40
+ * Provides Lucide icons for use with `com-icon`.
41
+ *
42
+ * Works at **all** injector levels: app root, lazy route, and component.
43
+ * Icons are merged into the root-level `ComIconRegistry`, so multiple calls
44
+ * accumulate rather than shadow.
45
+ *
46
+ * @example Root-level (app.config.ts)
47
+ * ```ts
48
+ * import { provideComIcons } from 'ngx-com/components/icon';
49
+ * import { ChevronRight, Star, Check, AlertTriangle } from 'lucide-angular';
50
+ *
51
+ * export const appConfig = {
52
+ * providers: [
53
+ * provideComIcons({ ChevronRight, Star, Check, AlertTriangle })
54
+ * ]
55
+ * };
56
+ * ```
57
+ *
58
+ * @example Lazy route adds more icons without losing root icons
59
+ * ```ts
60
+ * // feature.routes.ts
61
+ * export const routes: Routes = [{
62
+ * path: '',
63
+ * providers: [provideComIcons({ Settings, User })],
64
+ * component: FeatureComponent,
65
+ * }];
66
+ * ```
67
+ *
68
+ * @example Component-level registration for tree-shaking
69
+ * ```ts
70
+ * @Component({
71
+ * providers: [provideComIcons({ Trash2, Edit })],
72
+ * })
73
+ * ```
74
+ */
75
+ function provideComIcons(icons) {
76
+ return {
77
+ provide: COM_ICON_REGISTRAR,
78
+ multi: true,
79
+ useFactory: () => inject(ComIconRegistry).register(icons),
80
+ };
81
+ }
82
+
31
83
  const iconVariants = cva('inline-flex items-center justify-center shrink-0 align-middle', {
32
84
  variants: {
33
85
  color: {
@@ -109,6 +161,7 @@ function toPascalCase(str) {
109
161
  */
110
162
  class ComIcon {
111
163
  registry = inject(ComIconRegistry);
164
+ _registrar = inject(COM_ICON_REGISTRAR, { optional: true });
112
165
  /** Icon name in kebab-case (e.g. 'chevron-right'). Requires provideComIcons registration. */
113
166
  name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : []));
114
167
  /** Direct Lucide icon reference. Takes precedence over `name`. */
@@ -176,48 +229,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
176
229
  }]
177
230
  }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], img: [{ type: i0.Input, args: [{ isSignal: true, alias: "img", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], strokeWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "strokeWidth", required: false }] }], absoluteStrokeWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "absoluteStrokeWidth", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
178
231
 
179
- /**
180
- * Provides Lucide icons for use with `com-icon`.
181
- *
182
- * Icons are merged into a root-level registry, so multiple calls
183
- * (e.g. at root and in lazy routes) accumulate rather than shadow.
184
- *
185
- * @example
186
- * ```ts
187
- * // app.config.ts
188
- * import { provideComIcons } from 'ngx-com/components/icon';
189
- * import { ChevronRight, Star, Check, AlertTriangle } from 'lucide-angular';
190
- *
191
- * export const appConfig = {
192
- * providers: [
193
- * provideComIcons({ ChevronRight, Star, Check, AlertTriangle })
194
- * ]
195
- * };
196
- * ```
197
- *
198
- * @example Lazy route adds more icons without losing root icons
199
- * ```ts
200
- * // feature.routes.ts
201
- * export const routes: Routes = [{
202
- * path: '',
203
- * providers: [provideComIcons({ Settings, User })],
204
- * component: FeatureComponent,
205
- * }];
206
- * ```
207
- */
208
- function provideComIcons(icons) {
209
- return makeEnvironmentProviders([
210
- {
211
- provide: ENVIRONMENT_INITIALIZER,
212
- multi: true,
213
- useValue: () => inject(ComIconRegistry).register(icons),
214
- },
215
- ]);
216
- }
217
-
218
232
  /**
219
233
  * Generated bundle index. Do not edit.
220
234
  */
221
235
 
222
- export { ComIcon, ComIconRegistry, ICON_SIZE_PX, iconVariants, provideComIcons };
236
+ export { COM_ICON_REGISTRAR, ComIcon, ComIconRegistry, ICON_SIZE_PX, iconVariants, provideComIcons };
223
237
  //# sourceMappingURL=ngx-com-components-icon.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-com-components-icon.mjs","sources":["../../../projects/com/components/icon/icon.registry.ts","../../../projects/com/components/icon/icon.variants.ts","../../../projects/com/components/icon/icon.component.ts","../../../projects/com/components/icon/icon.providers.ts","../../../projects/com/components/icon/ngx-com-components-icon.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport type { LucideIconData, LucideIcons } from 'lucide-angular';\n\n/**\n * Singleton registry for Lucide icons used by `com-icon`.\n *\n * Unlike lucide-angular's `LUCIDE_ICONS` token (which gets shadowed by child injectors),\n * this registry lives at root and merges all icons registered via `provideComIcons()`.\n */\n@Injectable({ providedIn: 'root' })\nexport class ComIconRegistry {\n private readonly icons: LucideIcons = {};\n\n /** Merges the given icons into the registry. */\n register(icons: LucideIcons): void {\n Object.assign(this.icons, icons);\n }\n\n /** Returns the icon data for the given PascalCase name, or `null` if not registered. */\n get(name: string): LucideIconData | null {\n return (this.icons[name] as LucideIconData) ?? null;\n }\n}\n","import { cva, type VariantProps } from 'class-variance-authority';\n\nexport type IconColor = 'current' | 'primary' | 'accent' | 'warn' | 'success' | 'muted' | 'disabled';\nexport type IconSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';\n\nexport const iconVariants: (props?: { color?: IconColor; size?: IconSize }) => string = cva(\n 'inline-flex items-center justify-center shrink-0 align-middle',\n {\n variants: {\n color: {\n current: '',\n primary: 'text-primary',\n accent: 'text-accent',\n warn: 'text-warn',\n success: 'text-success',\n muted: 'text-muted-foreground',\n disabled: 'text-disabled-foreground',\n },\n size: {\n xs: 'size-icon-xs',\n sm: 'size-icon-sm',\n md: 'size-icon-md',\n lg: 'size-icon-lg',\n xl: 'size-icon-xl',\n '2xl': 'size-icon-2xl',\n },\n },\n defaultVariants: {\n color: 'current',\n size: 'lg',\n },\n }\n);\n\n/** Pixel values matching the CSS tokens — passed to Lucide's numeric [size] prop */\nexport const ICON_SIZE_PX: Record<IconSize, number> = {\n xs: 12,\n sm: 16,\n md: 20,\n lg: 24,\n xl: 32,\n '2xl': 40,\n};\n\nexport type IconVariants = VariantProps<typeof iconVariants>;\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n input,\n ViewEncapsulation,\n} from '@angular/core';\nimport type { InputSignal, Signal } from '@angular/core';\nimport { LucideAngularModule } from 'lucide-angular';\nimport type { LucideIconData } from 'lucide-angular';\nimport { ComIconRegistry } from './icon.registry';\nimport { iconVariants, ICON_SIZE_PX, type IconColor, type IconSize } from './icon.variants';\n\n/**\n * Converts a kebab-case or space-separated icon name to PascalCase.\n *\n * Uses the same regex as lucide-angular for consistency.\n */\nfunction toPascalCase(str: string): string {\n return str.replace(/(\\w)([a-z0-9]*)(_|-|\\s*)/g, (_g0, g1: string, g2: string) =>\n g1.toUpperCase() + g2.toLowerCase()\n );\n}\n\n/**\n * Icon component — renders Lucide icons with CVA-powered color and size variants.\n *\n * Icons inherit `currentColor` by default, making them automatically match\n * surrounding text. Use the `color` input for semantic color variants that\n * respond to theme changes.\n *\n * @tokens `--color-primary`, `--color-accent`, `--color-warn`, `--color-success`,\n * `--color-muted-foreground`, `--color-disabled-foreground`,\n * `--size-icon-xs`, `--size-icon-sm`, `--size-icon-md`,\n * `--size-icon-lg`, `--size-icon-xl`, `--size-icon-2xl`\n *\n * @example Basic usage (requires icon registration via provideComIcons)\n * ```html\n * <com-icon name=\"star\" />\n * <com-icon name=\"check\" color=\"success\" size=\"sm\" />\n * <com-icon name=\"alert-triangle\" color=\"warn\" />\n * ```\n *\n * @example Direct icon reference (no provider needed)\n * ```html\n * <com-icon [img]=\"StarIcon\" color=\"accent\" size=\"2xl\" />\n * ```\n *\n * @example Accessible icon (not decorative)\n * ```html\n * <com-icon name=\"check\" color=\"success\" ariaLabel=\"Task completed\" />\n * ```\n *\n * @example Inline with text (inherits parent color)\n * ```html\n * <span class=\"text-primary\">\n * <com-icon name=\"star\" size=\"sm\" /> Favorite\n * </span>\n * ```\n */\n@Component({\n selector: 'com-icon',\n template: `\n @if (resolvedIcon(); as iconData) {\n <lucide-icon\n [img]=\"iconData\"\n [size]=\"sizeInPx()\"\n [strokeWidth]=\"strokeWidth()\"\n [absoluteStrokeWidth]=\"absoluteStrokeWidth()\"\n color=\"currentColor\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-hidden]=\"ariaLabel() ? null : 'true'\"\n />\n }\n `,\n host: {\n '[class]': 'hostClasses()',\n },\n imports: [LucideAngularModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class ComIcon {\n private readonly registry = inject(ComIconRegistry);\n\n /** Icon name in kebab-case (e.g. 'chevron-right'). Requires provideComIcons registration. */\n readonly name: InputSignal<string | undefined> = input<string>();\n\n /** Direct Lucide icon reference. Takes precedence over `name`. */\n readonly img: InputSignal<LucideIconData | undefined> = input<LucideIconData>();\n\n /** Semantic color variant. Defaults to 'current' (inherits from parent). */\n readonly color: InputSignal<IconColor> = input<IconColor>('current');\n\n /** Size variant. Defaults to 'lg' (24px). */\n readonly size: InputSignal<IconSize> = input<IconSize>('lg');\n\n /** Stroke width. Defaults to 2. */\n readonly strokeWidth: InputSignal<number> = input<number>(2);\n\n /** When true, stroke width doesn't scale with icon size. */\n readonly absoluteStrokeWidth: InputSignal<boolean> = input<boolean>(false);\n\n /** Applies aria-label and removes aria-hidden. Use for meaningful icons. */\n readonly ariaLabel: InputSignal<string | undefined> = input<string>();\n\n /** Resolves icon data from either `img` (direct ref) or `name` (registry lookup). */\n protected readonly resolvedIcon: Signal<LucideIconData | undefined> = computed(() => {\n const imgData = this.img();\n if (imgData) return imgData;\n\n const iconName = this.name();\n if (iconName) return this.registry.get(toPascalCase(iconName)) ?? undefined;\n\n return undefined;\n });\n\n protected readonly sizeInPx: Signal<number> = computed(() => ICON_SIZE_PX[this.size()]);\n protected readonly hostClasses: Signal<string> = computed(() =>\n iconVariants({ color: this.color(), size: this.size() })\n );\n}\n","import { ENVIRONMENT_INITIALIZER, inject, makeEnvironmentProviders } from '@angular/core';\nimport type { EnvironmentProviders } from '@angular/core';\nimport type { LucideIcons } from 'lucide-angular';\nimport { ComIconRegistry } from './icon.registry';\n\n/**\n * Provides Lucide icons for use with `com-icon`.\n *\n * Icons are merged into a root-level registry, so multiple calls\n * (e.g. at root and in lazy routes) accumulate rather than shadow.\n *\n * @example\n * ```ts\n * // app.config.ts\n * import { provideComIcons } from 'ngx-com/components/icon';\n * import { ChevronRight, Star, Check, AlertTriangle } from 'lucide-angular';\n *\n * export const appConfig = {\n * providers: [\n * provideComIcons({ ChevronRight, Star, Check, AlertTriangle })\n * ]\n * };\n * ```\n *\n * @example Lazy route adds more icons without losing root icons\n * ```ts\n * // feature.routes.ts\n * export const routes: Routes = [{\n * path: '',\n * providers: [provideComIcons({ Settings, User })],\n * component: FeatureComponent,\n * }];\n * ```\n */\nexport function provideComIcons(icons: LucideIcons): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: ENVIRONMENT_INITIALIZER,\n multi: true,\n useValue: () => inject(ComIconRegistry).register(icons),\n },\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngx-com-components-icon.mjs","sources":["../../../projects/com/components/icon/icon.registry.ts","../../../projects/com/components/icon/icon.providers.ts","../../../projects/com/components/icon/icon.variants.ts","../../../projects/com/components/icon/icon.component.ts","../../../projects/com/components/icon/ngx-com-components-icon.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport type { LucideIconData, LucideIcons } from 'lucide-angular';\n\n/**\n * Singleton registry for Lucide icons used by `com-icon`.\n *\n * Unlike lucide-angular's `LUCIDE_ICONS` token (which gets shadowed by child injectors),\n * this registry lives at root and merges all icons registered via `provideComIcons()`.\n */\n@Injectable({ providedIn: 'root' })\nexport class ComIconRegistry {\n private readonly icons: LucideIcons = {};\n\n /** Merges the given icons into the registry. */\n register(icons: LucideIcons): void {\n Object.assign(this.icons, icons);\n }\n\n /** Returns the icon data for the given PascalCase name, or `null` if not registered. */\n get(name: string): LucideIconData | null {\n return (this.icons[name] as LucideIconData) ?? null;\n }\n}\n","import { inject, InjectionToken } from '@angular/core';\nimport type { Provider } from '@angular/core';\nimport type { LucideIcons } from 'lucide-angular';\nimport { ComIconRegistry } from './icon.registry';\n\n/**\n * Token injected by `ComIcon` to trigger icon registration factories.\n *\n * Each `provideComIcons()` call adds a `multi` provider whose factory\n * registers icons into the singleton `ComIconRegistry`. The token itself\n * is never read — its purpose is to force Angular's DI to run the factories.\n */\nexport const COM_ICON_REGISTRAR: InjectionToken<void[]> = new InjectionToken<void[]>('ComIconRegistrar');\n\n/**\n * Provides Lucide icons for use with `com-icon`.\n *\n * Works at **all** injector levels: app root, lazy route, and component.\n * Icons are merged into the root-level `ComIconRegistry`, so multiple calls\n * accumulate rather than shadow.\n *\n * @example Root-level (app.config.ts)\n * ```ts\n * import { provideComIcons } from 'ngx-com/components/icon';\n * import { ChevronRight, Star, Check, AlertTriangle } from 'lucide-angular';\n *\n * export const appConfig = {\n * providers: [\n * provideComIcons({ ChevronRight, Star, Check, AlertTriangle })\n * ]\n * };\n * ```\n *\n * @example Lazy route adds more icons without losing root icons\n * ```ts\n * // feature.routes.ts\n * export const routes: Routes = [{\n * path: '',\n * providers: [provideComIcons({ Settings, User })],\n * component: FeatureComponent,\n * }];\n * ```\n *\n * @example Component-level registration for tree-shaking\n * ```ts\n * @Component({\n * providers: [provideComIcons({ Trash2, Edit })],\n * })\n * ```\n */\nexport function provideComIcons(icons: LucideIcons): Provider {\n return {\n provide: COM_ICON_REGISTRAR,\n multi: true,\n useFactory: () => inject(ComIconRegistry).register(icons),\n };\n}\n","import { cva, type VariantProps } from 'class-variance-authority';\n\nexport type IconColor = 'current' | 'primary' | 'accent' | 'warn' | 'success' | 'muted' | 'disabled';\nexport type IconSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';\n\nexport const iconVariants: (props?: { color?: IconColor; size?: IconSize }) => string = cva(\n 'inline-flex items-center justify-center shrink-0 align-middle',\n {\n variants: {\n color: {\n current: '',\n primary: 'text-primary',\n accent: 'text-accent',\n warn: 'text-warn',\n success: 'text-success',\n muted: 'text-muted-foreground',\n disabled: 'text-disabled-foreground',\n },\n size: {\n xs: 'size-icon-xs',\n sm: 'size-icon-sm',\n md: 'size-icon-md',\n lg: 'size-icon-lg',\n xl: 'size-icon-xl',\n '2xl': 'size-icon-2xl',\n },\n },\n defaultVariants: {\n color: 'current',\n size: 'lg',\n },\n }\n);\n\n/** Pixel values matching the CSS tokens — passed to Lucide's numeric [size] prop */\nexport const ICON_SIZE_PX: Record<IconSize, number> = {\n xs: 12,\n sm: 16,\n md: 20,\n lg: 24,\n xl: 32,\n '2xl': 40,\n};\n\nexport type IconVariants = VariantProps<typeof iconVariants>;\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n input,\n ViewEncapsulation,\n} from '@angular/core';\nimport type { InputSignal, Signal } from '@angular/core';\nimport { LucideAngularModule } from 'lucide-angular';\nimport type { LucideIconData } from 'lucide-angular';\nimport { COM_ICON_REGISTRAR } from './icon.providers';\nimport { ComIconRegistry } from './icon.registry';\nimport { iconVariants, ICON_SIZE_PX, type IconColor, type IconSize } from './icon.variants';\n\n/**\n * Converts a kebab-case or space-separated icon name to PascalCase.\n *\n * Uses the same regex as lucide-angular for consistency.\n */\nfunction toPascalCase(str: string): string {\n return str.replace(/(\\w)([a-z0-9]*)(_|-|\\s*)/g, (_g0, g1: string, g2: string) =>\n g1.toUpperCase() + g2.toLowerCase()\n );\n}\n\n/**\n * Icon component — renders Lucide icons with CVA-powered color and size variants.\n *\n * Icons inherit `currentColor` by default, making them automatically match\n * surrounding text. Use the `color` input for semantic color variants that\n * respond to theme changes.\n *\n * @tokens `--color-primary`, `--color-accent`, `--color-warn`, `--color-success`,\n * `--color-muted-foreground`, `--color-disabled-foreground`,\n * `--size-icon-xs`, `--size-icon-sm`, `--size-icon-md`,\n * `--size-icon-lg`, `--size-icon-xl`, `--size-icon-2xl`\n *\n * @example Basic usage (requires icon registration via provideComIcons)\n * ```html\n * <com-icon name=\"star\" />\n * <com-icon name=\"check\" color=\"success\" size=\"sm\" />\n * <com-icon name=\"alert-triangle\" color=\"warn\" />\n * ```\n *\n * @example Direct icon reference (no provider needed)\n * ```html\n * <com-icon [img]=\"StarIcon\" color=\"accent\" size=\"2xl\" />\n * ```\n *\n * @example Accessible icon (not decorative)\n * ```html\n * <com-icon name=\"check\" color=\"success\" ariaLabel=\"Task completed\" />\n * ```\n *\n * @example Inline with text (inherits parent color)\n * ```html\n * <span class=\"text-primary\">\n * <com-icon name=\"star\" size=\"sm\" /> Favorite\n * </span>\n * ```\n */\n@Component({\n selector: 'com-icon',\n template: `\n @if (resolvedIcon(); as iconData) {\n <lucide-icon\n [img]=\"iconData\"\n [size]=\"sizeInPx()\"\n [strokeWidth]=\"strokeWidth()\"\n [absoluteStrokeWidth]=\"absoluteStrokeWidth()\"\n color=\"currentColor\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-hidden]=\"ariaLabel() ? null : 'true'\"\n />\n }\n `,\n host: {\n '[class]': 'hostClasses()',\n },\n imports: [LucideAngularModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class ComIcon {\n private readonly registry = inject(ComIconRegistry);\n private readonly _registrar = inject(COM_ICON_REGISTRAR, { optional: true });\n\n /** Icon name in kebab-case (e.g. 'chevron-right'). Requires provideComIcons registration. */\n readonly name: InputSignal<string | undefined> = input<string>();\n\n /** Direct Lucide icon reference. Takes precedence over `name`. */\n readonly img: InputSignal<LucideIconData | undefined> = input<LucideIconData>();\n\n /** Semantic color variant. Defaults to 'current' (inherits from parent). */\n readonly color: InputSignal<IconColor> = input<IconColor>('current');\n\n /** Size variant. Defaults to 'lg' (24px). */\n readonly size: InputSignal<IconSize> = input<IconSize>('lg');\n\n /** Stroke width. Defaults to 2. */\n readonly strokeWidth: InputSignal<number> = input<number>(2);\n\n /** When true, stroke width doesn't scale with icon size. */\n readonly absoluteStrokeWidth: InputSignal<boolean> = input<boolean>(false);\n\n /** Applies aria-label and removes aria-hidden. Use for meaningful icons. */\n readonly ariaLabel: InputSignal<string | undefined> = input<string>();\n\n /** Resolves icon data from either `img` (direct ref) or `name` (registry lookup). */\n protected readonly resolvedIcon: Signal<LucideIconData | undefined> = computed(() => {\n const imgData = this.img();\n if (imgData) return imgData;\n\n const iconName = this.name();\n if (iconName) return this.registry.get(toPascalCase(iconName)) ?? undefined;\n\n return undefined;\n });\n\n protected readonly sizeInPx: Signal<number> = computed(() => ICON_SIZE_PX[this.size()]);\n protected readonly hostClasses: Signal<string> = computed(() =>\n iconVariants({ color: this.color(), size: this.size() })\n );\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-com",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/avs2001/ngx-com"
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InputSignal, Signal, EnvironmentProviders } from '@angular/core';
2
+ import { InputSignal, Signal, InjectionToken, Provider } from '@angular/core';
3
3
  import { LucideIconData, LucideIcons } from 'lucide-angular';
4
4
  import { VariantProps } from 'class-variance-authority';
5
5
 
@@ -51,6 +51,7 @@ type IconVariants = VariantProps<typeof iconVariants>;
51
51
  */
52
52
  declare class ComIcon {
53
53
  private readonly registry;
54
+ private readonly _registrar;
54
55
  /** Icon name in kebab-case (e.g. 'chevron-right'). Requires provideComIcons registration. */
55
56
  readonly name: InputSignal<string | undefined>;
56
57
  /** Direct Lucide icon reference. Takes precedence over `name`. */
@@ -89,15 +90,23 @@ declare class ComIconRegistry {
89
90
  static ɵprov: i0.ɵɵInjectableDeclaration<ComIconRegistry>;
90
91
  }
91
92
 
93
+ /**
94
+ * Token injected by `ComIcon` to trigger icon registration factories.
95
+ *
96
+ * Each `provideComIcons()` call adds a `multi` provider whose factory
97
+ * registers icons into the singleton `ComIconRegistry`. The token itself
98
+ * is never read — its purpose is to force Angular's DI to run the factories.
99
+ */
100
+ declare const COM_ICON_REGISTRAR: InjectionToken<void[]>;
92
101
  /**
93
102
  * Provides Lucide icons for use with `com-icon`.
94
103
  *
95
- * Icons are merged into a root-level registry, so multiple calls
96
- * (e.g. at root and in lazy routes) accumulate rather than shadow.
104
+ * Works at **all** injector levels: app root, lazy route, and component.
105
+ * Icons are merged into the root-level `ComIconRegistry`, so multiple calls
106
+ * accumulate rather than shadow.
97
107
  *
98
- * @example
108
+ * @example Root-level (app.config.ts)
99
109
  * ```ts
100
- * // app.config.ts
101
110
  * import { provideComIcons } from 'ngx-com/components/icon';
102
111
  * import { ChevronRight, Star, Check, AlertTriangle } from 'lucide-angular';
103
112
  *
@@ -117,8 +126,15 @@ declare class ComIconRegistry {
117
126
  * component: FeatureComponent,
118
127
  * }];
119
128
  * ```
129
+ *
130
+ * @example Component-level registration for tree-shaking
131
+ * ```ts
132
+ * @Component({
133
+ * providers: [provideComIcons({ Trash2, Edit })],
134
+ * })
135
+ * ```
120
136
  */
121
- declare function provideComIcons(icons: LucideIcons): EnvironmentProviders;
137
+ declare function provideComIcons(icons: LucideIcons): Provider;
122
138
 
123
- export { ComIcon, ComIconRegistry, ICON_SIZE_PX, iconVariants, provideComIcons };
139
+ export { COM_ICON_REGISTRAR, ComIcon, ComIconRegistry, ICON_SIZE_PX, iconVariants, provideComIcons };
124
140
  export type { IconColor, IconSize, IconVariants };