@angular/flex-layout
Version:
Angular 2 Flexbox Layout
238 lines • 9.04 kB
JavaScript
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
import { Directive, ElementRef, Input, Renderer, Self, Optional } from '@angular/core';
import { BaseFxDirective } from './base';
import { MediaMonitor } from '../../media-query/media-monitor';
import { LayoutDirective, LAYOUT_VALUES } from './layout';
/**
* 'layout-padding' styling directive
* Defines padding of child elements in a layout container
*/
export var LayoutGapDirective = (function (_super) {
__extends(LayoutGapDirective, _super);
function LayoutGapDirective(monitor, elRef, renderer, container) {
_super.call(this, monitor, elRef, renderer);
this._layout = 'row'; // default flex-direction
if (container) {
this._layoutWatcher = container.layout$.subscribe(this._onLayoutChange.bind(this));
}
}
Object.defineProperty(LayoutGapDirective.prototype, "gap", {
set: function (val) {
this._cacheInput('gap', val);
},
enumerable: true,
configurable: true
});
Object.defineProperty(LayoutGapDirective.prototype, "gapXs", {
set: function (val) {
this._cacheInput('gapXs', val);
},
enumerable: true,
configurable: true
});
Object.defineProperty(LayoutGapDirective.prototype, "gapGtXs", {
set: function (val) {
this._cacheInput('gapGtXs', val);
},
enumerable: true,
configurable: true
});
;
Object.defineProperty(LayoutGapDirective.prototype, "gapSm", {
set: function (val) {
this._cacheInput('gapSm', val);
},
enumerable: true,
configurable: true
});
;
Object.defineProperty(LayoutGapDirective.prototype, "gapGtSm", {
set: function (val) {
this._cacheInput('gapGtSm', val);
},
enumerable: true,
configurable: true
});
;
Object.defineProperty(LayoutGapDirective.prototype, "gapMd", {
set: function (val) {
this._cacheInput('gapMd', val);
},
enumerable: true,
configurable: true
});
;
Object.defineProperty(LayoutGapDirective.prototype, "gapGtMd", {
set: function (val) {
this._cacheInput('gapGtMd', val);
},
enumerable: true,
configurable: true
});
;
Object.defineProperty(LayoutGapDirective.prototype, "gapLg", {
set: function (val) {
this._cacheInput('gapLg', val);
},
enumerable: true,
configurable: true
});
;
Object.defineProperty(LayoutGapDirective.prototype, "gapGtLg", {
set: function (val) {
this._cacheInput('gapGtLg', val);
},
enumerable: true,
configurable: true
});
;
Object.defineProperty(LayoutGapDirective.prototype, "gapXl", {
set: function (val) {
this._cacheInput('gapXl', val);
},
enumerable: true,
configurable: true
});
;
// *********************************************
// Lifecycle Methods
// *********************************************
LayoutGapDirective.prototype.ngOnChanges = function (changes) {
if (changes['gap'] != null || this._mqActivation) {
this._updateWithValue();
}
};
/**
* After the initial onChanges, build an mqActivation object that bridges
* mql change events to onMediaQueryChange handlers
*/
LayoutGapDirective.prototype.ngAfterContentInit = function () {
var _this = this;
this._watchContentChanges();
this._listenForMediaQueryChanges('gap', '0', function (changes) {
_this._updateWithValue(changes.value);
});
this._updateWithValue();
};
LayoutGapDirective.prototype.ngOnDestroy = function () {
_super.prototype.ngOnDestroy.call(this);
if (this._layoutWatcher) {
this._layoutWatcher.unsubscribe();
}
if (this._observer) {
this._observer.disconnect();
}
};
// *********************************************
// Protected methods
// *********************************************
/**
* Watch for child nodes to be added... and apply the layout gap styles to each.
* NOTE: this does NOT! differentiate between viewChildren and contentChildren
*/
LayoutGapDirective.prototype._watchContentChanges = function () {
var _this = this;
var onMutationCallback = function (mutations) {
var validatedChanges = function (it) {
return (it.addedNodes && it.addedNodes.length) ||
(it.removedNodes && it.removedNodes.length);
};
// update gap styles only for child 'added' or 'removed' events
if (mutations.filter(validatedChanges).length) {
_this._updateWithValue();
}
};
this._observer = new MutationObserver(onMutationCallback);
this._observer.observe(this._elementRef.nativeElement, { childList: true });
};
/**
* Cache the parent container 'flex-direction' and update the 'margin' styles
*/
LayoutGapDirective.prototype._onLayoutChange = function (direction) {
var _this = this;
this._layout = (direction || '').toLowerCase();
if (!LAYOUT_VALUES.find(function (x) { return x === _this._layout; })) {
this._layout = 'row';
}
this._updateWithValue();
};
/**
*
*/
LayoutGapDirective.prototype._updateWithValue = function (value) {
var _this = this;
value = value || this._queryInput("gap") || '0';
if (this._mqActivation) {
value = this._mqActivation.activatedInput;
}
// Gather all non-hidden Element nodes
var items = this.childrenNodes
.filter(function (el) { return (el.nodeType === 1); }) // only Element types
.filter(function (el) { return _this._getDisplayStyle(el) != "none"; });
var numItems = items.length;
if (numItems > 1) {
var lastItem = items[numItems - 1];
// For each `element` children EXCEPT the last,
// set the margin right/bottom styles...
items = items.filter(function (el, j) { return j < numItems - 1; });
this._applyStyleToElements(this._buildCSS(value), items);
// Clear all gaps for all visible elements
this._applyStyleToElements(this._buildCSS(), [lastItem]);
}
};
/**
* Prepare margin CSS, remove any previous explicitly
* assigned margin assignments
*/
LayoutGapDirective.prototype._buildCSS = function (value) {
if (value === void 0) { value = null; }
var key, margins = {
'margin-left': null,
'margin-right': null,
'margin-top': null,
'margin-bottom': null
};
switch (this._layout) {
case 'column':
case 'column-reverse':
key = 'margin-bottom';
break;
case "row":
case 'row-reverse':
default:
key = 'margin-right';
break;
}
margins[key] = value;
return margins;
};
LayoutGapDirective.decorators = [
{ type: Directive, args: [{ selector: "\n [fxLayoutGap],\n [fxLayoutGap.xs],\n [fxLayoutGap.gt-xs],\n [fxLayoutGap.sm],\n [fxLayoutGap.gt-sm]\n [fxLayoutGap.md],\n [fxLayoutGap.gt-md]\n [fxLayoutGap.lg],\n [fxLayoutGap.gt-lg],\n [fxLayoutGap.xl]\n"
},] },
];
/** @nocollapse */
LayoutGapDirective.ctorParameters = function () { return [
{ type: MediaMonitor, },
{ type: ElementRef, },
{ type: Renderer, },
{ type: LayoutDirective, decorators: [{ type: Optional }, { type: Self },] },
]; };
LayoutGapDirective.propDecorators = {
'gap': [{ type: Input, args: ['fxLayoutGap',] },],
'gapXs': [{ type: Input, args: ['fxLayoutGap.xs',] },],
'gapGtXs': [{ type: Input, args: ['fxLayoutGap.gt-xs',] },],
'gapSm': [{ type: Input, args: ['fxLayoutGap.sm',] },],
'gapGtSm': [{ type: Input, args: ['fxLayoutGap.gt-sm',] },],
'gapMd': [{ type: Input, args: ['fxLayoutGap.md',] },],
'gapGtMd': [{ type: Input, args: ['fxLayoutGap.gt-md',] },],
'gapLg': [{ type: Input, args: ['fxLayoutGap.lg',] },],
'gapGtLg': [{ type: Input, args: ['fxLayoutGap.gt-lg',] },],
'gapXl': [{ type: Input, args: ['fxLayoutGap.xl',] },],
};
return LayoutGapDirective;
}(BaseFxDirective));
//# sourceMappingURL=/usr/local/google/home/tinagao/WebstormProjects/caretaker/flex-layout/src/lib/flexbox/api/layout-gap.js.map