Skip to content

Commit

Permalink
fix(ngClass): add ngClass selector support (#223)
Browse files Browse the repository at this point in the history
*  add missing static `ngClass` and `class`  selectors
*  add tests to demonstrate fallbacks to static selector values

Fixes #206.
  • Loading branch information
ThomasBurleson authored and mmalerba committed Mar 16, 2017
1 parent ba0d85d commit 980d412
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 8 deletions.
26 changes: 24 additions & 2 deletions src/lib/flexbox/api/class.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,22 @@ describe('class directive', () => {
</div>
`);

expectNativeEl(fixture).toHaveCssClass('existing-class');
activateMediaQuery('xs');
expectNativeEl(fixture).not.toHaveCssClass('existing-class');

activateMediaQuery('lg');
expectNativeEl(fixture).toHaveCssClass('existing-class');
expectNativeEl(fixture).not.toHaveCssClass('xs-class');
});

it('should keep existing ngClass selector', () => {
// @see documentation for @angular/core ngClass =http://bit.ly/2mz0LAa
fixture = createTestComponent(`
<div ngClass="existing-class" ngClass.xs="existing-class xs-class">
</div>
`);

expectNativeEl(fixture).toHaveCssClass('existing-class');
activateMediaQuery('xs');
expectNativeEl(fixture).toHaveCssClass('existing-class');
Expand All @@ -80,7 +96,7 @@ describe('class directive', () => {
expectNativeEl(fixture).not.toHaveCssClass('xs-class');
});

it('should allow more than one responsive breakpoint on one element', () => {
it('should support more than one responsive breakpoint on one element', () => {
fixture = createTestComponent(`
<div ngClass.xs="xs-class"
ngClass.md="md-class">
Expand All @@ -96,7 +112,8 @@ describe('class directive', () => {

it('should work with ngClass object notation', () => {
fixture = createTestComponent(`
<div [ngClass.xs]="{'xs-1': hasXs1, 'xs-2': hasXs2}">
<div [ngClass]="{'xs-1': hasXs1, 'xs-3': hasXs3}"
[ngClass.xs]="{'xs-1': hasXs1, 'xs-2': hasXs2}">
</div>
`);
activateMediaQuery('xs');
Expand All @@ -105,6 +122,11 @@ describe('class directive', () => {

expectNativeEl(fixture, {hasXs1: false, hasXs2: true}).toHaveCssClass('xs-2');
expectNativeEl(fixture, {hasXs1: false, hasXs2: true}).not.toHaveCssClass('xs-1');

activateMediaQuery('md');
expectNativeEl(fixture, {hasXs1: true, hasX2: false, hasXs3: true}).toHaveCssClass('xs-3');
expectNativeEl(fixture, {hasXs1: true, hasX2: false, hasXs3: true}).not.toHaveCssClass('xs-2');
expectNativeEl(fixture, {hasXs1: true, hasX2: false, hasXs3: true}).toHaveCssClass('xs-1');
});

it('should work with ngClass array notation', () => {
Expand Down
24 changes: 18 additions & 6 deletions src/lib/flexbox/api/class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,28 @@ export type NgClassType = string | string[] | Set<string> | {[klass: string]: an
*/
@Directive({
selector: `
[class],
[class.xs], [class.sm], [class.md], [class.lg], [class.xl],
[class.lt-sm], [class.lt-md], [class.lt-lg], [class.lt-xl],
[class.gt-xs], [class.gt-sm], [class.gt-md], [class.gt-lg],
[class.gt-xs], [class.gt-sm], [class.gt-md], [class.gt-lg],
[ngClass],
[ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl],
[ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl],
[ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]
`
})
export class ClassDirective extends NgClass implements OnInit, OnChanges, OnDestroy {

/**
* Intercept ngClass assignments so we cache the default classes
* which are merged with activated styles or used as fallbacks.
*/
@Input('ngClass')
set ngClassBase(val: NgClassType) {
this._base.cacheInput('class', val, true);
this.ngClass = this._base.inputMap['class'];
}

/* tslint:disable */
@Input('ngClass.xs') set ngClassXs(val: NgClassType) { this._base.cacheInput('classXs', val, true); }
@Input('ngClass.sm') set ngClassSm(val: NgClassType) { this._base.cacheInput('classSm', val, true); };
Expand All @@ -61,6 +72,7 @@ export class ClassDirective extends NgClass implements OnInit, OnChanges, OnDest
@Input('ngClass.gt-lg') set ngClassGtLg(val: NgClassType) { this._base.cacheInput('classGtLg', val, true); };

/** Deprecated selectors */
@Input('class') set classBase(val: NgClassType) { this._base.cacheInput('class', val, true); }
@Input('class.xs') set classXs(val: NgClassType) { this._base.cacheInput('classXs', val, true); }
@Input('class.sm') set classSm(val: NgClassType) { this._base.cacheInput('classSm', val, true); };
@Input('class.md') set classMd(val: NgClassType) { this._base.cacheInput('classMd', val, true);};
Expand Down Expand Up @@ -94,7 +106,7 @@ export class ClassDirective extends NgClass implements OnInit, OnChanges, OnDest
return (`ngClass${it.suffix}` in changes) || (`class${it.suffix}` in changes);
});
if (changed || this._base.mqActivation) {
this._updateStyle();
this._updateClass();
}
}

Expand All @@ -104,16 +116,16 @@ export class ClassDirective extends NgClass implements OnInit, OnChanges, OnDest
*/
ngOnInit() {
this._base.listenForMediaQueryChanges('class', '', (changes: MediaChange) => {
this._updateStyle(changes.value);
this._updateClass(changes.value);
});
this._updateStyle();
this._updateClass();
}

ngOnDestroy() {
this._base.ngOnDestroy();
}

protected _updateStyle(value?: NgClassType) {
protected _updateClass(value?: NgClassType) {
let clazz = value || this._base.queryInput("class") || '';
if (this._base.mqActivation) {
clazz = this._base.mqActivation.activatedInput;
Expand Down

0 comments on commit 980d412

Please sign in to comment.