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

Commit ce9b989

Browse files
authored
fix(fxLayoutGap): correctly handle lack of fallback value (#1037)
In most directives, style generation and removal happens in a contained cycle: styles are generated, cached, and then removed when no longer needed. This is facilitated by caching the results of the `StyleBuilder`s for each directive in a local object on the directive, and then removing those styles when called. In the case of `fxLayoutGap`, most of the style generation is applied to the children, and so in most cases just removing the parent styles is insufficient, and in other cases, just ineffective (because no parent styles are actually generated). To fix this, we override the default style clearing method, and replace it with one that actually removes the child styles (and the parent styles if any are present). Fixes #1011
1 parent c23621c commit ce9b989

File tree

2 files changed

+64
-16
lines changed

2 files changed

+64
-16
lines changed

src/lib/flex/layout-gap/layout-gap.spec.ts

+36
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ describe('layout-gap directive', () => {
374374

375375
let nodes = queryFor(fixture, '[fxFlex]');
376376
expect(nodes.length).toEqual(3);
377+
mediaController.activate('sm');
377378
expectEl(nodes[0]).not.toHaveStyle({'margin-right': '*'}, styler);
378379
expectEl(nodes[1]).not.toHaveStyle({'margin-right': '*'}, styler);
379380
expectEl(nodes[2]).not.toHaveStyle({'margin-right': '*'}, styler);
@@ -384,6 +385,11 @@ describe('layout-gap directive', () => {
384385
expectEl(nodes[1]).toHaveStyle({'margin-right': '24px'}, styler);
385386
expectEl(nodes[2]).not.toHaveStyle({'margin-right': '24px'}, styler);
386387
expectEl(nodes[2]).not.toHaveStyle({'margin-right': '0px'}, styler);
388+
389+
mediaController.activate('sm');
390+
expectEl(nodes[0]).not.toHaveStyle({'margin-right': '*'}, styler);
391+
expectEl(nodes[1]).not.toHaveStyle({'margin-right': '*'}, styler);
392+
expectEl(nodes[2]).not.toHaveStyle({'margin-right': '*'}, styler);
387393
});
388394

389395
it('should set gap with responsive layout change', () => {
@@ -503,6 +509,36 @@ describe('layout-gap directive', () => {
503509
expectNativeEl(fixture).toHaveStyle(expectedMargin, styler);
504510
});
505511

512+
it('should set gap without fallback', () => {
513+
let template = `
514+
<div fxLayoutAlign='center center' fxLayoutGap.md="24px grid">
515+
<div fxFlex></div>
516+
<div fxFlex></div>
517+
<div fxFlex></div>
518+
</div>
519+
`;
520+
createTestComponent(template);
521+
fixture.detectChanges();
522+
523+
let nodes = queryFor(fixture, '[fxFlex]');
524+
expect(nodes.length).toEqual(3);
525+
mediaController.activate('sm');
526+
expectEl(nodes[0]).not.toHaveStyle({'padding': '*'}, styler);
527+
expectEl(nodes[1]).not.toHaveStyle({'padding': '*'}, styler);
528+
expectEl(nodes[2]).not.toHaveStyle({'padding': '*'}, styler);
529+
530+
mediaController.activate('md');
531+
fixture.detectChanges();
532+
expectEl(nodes[0]).toHaveStyle({'padding': '0px 24px 24px 0px'}, styler);
533+
expectEl(nodes[1]).toHaveStyle({'padding': '0px 24px 24px 0px'}, styler);
534+
expectEl(nodes[2]).toHaveStyle({'padding': '0px 24px 24px 0px'}, styler);
535+
536+
mediaController.activate('sm');
537+
expectEl(nodes[0]).not.toHaveStyle({'padding': '*'}, styler);
538+
expectEl(nodes[1]).not.toHaveStyle({'padding': '*'}, styler);
539+
expectEl(nodes[2]).not.toHaveStyle({'padding': '*'}, styler);
540+
});
541+
506542
it('should add gap styles correctly for rtl', () => {
507543
fakeDocument.body.dir = 'rtl';
508544
let template = `

src/lib/flex/layout-gap/layout-gap.ts

+28-16
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,21 @@ export class LayoutGapDirective extends BaseDirective2 implements AfterContentIn
197197
}
198198
}
199199

200+
/** We need to override clearStyles because in most cases mru isn't populated */
201+
protected clearStyles() {
202+
const gridMode = Object.keys(this.mru).length > 0;
203+
const childrenStyle = gridMode ? 'padding' :
204+
getMarginType(this.directionality.value, this.layout);
205+
206+
// If there are styles on the parent remove them
207+
if (gridMode) {
208+
super.clearStyles();
209+
}
210+
211+
// Then remove the children styles too
212+
this.styleUtils.applyStyleToElements({[childrenStyle]: ''}, this.childrenNodes);
213+
}
214+
200215
/** Determine if an element will show or hide based on current activation */
201216
protected willDisplay(source: HTMLElement): boolean {
202217
const value = this.marshal.getValue(source, 'show-hide');
@@ -262,28 +277,25 @@ function buildGridMargin(value: string, directionality: string): StyleDefinition
262277
return {'margin': `${marginTop} ${marginRight} ${marginBottom} ${marginLeft}`};
263278
}
264279

265-
function buildGapCSS(gapValue: string,
266-
parent: {directionality: string, layout: string}): StyleDefinition {
267-
let key, margins: {[key: string]: string | null} = {...CLEAR_MARGIN_CSS};
268-
269-
switch (parent.layout) {
280+
function getMarginType(directionality: string, layout: string) {
281+
switch (layout) {
270282
case 'column':
271-
key = 'margin-bottom';
272-
break;
283+
return 'margin-bottom';
273284
case 'column-reverse':
274-
key = 'margin-top';
275-
break;
285+
return 'margin-top';
276286
case 'row':
277-
key = parent.directionality === 'rtl' ? 'margin-left' : 'margin-right';
278-
break;
287+
return directionality === 'rtl' ? 'margin-left' : 'margin-right';
279288
case 'row-reverse':
280-
key = parent.directionality === 'rtl' ? 'margin-right' : 'margin-left';
281-
break;
289+
return directionality === 'rtl' ? 'margin-right' : 'margin-left';
282290
default :
283-
key = parent.directionality === 'rtl' ? 'margin-left' : 'margin-right';
284-
break;
291+
return directionality === 'rtl' ? 'margin-left' : 'margin-right';
285292
}
286-
margins[key] = gapValue;
293+
}
287294

295+
function buildGapCSS(gapValue: string,
296+
parent: {directionality: string, layout: string}): StyleDefinition {
297+
const key = getMarginType(parent.directionality, parent.layout);
298+
const margins: {[key: string]: string | null} = {...CLEAR_MARGIN_CSS};
299+
margins[key] = gapValue;
288300
return margins;
289301
}

0 commit comments

Comments
 (0)