Posted under Angular & CSS & PrimeNG
Permalink
Tags Angular, Gotcha, Tip, Tutorial
I was using a button component to encapsulate the primeNG one, to allow it to responsively change to an icon only button at smaller screen widths. Whilst in theory I could have dynamically modified the internal primeNG button CSS, this was complex and I did not want to become tightly coupled to it. My button component therefore simply selected one of 2 buttons via a media query, setting the unwanted one to display:none.
I wanted any classes added to the top level ss-button to be set on the underlying primeNG buttons. One use of these buttons was in a home brewed tab component, and I was dynamically changing the button colour via ui-button-primary, ui-button-secondary so that the active tab had a ‘primary’ coloured button and the inactive ones were ‘secondary’ which caused them to become uncoloured ghost buttons – ideal for my requirement.
During refactoring to replace the ‘full size only’ primeNG buttons with the resizing ss-buttons I introduced a bug and the colour change failed to work. The initial (incorrect) refactored code was as follows:-
ss-tab-toolbar.component.html
<ng-container *ngFor="let tab of tabs">
<app-ss-button [label]="tab.label" [icon]="tab.icon" (click)="setActiveTab(tab)"
[ngClass]="{'ui-button-primary': isActiveTab(tab), 'ui-button-secondary': ! isActiveTab(tab)}"></app-ss-button>
</ng-container>
ss-button.component.html
<button pButton type="button" [title]="label" [label]="label" [icon]="icon" class="ss-button icon-text"
[ngClass]="class" ></button>
<button pButton type="button" [title]="label" [icon]="icon" class="ss-button icon-only"
[ngClass]="class" ></button>
ss-button.component.ts
@Component({
selector: 'app-ss-button',
templateUrl: './ss-button.component.html',
styleUrls: ['./ss-button.component.scss']
})
export class SSTabButtonComponent {
@Input() label: string;
@Input() icon: string;
@Input() class: string;
constructor() { }
}
The issue was that I was using [ngClass] dynamically to update the classes on the <app-ss-button> in ss-tab-toolbar.component. html. This used to work for the PrimeNG buttons, but now would have no effect as the classes need to be changed on the child buttons not the encapsulating parent. A simple change of [ngClass] to [class] fixed the problem, as the parent style change then updated the property on the parent component which was then picked up by the children correctly.
modified ss-tab-toolbar.component.html
<ng-container *ngFor="let tab of tabs">
<app-ss-button [label]="tab.label" [icon]="tab.icon" (click)="setActiveTab(tab)"
[class]="{'ui-button-primary': isActiveTab(tab), 'ui-button-secondary': ! isActiveTab(tab)}"></app-ss-button>
</ng-container>
Happily the dynamic nature of angular meant that this worked perfectly for tab changes – the change on the parent class was propagated correctly to the child and the button colours changed correctly.
I was wondering initially whether I would need to involve observables to make this work but this was not the case – this kind of dynamic propagation pattern is worth remembering in future.