feat(icons): add Lucide icon foundation
Add @lucide/angular dependency and a single shared entry point for every icon in the app: app-icon (src/app/shared/ui/icon), backed by a canonical name -> Lucide-icon registry (icon-registry.ts) covering every concept the RC icon audit needs across storefront, builder, and backoffice. One name per meaning, one default size/stroke-width, so every screen renders the same icon the same way. Package note: lucide-angular (unscoped) is deprecated upstream in favor of @lucide/angular - installed the maintained package directly. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
39
src/app/shared/ui/icon/icon.component.ts
Normal file
39
src/app/shared/ui/icon/icon.component.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';
|
||||
import { LucideDynamicIcon } from '@lucide/angular';
|
||||
import { APP_ICONS, type AppIconName } from './icon-registry';
|
||||
|
||||
/**
|
||||
* Single entry point for every icon in the app. Renders a Lucide icon by
|
||||
* canonical name (see icon-registry.ts) so every screen uses one icon family
|
||||
* at one consistent size/stroke-width by default.
|
||||
*
|
||||
* Decorative by default (aria-hidden). Pass `ariaLabel` only when the icon
|
||||
* itself carries meaning with no adjacent text (e.g. inside an icon-only
|
||||
* button) - the label belongs on the interactive element when there is one.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'app-icon',
|
||||
standalone: true,
|
||||
imports: [LucideDynamicIcon],
|
||||
template: `
|
||||
<svg
|
||||
[lucideIcon]="iconData()"
|
||||
[size]="size()"
|
||||
[strokeWidth]="strokeWidth()"
|
||||
[title]="ariaLabel()"
|
||||
></svg>
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
host: {
|
||||
class: 'app-icon',
|
||||
'[style.display]': "'inline-flex'"
|
||||
}
|
||||
})
|
||||
export class IconComponent {
|
||||
readonly name = input.required<AppIconName>();
|
||||
readonly size = input<number>(20);
|
||||
readonly strokeWidth = input<number>(2);
|
||||
readonly ariaLabel = input<string | null>(null);
|
||||
|
||||
protected readonly iconData = computed(() => APP_ICONS[this.name()]);
|
||||
}
|
||||
Reference in New Issue
Block a user