Skip to content

Instantly share code, notes, and snippets.

@kevupton
Last active September 1, 2019 03:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kevupton/eee9764e6e3082d0b6edc0a7f7a1de8b to your computer and use it in GitHub Desktop.
Save kevupton/eee9764e6e3082d0b6edc0a7f7a1de8b to your computer and use it in GitHub Desktop.
Angular Flex Layout fxIf equivalent of ngIf
import { isPlatformBrowser } from '@angular/common';
import { Directive, ElementRef, Inject, Input, OnDestroy, OnInit, PLATFORM_ID } from '@angular/core';
import { MediaObserver } from '@angular/flex-layout';
import { BehaviorSubject, combineLatest, Subscription } from 'rxjs';
@Directive({
selector: '[fxIf],' + ['xs', 'md', 'lg', 'xl', 'lt-sm', 'lt-md', 'lt-lg',
'lt-xl', 'gt-xs', 'gt-sm', 'gt-md', 'gt-lg'].map(key => `[fxIf.${key}]`).join(','),
})
export class FxIfDirective implements OnInit, OnDestroy {
@Input('fxIf.xs')
set xs (value : string) {
this.set('xs', value);
}
@Input('fxIf.sm')
set sm (value : string) {
this.set('sm', value);
}
@Input('fxIf.md')
set md (value : string) {
this.set('md', value);
}
@Input('fxIf.lg')
set lg (value : string) {
this.set('lg', value);
}
@Input('fxIf.xl')
set xl (value : string) {
this.set('xl', value);
}
@Input('fxIf.gt-xs')
set gtXs (value : string) {
this.set('gt-xs', value);
}
@Input('fxIf.gt-sm')
set gtSm (value : string) {
this.set('gt-sm', value);
}
@Input('fxIf.gt-md')
set gtMd (value : string) {
this.set('gt-md', value);
}
@Input('fxIf.gt-lg')
set gtLg (value : string) {
this.set('gt-lg', value);
}
@Input('fxIf.lt-xl')
set ltXl (value : string) {
this.set('lt-xl', value);
}
@Input('fxIf.lt-lg')
set ltLg (value : string) {
this.set('lt-lg', value);
}
@Input('fxIf.lt-md')
set ltMd (value : string) {
this.set('lt-md', value);
}
@Input('fxIf.lt-sm')
set ltSm (value : string) {
this.set('lt-sm', value);
}
private settingsSubject = new BehaviorSubject<{ [key : string] : string; }>({});
private readonly subscription = new Subscription();
private readonly dummyElement : Comment;
private attached = true;
constructor (
private readonly media : MediaObserver,
@Inject(PLATFORM_ID)
private readonly platformId : string,
private readonly elementRef : ElementRef<HTMLElement>,
) {
if (!isPlatformBrowser(this.platformId)) {
return;
}
this.dummyElement = document.createComment(' fx-hidden ');
}
public ngOnInit () : void {
if (!isPlatformBrowser(this.platformId)) {
return;
}
const sub = combineLatest([
this.media.asObservable(),
this.settingsSubject,
]).subscribe(([changes, settings]) => {
const found = changes.find(change => settings[change.mqAlias] !== undefined);
if (found) {
this.attach();
}
else {
this.detach();
}
});
this.subscription.add(sub);
}
public ngOnDestroy () {
this.subscription.unsubscribe();
}
private set (key : string, value : string) {
this.settingsSubject.next({
...this.settingsSubject.value,
[key]: value,
});
}
private attach () {
if (this.attached) {
return;
}
this.attached = true;
const element = this.elementRef.nativeElement;
this.dummyElement.parentElement.insertBefore(element, this.dummyElement);
this.dummyElement.remove();
}
private detach () {
if (!this.attached) {
return;
}
this.attached = false;
const element = this.elementRef.nativeElement;
element.parentElement.insertBefore(this.dummyElement, element);
element.remove();
}
}
@kevupton
Copy link
Author

Usage

<div fxIf.gt-sm>

</div>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment