/
githubmirror
/
components
Обзор
Документация
Войти
/
githubmirror
/
components
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/cdk/overlay/scroll/close-scroll-strategy.ts
117 строк
3 KB
Kristiyan Kostadinov
refactor(cdk/overlay): fix strict property initialization errors
15 дек 2025, 22:07
15 дек 2025, 22:07
4fe24b1
Код
Авторство
О чём код?
/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.dev/license */ import {Injector, NgZone} from '@angular/core'; import {ScrollStrategy, getMatScrollStrategyAlreadyAttachedError} from './scroll-strategy'; import {Subscription} from 'rxjs'; import {ScrollDispatcher, ViewportRuler} from '../../scrolling'; import {filter} from 'rxjs/operators'; import type {OverlayRef} from '../overlay-ref'; /** * Config options for the CloseScrollStrategy. */ export interface CloseScrollStrategyConfig { /** Amount of pixels the user has to scroll before the overlay is closed. */ threshold?: number; } /** * Creates a scroll strategy that closes the overlay when the user starts to scroll. * @param injector Injector used to resolve dependencies of the scroll strategy. * @param config Configuration options for the scroll strategy. */ export function createCloseScrollStrategy( injector: Injector, config?: CloseScrollStrategyConfig, ): CloseScrollStrategy { return new CloseScrollStrategy( injector.get(ScrollDispatcher), injector.get(NgZone), injector.get(ViewportRuler), config, ); } /** * Strategy that will close the overlay as soon as the user starts scrolling. */ export class CloseScrollStrategy implements ScrollStrategy { private _scrollSubscription: Subscription | null = null; private _overlayRef!: OverlayRef; private _initialScrollPosition!: number; constructor( private _scrollDispatcher: ScrollDispatcher, private _ngZone: NgZone, private _viewportRuler: ViewportRuler, private _config?: CloseScrollStrategyConfig, ) {} /** Attaches this scroll strategy to an overlay. */ attach(overlayRef: OverlayRef) { if (this._overlayRef && (typeof ngDevMode === 'undefined' || ngDevMode)) { throw getMatScrollStrategyAlreadyAttachedError(); } this._overlayRef = overlayRef; } /** Enables the closing of the attached overlay on scroll. */ enable() { if (this._scrollSubscription) { return; } const stream = this._scrollDispatcher.scrolled(0).pipe( filter(scrollable => { return ( !scrollable || !this._overlayRef.overlayElement.contains(scrollable.getElementRef().nativeElement) ); }), ); if (this._config && this._config.threshold && this._config.threshold > 1) { this._initialScrollPosition = this._viewportRuler.getViewportScrollPosition().top; this._scrollSubscription = stream.subscribe(() => { const scrollPosition = this._viewportRuler.getViewportScrollPosition().top; if (Math.abs(scrollPosition - this._initialScrollPosition) > this._config!.threshold!) { this._detach(); } else { this._overlayRef.updatePosition(); } }); } else { this._scrollSubscription = stream.subscribe(this._detach); } } /** Disables the closing the attached overlay on scroll. */ disable() { if (this._scrollSubscription) { this._scrollSubscription.unsubscribe(); this._scrollSubscription = null; } } detach() { this.disable(); this._overlayRef = null!; } /** Detaches the overlay ref and disables the scroll strategy. */ private _detach = () => { this.disable(); if (this._overlayRef.hasAttached()) { this._ngZone.run(() => this._overlayRef.detach()); } }; }