From 90f4238504106f5fd7cfeecc4c8f1220b60b6cac Mon Sep 17 00:00:00 2001 From: Thomas Burleson Date: Sun, 6 Aug 2017 07:33:06 -0500 Subject: [PATCH] fix(flexbox): scan flex-direction in css stylesheet fxFlex works best if the parent container has flexbox styles assigned (display, flex-direction, etc.). If not assiged (inline or via stylesheet), then these styles are auto-injected inline on the DOM parent element. When scanning parent DOM element for flexbox flow direction, first scan the in element's inline style and then scan the computed stylesheet for the `flex-direction` value. Fixes #272, #364. --- src/lib/flexbox/api/base.ts | 12 +++++++++--- src/lib/flexbox/api/flex.spec.ts | 20 ++++++++++++++++++++ src/lib/flexbox/api/flex.ts | 6 +++--- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/lib/flexbox/api/base.ts b/src/lib/flexbox/api/base.ts index efc1abd14..3ac07671b 100644 --- a/src/lib/flexbox/api/base.ts +++ b/src/lib/flexbox/api/base.ts @@ -18,7 +18,6 @@ import {ResponsiveActivation, KeyOptions} from '../responsive/responsive-activat import {MediaMonitor} from '../../media-query/media-monitor'; import {MediaQuerySubscriber} from '../../media-query/media-change'; - /** * Definition of a css style. Either a property name (e.g. "flex-basis") or an object * map of property name and value (e.g. {display: 'none', flex-order: 5}). @@ -120,9 +119,16 @@ export abstract class BaseFxDirective implements OnDestroy, OnChanges { let element: HTMLElement = source || this._elementRef.nativeElement; let value = this._lookupStyle(element, 'display'); - return value ? value.trim() : ((element.nodeType === 1) ? 'block' : 'inline-block'); + return value ? value.trim() : + ((element.nodeType === 1) ? 'block' : 'inline-block'); } + /** + * Determine the DOM element's Flexbox flow (flex-direction). + * + * Check inline style first then check computed (stylesheet) style. + * And optionally add the flow value to element's inline style. + */ protected _getFlowDirection(target: any, addIfMissing = false): string { let value = 'row'; @@ -146,7 +152,7 @@ export abstract class BaseFxDirective implements OnDestroy, OnChanges { try { if (element) { let immediateValue = getDom().getStyle(element, styleName); - value = immediateValue || getDom().getComputedStyle(element).display; + value = immediateValue || getDom().getComputedStyle(element).getPropertyValue(styleName); } } catch (e) { // TODO: platform-server throws an exception for getComputedStyle diff --git a/src/lib/flexbox/api/flex.spec.ts b/src/lib/flexbox/api/flex.spec.ts index 8307e763c..99d68e3da 100644 --- a/src/lib/flexbox/api/flex.spec.ts +++ b/src/lib/flexbox/api/flex.spec.ts @@ -118,6 +118,26 @@ describe('flex directive', () => { expect(element).not.toHaveCssStyle({'min-width': '30px'}); }); + it('should CSS stylesheet and not inject flex-direction on parent', () => { + componentWithTemplate(` + +
+
+
+ `); + + 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(() => { componentWithTemplate(`
diff --git a/src/lib/flexbox/api/flex.ts b/src/lib/flexbox/api/flex.ts index 721a92ac2..aedaa680a 100644 --- a/src/lib/flexbox/api/flex.ts +++ b/src/lib/flexbox/api/flex.ts @@ -77,10 +77,10 @@ export class FlexDirective extends BaseFxDirective implements OnInit, OnChanges, @Input('fxFlex.lt-md') set flexLtMd(val) { this._cacheInput('flexLtMd', val); }; @Input('fxFlex.lt-lg') set flexLtLg(val) { this._cacheInput('flexLtLg', val); }; @Input('fxFlex.lt-xl') set flexLtXl(val) { this._cacheInput('flexLtXl', val); }; - /* tslint:enable */ - // Explicitly @SkipSelf on LayoutDirective and LayoutWrapDirective because we want the - // parent flex container for this flex item. + + // Note: Explicitly @SkipSelf on LayoutDirective and LayoutWrapDirective because we are looking + // for the parent flex container for this flex item. constructor(monitor: MediaMonitor, elRef: ElementRef, renderer: Renderer,