Skip to content
This repository was archived by the owner on Jan 6, 2025. It is now read-only.

Commit 6c45b35

Browse files
ThomasBurlesonkara
authored andcommitted
fix(fxLayoutGap): skip hidden element nodes (#145)
Fixes #136.
1 parent 6e46561 commit 6c45b35

File tree

5 files changed

+77
-30
lines changed

5 files changed

+77
-30
lines changed

src/lib/flexbox/api/base.ts

+18-6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88
import {ElementRef, Renderer, OnDestroy} from '@angular/core';
9+
10+
import {__platform_browser_private__} from '@angular/platform-browser';
11+
const getDOM = __platform_browser_private__.getDOM;
12+
913
import {applyCssPrefixes} from '../../utils/auto-prefixer';
1014

1115
import {ResponsiveActivation, KeyOptions} from '../responsive/responsive-activation';
@@ -16,7 +20,7 @@ import {MediaQuerySubscriber} from '../../media-query/media-change';
1620
* Definition of a css style. Either a property name (e.g. "flex-basis") or an object
1721
* map of property name and value (e.g. {display: 'none', flex-order: 5}).
1822
*/
19-
export type StyleDefinition = string|{[property: string]: string|number};
23+
export type StyleDefinition = string|{ [property: string]: string|number };
2024

2125
/** Abstract base class for the Layout API styling directives. */
2226
export abstract class BaseFxDirective implements OnDestroy {
@@ -86,9 +90,10 @@ export abstract class BaseFxDirective implements OnDestroy {
8690
* Note: this allows use to preserve the original style
8791
* and optional restore it when the mediaQueries deactivate
8892
*/
89-
protected _getDisplayStyle(): string {
90-
let element: HTMLElement = this._elementRef.nativeElement;
91-
return (element.style as any)['display'] || "flex";
93+
protected _getDisplayStyle(source?: HTMLElement): string {
94+
let element: HTMLElement = source || this._elementRef.nativeElement;
95+
let value = (element.style as any)['display'] || getDOM().getComputedStyle(element)['display'];
96+
return value.trim();
9297
}
9398

9499
/**
@@ -109,7 +114,7 @@ export abstract class BaseFxDirective implements OnDestroy {
109114

110115
// Iterate all properties in hashMap and set styles
111116
for (let key in styles) {
112-
this._renderer.setElementStyle(element, key, styles[key]);
117+
this._renderer.setElementStyle(element, key, styles[key] as string);
113118
}
114119
}
115120

@@ -122,7 +127,7 @@ export abstract class BaseFxDirective implements OnDestroy {
122127
elements.forEach(el => {
123128
// Iterate all properties in hashMap and set styles
124129
for (let key in styles) {
125-
this._renderer.setElementStyle(el, key, styles[key]);
130+
this._renderer.setElementStyle(el, key, styles[key] as string);
126131
}
127132
});
128133

@@ -172,4 +177,11 @@ export abstract class BaseFxDirective implements OnDestroy {
172177
return buffer;
173178
}
174179

180+
/**
181+
* Fast validator for presence of attribute on the host element
182+
*/
183+
protected hasKeyValue(key) {
184+
return this._mqActivation.hasKeyValue(key);
185+
}
186+
175187
}

src/lib/flexbox/api/layout-gap.spec.ts

+36-14
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,22 @@ describe('layout-gap directive', () => {
4141
});
4242
});
4343

44+
function verifyCorrectMargin(layout: string, marginKey: string) {
45+
const margin = '8px';
46+
const template = `
47+
<div fxLayout='${layout}' fxLayoutGap='${margin}'>
48+
<span></span>
49+
<span></span>
50+
</div>
51+
`;
52+
53+
const fixture1 = createTestComponent(template);
54+
fixture1.detectChanges();
55+
56+
const nodes = queryFor(fixture1, 'span');
57+
expect(nodes[1].nativeElement).toHaveCssStyle({[marginKey]: margin});
58+
}
59+
4460
describe('with static features', () => {
4561

4662
it('should not add gap styles for a single child', () => {
@@ -163,23 +179,29 @@ describe('layout-gap directive', () => {
163179
expect(nodes[1].nativeElement).not.toHaveCssStyle({'margin-bottom': '8px'});
164180
expect(nodes[1].nativeElement).toHaveCssStyle({'margin-right': '8px'});
165181
});
166-
});
167182

168-
function verifyCorrectMargin(layout: string, marginKey: string) {
169-
const margin = '8px';
170-
const template = `
171-
<div fxLayout='${layout}' fxLayoutGap='${margin}'>
172-
<span></span>
173-
<span></span>
174-
</div>
175-
`;
183+
it('should recognize hidden elements when applying gaps', () => {
184+
let styles = ['.col1 { display:none !important;'];
185+
let template = `
186+
<div class="container" fxLayout="row" fxLayoutGap="16px">
187+
<div fxFlex class="col1">Div 1</div>
188+
<div fxFlex class="col2">Div 2</div>
189+
<div fxFlex class="col3">Div 3</div>
190+
</div>
191+
`;
192+
fixture = createTestComponent(template, styles);
193+
fixture.componentInstance.direction = 'row';
194+
fixture.detectChanges();
176195

177-
const fixture1 = createTestComponent(template);
178-
fixture1.detectChanges();
196+
let nodes = queryFor(fixture, '[fxFlex]');
179197

180-
const nodes = queryFor(fixture1, 'span');
181-
expect(nodes[1].nativeElement).toHaveCssStyle({[marginKey]: margin});
182-
}
198+
expect(nodes.length).toEqual(3);
199+
expect(nodes[0].nativeElement).not.toHaveCssStyle({'margin-left': '0px'});
200+
expect(nodes[1].nativeElement).toHaveCssStyle({'margin-left': '0px'});
201+
expect(nodes[2].nativeElement).toHaveCssStyle({'margin-left': '16px'});
202+
203+
});
204+
});
183205

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

src/lib/flexbox/api/layout-gap.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -171,18 +171,18 @@ export class LayoutGapDirective extends BaseFxDirective implements AfterContentI
171171
value = this._mqActivation.activatedInput;
172172
}
173173

174-
// Reset 1st child element to 0px gap
174+
// Gather all non-hidden Element nodes
175175
let items = this.childrenNodes
176-
.filter(el => (el.nodeType === 1)) // only Element types
177-
.filter((el, j) => j == 0);
178-
this._applyStyleToElements(this._buildCSS(0), items);
176+
.filter(el => (el.nodeType === 1)) // only Element types
177+
.filter(el => this._getDisplayStyle(el) != "none");
178+
179+
// Reset 1st child element to 0px gap
180+
let skipped = items.filter((el, j) => j == 0);
181+
this._applyStyleToElements(this._buildCSS(0), skipped);
179182

180183
// For each `element` child, set the padding styles...
181-
items = this.childrenNodes
182-
.filter(el => (el.nodeType === 1)) // only Element types
183-
.filter((el, j) => j > 0); // skip first element since gaps are needed
184+
items = items.filter((el, j) => j > 0); // skip first element since gaps are needed
184185
this._applyStyleToElements(this._buildCSS(value), items);
185-
186186
}
187187

188188
/**

src/lib/flexbox/responsive/responsive-activation.ts

+8
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@ export class ResponsiveActivation {
8181
return this._hasKeyValue(key) ? this._lookupKeyValue(key) : this._options.defaultValue;
8282
}
8383

84+
/**
85+
* Fast validator for presence of attribute on the host element
86+
*/
87+
public hasKeyValue(key) {
88+
let value = this._options.inputKeys[key];
89+
return typeof value !== 'undefined';
90+
}
91+
8492
/**
8593
* Remove interceptors, restore original functions, and forward the onDestroy() call
8694
*/

src/lib/utils/testing/helpers.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,18 @@ export function makeCreateTestComponent(getClass: ComponentClazzFn) {
4646
let componentAny: Type<any>;
4747

4848
// Return actual `createTestComponent()` function
49-
return function createTestComponent(template: string): ComponentFixture<Type<any>> {
49+
return function createTestComponent(template: string, styles?: any): ComponentFixture<Type<any>> {
5050
if (!componentAny) {
5151
// Defer access to Component class to enable metadata to be configured properly...
5252
componentAny = getClass();
5353
}
5454
return TestBed
55-
.overrideComponent(componentAny, {set: {template: template}})
55+
.overrideComponent(componentAny, {
56+
set: {
57+
template: template,
58+
styles: styles || [],
59+
}
60+
})
5661
.createComponent(componentAny);
5762
};
5863
}

0 commit comments

Comments
 (0)