@schoolbelle/common
Version:
385 lines (379 loc) • 12.6 kB
JavaScript
import { Component, ElementRef, Input, Output, EventEmitter, HostListener, ChangeDetectionStrategy, NgModule } from '@angular/core';
import { fromEvent, merge, Subject, Subscription } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var StickyComponent = /** @class */ (function () {
function StickyComponent(element) {
this.element = element;
this.zIndex = 10;
this.width = 'auto';
this.offsetTop = 0;
this.offsetBottom = 0;
this.start = 0;
this.stickClass = 'sticky';
this.endStickClass = 'sticky-end';
this.mediaQuery = '';
this.parentMode = true;
this.orientation = 'none';
this.activated = new EventEmitter();
this.deactivated = new EventEmitter();
this.reset = new EventEmitter();
this.isStuck = false;
this.subscription = new Subscription();
this.onChangeEvent = new Subject();
}
/**
* @return {?}
*/
StickyComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
var _this = this;
this.elem = this.element.nativeElement;
if (this.parentScroll) {
this.subscription.add(merge(fromEvent(this.parentScroll, 'scroll'), fromEvent(this.parentScroll, 'resize'))
.subscribe((/**
* @return {?}
*/
function () {
_this.sticker();
})));
}
this.subscription.add(this.onChangeEvent
.pipe(debounceTime(100))
.subscribe((/**
* @return {?}
*/
function () { return _this.sticker(); })));
};
/**
* @return {?}
*/
StickyComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.subscription.unsubscribe();
};
/**
* @return {?}
*/
StickyComponent.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
var _this = this;
// define scroll container as parent element
this.container = this.elem.parentNode;
// fix : for ngIf to kick in
setTimeout((/**
* @return {?}
*/
function () {
_this.defineOriginalDimensions();
_this.sticker();
}));
// this.defineOriginalDimensions();
// this.sticker();
};
/**
* @param {?} $event
* @return {?}
*/
StickyComponent.prototype.onChange = /**
* @param {?} $event
* @return {?}
*/
function ($event) {
this.onChangeEvent.next(null);
};
/**
* @return {?}
*/
StickyComponent.prototype.defineOriginalDimensions = /**
* @return {?}
*/
function () {
this.originalCss = {
zIndex: this.getCssValue(this.elem, 'zIndex'),
position: this.getCssValue(this.elem, 'position'),
top: this.getCssValue(this.elem, 'top'),
right: this.getCssValue(this.elem, 'right'),
left: this.getCssValue(this.elem, 'left'),
bottom: this.getCssValue(this.elem, 'bottom'),
width: this.elem.getBoundingClientRect().width + 'px',
};
if (this.width === 'auto') {
this.width = this.originalCss.width;
}
};
/**
* @return {?}
*/
StickyComponent.prototype.defineDimensions = /**
* @return {?}
*/
function () {
/** @type {?} */
var containerTop = this.getBoundingClientRectValue(this.container, 'top');
this.windowHeight = window.innerHeight;
this.elemHeight = this.getCssNumber(this.elem, 'height');
this.containerHeight = this.getCssNumber(this.container, 'height');
this.containerStart = containerTop + this.scrollbarYPos() - this.offsetTop + this.start;
if (this.parentMode) {
this.scrollFinish = this.containerStart - this.start - this.offsetBottom + (this.containerHeight - this.elemHeight);
}
else {
this.scrollFinish = document.body.offsetHeight;
}
};
/**
* @return {?}
*/
StickyComponent.prototype.resetElement = /**
* @return {?}
*/
function () {
this.elem.classList.remove(this.stickClass);
Object.assign(this.elem.style, this.originalCss);
this.reset.next(this.elem);
};
/**
* @return {?}
*/
StickyComponent.prototype.stuckElement = /**
* @return {?}
*/
function () {
this.isStuck = true;
this.elem.classList.remove(this.endStickClass);
this.elem.classList.add(this.stickClass);
Object.assign(this.elem.style, {
zIndex: this.zIndex,
position: 'fixed',
top: this.offsetTop + 'px',
right: 'auto',
bottom: 'auto',
left: this.getBoundingClientRectValue(this.elem, 'left') + 'px',
width: this.elem.getBoundingClientRect().width + 'px',
});
this.activated.next(this.elem);
};
/**
* @return {?}
*/
StickyComponent.prototype.unstuckElement = /**
* @return {?}
*/
function () {
this.isStuck = false;
this.elem.classList.add(this.endStickClass);
this.container.style.position = 'relative';
Object.assign(this.elem.style, {
position: 'absolute',
top: 'auto',
left: 'auto',
right: this.getCssValue(this.elem, 'float') === 'right' || this.orientation === 'right' ? 0 : 'auto',
bottom: this.offsetBottom + 'px',
width: this.elem.getBoundingClientRect().width + 'px',
});
this.deactivated.next(this.elem);
};
/**
* @return {?}
*/
StickyComponent.prototype.matchMediaQuery = /**
* @return {?}
*/
function () {
if (!this.mediaQuery)
return true;
return (window.matchMedia('(' + this.mediaQuery + ')').matches ||
window.matchMedia(this.mediaQuery).matches);
};
/**
* @return {?}
*/
StickyComponent.prototype.sticker = /**
* @return {?}
*/
function () {
// check media query
if (this.isStuck && !this.matchMediaQuery()) {
this.resetElement();
return;
}
// detecting when a container's height changes
/** @type {?} */
var currentContainerHeight = this.getCssNumber(this.container, 'height');
if (currentContainerHeight !== this.containerHeight) {
this.defineDimensions();
}
// check if the sticky element is above the container
if (this.elemHeight >= currentContainerHeight) {
if (this.isStuck)
this.resetElement();
return;
}
/** @type {?} */
var position = this.scrollbarYPos();
// if parent container is window
if (this.parentMode === false) {
// unstick
if (position < this.containerStart) {
this.resetElement();
this.isStuck = false;
}
// stick
else if (position > this.containerStart) {
this.stuckElement();
}
}
else {
// unstick
// if (this.parentMode === true && (this.isStuck && (position < this.containerStart || position > this.scrollFinish) || position > this.scrollFinish)) {
if (this.parentMode === true && (this.isStuck && (position <= this.containerStart || position > this.scrollFinish) || position > this.scrollFinish)) {
this.resetElement();
if (position > this.scrollFinish)
this.unstuckElement();
this.isStuck = false;
}
// stick
else if (position > this.containerStart && position < this.scrollFinish) {
this.stuckElement();
}
}
};
/**
* @private
* @return {?}
*/
StickyComponent.prototype.scrollbarYPos = /**
* @private
* @return {?}
*/
function () {
return this.parentScroll && this.parentScroll.scrollTop || window.pageYOffset || document.documentElement.scrollTop;
};
/**
* @private
* @param {?} element
* @param {?} property
* @return {?}
*/
StickyComponent.prototype.getBoundingClientRectValue = /**
* @private
* @param {?} element
* @param {?} property
* @return {?}
*/
function (element, property) {
/** @type {?} */
var result = 0;
if (element && element.getBoundingClientRect) {
/** @type {?} */
var rect = element.getBoundingClientRect();
result = (typeof rect[property] !== 'undefined') ? rect[property] : 0;
}
return result;
};
/**
* @private
* @param {?} element
* @param {?} property
* @return {?}
*/
StickyComponent.prototype.getCssValue = /**
* @private
* @param {?} element
* @param {?} property
* @return {?}
*/
function (element, property) {
/** @type {?} */
var result = '';
if (typeof window.getComputedStyle !== 'undefined') {
result = window.getComputedStyle(element, '').getPropertyValue(property);
}
else if (typeof element.currentStyle !== 'undefined') {
result = element.currentStyle[property];
}
return result;
};
/**
* @private
* @param {?} element
* @param {?} property
* @return {?}
*/
StickyComponent.prototype.getCssNumber = /**
* @private
* @param {?} element
* @param {?} property
* @return {?}
*/
function (element, property) {
if (typeof element === 'undefined')
return 0;
return parseInt(this.getCssValue(element, property), 10) || 0;
};
StickyComponent.decorators = [
{ type: Component, args: [{
selector: 'sticky,[sticky]',
template: '<ng-content></ng-content>',
changeDetection: ChangeDetectionStrategy.OnPush
}] }
];
/** @nocollapse */
StickyComponent.ctorParameters = function () { return [
{ type: ElementRef }
]; };
StickyComponent.propDecorators = {
sticky: [{ type: Input, args: ['sticky',] }],
zIndex: [{ type: Input, args: ['sticky-zIndex',] }],
width: [{ type: Input, args: ['sticky-width',] }],
offsetTop: [{ type: Input, args: ['sticky-offset-top',] }],
offsetBottom: [{ type: Input, args: ['sticky-offset-bottom',] }],
start: [{ type: Input, args: ['sticky-start',] }],
stickClass: [{ type: Input, args: ['sticky-class',] }],
endStickClass: [{ type: Input, args: ['sticky-end-class',] }],
mediaQuery: [{ type: Input, args: ['sticky-media-query',] }],
parentMode: [{ type: Input, args: ['sticky-parent',] }],
orientation: [{ type: Input, args: ['sticky-orientation',] }],
parentScroll: [{ type: Input, args: ['parentScroll',] }],
activated: [{ type: Output }],
deactivated: [{ type: Output }],
reset: [{ type: Output }],
onChange: [{ type: HostListener, args: ['window:scroll', ['$event'],] }, { type: HostListener, args: ['window:resize', ['$event'],] }, { type: HostListener, args: ['window:orientationchange', ['$event'],] }]
};
return StickyComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var StickyModule = /** @class */ (function () {
function StickyModule() {
}
StickyModule.decorators = [
{ type: NgModule, args: [{
declarations: [StickyComponent],
exports: [StickyComponent]
},] }
];
return StickyModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
export { StickyModule, StickyComponent };
//# sourceMappingURL=schoolbelle-common-sticky.js.map