import * as tslib_1 from "tslib";
import React, { useState, useEffect, useRef } from 'react';
import classnames from 'classnames';
var defaultProps = {
    prefixCls: 'ty-affix',
    container: function () { return window; },
};
var getScroll = function (node, isVertical) {
    if (typeof window === 'undefined') {
        return 0;
    }
    var windowProp = isVertical ? 'pageYOffset' : 'pageXOffset';
    var elementProp = isVertical ? 'scrollTop' : 'scrollLeft';
    return node === window ? node[windowProp] : node[elementProp];
};
var getRect = function (node) {
    if (node === void 0) { node = window; }
    return node !== window
        ? node.getBoundingClientRect()
        : { top: 0, left: 0, bottom: 0 };
};
var getNodeHeight = function (node) {
    if (!node) {
        return 0;
    }
    if (node === window) {
        return window.innerHeight;
    }
    return node.clientHeight;
};
var affixMode = {
    top: false,
    bottom: false,
    offset: 0,
};
var lastAffixed = null;
var Affix = function (props) {
    var container = props.container, relative = props.relative, offsetTop = props.offsetTop, offsetBottom = props.offsetBottom, onChange = props.onChange, prefixCls = props.prefixCls, className = props.className, style = props.style, children = props.children;
    var _a = useState({}), placeholderNodeStyle = _a[0], setPlaceholderNodeStyle = _a[1];
    var _b = useState({}), affixNodeStyle = _b[0], setAffixNodeStyle = _b[1];
    var placeholderEl = useRef(null);
    var affixEl = useRef(null);
    var cls = classnames(prefixCls, className);
    var getAffixMode = function () {
        if (typeof offsetTop !== 'number' && typeof offsetBottom !== 'number') {
            affixMode.top = true;
        }
        else if (typeof offsetTop === 'number') {
            affixMode.top = true;
            affixMode.bottom = false;
            affixMode.offset = offsetTop;
        }
        else if (typeof offsetBottom === 'number') {
            affixMode.bottom = true;
            affixMode.top = false;
            affixMode.offset = offsetBottom;
        }
    };
    var getOffset = function (affixNode, affixContainer) {
        var affixRect = affixNode.getBoundingClientRect();
        var containerRect = getRect(affixContainer);
        var containerScrollTop = getScroll(affixContainer, true);
        var containerScrollLeft = getScroll(affixContainer, false);
        return {
            top: affixRect.top - containerRect.top + containerScrollTop,
            left: affixRect.left - containerRect.left + containerScrollLeft,
            width: affixRect.width,
            height: affixRect.height,
        };
    };
    var updateNodePosition = function () {
        var affixContainer = container();
        if (!affixContainer || !placeholderEl.current || !affixEl.current) {
            return false;
        }
        var containerScrollTop = getScroll(affixContainer, true);
        var affixOffset = getOffset(placeholderEl.current, affixContainer);
        var containerHeight = getNodeHeight(affixContainer);
        var affixHeight = placeholderEl.current.offsetHeight;
        var containerRect = getRect(affixContainer);
        var affixChildHeight = affixEl.current.offsetHeight;
        var affixStyle = {
            width: affixOffset.width,
        };
        var containerStyle = {
            width: affixOffset.width,
            height: affixChildHeight,
        };
        if (affixMode.top && containerScrollTop > affixOffset.top - affixMode.offset) {
            if (relative) {
                affixStyle.position = 'absolute';
                affixStyle.zIndex = 1;
                affixStyle.top = containerScrollTop - (affixOffset.top - affixMode.offset);
                containerStyle.position = 'relative';
            }
            else {
                affixStyle.position = 'fixed';
                affixStyle.zIndex = 1;
                affixStyle.top = affixMode.offset + containerRect.top;
            }
            setAffixStyle(affixStyle, true, true);
            setContainerStyle(containerStyle);
        }
        else if (affixMode.bottom && containerScrollTop
            < affixOffset.top + affixHeight + affixMode.offset - containerHeight) {
            affixStyle.height = affixHeight;
            if (relative) {
                affixStyle.zIndex = 1;
                affixStyle.position = 'absolute';
                affixStyle.top = containerScrollTop
                    - (affixOffset.top + affixHeight + affixMode.offset - containerHeight);
                containerStyle.position = 'relative';
            }
            else {
                affixStyle.zIndex = 1;
                affixStyle.position = 'fixed';
                affixStyle.bottom = affixMode.offset;
            }
            setAffixStyle(affixStyle, true, false);
            setContainerStyle(containerStyle);
        }
        else {
            setAffixStyle({}, false, undefined);
            setContainerStyle({});
        }
    };
    var setAffixStyle = function (affixStyle, affixed, isTop) {
        if (affixed === void 0) { affixed = false; }
        if (isTop === void 0) { isTop = undefined; }
        setAffixNodeStyle(affixStyle);
        if (lastAffixed !== affixed) {
            lastAffixed = affixed;
            onChange && onChange(affixed, isTop);
        }
    };
    var setContainerStyle = function (containerStyle) {
        setPlaceholderNodeStyle(containerStyle);
    };
    useEffect(function () {
        getAffixMode();
        updateNodePosition();
        container().addEventListener('scroll', updateNodePosition);
        container().addEventListener('resize', updateNodePosition);
        return function () {
            container().removeEventListener('scroll', updateNodePosition);
            container().removeEventListener('resize', updateNodePosition);
        };
    }, []);
    return (React.createElement("div", { ref: placeholderEl, style: tslib_1.__assign({}, placeholderNodeStyle, style) },
        React.createElement("div", { ref: affixEl, className: cls, style: affixNodeStyle }, children)));
};
Affix.defaultProps = defaultProps;
export default Affix;
//# sourceMappingURL=index.js.map