* After the content is checked, this component knows what tabs have been defined * and what the selected index should be. This is where we can know exactly what position * each tab should be in according to the new selected index, and additionally we know how * a new selected tab should tra
()
| 322 | * a new selected tab should transition in (from the left or right). |
| 323 | */ |
| 324 | ngAfterContentChecked() { |
| 325 | // Don't clamp the `indexToSelect` immediately in the setter because it can happen that |
| 326 | // the amount of tabs changes before the actual change detection runs. |
| 327 | const indexToSelect = (this._indexToSelect = this._clampTabIndex(this._indexToSelect)); |
| 328 | |
| 329 | // If there is a change in selected index, emit a change event. Should not trigger if |
| 330 | // the selected index has not yet been initialized. |
| 331 | if (this._selectedIndex != indexToSelect) { |
| 332 | const isFirstRun = this._selectedIndex == null; |
| 333 | |
| 334 | if (!isFirstRun) { |
| 335 | this.selectedTabChange.emit(this._createChangeEvent(indexToSelect)); |
| 336 | // Preserve the height so page doesn't scroll up during tab change. |
| 337 | // Fixes https://stackblitz.com/edit/mat-tabs-scroll-page-top-on-tab-change |
| 338 | const wrapper = this._tabBodyWrapper.nativeElement; |
| 339 | wrapper.style.minHeight = wrapper.clientHeight + 'px'; |
| 340 | } |
| 341 | |
| 342 | // Changing these values after change detection has run |
| 343 | // since the checked content may contain references to them. |
| 344 | Promise.resolve().then(() => { |
| 345 | this._tabs.forEach((tab, index) => (tab.isActive = index === indexToSelect)); |
| 346 | |
| 347 | if (!isFirstRun) { |
| 348 | this.selectedIndexChange.emit(indexToSelect); |
| 349 | // Clear the min-height, this was needed during tab change to avoid |
| 350 | // unnecessary scrolling. |
| 351 | this._tabBodyWrapper.nativeElement.style.minHeight = ''; |
| 352 | } |
| 353 | }); |
| 354 | } |
| 355 | |
| 356 | // Setup the position for each tab and optionally setup an origin on the next selected tab. |
| 357 | this._tabs.forEach((tab: MatTab, index: number) => { |
| 358 | tab.position = index - indexToSelect; |
| 359 | |
| 360 | // If there is already a selected tab, then set up an origin for the next selected tab |
| 361 | // if it doesn't have one already. |
| 362 | if (this._selectedIndex != null && tab.position == 0 && !tab.origin) { |
| 363 | tab.origin = indexToSelect - this._selectedIndex; |
| 364 | } |
| 365 | }); |
| 366 | |
| 367 | if (this._selectedIndex !== indexToSelect) { |
| 368 | this._selectedIndex = indexToSelect; |
| 369 | this._lastFocusedTabIndex = null; |
| 370 | this._changeDetectorRef.markForCheck(); |
| 371 | } |
| 372 | } |
| 373 | |
| 374 | ngAfterContentInit() { |
| 375 | this._subscribeToAllTabChanges(); |
nothing calls this directly
no test coverage detected