Kind of late reply, but for future people searching:
HTML:
<tabset class="nav nav-tabs">
<ng-container *ngFor="let template of templates">
<tab #tab="routerLinkActive"
(selectTab)="(!template.disabled || firstSelection) && routeChange(template.appRouterLink)"
[active]="tab.isActive"
[customClass]="template.disabled && template.hideDisabled ?
'd-none' : template.disabled ? 'disabled' : ''"
[heading]="template.labelKey | translate"
[routerLink]="template.appRouterLink"
routerLinkActive="active">
</tab>
</ng-container>
</tabset>
<div class="tab-content">
<div class="tab-pane active">
<router-outlet></router-outlet>
</div>
</div>
TS:
@ContentChildren(TabsDirective) public templates: QueryList<TabsDirective>;
private firstSelection = true;
public constructor(private router: Router, private route: ActivatedRoute) {
}
public async routeChange(appRouterLink: any[] | string): Promise<any> {
if (this.firstSelection) {
this.firstSelection = false;
} else {
const route = appRouterLink instanceof Array ? appRouterLink : [appRouterLink];
this.router.navigate(route, {relativeTo: this.route});
}
}
And the directive:
@Directive({selector: '[appTabs]'})
export class TabsDirective {
@Input() public disabled: boolean;
@Input() public hideDisabled: boolean;
@Input() public labelKey: string;
@Input() public appRouterLink: any[] | string | null | undefined;
}
Usage example:
<app-nav>
<ng-template [disabled]="!can_see_info" appRouterLink="info"
appTabs labelKey="INFO"></ng-template>
<ng-template [disabled]="!can_see_events || !company?.id" appRouterLink="events"
appTabs labelKey="EVENTS"></ng-template>
</app-nav>
Few notes on why the code is like this:
- If you use the disabled property on tab tag and the initial value is set to true but is later changed, it will dismiss the trigger of select event, which will make the tab not show as selected.
- If you use *ngIf on tab tag, the order of the tabs might get all screwed up if you hide one and later show it again (sort of a FIFO behaviour).