This repository has been archived by the owner on Jan 6, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 772
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(api): add responsive support for ngClass and ngStyle (#170)
* update(flexbox): refactor fxStyle and fxClass code * refactor code to `base-adapter.ts` * update(flexbox): refactor fxStyle and fxClass code * refactor code to `base-adapter.ts` * feat(api): add responsive support for ngClass and ngStyle
- Loading branch information
1 parent
e6bc451
commit f57a63d
Showing
12 changed files
with
839 additions
and
5 deletions.
There are no files selected for viewing
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
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
110 changes: 110 additions & 0 deletions
110
src/demo-app/app/docs-layout-responsive/responsiveStyle.demo.ts
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import { Component, OnInit, Inject, OnDestroy } from '@angular/core'; | ||
import { Subscription } from "rxjs/Subscription"; | ||
import 'rxjs/add/operator/filter'; | ||
|
||
import { MediaChange } from "../../../lib/media-query/media-change"; | ||
import { ObservableMedia } from "../../../lib/media-query/observable-media-service"; | ||
|
||
@Component({ | ||
selector: 'demo-responsive-style', | ||
styleUrls: [ | ||
'../demo-app/material2.css' | ||
], | ||
template: ` | ||
<md-card class="card-demo" > | ||
<md-card-title>Responsive Style</md-card-title> | ||
<md-card-subtitle> | ||
Use the fxClass and fxStyle APIs to responsively apply styles to elements: | ||
</md-card-subtitle> | ||
<md-card-content> | ||
<div class="containerX"> | ||
<div fxLayout="row" fxFlex class="coloredContainerX box"> | ||
<div | ||
fxFlex | ||
class="fxClass-all" | ||
class.xs="fxClass-xs" | ||
[class.sm]="{'fxClass-sm': hasStyle}" | ||
[class.md]="{'fxClass-md': hasStyle, 'fxClass-md2': hasStyle}" | ||
[class.lg]="['fxClass-lg', 'fxClass-lg2']"> | ||
{{ activeMediaQueryAlias }} | ||
<md-checkbox | ||
[(ngModel)]="hasStyle" | ||
fxShow="false" | ||
[fxShow.sm]="true" | ||
[fxShow.md]="true"> | ||
Activate styles | ||
</md-checkbox> | ||
</div> | ||
</div> | ||
</div> | ||
</md-card-content> | ||
<md-card-content> | ||
<pre> | ||
<div | ||
fxFlex | ||
class="fxClass-all" | ||
class.xs="fxClass-xs" | ||
[class.sm]="{'fxClass-sm': hasStyle}" | ||
[class.md]="{'fxClass-md': hasStyle, 'fxClass-md2': hasStyle}" | ||
[class.lg]="['fxClass-lg', 'fxClass-lg2']"> | ||
</div> | ||
</pre> | ||
</md-card-content> | ||
<md-card-content> | ||
<div class="containerX"> | ||
<div fxLayout="row" fxFlex class="coloredContainerX box"> | ||
<div | ||
fxFlex | ||
style="font-style: italic" | ||
[style.xs]="{'font-size.px': 10, color: 'blue'}" | ||
[style.sm]="{'font-size.px': 20, color: 'lightblue'}" | ||
[style.md]="{'font-size.px': 30, color: 'orange'}" | ||
[style.lg]="styleLgExp"> | ||
{{ activeMediaQueryAlias }} | ||
</div> | ||
</div> | ||
</div> | ||
</md-card-content> | ||
<md-card-content> | ||
<pre> | ||
<div | ||
style="font-style: italic" | ||
[style.xs]="{'font-size.px': 10, color: 'blue'}" | ||
[style.sm]="{'font-size.px': 20, color: 'lightblue'}" | ||
[style.md]="{'font-size.px': 30, color: 'orange'}" | ||
[style.lg]="styleLgExp"> | ||
</div> | ||
</pre> | ||
</md-card-content> | ||
<md-card-footer style="width:95%"> | ||
<div class="hint" >Active mediaQuery: <span style="padding-left: 20px; color: rgba(0, 0, 0, 0.54)">{{ activeMediaQuery }}</span></div> | ||
</md-card-footer> | ||
</md-card> | ||
` | ||
}) | ||
export class DemoResponsiveStyle implements OnDestroy { | ||
private _watcher: Subscription; | ||
public activeMediaQuery = ""; | ||
public activeMediaQueryAlias = ""; | ||
public hasStyle: boolean = false; | ||
public styleLgExp = { | ||
'font-size': '40px', | ||
color: 'lightgreen' | ||
}; | ||
|
||
constructor( private _media$:ObservableMedia ) { | ||
this._watcher = this._media$.subscribe((change: MediaChange) => { | ||
this.activeMediaQuery = change ? `'${change.mqAlias}' = ${change.mediaQuery} )` : ""; | ||
this.activeMediaQueryAlias = change.mqAlias; | ||
}); | ||
} | ||
|
||
ngOnDestroy() { | ||
this._watcher.unsubscribe(); | ||
} | ||
} |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/** | ||
* @license | ||
* Copyright Google Inc. All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
import {ElementRef} from '@angular/core'; | ||
import {BaseFxDirectiveAdapter} from './base-adapter'; | ||
import {expect} from '../../utils/testing/custom-matchers'; | ||
|
||
export class MockElementRef extends ElementRef { | ||
constructor() { | ||
const nEl = document.createElement('DIV'); | ||
super(nEl); | ||
this.nativeElement = nEl; | ||
} | ||
} | ||
|
||
describe('BaseFxDirectiveAdapter class', () => { | ||
let component; | ||
beforeEach(() => { | ||
component = new BaseFxDirectiveAdapter(null, new MockElementRef(), null); | ||
}); | ||
describe('cacheInput', () => { | ||
it('should call _cacheInputArray when source is an array', () => { | ||
spyOn(component, '_cacheInputArray'); | ||
component.cacheInput('key', []); | ||
expect(component._cacheInputArray).toHaveBeenCalled(); | ||
}); | ||
it('should call _cacheInputObject when source is an object', () => { | ||
spyOn(component, '_cacheInputObject'); | ||
component.cacheInput('key', {}); | ||
expect(component._cacheInputObject).toHaveBeenCalled(); | ||
}); | ||
it('should call _cacheInputString when source is a string', () => { | ||
spyOn(component, '_cacheInputString'); | ||
component.cacheInput('key', ''); | ||
expect(component._cacheInputString).toHaveBeenCalled(); | ||
}); | ||
it('should throw when source is not an object, array or string', () => { | ||
expect(component.cacheInput.bind(null, true)).toThrow(); | ||
}); | ||
}); | ||
|
||
}); | ||
|
||
|
||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/** | ||
* Adapted BaseFxDirective abtract class version so it can be used via composition. | ||
* | ||
* @see BaseFxDirective | ||
*/ | ||
import {BaseFxDirective} from './base'; | ||
import {ResponsiveActivation} from './../responsive/responsive-activation'; | ||
import {MediaQuerySubscriber} from '../../media-query/media-change'; | ||
|
||
export class BaseFxDirectiveAdapter extends BaseFxDirective { | ||
get inputMap() { | ||
return this._inputMap; | ||
} | ||
|
||
/** | ||
* Save the property value. | ||
*/ | ||
cacheInput(key?: string, source?: any) { | ||
if (Array.isArray(source)) { | ||
this._cacheInputArray(key, source); | ||
} else if (typeof source === 'object') { | ||
this._cacheInputObject(key, source); | ||
} else if (typeof source === 'string') { | ||
this._cacheInputString(key, source); | ||
} else { | ||
throw new Error('Invalid class value provided'); | ||
} | ||
} | ||
|
||
_cacheInputRaw(key?: string, source?: any) { | ||
this._inputMap[key] = source; | ||
} | ||
|
||
/** | ||
* Save the property value for Array values. | ||
*/ | ||
_cacheInputArray(key?: string, source?: boolean[]) { | ||
this._inputMap[key] = source.join(' '); | ||
} | ||
|
||
/** | ||
* Save the property value for key/value pair values. | ||
*/ | ||
_cacheInputObject(key?: string, source?: {[key: string]: boolean}) { | ||
let classes = []; | ||
for (let prop in source) { | ||
if (!!source[prop]) { | ||
classes.push(prop); | ||
} | ||
} | ||
this._inputMap[key] = classes.join(' '); | ||
} | ||
|
||
/** | ||
* Save the property value for string values. | ||
*/ | ||
_cacheInputString(key?: string, source?: string) { | ||
this._inputMap[key] = source; | ||
} | ||
|
||
/** | ||
* @see BaseFxDirective._listenForMediaQueryChanges | ||
*/ | ||
listenForMediaQueryChanges(key: string, | ||
defaultValue: any, | ||
onMediaQueryChange: MediaQuerySubscriber): ResponsiveActivation { | ||
return this._listenForMediaQueryChanges(key, defaultValue, onMediaQueryChange); | ||
} | ||
|
||
/** | ||
* @see BaseFxDirective._queryInput | ||
*/ | ||
queryInput(key) { | ||
return this._queryInput(key); | ||
} | ||
|
||
/** | ||
* @see BaseFxDirective._mqActivation | ||
*/ | ||
get mqActivation(): ResponsiveActivation { | ||
return this._mqActivation; | ||
} | ||
} |
Oops, something went wrong.