UNPKG

ng-zorro-antd

Version:

An enterprise-class UI components based on Ant Design and Angular

400 lines (394 loc) 12.9 kB
import { __decorate, __metadata } from 'tslib'; import { Platform } from '@angular/cdk/platform'; import { DOCUMENT, CommonModule } from '@angular/common'; import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Inject, Input, Output, ViewChild, ViewEncapsulation, NgModule } from '@angular/core'; import { shallowEqual, throttleByAnimationFrameDecorator, toNumber, NzScrollService, SCROLL_SERVICE_PROVIDER } from 'ng-zorro-antd/core'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NzAffixComponent { /** * @param {?} _el * @param {?} scrollSrv * @param {?} doc * @param {?} platform */ constructor(_el, scrollSrv, doc, platform) { this.scrollSrv = scrollSrv; this.doc = doc; this.platform = platform; this.nzChange = new EventEmitter(); this.events = ['resize', 'scroll', 'touchstart', 'touchmove', 'touchend', 'pageshow', 'load']; this._target = null; this.placeholderNode = _el.nativeElement; if (this.platform.isBrowser) { this._target = window; } } /** * @param {?} value * @return {?} */ set nzTarget(value) { if (this.platform.isBrowser) { this.clearEventListeners(); this._target = typeof value === 'string' ? this.doc.querySelector(value) : value || window; this.setTargetEventListeners(); this.updatePosition((/** @type {?} */ ({}))); } } /** * @param {?} value * @return {?} */ set nzOffsetTop(value) { if (value === undefined || value === null) { return; } this._offsetTop = toNumber(value, null); this.updatePosition((/** @type {?} */ ({}))); } /** * @return {?} */ get nzOffsetTop() { return this._offsetTop; } /** * @param {?} value * @return {?} */ set nzOffsetBottom(value) { if (typeof value === 'undefined') { return; } this._offsetBottom = toNumber(value, null); this.updatePosition((/** @type {?} */ ({}))); } /** * @return {?} */ ngOnInit() { this.timeout = setTimeout((/** * @return {?} */ () => { this.setTargetEventListeners(); this.updatePosition((/** @type {?} */ ({}))); })); } /** * @return {?} */ ngOnDestroy() { this.clearEventListeners(); clearTimeout(this.timeout); // tslint:disable-next-line:no-any ((/** @type {?} */ (this.updatePosition))).cancel(); } /** * @param {?} element * @param {?} target * @return {?} */ getOffset(element, target) { /** @type {?} */ const elemRect = element.getBoundingClientRect(); /** @type {?} */ const targetRect = this.getTargetRect(target); /** @type {?} */ const scrollTop = this.scrollSrv.getScroll(target, true); /** @type {?} */ const scrollLeft = this.scrollSrv.getScroll(target, false); /** @type {?} */ const docElem = this.doc.body; /** @type {?} */ const clientTop = docElem.clientTop || 0; /** @type {?} */ const clientLeft = docElem.clientLeft || 0; return { top: elemRect.top - targetRect.top + scrollTop - clientTop, left: elemRect.left - targetRect.left + scrollLeft - clientLeft, width: elemRect.width, height: elemRect.height }; } /** * @private * @return {?} */ setTargetEventListeners() { this.clearEventListeners(); if (this.platform.isBrowser) { this.events.forEach((/** * @param {?} eventName * @return {?} */ (eventName) => { (/** @type {?} */ (this._target)).addEventListener(eventName, this.updatePosition, false); })); } } /** * @private * @return {?} */ clearEventListeners() { if (this.platform.isBrowser) { this.events.forEach((/** * @param {?} eventName * @return {?} */ eventName => { (/** @type {?} */ (this._target)).removeEventListener(eventName, this.updatePosition, false); })); } } /** * @private * @param {?} target * @return {?} */ getTargetRect(target) { return target !== window ? ((/** @type {?} */ (target))).getBoundingClientRect() : ((/** @type {?} */ ({ top: 0, left: 0, bottom: 0 }))); } /** * @private * @param {?=} affixStyle * @return {?} */ genStyle(affixStyle) { if (!affixStyle) { return ''; } return Object.keys(affixStyle) .map((/** * @param {?} key * @return {?} */ key => { /** @type {?} */ const val = affixStyle[key]; return `${key}:${typeof val === 'string' ? val : val + 'px'}`; })) .join(';'); } /** * @private * @param {?} e * @param {?=} affixStyle * @return {?} */ setAffixStyle(e, affixStyle) { /** @type {?} */ const originalAffixStyle = this.affixStyle; /** @type {?} */ const isWindow = this._target === window; if (e.type === 'scroll' && originalAffixStyle && affixStyle && isWindow) { return; } if (shallowEqual(originalAffixStyle, affixStyle)) { return; } /** @type {?} */ const fixed = !!affixStyle; /** @type {?} */ const wrapEl = (/** @type {?} */ (this.fixedEl.nativeElement)); wrapEl.style.cssText = this.genStyle(affixStyle); this.affixStyle = affixStyle; /** @type {?} */ const cls = 'ant-affix'; if (fixed) { wrapEl.classList.add(cls); } else { wrapEl.classList.remove(cls); } if ((affixStyle && !originalAffixStyle) || (!affixStyle && originalAffixStyle)) { this.nzChange.emit(fixed); } } /** * @private * @param {?=} placeholderStyle * @return {?} */ setPlaceholderStyle(placeholderStyle) { /** @type {?} */ const originalPlaceholderStyle = this.placeholderStyle; if (shallowEqual(placeholderStyle, originalPlaceholderStyle)) { return; } this.placeholderNode.style.cssText = this.genStyle(placeholderStyle); this.placeholderStyle = placeholderStyle; } /** * @private * @param {?} e * @return {?} */ syncPlaceholderStyle(e) { if (!this.affixStyle) { return; } this.placeholderNode.style.cssText = ''; this.placeholderStyle = undefined; /** @type {?} */ const styleObj = { width: this.placeholderNode.offsetWidth, height: this.fixedEl.nativeElement.offsetHeight }; this.setAffixStyle(e, Object.assign({}, this.affixStyle, styleObj)); this.setPlaceholderStyle(styleObj); } /** * @param {?} e * @return {?} */ updatePosition(e) { if (!this.platform.isBrowser) { return; } /** @type {?} */ const targetNode = (/** @type {?} */ (this._target)); // Backwards support /** @type {?} */ let offsetTop = this.nzOffsetTop; /** @type {?} */ const scrollTop = this.scrollSrv.getScroll((/** @type {?} */ (targetNode)), true); /** @type {?} */ const elemOffset = this.getOffset(this.placeholderNode, (/** @type {?} */ (targetNode))); /** @type {?} */ const fixedNode = (/** @type {?} */ (this.fixedEl.nativeElement)); /** @type {?} */ const elemSize = { width: fixedNode.offsetWidth, height: fixedNode.offsetHeight }; /** @type {?} */ const offsetMode = { top: false, bottom: false }; // Default to `offsetTop=0`. if (typeof offsetTop !== 'number' && typeof this._offsetBottom !== 'number') { offsetMode.top = true; offsetTop = 0; } else { offsetMode.top = typeof offsetTop === 'number'; offsetMode.bottom = typeof this._offsetBottom === 'number'; } /** @type {?} */ const targetRect = this.getTargetRect((/** @type {?} */ (targetNode))); /** @type {?} */ const targetInnerHeight = ((/** @type {?} */ (targetNode))).innerHeight || ((/** @type {?} */ (targetNode))).clientHeight; if (scrollTop >= elemOffset.top - ((/** @type {?} */ (offsetTop))) && offsetMode.top) { /** @type {?} */ const width = elemOffset.width; /** @type {?} */ const top = targetRect.top + ((/** @type {?} */ (offsetTop))); this.setAffixStyle(e, { position: 'fixed', top, left: targetRect.left + elemOffset.left, maxHeight: `calc(100vh - ${top}px)`, width }); this.setPlaceholderStyle({ width, height: elemSize.height }); } else if (scrollTop <= elemOffset.top + elemSize.height + ((/** @type {?} */ (this._offsetBottom))) - targetInnerHeight && offsetMode.bottom) { /** @type {?} */ const targetBottomOffet = targetNode === window ? 0 : window.innerHeight - targetRect.bottom; /** @type {?} */ const width = elemOffset.width; this.setAffixStyle(e, { position: 'fixed', bottom: targetBottomOffet + ((/** @type {?} */ (this._offsetBottom))), left: targetRect.left + elemOffset.left, width }); this.setPlaceholderStyle({ width, height: elemOffset.height }); } else { if (e.type === 'resize' && this.affixStyle && this.affixStyle.position === 'fixed' && this.placeholderNode.offsetWidth) { this.setAffixStyle(e, Object.assign({}, this.affixStyle, { width: this.placeholderNode.offsetWidth })); } else { this.setAffixStyle(e); } this.setPlaceholderStyle(); } if (e.type === 'resize') { this.syncPlaceholderStyle(e); } } } NzAffixComponent.decorators = [ { type: Component, args: [{ selector: 'nz-affix', exportAs: 'nzAffix', template: "<div #fixedEl>\n <ng-content></ng-content>\n</div>", changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, styles: [` nz-affix { display: block; } `] }] } ]; /** @nocollapse */ NzAffixComponent.ctorParameters = () => [ { type: ElementRef }, { type: NzScrollService }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }, { type: Platform } ]; NzAffixComponent.propDecorators = { nzTarget: [{ type: Input }], nzOffsetTop: [{ type: Input }], nzOffsetBottom: [{ type: Input }], nzChange: [{ type: Output }], fixedEl: [{ type: ViewChild, args: ['fixedEl',] }] }; __decorate([ throttleByAnimationFrameDecorator(), __metadata("design:type", Function), __metadata("design:paramtypes", [Event]), __metadata("design:returntype", void 0) ], NzAffixComponent.prototype, "updatePosition", null); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NzAffixModule { } NzAffixModule.decorators = [ { type: NgModule, args: [{ declarations: [NzAffixComponent], exports: [NzAffixComponent], imports: [CommonModule], providers: [SCROLL_SERVICE_PROVIDER] },] } ]; /** * @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 { NzAffixComponent, NzAffixModule }; //# sourceMappingURL=ng-zorro-antd-affix.js.map