ionic-framework icon indicating copy to clipboard operation
ionic-framework copied to clipboard

bug: Standalone IonIcon type does not expose any component properties

Open zolakt opened this issue 1 week ago • 0 comments

Prerequisites

Ionic Framework Version

v7.x, v8.x

Current Behavior

I have a custom directive on IonIcon which modifies the "name" and "src" attributes. For example:

import { Directive, OnInit } from '@angular/core';
import { IonIcon } from '@ionic/angular';

@Directive({
    selector: 'ion-icon[name]',
    standalone: true,
    providers: [IonIcon]
})
export class FontIconDirective implements OnInit {
    constructor(private host: IonIcon) {
    }

    public ngOnInit(): void {
        const name = this.host.name;

        if (name) {
            this.host.name = undefined;
            this.host.src = 'data:text/plain,' + name;
        }
    }
}

Everything works fine if I import from import { IonIcon } from '@ionic/angular'

But if I import the standalone component, it doesn't have "name" and "src" properties import { IonIcon } from '@ionic/angular/standalone';

The non-standalone IonIcon extends Components.IonIcon, which contains there properties: image

But the standalone version doesn't extend it: image

Is this intentional or a bug? It looks like a bug to me, since I see other standalone components do extends the Components interfaces, e.g: image

If it is intentional, what type should I inject then, to get access to those properties?

It does work if I leave it non-standalone, but that is the only remaining place where I import non-standalone, and I'd like to avoid that. Also, with the new Angulars ESBuild, vite is throwing these warnings https://github.com/ionic-team/ionic-framework/issues/28576, I suspect due to this non-standalone import

Expected Behavior

Standalone IonIcon should extend Components.IonIcon

Steps to Reproduce

No special reproduction steps. Whenever you use the IonIcon from import { IonIcon } from '@ionic/angular/standalone'; none of the component properties are exposed. In injection, ViewChild, ContentChild...etc. Whenever you need to programmatically reference it

Code Reproduction URL

There is no need for a repo

Ionic Info

[WARN] Error loading @capacitor/ios package.json: Error: Cannot find module '@capacitor/ios/package.json'

   Require stack:
   - C:\Users\test\AppData\Roaming\nvm\v18.13.0\node_modules\@ionic\cli\lib\project\index.js
   - C:\Users\test\AppData\Roaming\nvm\v18.13.0\node_modules\@ionic\cli\lib\index.js
   - C:\Users\test\AppData\Roaming\nvm\v18.13.0\node_modules\@ionic\cli\index.js
   - C:\Users\test\AppData\Roaming\nvm\v18.13.0\node_modules\@ionic\cli\bin\ionic

[WARN] Error loading @capacitor/android package.json: Error: Cannot find module '@capacitor/android/package.json'

   Require stack:
   - C:\Users\test\AppData\Roaming\nvm\v18.13.0\node_modules\@ionic\cli\lib\project\index.js
   - C:\Users\test\AppData\Roaming\nvm\v18.13.0\node_modules\@ionic\cli\lib\index.js
   - C:\Users\test\AppData\Roaming\nvm\v18.13.0\node_modules\@ionic\cli\index.js
   - C:\Users\test\AppData\Roaming\nvm\v18.13.0\node_modules\@ionic\cli\bin\ionic

Ionic:

Ionic CLI : 7.1.5 (C:\Users\test\AppData\Roaming\nvm\v18.13.0\node_modules@ionic\cli) Ionic Framework : @ionic/angular 8.2.3 @angular-devkit/build-angular : 17.3.1 @angular-devkit/schematics : 17.3.1 @angular/cli : 17.3.1 @ionic/angular-toolkit : 11.0.1

Capacitor:

Capacitor CLI : 6.1.0 @capacitor/android : not installed @capacitor/core : 6.1.0 @capacitor/ios : not installed

Utility:

cordova-res : not installed globally native-run : 2.0.1

System:

NodeJS : v18.13.0 (C:\Program Files\nodejs\node.exe) npm : 8.19.3 OS : Windows 10

Additional Information

I can do this as a workaround, and it seems to work, but it's dirty...

import { Directive, OnInit } from '@angular/core';
import { IonIcon } from '@ionic/angular/standalone';
import { Components } from '@ionic/core/dist/types/interface'

@Directive({
    selector: 'ion-icon[name]',
    standalone: true,
    providers: [IonIcon]
})
export class FontIconDirective implements OnInit {
    constructor(private host: IonIcon) {
    }

    public ngOnInit(): void {
        const component = <IonIcon & Components.IonIcon>this.host;
        const name = component.name;

        if (name) {
            component.name = undefined;
            component.src = 'data:text/plain,' + name;
        }
    }
}

zolakt avatar Jun 28 '24 11:06 zolakt