diff --git a/projects/core/components/root/root.component.ts b/projects/core/components/root/root.component.ts index 8a3bca5176c9..58f78d20056e 100644 --- a/projects/core/components/root/root.component.ts +++ b/projects/core/components/root/root.component.ts @@ -12,12 +12,8 @@ import { TUI_IS_MOBILE, TUI_VERSION, } from '@taiga-ui/cdk'; -import {TUI_IS_MOBILE_RES_PROVIDER} from '@taiga-ui/core/providers'; -import { - TUI_ANIMATIONS_DURATION, - TUI_IS_MOBILE_RES, - TUI_THEME, -} from '@taiga-ui/core/tokens'; +import {TuiBreakpointService} from '@taiga-ui/core/services'; +import {TUI_ANIMATIONS_DURATION, TUI_THEME} from '@taiga-ui/core/tokens'; import {combineLatest, Observable, of} from 'rxjs'; import {debounceTime, map} from 'rxjs/operators'; @@ -28,17 +24,21 @@ import {debounceTime, map} from 'rxjs/operators'; // So that we do not force OnPush on custom dialogs // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection changeDetection: ChangeDetectionStrategy.Default, - providers: [TUI_IS_MOBILE_RES_PROVIDER], encapsulation: ViewEncapsulation.None, host: { 'data-tui-version': TUI_VERSION, '[style.--tui-duration.ms]': 'duration', '[class._ios]': 'isIOS', '[class._android]': 'isAndroid', + '[$.class._mobile]': 'isMobileRes$', '($.class._mobile)': 'isMobileRes$', }, }) export class TuiRootComponent { + readonly isMobileRes$ = this.breakpoint.pipe( + map(breakpoint => breakpoint === 'mobile'), + ); + readonly scrollbars$: Observable = this.dialogs.length && !this.isMobile ? combineLatest([...this.dialogs]).pipe( @@ -52,7 +52,7 @@ export class TuiRootComponent { @Inject(TUI_DIALOGS) readonly dialogs: ReadonlyArray>, @Inject(TUI_IS_MOBILE) private readonly isMobile: boolean, - @Inject(TUI_IS_MOBILE_RES) readonly isMobileRes$: Observable, + @Inject(TuiBreakpointService) private readonly breakpoint: TuiBreakpointService, @Inject(TUI_IS_IOS) readonly isIOS: boolean, @Inject(TUI_IS_ANDROID) readonly isAndroid: boolean, @Inject(DOCUMENT) {body}: Document, diff --git a/projects/core/providers/is-mobile-resolution.provider.ts b/projects/core/providers/is-mobile-resolution.provider.ts index f68f343af8a6..113c34517fe2 100644 --- a/projects/core/providers/is-mobile-resolution.provider.ts +++ b/projects/core/providers/is-mobile-resolution.provider.ts @@ -2,6 +2,9 @@ import {ElementRef, Provider, SkipSelf} from '@angular/core'; import {TUI_IS_MOBILE_RES} from '@taiga-ui/core/tokens'; import {Observable} from 'rxjs'; +/** + * @deprecated: drop in v4.0 + */ export const TUI_IS_MOBILE_RES_PROVIDER: Provider = { provide: TUI_IS_MOBILE_RES, deps: [[new SkipSelf(), TUI_IS_MOBILE_RES], ElementRef], diff --git a/projects/core/services/breakpoint.service.ts b/projects/core/services/breakpoint.service.ts index bb60f2f98db2..d80f1440ef02 100644 --- a/projects/core/services/breakpoint.service.ts +++ b/projects/core/services/breakpoint.service.ts @@ -1,5 +1,5 @@ -import {Inject, Injectable} from '@angular/core'; -import {TUI_WINDOW_SIZE} from '@taiga-ui/cdk'; +import {Inject, Injectable, NgZone} from '@angular/core'; +import {TUI_WINDOW_SIZE, tuiZoneOptimized} from '@taiga-ui/cdk'; import {TuiMedia} from '@taiga-ui/core/interfaces'; import {TUI_MEDIA} from '@taiga-ui/core/tokens'; import {Observable} from 'rxjs'; @@ -29,11 +29,13 @@ export class TuiBreakpointService extends Observable this.sorted.find(size => size > width)), map(key => this.invert[key || this.sorted[this.sorted.length - 1]]), distinctUntilChanged(), + tuiZoneOptimized(this.ngZone), shareReplay({bufferSize: 1, refCount: true}), ); constructor( @Inject(TUI_MEDIA) private readonly media: TuiMedia, + @Inject(NgZone) private readonly ngZone: NgZone, @Inject(TUI_WINDOW_SIZE) private readonly size$: Observable, ) { super(subscriber => this.stream$.subscribe(subscriber));