diff --git a/docs/src/app/pages/component-sidenav/component-sidenav.ts b/docs/src/app/pages/component-sidenav/component-sidenav.ts index 7ae42ab87d93..38064a23b43a 100644 --- a/docs/src/app/pages/component-sidenav/component-sidenav.ts +++ b/docs/src/app/pages/component-sidenav/component-sidenav.ts @@ -6,21 +6,13 @@ * found in the LICENSE file at https://angular.dev/license */ -import { - Component, - OnDestroy, - OnInit, - ViewEncapsulation, - forwardRef, - inject, - viewChild, -} from '@angular/core'; +import {Component, ViewEncapsulation, forwardRef, inject, viewChild} from '@angular/core'; import {BreakpointObserver} from '@angular/cdk/layout'; import {AsyncPipe} from '@angular/common'; import {MatListItem, MatNavList} from '@angular/material/list'; import {MatSidenav, MatSidenavContainer} from '@angular/material/sidenav'; import {ActivatedRoute, Routes, RouterOutlet, RouterLinkActive, RouterLink} from '@angular/router'; -import {Observable, of, Subscription} from 'rxjs'; +import {Observable, of} from 'rxjs'; import {map, switchMap} from 'rxjs/operators'; import {DocumentationItems} from '../../shared/documentation-items/documentation-items'; @@ -37,6 +29,7 @@ import { ComponentViewer, } from '../component-viewer/component-viewer'; import {ComponentStyling} from '../component-viewer/component-styling'; +import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; // These constants are used by the ComponentSidenav for orchestrating the MatSidenav in a responsive // way. This includes hiding the sidenav, defaulting it to open, changing the mode from over to @@ -63,14 +56,13 @@ const SMALL_WIDTH_BREAKPOINT = 959; AsyncPipe, ], }) -export class ComponentSidenav implements OnInit, OnDestroy { +export class ComponentSidenav { docItems = inject(DocumentationItems); private _navigationFocusService = inject(NavigationFocusService); readonly sidenav = viewChild(MatSidenav); isExtraScreenSmall: Observable; isScreenSmall: Observable; - private _subscriptions = new Subscription(); constructor() { const breakpoints = inject(BreakpointObserver); @@ -81,23 +73,19 @@ export class ComponentSidenav implements OnInit, OnDestroy { this.isScreenSmall = breakpoints .observe(`(max-width: ${SMALL_WIDTH_BREAKPOINT}px)`) .pipe(map(breakpoint => breakpoint.matches)); - } - - ngOnInit() { - this._subscriptions.add( - this._navigationFocusService.navigationEndEvents - .pipe(map(() => this.isScreenSmall)) - .subscribe(shouldCloseSideNav => { - const sidenav = this.sidenav(); - if (shouldCloseSideNav && sidenav) { - sidenav.close(); - } - }), - ); - } - ngOnDestroy() { - this._subscriptions.unsubscribe(); + // Close the sidenav on navigation when the screen is small. + this._navigationFocusService.navigationEndEvents + .pipe( + takeUntilDestroyed(), + map(() => this.isScreenSmall), + ) + .subscribe(shouldCloseSideNav => { + const sidenav = this.sidenav(); + if (shouldCloseSideNav && sidenav) { + sidenav.close(); + } + }); } toggleSidenav(): void { diff --git a/docs/src/app/shared/navigation-focus/navigation-focus.service.ts b/docs/src/app/shared/navigation-focus/navigation-focus.service.ts index 2b224515bf36..5669f94859eb 100644 --- a/docs/src/app/shared/navigation-focus/navigation-focus.service.ts +++ b/docs/src/app/shared/navigation-focus/navigation-focus.service.ts @@ -6,17 +6,16 @@ * found in the LICENSE file at https://angular.dev/license */ -import {Injectable, OnDestroy, inject} from '@angular/core'; +import {Injectable, inject} from '@angular/core'; import {Event, NavigationEnd, Router} from '@angular/router'; import {filter, skip} from 'rxjs/operators'; -import {Subscription} from 'rxjs'; +import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; @Injectable({ providedIn: 'root', }) -export class NavigationFocusService implements OnDestroy { +export class NavigationFocusService { private _router = inject(Router); - private _subscriptions = new Subscription(); private _navigationFocusRequests: HTMLElement[] = []; private _skipLinkFocusRequests: HTMLElement[] = []; private _skipLinkHref: string | null | undefined; @@ -27,24 +26,18 @@ export class NavigationFocusService implements OnDestroy { readonly softNavigations = this.navigationEndEvents.pipe(skip(1)); constructor() { - this._subscriptions.add( - this.softNavigations.subscribe(() => { - // focus if url does not have fragment - if (!this._router.url.split('#')[1]) { - setTimeout(() => { - if (this._navigationFocusRequests.length) { - this._navigationFocusRequests[this._navigationFocusRequests.length - 1].focus({ - preventScroll: true, - }); - } - }, 100); - } - }), - ); - } - - ngOnDestroy() { - this._subscriptions.unsubscribe(); + this.softNavigations.pipe(takeUntilDestroyed()).subscribe(() => { + // focus if url does not have fragment + if (!this._router.url.split('#')[1]) { + setTimeout(() => { + if (this._navigationFocusRequests.length) { + this._navigationFocusRequests[this._navigationFocusRequests.length - 1].focus({ + preventScroll: true, + }); + } + }, 100); + } + }); } requestFocusOnNavigation(el: HTMLElement) {