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

Commit 01c4148

Browse files
authored
fix(core): correctly handle lack of fallback values (#949)
Fixes #947
1 parent 5db4ccf commit 01c4148

File tree

7 files changed

+55
-13
lines changed

7 files changed

+55
-13
lines changed

src/lib/core/base/base2.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ export abstract class BaseDirective2 implements OnChanges, OnDestroy {
108108
/** Force trigger style updates on DOM element */
109109
protected triggerUpdate() {
110110
const val = this.marshal.getValue(this.nativeElement, this.DIRECTIVE_KEY);
111-
this.marshal.updateElement(this.nativeElement, this.DIRECTIVE_KEY, val);
111+
if (val !== undefined) {
112+
this.marshal.updateElement(this.nativeElement, this.DIRECTIVE_KEY, val);
113+
}
112114
}
113115

114116
/**

src/lib/core/media-marshaller/media-marshaller.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,10 @@ export class MediaMarshaller {
108108
if (bpMap) {
109109
const values = bp !== undefined ? bpMap.get(bp) : this.getFallback(bpMap, key);
110110
if (values) {
111-
const value = values.get(key);
112-
return value !== undefined ? value : '';
111+
return values.get(key);
113112
}
114113
}
115-
return '';
114+
return undefined;
116115
}
117116

118117
/**
@@ -148,7 +147,10 @@ export class MediaMarshaller {
148147
bpMap.set(bp, values);
149148
this.elementMap.set(element, bpMap);
150149
}
151-
this.updateElement(element, key, this.getValue(element, key));
150+
const value = this.getValue(element, key);
151+
if (value !== undefined) {
152+
this.updateElement(element, key, value);
153+
}
152154
}
153155

154156
/** Track element value changes for a specific key */
@@ -286,7 +288,8 @@ export class MediaMarshaller {
286288
}
287289
}
288290
}
289-
return bpMap.get('');
291+
const lastHope = bpMap.get('');
292+
return (key === undefined || lastHope && lastHope.has(key)) ? lastHope : undefined;
290293
}
291294

292295
private registerBreakpoints() {

src/lib/extended/style/style.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import {
3535
export class StyleDirective extends BaseDirective2 implements DoCheck {
3636

3737
protected DIRECTIVE_KEY = 'ngStyle';
38-
protected fallbackStyles: NgStyleMap = {};
38+
protected fallbackStyles: NgStyleMap;
3939

4040
constructor(protected elementRef: ElementRef,
4141
protected styler: StyleUtils,
@@ -55,12 +55,19 @@ export class StyleDirective extends BaseDirective2 implements DoCheck {
5555
this.fallbackStyles = this.buildStyleMap(styles);
5656
}
5757

58+
/** Add generated styles */
5859
protected updateWithValue(value: any) {
5960
const styles = this.buildStyleMap(value);
6061
this.ngStyleInstance.ngStyle = {...this.fallbackStyles, ...styles};
6162
this.ngStyleInstance.ngDoCheck();
6263
}
6364

65+
/** Remove generated styles */
66+
protected clearStyles() {
67+
this.ngStyleInstance.ngStyle = this.fallbackStyles;
68+
this.ngStyleInstance.ngDoCheck();
69+
}
70+
6471
/**
6572
* Convert raw strings to ngStyleMap; which is required by ngStyle
6673
* NOTE: Raw string key-value pairs MUST be delimited by `;`

src/lib/flex/flex/flex.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,11 @@ export class FlexDirective extends BaseDirective2 {
274274

275275
/** Trigger a style reflow, usually based on a shrink/grow input event */
276276
protected triggerReflow() {
277-
const parts = validateBasis(this.activatedValue, this.flexGrow, this.flexShrink);
278-
this.marshal.updateElement(this.nativeElement, this.DIRECTIVE_KEY, parts.join(' '));
277+
const activatedValue = this.activatedValue;
278+
if (activatedValue !== undefined) {
279+
const parts = validateBasis(activatedValue, this.flexGrow, this.flexShrink);
280+
this.marshal.updateElement(this.nativeElement, this.DIRECTIVE_KEY, parts.join(' '));
281+
}
279282
}
280283
}
281284

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,35 @@ describe('layout-align directive', () => {
363363
}, styler);
364364
});
365365

366+
it('should not fallback to value not registered with fxLayout', () => {
367+
createTestComponent(`
368+
<section fxLayout="row"
369+
fxLayoutAlign.lt-md="center center">
370+
</section>
371+
`);
372+
373+
matchMedia.activate('lt-md');
374+
expectNativeEl(fixture).toHaveStyle({
375+
'justify-content': 'center',
376+
'align-items': 'center',
377+
'align-content': 'center'
378+
}, styler);
379+
380+
matchMedia.activate('md');
381+
expectNativeEl(fixture).not.toHaveStyle({
382+
'justify-content': 'center',
383+
'align-items': 'center',
384+
'align-content': 'center'
385+
}, styler);
386+
387+
matchMedia.activate('lt-md');
388+
expectNativeEl(fixture).toHaveStyle({
389+
'justify-content': 'center',
390+
'align-items': 'center',
391+
'align-content': 'center'
392+
}, styler);
393+
});
394+
366395
it('should fallback to closest overlapping value when the active mediaQuery change is not configured', () => { // tslint:disable-line:max-line-length
367396
createTestComponent(`
368397
<div fxLayout

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,7 @@ describe('layout-gap directive', () => {
543543

544544
@Injectable({providedIn: FlexModule})
545545
export class MockLayoutGapStyleBuilder extends StyleBuilder {
546+
shouldCache = false;
546547
buildStyles(_input: string) {
547548
return {'margin-top': '12px'};
548549
}

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,6 @@ export class LayoutGapDirective extends BaseDirective2 implements AfterContentIn
168168
*
169169
*/
170170
protected updateWithValue(value: string) {
171-
if (!value) {
172-
value = this.marshal.getValue(this.nativeElement, this.DIRECTIVE_KEY);
173-
}
174171
// Gather all non-hidden Element nodes
175172
const items = this.childrenNodes
176173
.filter(el => el.nodeType === 1 && this.willDisplay(el))
@@ -204,7 +201,7 @@ export class LayoutGapDirective extends BaseDirective2 implements AfterContentIn
204201
protected willDisplay(source: HTMLElement): boolean {
205202
const value = this.marshal.getValue(source, 'show-hide');
206203
return value === true ||
207-
(value === '' && this.styleUtils.lookupStyle(source, 'display') !== 'none');
204+
(value === undefined && this.styleUtils.lookupStyle(source, 'display') !== 'none');
208205
}
209206

210207
protected buildChildObservable(): void {

0 commit comments

Comments
 (0)