(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/cdk/platform'), require('@angular/common'), require('@angular/core'), require('ng-zorro-antd/core')) :
    typeof define === 'function' && define.amd ? define('ng-zorro-antd/affix', ['exports', '@angular/cdk/platform', '@angular/common', '@angular/core', 'ng-zorro-antd/core'], factory) :
    (global = global || self, factory((global['ng-zorro-antd'] = global['ng-zorro-antd'] || {}, global['ng-zorro-antd'].affix = {}), global.ng.cdk.platform, global.ng.common, global.ng.core, global['ng-zorro-antd'].core));
}(this, function (exports, platform, common, core, core$1) { 'use strict';

    /*! *****************************************************************************
    Copyright (c) Microsoft Corporation. All rights reserved.
    Licensed under the Apache License, Version 2.0 (the "License"); you may not use
    this file except in compliance with the License. You may obtain a copy of the
    License at http://www.apache.org/licenses/LICENSE-2.0

    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
    MERCHANTABLITY OR NON-INFRINGEMENT.

    See the Apache Version 2.0 License for specific language governing permissions
    and limitations under the License.
    ***************************************************************************** */

    var __assign = function() {
        __assign = Object.assign || function __assign(t) {
            for (var s, i = 1, n = arguments.length; i < n; i++) {
                s = arguments[i];
                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
            }
            return t;
        };
        return __assign.apply(this, arguments);
    };

    function __decorate(decorators, target, key, desc) {
        var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
        if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
        else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
        return c > 3 && r && Object.defineProperty(target, key, r), r;
    }

    function __metadata(metadataKey, metadataValue) {
        if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
    }

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

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
     */
    var NzAffixModule = /** @class */ (function () {
        function NzAffixModule() {
        }
        NzAffixModule.decorators = [
            { type: core.NgModule, args: [{
                        declarations: [NzAffixComponent],
                        exports: [NzAffixComponent],
                        imports: [common.CommonModule],
                        providers: [core$1.SCROLL_SERVICE_PROVIDER]
                    },] }
        ];
        return NzAffixModule;
    }());

    exports.NzAffixComponent = NzAffixComponent;
    exports.NzAffixModule = NzAffixModule;

    Object.defineProperty(exports, '__esModule', { value: true });

}));
//# sourceMappingURL=ng-zorro-antd-affix.umd.js.map
