ionic-framework
ionic-framework copied to clipboard
bug: Standalone IonIcon type does not expose any component properties
Prerequisites
- [X] I have read the Contributing Guidelines.
- [X] I agree to follow the Code of Conduct.
- [X] I have searched for existing issues that already report this problem, without success.
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:
But the standalone version doesn't extend it:
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:
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;
}
}
}