MCPcopy Create free account
hub / github.com/angular/components / ngAfterContentInit

Function ngAfterContentInit

src/material/tabs/paginated-tab-header.ts:206–269  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

204 }
205
206 ngAfterContentInit() {
207 const dirChange = this._dir ? this._dir.change : observableOf('ltr');
208 // We need to debounce resize events because the alignment logic is expensive.
209 // If someone animates the width of tabs, we don't want to realign on every animation frame.
210 // Once we haven't seen any more resize events in the last 32ms (~2 animaion frames) we can
211 // re-align.
212 const resize = this._sharedResizeObserver
213 .observe(this._elementRef.nativeElement)
214 .pipe(debounceTime(32), takeUntil(this._destroyed));
215 // Note: We do not actually need to watch these events for proper functioning of the tabs,
216 // the resize events above should capture any viewport resize that we care about. However,
217 // removing this is fairly breaking for screenshot tests, so we're leaving it here for now.
218 const viewportResize = this._viewportRuler.change(150).pipe(takeUntil(this._destroyed));
219
220 const realign = () => {
221 this.updatePagination();
222 this._alignInkBarToSelectedTab();
223 };
224
225 this._keyManager = new FocusKeyManager<MatPaginatedTabHeaderItem>(this._items)
226 .withHorizontalOrientation(this._getLayoutDirection())
227 .withHomeAndEnd()
228 .withWrap()
229 // Allow focus to land on disabled tabs, as per https://w3c.github.io/aria-practices/#kbd_disabled_controls
230 .skipPredicate(() => false);
231
232 // Fall back to the first link as being active if there isn't a selected one.
233 // This is relevant primarily for the tab nav bar.
234 this._keyManager.updateActiveItem(Math.max(this._selectedIndex, 0));
235
236 // Note: We do not need to realign after the first render for proper functioning of the tabs
237 // the resize events above should fire when we first start observing the element. However,
238 // removing this is fairly breaking for screenshot tests, so we're leaving it here for now.
239 afterNextRender(realign, {injector: this._injector});
240
241 // On dir change or resize, realign the ink bar and update the orientation of
242 // the key manager if the direction has changed.
243 merge(dirChange, viewportResize, resize, this._items.changes, this._itemsResized())
244 .pipe(takeUntil(this._destroyed))
245 .subscribe(() => {
246 // We need to defer this to give the browser some time to recalculate
247 // the element dimensions. The call has to be wrapped in `NgZone.run`,
248 // because the viewport change handler runs outside of Angular.
249 this._ngZone.run(() => {
250 Promise.resolve().then(() => {
251 // Clamp the scroll distance, because it can change with the number of tabs.
252 this._scrollDistance = Math.max(
253 0,
254 Math.min(this._getMaxScrollDistance(), this._scrollDistance),
255 );
256 realign();
257 });
258 });
259 this._keyManager?.withHorizontalOrientation(this._getLayoutDirection());
260 });
261
262 // If there is a change in the focus key manager we need to emit the `indexFocused`
263 // event in order to provide a public event that notifies about focus changes. Also we realign

Callers

nothing calls this directly

Calls 12

realignFunction · 0.85
changeMethod · 0.80
skipPredicateMethod · 0.80
withWrapMethod · 0.80
withHomeAndEndMethod · 0.80
_getLayoutDirectionMethod · 0.80
updateActiveItemMethod · 0.80
resolveMethod · 0.80
observeMethod · 0.45
maxMethod · 0.45
minMethod · 0.45

Tested by

no test coverage detected