lucide-icons / lucide

Beautiful & consistent icon toolkit made by the community. Open-source project and a fork of Feather Icons.
https://lucide.dev
ISC License
8.94k stars 380 forks source link

[Angular] Standalone component compatibility #2097

Closed hakimio closed 3 weeks ago

hakimio commented 3 weeks ago

Package

Description

Standalone component API is now stable in Angular. However, lucide-angular is not compatible with Angular standalone applications which results in a bad DX.

  1. LucideAngularModule.pick() can only be used with the importProvidersFrom() compatibility function:
    export const appConfig: ApplicationConfig = {
    providers: [
        importProvidersFrom(
            LucideAngularModule.pick(appIcons)
       )
    ]
    };

    Instead of having dedicated provideLucideIcons() provider function like most libraries have nowadays:

    export const appConfig: ApplicationConfig = {
    providers: [
        provideLucideIcons(appIcons)
    ]
    };
  2. It's not possible to import Lucide icons in standalone component imports to have a local set of icons. The following code throws an error:
    @Component({
    selector: 'app-root',
    standalone: true,
    imports: [
        LucideAngularModule.pick(appIcons)
    ],
    templateUrl: './app.component.html'
    })
    export class AppComponent {}

    There should be a way to select icons in standalone components like it's now possible when using Ionic icons.

Use cases

Standalone component compatibility.

Checklist

karsa-mistmere commented 3 weeks ago

Hi @hakimio,

This isn't really an issue with lucide-angular, this is just how Angular works. Standalone components have no support for ModuleWithProvider declarations, if you want to use Lucide with standalone components, you already can do it, see: https://github.com/lucide-icons/lucide/issues/1288#issuecomment-1701754200

Of course it would be best if we could provide a standalone component, but we can't as long as we want to retain backwards compatibility with previous versions.

Due to performance reasons I also highly advise against injecting a list of icons within every standalone component and relying instead of tree-shaken single imports (basically: only provide icons to a standalone component that the component actually uses).

hakimio commented 3 weeks ago

Using importProvidersFrom() is not a proper solution. That's just a workaround. You can provide your own provideLucideIcons(appIcons) at least in addition to LucideAngularModule.pick(). It wouldn't break anything.

hakimio commented 3 weeks ago

Also, you can release a new major version of lucide-angular with breaking changes. I don't understand why in more than 3 years you haven't released any major version and kept going with 0.x releases.

hakimio commented 3 weeks ago

makeEnvironmentProviders is available since Angular v15. Older Angular versions are not supported.

karsa-mistmere commented 3 weeks ago

Using importProvidersFrom() is not a proper solution. That's just a workaround. You can provide your own provideLucideIcons(appIcons) at least in addition to LucideAngularModule.pick(). It wouldn't break anything.

importProvidersFrom is not something that we recommend using at all, we recommend using the dedicated injection token for this purpose as stated in https://github.com/lucide-icons/lucide/issues/1288#issuecomment-1701754200

But even moreso we recommend not providing more icons than necessary, so I'd recommend using this pattern:

import { Component } from '@angular/core';
import { ActivitySquareIcon, LucideAngularModule } from 'lucide-angular';

@Component({
  selector: 'app-demo',
  standalone: true,
  imports: [LucideAngularModule],
  template: `<lucide-icon [name]="ActivitySquareIcon" />`,
})
export class DemoComponent {
  protected readonly ActivitySquareIcon = ActivitySquareIcon;
}

Also, you can release a new major version of lucide-angular with breaking changes.

Every icon is bundled within the package, should we release a new version with breaking changes, people using earlier versions of Angular would be hung out to dry, and if you look at the usage statistics of major versions, people do still use earlier versions, a lot: https://www.npmjs.com/package/@angular/core?activeTab=versions.

hakimio commented 3 weeks ago

How about decoupling the core icon package and the Angular package to make life easier?

karsa-mistmere commented 3 weeks ago

How about decoupling the core icon package and the Angular package to make life easier?

It's planned, see https://github.com/lucide-icons/lucide/issues/1687

Once we do that, there will be nothing in the way of releasing a modern version of lucide-angular with proper standalone component support.

hakimio commented 3 weeks ago

Awesome 🙂