Reputation: 13
I cannot allign the icon position in a button to the end/start dynamically e.g. with Angular MatIcon attribute iconPositionEnd.
I created a Button component with the @Input() customIconPos:boolean = false;
import { Component, Input, OnInit } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatIcon, MatIconModule } from '@angular/material/icon';
import { MatToolbarModule } from '@angular/material/toolbar';
@Component({
selector: 'button-with-loading-icon',
standalone: true,
imports: [MatButtonModule, MatIconModule, MatToolbarModule, MatIcon],
templateUrl: './button-with-loading-icon.component.html',
styleUrl: './button-with-loading-icon.component.scss',
})
export class ButtonWithLoadingIconComponent implements OnInit {
@Input() btnText: string = '';
@Input() customIconPos: boolean = false;
@Input() icon: string = '';
@Input() type: string = '';
@Input() uiType: string = '';
test = true;
public ngOnInit() {}
}
Now in html I tried to make a dynamic attribute assignment:
<button mat-button mat-stroked-button class="button button-draft">
<mat-icon [iconPositionEnd]="customIconPos">save</mat-icon>
Als Entwurf
</button>
But it says: Can't bind to 'iconPositionEnd' since it isn't a known property of 'mat-icon'. Even though with the undynamic, static way it works and the icon is positioned to the end.
<button mat-button mat-stroked-button class="button button-draft">
<mat-icon iconPositionEnd>save</mat-icon>
Als Entwurf
</button>
I also tried different approaches like
<button mat-button mat-stroked-button class="button button-draft">
<mat-icon [attr.iconPositionEnd]="customIconPos" >save</mat-icon>
Als Entwurf
</button>
Or
<button mat-stroked-button class="button button-draft">
<mat-icon [iconPositionEnd]="customIconPos ? true : false" >save</mat-icon>
Als Entwurf speichern
</button>
But they didnt work. Couldnt find any solution here on stack or in the web about it. One solution that comes to my mind is of course that one, but I dont like this approach and want to use custom attribute binding in my projects for a modular principle.
<button mat-stroked-button class="button button-draft">
<mat-icon *ngIf="customIconPos" mat-icon iconPositionEnd>save</mat-icon>
<mat-icon *ngIf="!customIconPos" mat-icon>save</mat-icon>
Als Entwurf speichern
</button>
Thanks! Regards and I wish you a good day, thegreyluk
Upvotes: 0
Views: 29
Reputation: 57986
Looking at the source code, it seems to be content projected into the button component using this below line.
<span
class="mat-mdc-button-persistent-ripple"
[class.mdc-button__ripple]="!_isFab"
[class.mdc-fab__ripple]="_isFab"></span>
<ng-content select=".material-icons:not([iconPositionEnd]), mat-icon:not([iconPositionEnd]), [matButtonIcon]:not([iconPositionEnd])">
</ng-content>
<span class="mdc-button__label"><ng-content></ng-content></span>
<!-- inserted below -->
<ng-content select=".material-icons[iconPositionEnd], mat-icon[iconPositionEnd], [matButtonIcon][iconPositionEnd]">
</ng-content>
This does not evaluate [attr.iconPositionEnd]="customIconPos"
or [iconPositionEnd]="customIconPos ? true : false"
, I think content projection does not evaluate conditional attributes, like how directives cannot be initialized conditionally using ngClass
.
So to my knowledge the best solution is to just write an if else condition that add attribute manually.
<button mat-button mat-stroked-button class="button button-draft">
@if(customIconPos) {
<mat-icon iconPositionEnd>save</mat-icon>
} @else {
<mat-icon>save</mat-icon>
} Als Entwurf
</button>
Upvotes: 0