Skip to content

Commit

Permalink
fix(fxFlex): fxFlex=auto with overlapping breakpoints activated (#183)
Browse files Browse the repository at this point in the history
Layout changes from gt-sm will not restore default layout with auto

fixes #135.
  • Loading branch information
ThomasBurleson authored and mmalerba committed Feb 21, 2017
1 parent aa0dab4 commit cb614ed
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 24 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"@types/glob": "^5.0.29",
"@types/gulp": "^3.8.29",
"@types/hammerjs": "~2.0.33",
"@types/jasmine": "^2.2.34",
"@types/jasmine": "2.5.38",
"@types/merge2": "0.0.28",
"@types/minimist": "^1.1.28",
"@types/node": "^6.0.45",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ import {DemoResponsiveStyle} from "./responsiveStyle.demo";
DemoResponsiveFlexDirectives,
DemoResponsiveFlexOrder,
DemoResponsiveShowHide,
DemoResponsiveStyle

DemoResponsiveStyle,
],
imports : [
CommonModule,
Expand Down
27 changes: 15 additions & 12 deletions src/demo-app/app/github-issues/DemosGithubIssues.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,32 @@ import {Component} from '@angular/core';
@Component({
selector: 'demos-github-issues',
template: `
<demo-issue-5345></demo-issue-5345>
<demo-issue-9897></demo-issue-9897>
<demo-issue-181></demo-issue-181>
`
<demo-issue-5345></demo-issue-5345>
<demo-issue-9897></demo-issue-9897>
<demo-issue-181></demo-issue-181>
<demo-issue-135> </demo-issue-135>
`
})
export class DemosGithubIssues {
}

import {NgModule} from '@angular/core';
import {CommonModule} from "@angular/common";
import {MaterialModule} from "@angular/material";
import {FlexLayoutModule} from "../../../lib"; // `gulp build:components` to deploy to node_modules manually
import {NgModule} from '@angular/core';
import {CommonModule} from "@angular/common";
import {MaterialModule} from "@angular/material";
import {FlexLayoutModule} from "../../../lib"; // `gulp build:components` to deploy to node_modules manually

import {DemoIssue5345} from "./issue.5345.demo";
import {DemoIssue9897} from "./issue.9897.demo";
import {DemoIssue181} from './issue.181.demo';
import {DemoIssue5345} from "./issue.5345.demo";
import {DemoIssue9897} from "./issue.9897.demo";
import {DemoIssue181} from './issue.181.demo';
import {DemoIssue135} from "./issue.135.demo";

@NgModule({
declarations: [
DemosGithubIssues, // used by the Router with the root app component
DemoIssue5345,
DemoIssue9897,
DemoIssue181
DemoIssue181,
DemoIssue135
],
imports: [
CommonModule,
Expand Down
53 changes: 53 additions & 0 deletions src/demo-app/app/github-issues/issue.135.demo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {Component, OnInit, 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-issue-135',
styleUrls : [
'../demo-app/material2.css'
],
template: `
<md-card class="card-demo" >
<md-card-title><a href="https://github.com/angular/flex-layout/issues/135" target="_blank">Issue #135</a></md-card-title>
<md-card-subtitle>Layout with fxFlex="auto" not restoring max-height values properly:</md-card-subtitle>
<md-card-content>
<div class="containerX">
<div fxLayout="column" class="coloredContainerX box">
<div fxFlex="auto" fxFlex.gt-sm="70" > &lt;div fxFlex="auto" fxFlex.gt-sm="70" &gt; </div>
<div fxFlex="auto" fxFlex.gt-sm="14.6"> &lt;div fxFlex="auto" fxFlex.gt-sm="14.6"&gt; </div>
<div fxFlex="auto" fxFlex.gt-sm="15.4"> &lt;div fxFlex="auto" fxFlex.gt-sm="15.4"&gt; </div>
</div>
</div>
</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 DemoIssue135 implements OnInit, OnDestroy {
public activeMediaQuery = "";
private _watcher : Subscription;

constructor(private _media$:ObservableMedia) { }

ngOnInit() {
this._watcher = this.watchMQChanges();
}

ngOnDestroy() {
this._watcher.unsubscribe();
}


watchMQChanges() {
return this._media$.subscribe((change:MediaChange) => {
let value = change ? `'${change.mqAlias}' = (${change.mediaQuery})` : "";
this.activeMediaQuery = value;
});
}
}
83 changes: 76 additions & 7 deletions src/lib/flexbox/api/flex.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ import {MatchMedia} from '../../media-query/match-media';
import {FlexLayoutModule} from '../_module';

import {__platform_browser_private__} from '@angular/platform-browser';
import {customMatchers, expect } from '../../utils/testing/custom-matchers';
import {customMatchers, expect} from '../../utils/testing/custom-matchers';
import {
makeExpectDOMFrom,
makeExpectDOMForQuery,
makeCreateTestComponent
makeCreateTestComponent,
expectNativeEl,
queryFor
} from '../../utils/testing/helpers';

const getDOM = __platform_browser_private__.getDOM;
Expand All @@ -31,6 +33,10 @@ describe('flex directive', () => {
let expectDOMFrom = makeExpectDOMFrom(() => TestFlexComponent);
let expectDomForQuery = makeExpectDOMForQuery(() => TestFlexComponent);
let componentWithTemplate = makeCreateTestComponent(() => TestFlexComponent);
let activateMediaQuery = (alias, allowOverlaps?: boolean) => {
let matchMedia: MockMatchMedia = fixture.debugElement.injector.get(MatchMedia);
matchMedia.activate(alias, allowOverlaps);
};

beforeEach(() => {
jasmine.addMatchers(customMatchers);
Expand Down Expand Up @@ -60,10 +66,10 @@ describe('flex directive', () => {

let dom = fRef.debugElement.children[0].nativeElement;
let isBox = getDOM().hasStyle(dom, 'box-sizing', 'border-box');
let hasFlex = getDOM().hasStyle(dom, 'flex', '1 1 1e-09px') || // IE
getDOM().hasStyle(dom, 'flex', '1 1 1e-9px') || // Chrome
getDOM().hasStyle(dom, 'flex', '1 1 0.000000001px') || // Safari
getDOM().hasStyle(dom, 'flex', '1 1 0px');
let hasFlex = getDOM().hasStyle(dom, 'flex', '1 1 1e-09px') || // IE
getDOM().hasStyle(dom, 'flex', '1 1 1e-9px') || // Chrome
getDOM().hasStyle(dom, 'flex', '1 1 0.000000001px') || // Safari
getDOM().hasStyle(dom, 'flex', '1 1 0px');

expect(isBox).toBeTruthy();
expect(hasFlex).toBeTruthy();
Expand Down Expand Up @@ -104,7 +110,7 @@ describe('flex directive', () => {
});
it('should work with calc values', () => {
// @see http://caniuse.com/#feat=calc for IE issues with calc()
if ( !isIE ) {
if (!isIE) {
expectDOMFrom(`<div fxFlex="calc(30vw - 10px)"></div>`).toHaveCssStyle({
'box-sizing': 'border-box',
'flex': '1 1 calc(30vw - 10px)'
Expand Down Expand Up @@ -246,7 +252,70 @@ describe('flex directive', () => {
});
});

describe('with responsive features', () => {

it('should initialize the component with the largest matching breakpoint', () => {
fixture = componentWithTemplate(`
<div fxFlex="auto"
fxFlex.gt-xs="33%"
fxFlex.gt-sm="50%" >
</div>
`);

activateMediaQuery('xl');
expectNativeEl(fixture).toHaveCssStyle({
'flex': '1 1 50%'
});

activateMediaQuery('sm');
expectNativeEl(fixture).toHaveCssStyle({
'flex': '1 1 33%'
});
});

it('should fallback the default layout properly', () => {
fixture = componentWithTemplate(`
<div fxLayout="column">
<div fxFlex="auto" fxFlex.gt-sm="50" > </div>
<div fxFlex="auto" fxFlex.gt-sm="24.4"> </div>
<div fxFlex="auto" fxFlex.gt-sm="25.6"> </div>
</div>
`);

activateMediaQuery('sm', true);
fixture.detectChanges();

let nodes = queryFor(fixture, "[fxFlex]");
expect(nodes.length).toEqual(3);
expect(nodes[0].nativeElement).toHaveCssStyle({'flex': '1 1 auto'});
expect(nodes[1].nativeElement).toHaveCssStyle({'flex': '1 1 auto'});
expect(nodes[2].nativeElement).toHaveCssStyle({'flex': '1 1 auto'});

activateMediaQuery('xl', true);
fixture.detectChanges();

nodes = queryFor(fixture, "[fxFlex]");
expect(nodes[0].nativeElement).toHaveCssStyle({'flex': '1 1 100%', 'max-height': '50%'});
expect(nodes[1].nativeElement).toHaveCssStyle({'flex': '1 1 100%', 'max-height': '24.4%'});
expect(nodes[2].nativeElement).toHaveCssStyle({'flex': '1 1 100%', 'max-height': '25.6%'});

activateMediaQuery('sm', true);
fixture.detectChanges();

nodes = queryFor(fixture, "[fxFlex]");
expect(nodes.length).toEqual(3);
expect(nodes[0].nativeElement).toHaveCssStyle({'flex': '1 1 auto'});
expect(nodes[1].nativeElement).toHaveCssStyle({'flex': '1 1 auto'});
expect(nodes[2].nativeElement).toHaveCssStyle({'flex': '1 1 auto'});

expect(nodes[0].nativeElement).not.toHaveCssStyle({'max-height': '50%'});
expect(nodes[1].nativeElement).not.toHaveCssStyle({'max-height': '24.4%'});
expect(nodes[2].nativeElement).not.toHaveCssStyle({'max-height': '25.6%'});
expect(nodes[0].nativeElement).not.toHaveCssStyle({'max-height': '*'});
expect(nodes[1].nativeElement).not.toHaveCssStyle({'max-height': '*'});
expect(nodes[2].nativeElement).not.toHaveCssStyle({'max-height': '*'});
});
});
});


Expand Down
2 changes: 1 addition & 1 deletion src/lib/flexbox/api/flex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ export class FlexDirective extends BaseFxDirective implements OnInit, OnChanges,
let max = (direction === 'row') ? 'max-width' : 'max-height';
let min = (direction === 'row') ? 'min-width' : 'min-height';

let usingCalc = String(basis).indexOf('calc') > -1;
let usingCalc = (String(basis).indexOf('calc') > -1) || (basis == 'auto');
let isPx = String(basis).indexOf('px') > -1 || usingCalc;


Expand Down
3 changes: 2 additions & 1 deletion src/lib/utils/testing/custom-matchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ export const customMatchers: jasmine.CustomMatcherFactories = {
* (Safari, IE, etc) will use prefixed style instead of defaults.
*/
function hasPrefixedStyles(actual, key, value) {
let hasStyle = getDOM().hasStyle(actual, key, value.trim());
value = value !== "*" ? value.trim() : undefined;
let hasStyle = getDOM().hasStyle(actual, key, value);
if (!hasStyle) {
let prefixedStyles = applyCssPrefixes({[key]: value});
Object.keys(prefixedStyles).forEach(prop => {
Expand Down

0 comments on commit cb614ed

Please sign in to comment.