Reputation: 2411
I am currently trying to implement a tab feature using Angular Material. I can for the life of me not get the button to click that is in the header. I have tried moving the click event around the tabs and it doesn't seem to get triggered anywhere.
I am trying to add the functionality that you can close a tab by clicking on the close icon. I have tried putting it in a div. I've tried using a div instead of a button.
Here is the UI:
<mat-tab-group animationDuration="0ms">
<div *ngIf="tabs">
<mat-tab *ngFor="let tab of tabs; let index = index" [ngSwitch]="tab.type">
<ng-template mat-tab-label>
<div style="display: flex; flex-direction: row; align-items: center;">
{{tab["title"]}}
<div>
<button style="color:black" mat-icon-button (click)="closeTab($event, index)">
<mat-icon>close</mat-icon>
</button>
</div>
</div>
</ng-template>
<div *ngSwitchCase="'Work'">
<p>Work</p>
</div>
<div *ngSwitchCase="'Case'">
<p>Case</p>
</div>
<div *ngSwitchCase="'Document'">
<app-base></app-base>
</div>
</mat-tab>
</div>
</mat-tab-group>
</div>
And the backend:
import {MatTab, MatTabGroup} from '@angular/material/tabs';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent {
@ViewChild(MatTabGroup, {read: MatTabGroup})
public tabGroup: MatTabGroup;
@ViewChildren(MatTab, {read: MatTab})
public tabNodes: QueryList<MatTab>;
tabs: Tab[] = [];
workCounter: number = 0;
caseCounter: number = 0;
documentCounter: number = 0;
closedTabs: number[] = [];
ngOnInit(): void {
}
addNewTab(type: string): void {
let tab = new Tab();
switch (type) {
case 'Work':
this.workCounter++;
tab.type = type;
tab.title = `${type} # ${this.workCounter}`
break;
case 'Document':
this.documentCounter++;
tab.type = type;
tab.title = `${type} # ${this.documentCounter}`
break;
case 'Case':
this.caseCounter++;
tab.type = type;
tab.title = `${type} # ${this.caseCounter}`
break;
}
this.tabs.push(tab);
}
closeTab(event: Event, index: number) {
console.log(index);
event.stopPropagation();
this.closedTabs.push(index);
this.tabGroup.selectedIndex = this.tabNodes.length - 1;
console.log(index);
}
}
class Tab {
type: string;
title: string;
index: number;
}
Upvotes: 4
Views: 1733
Reputation: 825
in order to have a button in the tab header but not be a real tab, but be clickable and not look disabled you can add this to your style.scss
.mdc-tab.mat-mdc-tab:has(.fake-disabled){
opacity: initial;
.mdc-tab__content {
pointer-events: all;
}
}
and add a mat-tab disabled to html. you will need to add a class "fake-disabled" to your button
<ng-template mat-tab-label>
<mat-icon (click)="doStuff()" class="fake-disabled">add_circle</mat-icon>
</ng-template>
</mat-tab>
Upvotes: 0
Reputation: 2518
To add something a little more specific here, the material design specification doesn't mention anything about being able to close tabs.
However there is mention of the fact that if an element has point-events: none, but one of its descendants has pointer-events:auto then:
pointer events will trigger event listeners on this parent element as appropriate on their way to/from the descendant during the event capture/bubble phases
You can read more about that here.
So, instead of blanket applying pointer-events:all to all of your tabs, you can simply add it to the style of the icon:
<mat-icon style="pointer-events: auto;" *ngIf="index > 1" (click)="removeTab(index)">{{tab.icon}}</mat-icon>
Or I guess you could make a clickable-icon class:
.clickable-icon {
pointer-events: auto;
}
There are currently two issues open in the angular/components repo here and here that you can keep an eye on for resolution.
Upvotes: 4
Reputation: 101
try adding this to your style.css file
.mdc-tab__content{
pointer-events: all!important;
}
Upvotes: 1
Reputation: 3130
Found the problem, Material 15 has added pointer-events rule and sets it to None, overriding this should allow click events to call the ts methods
<mat-tab-group animationDuration="0ms" class="allow-tab-events">
</mat-tab-group>
.allow-tab-events ::ng-deep .mdc-tab .mdc-tab__content{
pointer-events: all;
}
Upvotes: 4