diff --git a/libs/components/src/dialog/dialog/dialog.component.html b/libs/components/src/dialog/dialog/dialog.component.html index 413f170efef..79d69423f2a 100644 --- a/libs/components/src/dialog/dialog/dialog.component.html +++ b/libs/components/src/dialog/dialog/dialog.component.html @@ -6,7 +6,7 @@ cdkTrapFocus cdkTrapFocusAutoCapture > - @let showHeaderBorder = !isDrawer || bodyHasScrolledFrom?.top(); + @let showHeaderBorder = !isDrawer || bodyHasScrolledFrom().top;
`, }) export class DrawerBodyComponent { - protected hasScrolledFrom = hasScrolledFrom(inject(CdkScrollable)); + protected hasScrolledFrom = hasScrolledFrom(); } diff --git a/libs/components/src/utils/has-scrolled-from.ts b/libs/components/src/utils/has-scrolled-from.ts index 36f3fddc61e..71ece920a9a 100644 --- a/libs/components/src/utils/has-scrolled-from.ts +++ b/libs/components/src/utils/has-scrolled-from.ts @@ -1,33 +1,40 @@ import { CdkScrollable } from "@angular/cdk/scrolling"; -import { Injector, Signal, inject, runInInjectionContext } from "@angular/core"; -import { toSignal } from "@angular/core/rxjs-interop"; -import { map } from "rxjs"; +import { Signal, inject, signal } from "@angular/core"; +import { toObservable, toSignal } from "@angular/core/rxjs-interop"; +import { map, switchMap } from "rxjs"; export type ScrollState = { /** `true` when the scrollbar is not at the top-most position */ - top: Signal; + top: boolean; /** `true` when the scrollbar is not at the bottom-most position */ - bottom: Signal; + bottom: boolean; }; /** * Check if a `CdkScrollable` instance has been scrolled - * @param scrollable The element to check - * @param injector An optional injector; needed if called from outside an injection context - * @returns {ScrollState} + * @param scrollable The instance to check, defaults to the one provided by the current injector + * @returns {Signal} */ -export const hasScrolledFrom = (scrollable: CdkScrollable, injector?: Injector): ScrollState => { - const _injector = injector ?? inject(Injector); - const scrollState$ = scrollable.elementScrolled().pipe( - map(() => ({ - top: scrollable.measureScrollOffset("top") > 0, - bottom: scrollable.measureScrollOffset("bottom") > 0, - })), +export const hasScrolledFrom = (scrollable?: Signal): Signal => { + const _scrollable = scrollable ?? signal(inject(CdkScrollable)); + const scrollable$ = toObservable(_scrollable); + + const scrollState$ = scrollable$.pipe( + switchMap((_scrollable) => + _scrollable.elementScrolled().pipe( + map(() => ({ + top: _scrollable.measureScrollOffset("top") > 0, + bottom: _scrollable.measureScrollOffset("bottom") > 0, + })), + ), + ), ); - return runInInjectionContext(_injector, () => ({ - top: toSignal(scrollState$.pipe(map(($) => $.top)), { initialValue: false }), - bottom: toSignal(scrollState$.pipe(map(($) => $.bottom)), { initialValue: false }), - })); + return toSignal(scrollState$, { + initialValue: { + top: false, + bottom: false, + }, + }); };