@@ -28,9 +28,10 @@ import {LayoutDirective, LAYOUT_VALUES} from './layout';
28
28
* 'layout-padding' styling directive
29
29
* Defines padding of child elements in a layout container
30
30
*/
31
- @Directive ( { selector : `
31
+ @Directive ( {
32
+ selector : `
32
33
[fxLayoutGap],
33
- [fxLayoutGap.xs]
34
+ [fxLayoutGap.xs],
34
35
[fxLayoutGap.gt-xs],
35
36
[fxLayoutGap.sm],
36
37
[fxLayoutGap.gt-sm]
@@ -39,28 +40,58 @@ import {LayoutDirective, LAYOUT_VALUES} from './layout';
39
40
[fxLayoutGap.lg],
40
41
[fxLayoutGap.gt-lg],
41
42
[fxLayoutGap.xl]
42
- ` } )
43
+ `
44
+ } )
43
45
export class LayoutGapDirective extends BaseFxDirective implements AfterContentInit , OnChanges ,
44
- OnDestroy {
46
+ OnDestroy {
45
47
private _layout = 'row' ; // default flex-direction
46
48
private _layoutWatcher : Subscription ;
49
+ private _observer : MutationObserver ;
47
50
48
- @Input ( 'fxLayoutGap' ) set gap ( val ) { this . _cacheInput ( 'gap' , val ) ; }
49
- @Input ( 'fxLayoutGap.xs' ) set gapXs ( val ) { this . _cacheInput ( 'gapXs' , val ) ; }
50
- @Input ( 'fxLayoutGap.gt-xs' ) set gapGtXs ( val ) { this . _cacheInput ( 'gapGtXs' , val ) ; } ;
51
- @Input ( 'fxLayoutGap.sm' ) set gapSm ( val ) { this . _cacheInput ( 'gapSm' , val ) ; } ;
52
- @Input ( 'fxLayoutGap.gt-sm' ) set gapGtSm ( val ) { this . _cacheInput ( 'gapGtSm' , val ) ; } ;
53
- @Input ( 'fxLayoutGap.md' ) set gapMd ( val ) { this . _cacheInput ( 'gapMd' , val ) ; } ;
54
- @Input ( 'fxLayoutGap.gt-md' ) set gapGtMd ( val ) { this . _cacheInput ( 'gapGtMd' , val ) ; } ;
55
- @Input ( 'fxLayoutGap.lg' ) set gapLg ( val ) { this . _cacheInput ( 'gapLg' , val ) ; } ;
56
- @Input ( 'fxLayoutGap.gt-lg' ) set gapGtLg ( val ) { this . _cacheInput ( 'gapGtLg' , val ) ; } ;
57
- @Input ( 'fxLayoutGap.xl' ) set gapXl ( val ) { this . _cacheInput ( 'gapXl' , val ) ; } ;
58
-
59
- constructor (
60
- monitor : MediaMonitor ,
61
- elRef : ElementRef ,
62
- renderer : Renderer ,
63
- @Optional ( ) @Self ( ) container : LayoutDirective ) {
51
+ @Input ( 'fxLayoutGap' ) set gap ( val ) {
52
+ this . _cacheInput ( 'gap' , val ) ;
53
+ }
54
+
55
+ @Input ( 'fxLayoutGap.xs' ) set gapXs ( val ) {
56
+ this . _cacheInput ( 'gapXs' , val ) ;
57
+ }
58
+
59
+ @Input ( 'fxLayoutGap.gt-xs' ) set gapGtXs ( val ) {
60
+ this . _cacheInput ( 'gapGtXs' , val ) ;
61
+ } ;
62
+
63
+ @Input ( 'fxLayoutGap.sm' ) set gapSm ( val ) {
64
+ this . _cacheInput ( 'gapSm' , val ) ;
65
+ } ;
66
+
67
+ @Input ( 'fxLayoutGap.gt-sm' ) set gapGtSm ( val ) {
68
+ this . _cacheInput ( 'gapGtSm' , val ) ;
69
+ } ;
70
+
71
+ @Input ( 'fxLayoutGap.md' ) set gapMd ( val ) {
72
+ this . _cacheInput ( 'gapMd' , val ) ;
73
+ } ;
74
+
75
+ @Input ( 'fxLayoutGap.gt-md' ) set gapGtMd ( val ) {
76
+ this . _cacheInput ( 'gapGtMd' , val ) ;
77
+ } ;
78
+
79
+ @Input ( 'fxLayoutGap.lg' ) set gapLg ( val ) {
80
+ this . _cacheInput ( 'gapLg' , val ) ;
81
+ } ;
82
+
83
+ @Input ( 'fxLayoutGap.gt-lg' ) set gapGtLg ( val ) {
84
+ this . _cacheInput ( 'gapGtLg' , val ) ;
85
+ } ;
86
+
87
+ @Input ( 'fxLayoutGap.xl' ) set gapXl ( val ) {
88
+ this . _cacheInput ( 'gapXl' , val ) ;
89
+ } ;
90
+
91
+ constructor ( monitor : MediaMonitor ,
92
+ elRef : ElementRef ,
93
+ renderer : Renderer ,
94
+ @Optional ( ) @Self ( ) container : LayoutDirective ) {
64
95
super ( monitor , elRef , renderer ) ;
65
96
66
97
if ( container ) { // Subscribe to layout direction changes
@@ -83,23 +114,43 @@ export class LayoutGapDirective extends BaseFxDirective implements AfterContentI
83
114
* mql change events to onMediaQueryChange handlers
84
115
*/
85
116
ngAfterContentInit ( ) {
117
+ this . _watchContentChanges ( ) ;
86
118
this . _listenForMediaQueryChanges ( 'gap' , '0' , ( changes : MediaChange ) => {
87
119
this . _updateWithValue ( changes . value ) ;
88
120
} ) ;
89
121
this . _updateWithValue ( ) ;
90
122
}
91
123
92
124
ngOnDestroy ( ) {
93
- super . ngOnDestroy ( ) ;
94
- if ( this . _layoutWatcher ) {
95
- this . _layoutWatcher . unsubscribe ( ) ;
96
- }
97
- }
125
+ super . ngOnDestroy ( ) ;
126
+ if ( this . _layoutWatcher ) {
127
+ this . _layoutWatcher . unsubscribe ( ) ;
128
+ }
129
+ if ( this . _observer ) {
130
+ this . _observer . disconnect ( ) ;
131
+ }
132
+ }
98
133
99
134
// *********************************************
100
135
// Protected methods
101
136
// *********************************************
102
137
138
+ /**
139
+ * Watch for child nodes to be added... and apply the layout gap styles to each.
140
+ * NOTE: this does NOT! differentiate between viewChildren and contentChildren
141
+ */
142
+ private _watchContentChanges ( ) {
143
+ let onMutationCallback = ( mutations ) => {
144
+ // update gap styles only for 'addedNodes' events
145
+ mutations
146
+ . filter ( ( it : MutationRecord ) => it . addedNodes && it . addedNodes . length )
147
+ . map ( ( ) => this . _updateWithValue ( ) ) ;
148
+ } ;
149
+
150
+ this . _observer = new MutationObserver ( onMutationCallback ) ;
151
+ this . _observer . observe ( this . _elementRef . nativeElement , { childList : true } ) ;
152
+ }
153
+
103
154
/**
104
155
* Cache the parent container 'flex-direction' and update the 'margin' styles
105
156
*/
@@ -108,7 +159,6 @@ export class LayoutGapDirective extends BaseFxDirective implements AfterContentI
108
159
if ( ! LAYOUT_VALUES . find ( x => x === this . _layout ) ) {
109
160
this . _layout = 'row' ;
110
161
}
111
-
112
162
this . _updateWithValue ( ) ;
113
163
}
114
164
@@ -121,11 +171,18 @@ export class LayoutGapDirective extends BaseFxDirective implements AfterContentI
121
171
value = this . _mqActivation . activatedInput ;
122
172
}
123
173
124
- // For each `element` child, set the padding styles...
174
+ // Reset 1st child element to 0px gap
125
175
let items = this . childrenNodes
126
- . filter ( el => ( el . nodeType === 1 ) ) // only Element types
127
- . filter ( ( el , j ) => j > 0 ) ; // skip first element since gaps are needed
128
- this . _applyStyleToElements ( this . _buildCSS ( value ) , items ) ;
176
+ . filter ( el => ( el . nodeType === 1 ) ) // only Element types
177
+ . filter ( ( el , j ) => j == 0 ) ;
178
+ this . _applyStyleToElements ( this . _buildCSS ( 0 ) , items ) ;
179
+
180
+ // 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
+ this . _applyStyleToElements ( this . _buildCSS ( value ) , items ) ;
185
+
129
186
}
130
187
131
188
/**
0 commit comments