import { computed, Directive, input } from '@angular/core'; import { outputFromObservable, toObservable } from '@angular/core/rxjs-interop'; import { fromEvent, map, startWith, switchMap } from 'rxjs'; type Size = 'sm' | 'md' | 'lg' | 'xl'; const mediaQueries = new Map([ ['sm', '(min-width: 640px)'], ['md', '(min-width: 768px)'], ['lg', '(min-width: 1024px)'], ['xl', '(min-width: 1280px)'], ]); @Directive({ selector: '[appMediaQuery]', standalone: true, }) export class MediaQueryDirective { mediaQuery = input.required({ alias: 'appMediaQuery' }); mediaQueryList = computed(() => window.matchMedia(mediaQueries.get(this.mediaQuery())!)); matches$ = toObservable(this.mediaQueryList).pipe( switchMap((mediaQueryList) => fromEvent(mediaQueryList, 'change').pipe(startWith(mediaQueryList.matches)) ), map((matches) => matches instanceof MediaQueryListEvent ? matches.matches : (matches as boolean) ) ); matches = outputFromObservable(this.matches$); }