import { AfterViewChecked, AfterViewInit, ChangeDetectorRef, Component, ContentChildren, Input, OnInit, QueryList, ViewChild } from '@angular/core'; import {MatTab, MatTabGroup} from '@angular/material/tabs'; import {ActivatedRoute, Params, Router} from '@angular/router'; @Component({ selector: 'app-tabs', templateUrl: './tabs.component.html', styleUrls: ['./tabs.component.scss'] }) /** * This component is pretty entangled with the material tabs component * - this is just here to provide a handy and styled short-hand for using the material * component. */ export class TabsComponent implements AfterViewInit, AfterViewChecked, OnInit { @Input() header: string|undefined; @ViewChild(MatTabGroup) matTabGroup: MatTabGroup|undefined; @ContentChildren(MatTab, {descendants: true}) tabsFromNgContent: QueryList|undefined; private index = 0; private ready = false; get tabIndex(): number { return this.index; } set tabIndex(newValue: number) { if (newValue === this.tabIndex || !this.ready && !newValue) { return; } const queryParams: Params = { tab: newValue }; this.index = newValue; this.router.navigate( [], { relativeTo: this.route, queryParams, queryParamsHandling: 'merge' }); } constructor(private route: ActivatedRoute, private router: Router) { } ngOnInit(): void { this.route.queryParamMap.subscribe((params) => { if (params.has('tab') && params.get('tab') !== this.matTabGroup?.selectedIndex) { this.tabIndex = Number(params.get('tab')); } }); } ngAfterViewInit(): void { if (this.tabsFromNgContent && this.matTabGroup) { // Add transcluded tabs to the view this.matTabGroup._tabs.reset([...this.tabsFromNgContent.toArray()]); this.matTabGroup.selectedIndex = this.tabIndex; this.matTabGroup._tabs.notifyOnChanges(); } } ngAfterViewChecked(): void { if (this.tabsFromNgContent) { const tabElements = this.matTabGroup?._elementRef?.nativeElement.childNodes[0].getElementsByClassName('mat-tab-label'); if (tabElements == null || tabElements.length === 0) { return; } // Compute with required to take up the fill width const computedWidth = `${100 / this.tabsFromNgContent?.length}%`; const tabs: HTMLDivElement[] = [...tabElements]; tabs.forEach(tab => tab.style.width = computedWidth); this.ready = true; } } } @Component({ // tslint:disable-next-line:component-selector selector: 'header-buttons', template: '' }) export class HeaderButtonsComponent {}