Last active
January 28, 2017 00:24
-
-
Save joanllenas/028990fb62628a1e77c96d0261de0898 to your computer and use it in GitHub Desktop.
Angular2 API for responsive ngClass, based on @angular/flex-layout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Toggles class based on media query breakpoint activation. | |
* Depends on @angular/flex-layout | |
* Usage: | |
* <span | |
* class="green" | |
* class.xs="my-xs-class" | |
* class.sm="my-sm-class" | |
* class.md="my-md-class" | |
* class.lg="my-lg-class"> | |
* Spniach | |
* </span> | |
*/ | |
import { | |
Directive, | |
ElementRef, | |
Inject, | |
Input | |
} from '@angular/core'; | |
import { MatchMediaObservable, MediaChange } from '@angular/flex-layout'; | |
import { Subscription } from 'rxjs'; | |
@Directive({ | |
selector: ` | |
[class.xs], | |
[class.sm], | |
[class.md], | |
[class.lg] | |
` | |
}) | |
export class ClassMediaQueryDirective { | |
@Input('class.xs') class_xs: string; | |
@Input('class.sm') class_sm: string; | |
@Input('class.md') class_md: string; | |
@Input('class.lg') class_lg: string; | |
private _watcher: Subscription; | |
private _mqAlias: string[] = ['xs', 'sm', 'md', 'lg']; | |
private _mqClasses: Array<string[]>; | |
constructor( | |
private el: ElementRef, | |
@Inject(MatchMediaObservable) private _media$ | |
) { } | |
ngOnInit() { | |
this._mqClasses = this._mqAlias | |
.map(mqAlias => this[`class_${mqAlias}`]) | |
.map(mqClassList => !!mqClassList ? mqClassList.split(' ') : []); | |
this._watcher = this._media$ | |
.subscribe((e: MediaChange) => { | |
this.changeClass(e.mqAlias); | |
}); | |
} | |
changeClass(mqAlias: string) { | |
const htmlEl = this.el.nativeElement as HTMLElement; | |
let classList = htmlEl.className.split(' '); | |
// clean all MediaQuery classes present in element classList | |
const flattenedMqClasses = this._mqClasses.reduce((a, b) => a.concat(b)); | |
classList = classList.filter(clazz => flattenedMqClasses.indexOf(clazz) === -1); | |
// apply the first media query found to have a value | |
let mqIndex = this._mqAlias.indexOf(mqAlias); | |
for (mqIndex; mqIndex >= 0; mqIndex--) { | |
const classes = this._mqClasses[mqIndex]; | |
if (classes.length > 0) { | |
classList = classList.concat(classes); | |
break; | |
} | |
} | |
htmlEl.className = classList.join(' '); | |
} | |
ngOnDestroy() { | |
this._watcher.unsubscribe(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment