Skip to content

Commit

Permalink
feat(api): add responsive API for img elements (#382)
Browse files Browse the repository at this point in the history
* feat(api, img-src): add ImgSrcDirective for responsive API for img elements

* add responsive API to img.src:  src.md, src.lt-lg, src.gt-xs, etc.
* repackage API classes to easily distinguish flexbox APIs and  extended responsive APIs

Closes #366, Fixes #376.

* chore(release): fix package.json version
  • Loading branch information
ThomasBurleson authored and andrewseguin committed Aug 18, 2017
1 parent d6b45a6 commit 45cfd2e
Show file tree
Hide file tree
Showing 38 changed files with 805 additions and 377 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Expand Down
6 changes: 3 additions & 3 deletions scripts/release/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@angular/flex-layout",
"version": "2.0.0-beta.8-3611003",
"version": "0.0.0-PLACEHOLDER",
"description": "Angular Flex-Layout",
"main": "./bundles/flex-layout.umd.js",
"module": "./@angular/flex-layout.es5.js",
Expand All @@ -24,8 +24,8 @@
},
"homepage": "https://github.com/angular/flex-layout#readme",
"peerDependencies": {
"@angular/core": "^4.0.0",
"@angular/common": "^4.0.0"
"@angular/core": "^4.3.0",
"@angular/common": "^4.3.0"
},
"dependencies": {
"tslib": "^1.7.1"
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import {ElementRef, Renderer2} from '@angular/core';

import {BaseFxDirective} from './base';
import {ResponsiveActivation} from './../responsive/responsive-activation';
import {ResponsiveActivation} from './responsive-activation';
import {MediaQuerySubscriber} from '../../media-query/media-change';
import {MediaMonitor} from '../../media-query/media-monitor';

Expand Down
12 changes: 8 additions & 4 deletions src/lib/flexbox/api/base.ts → src/lib/api/core/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
applyStyleToElements
} from '../../utils/style-utils';

import {ResponsiveActivation, KeyOptions} from '../responsive/responsive-activation';
import {ResponsiveActivation, KeyOptions} from '../core/responsive-activation';
import {MediaMonitor} from '../../media-query/media-monitor';
import {MediaQuerySubscriber} from '../../media-query/media-change';

Expand Down Expand Up @@ -78,6 +78,10 @@ export abstract class BaseFxDirective implements OnDestroy, OnChanges {
return this._elementRef.nativeElement.parentNode;
}

protected get nativeElement(): any {
return this._elementRef.nativeElement;
}

/**
* Access the current value (if any) of the @Input property.
*/
Expand Down Expand Up @@ -130,7 +134,7 @@ export abstract class BaseFxDirective implements OnDestroy, OnChanges {
* and optional restore it when the mediaQueries deactivate
*/
protected _getDisplayStyle(source?: HTMLElement): string {
let element: HTMLElement = source || this._elementRef.nativeElement;
let element: HTMLElement = source || this.nativeElement;
return lookupStyle(element, 'display');
}

Expand Down Expand Up @@ -161,7 +165,7 @@ export abstract class BaseFxDirective implements OnDestroy, OnChanges {
protected _applyStyleToElement(style: StyleDefinition,
value?: string | number,
nativeElement?: any) {
let element = nativeElement || this._elementRef.nativeElement;
let element = nativeElement || this.nativeElement;
applyStyleToElement(this._renderer, element, style, value);
}

Expand Down Expand Up @@ -209,7 +213,7 @@ export abstract class BaseFxDirective implements OnDestroy, OnChanges {
* Special accessor to query for all child 'element' nodes regardless of type, class, etc.
*/
protected get childrenNodes() {
const obj = this._elementRef.nativeElement.children;
const obj = this.nativeElement.children;
const buffer = [];

// iterate backwards ensuring that length is an UInt32
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,28 @@ export class KeyOptions {
export class ResponsiveActivation {
private _subscribers: SubscriptionList = [];
private _activatedInputKey: string;
private _registryMap: BreakPointX[];

/**
* Constructor
*/
constructor(private _options: KeyOptions,
private _mediaMonitor: MediaMonitor,
private _onMediaChanges: MediaQuerySubscriber) {
this._registryMap = this._buildRegistryMap();
this._subscribers = this._configureChangeObservers();
}

/**
* Get a readonly sorted list of the breakpoints corresponding to the directive properties
* defined in the HTML markup: the sorting is done from largest to smallest. The order is
* important when several media queries are 'registered' and from which, the browser uses the
* first matching media query.
*/
get registryFromLargest(): BreakPointX[] {
return [...this._registryMap].reverse();
}

/**
* Accessor to the DI'ed directive property
* Each directive instance has a reference to the MediaMonitor which is
Expand Down Expand Up @@ -107,7 +119,7 @@ export class ResponsiveActivation {
private _configureChangeObservers(): SubscriptionList {
let subscriptions = [];

this._buildRegistryMap().forEach((bp: BreakPointX) => {
this._registryMap.forEach((bp: BreakPointX) => {
if (this._keyInUse(bp.key)) {
// Inject directive default property key name: to let onMediaChange() calls
// know which property is being triggered...
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions src/lib/flexbox/api/class.ts → src/lib/api/ext/class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import {
} from '@angular/core';
import {NgClass} from '@angular/common';

import {BaseFxDirective} from './base';
import {BaseFxDirectiveAdapter} from './base-adapter';
import {BaseFxDirective} from '../core/base';
import {BaseFxDirectiveAdapter} from '../core/base-adapter';
import {MediaChange} from '../../media-query/media-change';
import {MediaMonitor} from '../../media-query/media-monitor';

Expand Down
72 changes: 36 additions & 36 deletions src/lib/flexbox/api/hide.spec.ts → src/lib/api/ext/hide.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,38 +69,38 @@ describe('hide directive', () => {

it('should initial with component not visible as default', () => {
createTestComponent(`<div fxHide></div>`);
expectNativeEl(fixture).toHaveCssStyle({'display': 'none'});
expectNativeEl(fixture).toHaveStyle({'display': 'none'});
});

it('should initial with component visible when set to `false`', () => {
createTestComponent(`<div fxHide="false"></div>`);
expectNativeEl(fixture).toHaveCssStyle({'display': 'block'});
expectNativeEl(fixture).toHaveStyle({'display': 'block'});
});

it('should initial with component visible when set to `0`', () => {
createTestComponent(`<div [fxHide]="isVisible"></div>`);
expectNativeEl(fixture, {isVisible: 0}).toHaveCssStyle({'display': 'block'});
expectNativeEl(fixture, {isVisible: 0}).toHaveStyle({'display': 'block'});
});

it('should update styles with binding changes', () => {
createTestComponent(`<div [fxHide]="menuHidden"></div>`);
expectNativeEl(fixture).toHaveCssStyle({'display': 'none'});
expectNativeEl(fixture).toHaveStyle({'display': 'none'});
fixture.componentInstance.toggleMenu();
expectNativeEl(fixture).toHaveCssStyle({'display': 'block'});
expectNativeEl(fixture).toHaveStyle({'display': 'block'});
fixture.componentInstance.toggleMenu();
expectNativeEl(fixture).toHaveCssStyle({'display': 'none'});
expectNativeEl(fixture).toHaveStyle({'display': 'none'});
});

it('should use "block" display style when not explicitly defined', () => {
createTestComponent(`<button [fxHide]="isHidden"></button>`);
expectNativeEl(fixture, {isHidden: true}).toHaveCssStyle({'display': 'none'});
expectNativeEl(fixture, {isHidden: false}).toHaveCssStyle({'display': 'inline-block'});
expectNativeEl(fixture, {isHidden: true}).toHaveStyle({'display': 'none'});
expectNativeEl(fixture, {isHidden: false}).toHaveStyle({'display': 'inline-block'});
});

it('should use "flex" display style when the element also has an fxLayout', () => {
createTestComponent(`<div fxLayout [fxHide]="isHidden"></div>`);
expectNativeEl(fixture, {isHidden: true}).toHaveCssStyle({'display': 'none'});
expectNativeEl(fixture, {isHidden: false}).toHaveCssStyle({'display': 'block'});
expectNativeEl(fixture, {isHidden: true}).toHaveStyle({'display': 'none'});
expectNativeEl(fixture, {isHidden: false}).toHaveStyle({'display': 'block'});
});


Expand All @@ -111,73 +111,73 @@ describe('hide directive', () => {
it('should show on `xs` viewports only when the default is included', () => {
createTestComponent(`<div fxHide="" fxHide.xs="false"></div>`);

expectNativeEl(fixture).toHaveCssStyle({'display': 'none'});
expectNativeEl(fixture).toHaveStyle({'display': 'none'});
matchMedia.activate('xs');
expectNativeEl(fixture).toHaveCssStyle({'display': 'block'});
expectNativeEl(fixture).toHaveStyle({'display': 'block'});
matchMedia.activate('md');
expectNativeEl(fixture).toHaveCssStyle({'display': 'none'});
expectNativeEl(fixture).toHaveStyle({'display': 'none'});
});

it('should preserve display and update only on activated mediaQuery', () => {
createTestComponent(`<div [fxHide.xs]="isHidden" style="display:inline-block"></div>`);
expectNativeEl(fixture).toHaveCssStyle({'display': 'inline-block'});
expectNativeEl(fixture).toHaveStyle({'display': 'inline-block'});

// should hide with this activation
matchMedia.activate('xs');
expectNativeEl(fixture).toHaveCssStyle({'display': 'none'});
expectNativeEl(fixture).toHaveStyle({'display': 'none'});

// should reset to original display style
matchMedia.activate('md');
expectNativeEl(fixture).toHaveCssStyle({'display': 'inline-block'});
expectNativeEl(fixture).toHaveStyle({'display': 'inline-block'});
});

it('should restore original display when disabled', () => {
createTestComponent(`<div [fxHide.xs]="isHidden" style="display:inline-block"></div>`);
expectNativeEl(fixture).toHaveCssStyle({'display': 'inline-block'});
expectNativeEl(fixture).toHaveStyle({'display': 'inline-block'});

// should hide with this activation
matchMedia.activate('xs');
expectNativeEl(fixture).toHaveCssStyle({'display': 'none'});
expectNativeEl(fixture).toHaveStyle({'display': 'none'});

// should reset to original display style
fixture.componentInstance.isHidden = false;
expectNativeEl(fixture).toHaveCssStyle({'display': 'inline-block'});
expectNativeEl(fixture).toHaveStyle({'display': 'inline-block'});
});

it('should restore original display when the mediaQuery deactivates', () => {
let originalDisplay = {'display': 'table'};
createTestComponent(`<div [fxHide.xs]="isHidden" style="display:table"></div>`);
expectNativeEl(fixture).toHaveCssStyle(originalDisplay);
expectNativeEl(fixture).toHaveStyle(originalDisplay);

// should hide with this activation
matchMedia.activate('xs');
expectNativeEl(fixture).toHaveCssStyle({'display': 'none'});
expectNativeEl(fixture).toHaveStyle({'display': 'none'});

// should reset to original display style
matchMedia.activate('md');
expectNativeEl(fixture).toHaveCssStyle(originalDisplay);
expectNativeEl(fixture).toHaveStyle(originalDisplay);
});

it('should support use of the `media` observable in templates ', () => {
createTestComponent(`<div [fxHide]="media.isActive('xs')"></div>`);
expectNativeEl(fixture).toHaveCssStyle({'display': 'block'});
expectNativeEl(fixture).toHaveStyle({'display': 'block'});

matchMedia.activate('xs');
expectNativeEl(fixture).toHaveCssStyle({'display': 'none'});
expectNativeEl(fixture).toHaveStyle({'display': 'none'});

matchMedia.activate('lg');
expectNativeEl(fixture).toHaveCssStyle({'display': 'block'});
expectNativeEl(fixture).toHaveStyle({'display': 'block'});
});

it('should support use of the `media` observable in adaptive templates ', () => {
createTestComponent(`<div fxHide="false" [fxHide.md]="media.isActive('xs')"></div>`);
expectNativeEl(fixture).toHaveCssStyle({'display': 'block'});
expectNativeEl(fixture).toHaveStyle({'display': 'block'});

matchMedia.activate('xs');
expectNativeEl(fixture).toHaveCssStyle({'display': 'block'});
expectNativeEl(fixture).toHaveStyle({'display': 'block'});

matchMedia.activate('md');
expectNativeEl(fixture).toHaveCssStyle({'display': 'block'});
expectNativeEl(fixture).toHaveStyle({'display': 'block'});
});

it('should hide when used with fxLayout and the ".md" breakpoint activates', () => {
Expand All @@ -198,8 +198,8 @@ describe('hide directive', () => {
`;
let expectActivation = makeExpectWithActivation(createTestComponent(template), '.hideOnMd');

expectActivation().toHaveCssStyle({'display': 'block'});
expectActivation('md').toHaveCssStyle({'display': 'none'});
expectActivation().toHaveStyle({'display': 'block'});
expectActivation('md').toHaveStyle({'display': 'none'});
});

it('should restore proper display mode when not hiding', () => {
Expand All @@ -210,9 +210,9 @@ describe('hide directive', () => {
`;
let expectActivation = makeExpectWithActivation(createTestComponent(template), '.hideOnXs');

expectActivation().toHaveCssStyle({'display': 'inline'});
expectActivation('xs').toHaveCssStyle({'display': 'none'});
expectActivation('md').toHaveCssStyle({'display': 'inline'});
expectActivation().toHaveStyle({'display': 'inline'});
expectActivation('xs').toHaveStyle({'display': 'none'});
expectActivation('md').toHaveStyle({'display': 'inline'});
});
});

Expand All @@ -222,13 +222,13 @@ describe('hide directive', () => {
This content to be shown ONLY when gt-sm
</div>
`);
expectNativeEl(fixture).toHaveCssStyle({'display': 'inline-block'});
expectNativeEl(fixture).toHaveStyle({'display': 'inline-block'});

matchMedia.activate('md', true);
expectNativeEl(fixture).toHaveCssStyle({'display': 'none'});
expectNativeEl(fixture).toHaveStyle({'display': 'none'});

matchMedia.activate('xs', true);
expectNativeEl(fixture).toHaveCssStyle({'display': 'inline-block'});
expectNativeEl(fixture).toHaveStyle({'display': 'inline-block'});
});

});
Expand Down
Loading

0 comments on commit 45cfd2e

Please sign in to comment.