Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(fxFlex): compute immediate parent flex-direction #220

Merged
merged 1 commit into from
Mar 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions src/demo-app/app/demo-app-module.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {SharedModule} from './shared/shared.module';

import {DemoApp} from './demo-app/demo-app';
import {DemoAppRoutingModule} from "./demo-app/demo-app-routes";
import {DemosStackOverflowModule} from "./stack-overflow/DemosStackOverflow";
import {DemosGithubIssuesModule} from './github-issues/DemosGithubIssues';
import {DemosLayoutAPIModule} from './docs-layout/DemosLayoutAPI';
import {DemosResponsiveLayoutsModule} from './docs-layout-responsive/DemosResponsiveLayouts';
import {SharedModule} from './shared/_module';
import {DemoRoutesModule} from "./demo-app/demo-routes";

import {DemosStackOverflowModule} from "./stack-overflow/_module";
import {DemosGithubIssuesModule} from './github-issues/_module';
import {DemosLayoutAPIModule} from './docs-layout/_module';
import {DemosResponsiveLayoutsModule} from './docs-layout-responsive/_module';

@NgModule({
declarations: [DemoApp],
bootstrap: [DemoApp],
imports: [
BrowserModule,
SharedModule,
DemoAppRoutingModule,
DemoRoutesModule,

/* Internal Demo App Modules */
DemosStackOverflowModule,
Expand Down
6 changes: 3 additions & 3 deletions src/demo-app/app/demo-app/demo-app.css
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,9 @@ div.colored.box.nopad > div {
min-width: 100px;
}

md-toolbar.bigger {
min-height: 145px;
padding: 10px;
.bigger {
padding: 0 20px;
padding-bottom: 30px;
}

md-toolbar .md-toolbar-layout md-toolbar-row {
Expand Down
13 changes: 5 additions & 8 deletions src/demo-app/app/demo-app/demo-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import {Component, ViewEncapsulation} from '@angular/core';
selector: 'demo-app',
styleUrls : [ 'demo-app.css' ],
template: `
<md-toolbar class="bigger" style="padding:0 20px;padding-bottom:30px;">
<md-toolbar-row>
<div fxLayout="column" class="bigger">
<div fxLayout="row"
fxLayoutAlign="start center"
fxLayoutGap="20px"
Expand All @@ -16,18 +15,16 @@ import {Component, ViewEncapsulation} from '@angular/core';
<button md-raised-button color="primary" [routerLink]="['issues']"> Github </button>
<button md-raised-button color="primary" [routerLink]="['stackoverflow']"> StackOverflow </button>
</div>
<div fxFlex="15px"></div>
</md-toolbar-row>
<md-toolbar-row fxFlex fxLayout="column"
<div fxFlex fxLayout="column"
fxLayoutAlign="left top"
style="font-size: 0.85em; margin-top: 0px; padding-bottom:20px; white-space:normal">
style="font-size: 0.85em; margin-top: 10px; padding-bottom:20px; white-space:normal">
These Layout demos are curated from the Angular Material v1.x documentation, GitHub Issues, StackOverflow,
and CodePen.
<span class="title" style="font-size: 0.7em; font-weight:normal;">
Hint: Click on any of the samples below to toggle the layout direction(s).
</span>
</md-toolbar-row>
</md-toolbar>
</div>
</div>

<div class="demo-content">
<router-outlet></router-outlet>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HashLocationStrategy, LocationStrategy } from "@angular/common";

import {DemosLayoutAPI} from "../docs-layout/DemosLayoutAPI";
import {DemosResponsiveLayout} from "../docs-layout-responsive/DemosResponsiveLayouts";
import {DemosGithubIssues} from "../github-issues/DemosGithubIssues";
import {DemosStackOverflow} from "../stack-overflow/DemosStackOverflow";
import {DemosLayoutAPI} from "../docs-layout/_module";
import {DemosResponsiveLayout} from "../docs-layout-responsive/_module";
import {DemosGithubIssues} from "../github-issues/_module";
import {DemosStackOverflow} from "../stack-overflow/_module";

const DemoAppRoutes: Routes = [
{path: '' , redirectTo: 'docs', pathMatch: 'full'},
Expand All @@ -24,7 +24,7 @@ const DemoAppRoutes: Routes = [
{ provide: LocationStrategy, useClass: HashLocationStrategy }
]
})
export class DemoAppRoutingModule { }
export class DemoRoutesModule { }

// These components are already exported in their associated Feature modules
// export const DemoAppRoutingComponents = [DemosLayoutAPI, DemosResponsiveLayout, DemosGithubIssues, DemosStackOverflow];
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {DemoResponsiveShowHide} from "./responsiveShowHide.demo";
import {DemoResponsiveFlexDirectives} from "./responsiveFlexDirective.demo";
import {DemoResponsiveFlexOrder} from "./responsiveFlexOrder.demo";
import {DemoResponsiveStyle} from "./responsiveStyle.demo";
import {SharedModule} from '../shared/shared.module';
import {SharedModule} from '../shared/_module';

@NgModule({
declarations : [
Expand Down
2 changes: 1 addition & 1 deletion src/demo-app/app/docs-layout/flexOtherValues.demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {Component} from '@angular/core';
<md-card-subtitle>Explore impact of non-numerical values for the 'fxFlex' API:</md-card-subtitle>
<md-card-content>
<div class="containerX">
<div fxLayout="row" fxLayoutWrap class="colored box nopad" >
<div fxLayout="row wrap" class="colored box nopad" >
<div fxFlex="none"> [flex="none"] </div>
<div fxFlex> [flex] </div>
<div fxFlex="nogrow"> [flex="nogrow"] </div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {DemoIssue9897} from "./issue.9897.demo";
import {DemoIssue135} from "./issue.135.demo";
import {DemoIssue181} from './issue.181.demo';
import {DemoIssue197} from './issue.197.demo';
import {SharedModule} from '../shared/shared.module';
import {SharedModule} from '../shared/_module';

@NgModule({
declarations: [
Expand Down
2 changes: 1 addition & 1 deletion src/demo-app/app/stack-overflow/columnOrder.demo.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Component, ViewEncapsulation} from '@angular/core';
import {Component} from '@angular/core';

@Component({
selector: 'demo-complex-column-ordering',
Expand Down
20 changes: 20 additions & 0 deletions src/lib/flexbox/api/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import {ElementRef, Renderer, OnDestroy} from '@angular/core';

import {applyCssPrefixes} from '../../utils/auto-prefixer';
import {buildLayoutCSS} from '../../utils/layout-validator';

import {ResponsiveActivation, KeyOptions} from '../responsive/responsive-activation';
import {MediaMonitor} from '../../media-query/media-monitor';
Expand Down Expand Up @@ -93,6 +94,25 @@ export abstract class BaseFxDirective implements OnDestroy {
return value.trim();
}

protected _getFlowDirection(target: any, addIfMissing = false): string {
let value = "";
if ( target ) {
let directionKeys = Object.keys(applyCssPrefixes({'flex-direction': ''}));
let findDirection = (styles) => directionKeys.reduce((direction, key) => {
return direction || styles[key];
}, null);

let immediateValue = findDirection(target['style']);
value = immediateValue || findDirection(getComputedStyle(target as Element));
if ( !immediateValue && addIfMissing ) {
value = value || 'row';
this._applyStyleToElements(buildLayoutCSS(value), [target]);
}
}

return value ? value.trim() : "row";
}

/**
* Applies styles given via string pair or object map to the directive element.
*/
Expand Down
56 changes: 56 additions & 0 deletions src/lib/flexbox/api/flex.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,62 @@ describe('flex directive', () => {
});
});

it('should work fxLayout parents', () => {
fixture = componentWithTemplate(`
<div fxLayout="column" class="test">
<div fxFlex="30px" fxFlex.gt-sm="50" > </div>
</div>
`);
fixture.detectChanges();
let parent = queryFor(fixture, ".test")[0].nativeElement;
let element = queryFor(fixture, "[fxFlex]")[0].nativeElement;

// parent flex-direction found with 'column' with child height styles
expect(parent).toHaveCssStyle({'flex-direction': 'column', 'display': 'flex'});
expect(element).toHaveCssStyle({'min-height': '30px'});
expect(element).not.toHaveCssStyle({'min-width': '30px'});
});

it('should not work with non-direct-parent fxLayouts', async(() => {
fixture = componentWithTemplate(`
<div fxLayout="column">
<div class="test">
<div fxFlex="40px" fxFlex.gt-sm="50" > </div>
</div>
</div>
`);
fixture.detectChanges();
let element = queryFor(fixture, "[fxFlex]")[0].nativeElement;
let parent = queryFor(fixture, ".test")[0].nativeElement;

setTimeout(() => {
// The parent flex-direction not found;
// A flex-direction should have been auto-injected to the parent...
// fallback to 'row' and set child width styles accordingly
expect(parent).toHaveCssStyle({ 'flex-direction': 'row' });
expect(element).toHaveCssStyle({ 'min-width': '40px' });
expect(element).not.toHaveCssStyle({ 'min-height': '40px' });
});

}));

it('should work with styled-parent flex directions', () => {
fixture = componentWithTemplate(`
<div fxLayout="row">
<div style="flex-direction:column" class="parent">
<div fxFlex="60px" > </div>
</div>
</div>
`);
fixture.detectChanges();
let element = queryFor(fixture, "[fxFlex]")[0].nativeElement;
let parent = queryFor(fixture, ".parent")[0].nativeElement;

// parent flex-direction found with 'column'; set child with height styles
expect(element).toHaveCssStyle({ 'min-height': '60px' });
expect(parent).toHaveCssStyle({ 'flex-direction': 'column' });
});

it('should work with "1 1 auto" values', () => {
fixture = componentWithTemplate(`
<div fxLayout="column">
Expand Down
27 changes: 13 additions & 14 deletions src/lib/flexbox/api/flex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export class FlexDirective extends BaseFxDirective implements OnInit, OnChanges,
*/
ngOnChanges(changes: SimpleChanges) {
if (changes['flex'] != null || this._mqActivation) {
this._onLayoutChange();
this._updateStyle();
}
}

Expand All @@ -120,7 +120,7 @@ export class FlexDirective extends BaseFxDirective implements OnInit, OnChanges,
this._listenForMediaQueryChanges('flex', '', (changes: MediaChange) => {
this._updateStyle(changes.value);
});
this._onLayoutChange();
this._updateStyle();
}

ngOnDestroy() {
Expand Down Expand Up @@ -158,18 +158,13 @@ export class FlexDirective extends BaseFxDirective implements OnInit, OnChanges,
protected _validateValue(grow: number|string,
shrink: number|string,
basis: string|number|FlexBasisAlias) {
// The flex-direction of this element's flex container. Defaults to 'row'.
let layout = this._getFlowDirection(this.parentElement, true);
let direction = (layout.indexOf('column') > -1) ? 'column' : 'row';
let css, isValue;
let direction = (this._layout === 'column') || (this._layout == 'column-reverse') ?
'column' :
'row';

if ( grow == "0" ) {
grow = 0;
}

if ( shrink == "0" ) {
shrink = 0;
}
grow = (grow == "0") ? 0 : grow;
shrink = (shrink == "0") ? 0 : shrink;

// flex-basis allows you to specify the initial/starting main-axis size of the element,
// before anything else is computed. It can either be a percentage or an absolute value.
Expand Down Expand Up @@ -256,6 +251,10 @@ export class FlexDirective extends BaseFxDirective implements OnInit, OnChanges,
css[min] = (basis == '0%') ? 0 : isFixed || (isPx && grow) ? basis : null;
css[max] = (basis == '0%') ? 0 : isFixed || (!usingCalc && shrink) ? basis : null;

return extendObject(css, {'box-sizing': 'border-box'});
}
return extendObject(css, {'box-sizing': 'border-box'});
}

protected get parentElement(): any {
return this._elementRef.nativeElement.parentNode;
}
}
3 changes: 2 additions & 1 deletion src/lib/flexbox/api/layout-align.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import {BaseFxDirective} from './base';
import {MediaChange} from '../../media-query/media-change';
import {MediaMonitor} from '../../media-query/media-monitor';

import {LAYOUT_VALUES, LayoutDirective} from './layout';
import {LayoutDirective} from './layout';
import {LAYOUT_VALUES} from '../../utils/layout-validator';


/**
Expand Down
4 changes: 2 additions & 2 deletions src/lib/flexbox/api/layout-gap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ import {
import {Subscription} from 'rxjs/Subscription';

import {BaseFxDirective} from './base';
import {LayoutDirective} from './layout';
import {MediaChange} from '../../media-query/media-change';
import {MediaMonitor} from '../../media-query/media-monitor';
import {LayoutDirective, LAYOUT_VALUES} from './layout';

import {LAYOUT_VALUES} from '../../utils/layout-validator';
/**
* 'layout-padding' styling directive
* Defines padding of child elements in a layout container
Expand Down
51 changes: 19 additions & 32 deletions src/lib/flexbox/api/layout-wrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@ import {
SimpleChanges, Self, Optional,
} from '@angular/core';
import {Subscription} from 'rxjs/Subscription';
import {extendObject} from '../../utils/object-extend';

import {BaseFxDirective} from './base';
import {LayoutDirective} from './layout';
import {MediaChange} from '../../media-query/media-change';
import {MediaMonitor} from '../../media-query/media-monitor';
import {LayoutDirective, LAYOUT_VALUES} from './layout';

import {validateWrapValue, LAYOUT_VALUES} from '../../utils/layout-validator';
/**
* @deprecated
* This functionality is now part of the `fxLayout` API
Expand Down Expand Up @@ -96,6 +95,12 @@ export class LayoutWrapDirective extends BaseFxDirective implements OnInit, OnCh
this._updateWithValue();
}

ngOnDestroy() {
super.ngOnDestroy();
if (this._layoutWatcher) {
this._layoutWatcher.unsubscribe();
}
}

// *********************************************
// Protected methods
Expand All @@ -114,47 +119,29 @@ export class LayoutWrapDirective extends BaseFxDirective implements OnInit, OnCh
}

protected _updateWithValue(value?: string) {
value = value || this._queryInput("wrap") || 'wrap';
value = value || this._queryInput("wrap");
if (this._mqActivation) {
value = this._mqActivation.activatedInput;
}
value = this._validateValue(value);
value = validateWrapValue(value || 'wrap');

this._applyStyleToElement(this._buildCSS(value));
}


/**
* Build the CSS that should be assigned to the element instance
*/
protected _buildCSS(value) {
return extendObject({ 'flex-wrap': value }, {
'display' : 'flex',
'flex-direction' : this._layout || 'row'
});
return {
'display': 'flex',
'flex-wrap': value,
'flex-direction': this.flowDirection
};
}

/**
* Convert layout-wrap="<value>" to expected flex-wrap style
*/
protected _validateValue(value) {
switch (value.toLowerCase()) {
case 'reverse':
case 'wrap-reverse':
value = 'wrap-reverse';
break;

case 'no':
case 'none':
case 'nowrap':
value = 'nowrap';
break;

// All other values fallback to "wrap"
default:
value = 'wrap';
break;
}
return value;
protected get flowDirection(): string {
let computeFlowDirection = () => this._getFlowDirection(this._elementRef.nativeElement);
return this._layoutWatcher ? this._layout : computeFlowDirection();
}

}
Loading