import * as tslib_1 from "tslib";
import * as React from 'react';
import { IconButton } from '../../Button';
import { Layer } from '../../Layer';
import { Overlay } from '../../Overlay';
import { Popup } from '../../Popup';
import { getTheme, IconFontSizes } from '../../Styling';
import { allowScrollOnElement, BaseComponent, classNamesFunction, divProperties, elementContains, getId, getNativeProps, getRTL } from '../../Utilities';
import { FocusTrapZone } from '../FocusTrapZone/index';
import { PanelType } from './Panel.types';
var getClassNames = classNamesFunction();
var PanelBase = /** @class */ (function (_super) {
    tslib_1.__extends(PanelBase, _super);
    function PanelBase(props) {
        var _this = _super.call(this, props) || this;
        _this._panel = React.createRef();
        _this.dismiss = function (ev) {
            if (_this.state.isOpen) {
                if (_this.props.onDismiss) {
                    _this.props.onDismiss(ev);
                }
                if (!ev || (ev && !ev.defaultPrevented)) {
                    _this.setState({
                        isOpen: false,
                        isAnimating: true
                    }, function () {
                        _this._async.setTimeout(_this._onTransitionComplete, 200);
                    });
                }
            }
        };
        // Allow the user to scroll within the panel but not on the body
        _this._allowScrollOnPanel = function (elt) {
            if (elt) {
                allowScrollOnElement(elt, _this._events);
            }
            else {
                _this._events.off(_this._scrollableContent);
            }
            _this._scrollableContent = elt;
        };
        _this._onRenderNavigation = function (props) {
            var closeButtonAriaLabel = props.closeButtonAriaLabel, hasCloseButton = props.hasCloseButton;
            var theme = getTheme();
            if (hasCloseButton) {
                // TODO -Issue #5689: Comment in once Button is converted to mergeStyles
                // const iconButtonStyles = this._classNames.subComponentStyles
                // ? (this._classNames.subComponentStyles.iconButton as IStyleFunctionOrObject<IButtonStyleProps, IButtonStyles>)
                // : undefined;
                return (React.createElement("div", { className: _this._classNames.navigation },
                    React.createElement(IconButton
                    // TODO -Issue #5689: Comment in once Button is converted to mergeStyles
                    // className={iconButtonStyles}
                    , { 
                        // TODO -Issue #5689: Comment in once Button is converted to mergeStyles
                        // className={iconButtonStyles}
                        styles: {
                            root: {
                                height: 'auto',
                                width: '44px',
                                color: theme.palette.neutralSecondary,
                                fontSize: IconFontSizes.large
                            },
                            rootHovered: {
                                color: theme.palette.neutralPrimary
                            }
                        }, className: _this._classNames.closeButton, onClick: _this._onPanelClick, ariaLabel: closeButtonAriaLabel, "data-is-visible": true, iconProps: { iconName: 'Cancel' } })));
            }
            return null;
        };
        _this._onRenderHeader = function (props, defaultRender, headerTextId) {
            var headerText = props.headerText;
            if (headerText) {
                return (React.createElement("div", { className: _this._classNames.header },
                    React.createElement("p", { className: _this._classNames.headerText, id: headerTextId, role: "heading", "aria-level": 2 }, headerText)));
            }
            return null;
        };
        _this._onRenderBody = function (props) {
            return React.createElement("div", { className: _this._classNames.content }, props.children);
        };
        _this._onRenderFooter = function (props) {
            var _a = _this.props.onRenderFooterContent, onRenderFooterContent = _a === void 0 ? null : _a;
            if (onRenderFooterContent) {
                return (React.createElement("div", { className: _this._classNames.footer },
                    React.createElement("div", { className: _this._classNames.footerInner }, onRenderFooterContent())));
            }
            return null;
        };
        _this._onPanelClick = function (ev) {
            _this.dismiss(ev);
        };
        _this._onTransitionComplete = function () {
            _this._updateFooterPosition();
            _this.setState({
                isAnimating: false
            });
            if (!_this.state.isOpen && _this.props.onDismissed) {
                _this.props.onDismissed();
            }
        };
        _this._warnDeprecations({
            ignoreExternalFocusing: 'focusTrapZoneProps',
            forceFocusInsideTrap: 'focusTrapZoneProps',
            firstFocusableSelector: 'focusTrapZoneProps'
        });
        _this.state = {
            isFooterSticky: false,
            isOpen: false,
            isAnimating: false,
            id: getId('Panel')
        };
        return _this;
    }
    PanelBase.prototype.componentDidMount = function () {
        this._events.on(window, 'resize', this._updateFooterPosition);
        if (this._shouldListenForOuterClick(this.props)) {
            this._events.on(document.body, 'mousedown', this._dismissOnOuterClick, true);
        }
        if (this.props.isOpen) {
            this.open();
        }
    };
    PanelBase.prototype.componentDidUpdate = function (previousProps) {
        var shouldListenOnOuterClick = this._shouldListenForOuterClick(this.props);
        var previousShouldListenOnOuterClick = this._shouldListenForOuterClick(previousProps);
        if (shouldListenOnOuterClick && !previousShouldListenOnOuterClick) {
            this._events.on(document.body, 'mousedown', this._dismissOnOuterClick, true);
        }
        else if (!shouldListenOnOuterClick && previousShouldListenOnOuterClick) {
            this._events.off(document.body, 'mousedown', this._dismissOnOuterClick, true);
        }
    };
    PanelBase.prototype.componentWillReceiveProps = function (newProps) {
        if (newProps.isOpen !== this.state.isOpen) {
            if (newProps.isOpen) {
                this.open();
            }
            else {
                this.dismiss();
            }
        }
    };
    PanelBase.prototype.render = function () {
        var _a = this.props, _b = _a.className, className = _b === void 0 ? '' : _b, elementToFocusOnDismiss = _a.elementToFocusOnDismiss, firstFocusableSelector = _a.firstFocusableSelector, focusTrapZoneProps = _a.focusTrapZoneProps, forceFocusInsideTrap = _a.forceFocusInsideTrap, hasCloseButton = _a.hasCloseButton, headerText = _a.headerText, _c = _a.headerClassName, headerClassName = _c === void 0 ? '' : _c, ignoreExternalFocusing = _a.ignoreExternalFocusing, isBlocking = _a.isBlocking, isFooterAtBottom = _a.isFooterAtBottom, isLightDismiss = _a.isLightDismiss, isHiddenOnDismiss = _a.isHiddenOnDismiss, layerProps = _a.layerProps, type = _a.type, styles = _a.styles, theme = _a.theme, customWidth = _a.customWidth, _d = _a.onLightDismissClick, onLightDismissClick = _d === void 0 ? this._onPanelClick : _d, _e = _a.onRenderNavigation, onRenderNavigation = _e === void 0 ? this._onRenderNavigation : _e, _f = _a.onRenderHeader, onRenderHeader = _f === void 0 ? this._onRenderHeader : _f, _g = _a.onRenderBody, onRenderBody = _g === void 0 ? this._onRenderBody : _g, _h = _a.onRenderFooter, onRenderFooter = _h === void 0 ? this._onRenderFooter : _h;
        var _j = this.state, isFooterSticky = _j.isFooterSticky, isOpen = _j.isOpen, isAnimating = _j.isAnimating, id = _j.id;
        var isLeft = type === PanelType.smallFixedNear ? true : false;
        var isRTL = getRTL();
        var isOnRightSide = isRTL ? isLeft : !isLeft;
        var headerTextId = headerText && id + '-headerText';
        var customWidthStyles = type === PanelType.custom ? { width: customWidth } : {};
        var nativeProps = getNativeProps(this.props, divProperties);
        if (!isOpen && !isAnimating && !isHiddenOnDismiss) {
            return null;
        }
        this._classNames = getClassNames(styles, {
            theme: theme,
            className: className,
            focusTrapZoneClassName: focusTrapZoneProps ? focusTrapZoneProps.className : undefined,
            hasCloseButton: hasCloseButton,
            headerClassName: headerClassName,
            isAnimating: this.state.isAnimating,
            isFooterAtBottom: isFooterAtBottom,
            isFooterSticky: isFooterSticky,
            isOnRightSide: isOnRightSide,
            isOpen: this.state.isOpen,
            isHiddenOnDismiss: isHiddenOnDismiss,
            type: type
        });
        var _classNames = this._classNames;
        var overlay;
        if (isBlocking && isOpen) {
            overlay = React.createElement(Overlay, { className: _classNames.overlay, isDarkThemed: false, onClick: isLightDismiss ? onLightDismissClick : undefined });
        }
        var header = onRenderHeader(this.props, this._onRenderHeader, headerTextId);
        return (React.createElement(Layer, tslib_1.__assign({}, layerProps),
            React.createElement(Popup, { role: "dialog", "aria-modal": "true", ariaLabelledBy: header ? headerTextId : undefined, onDismiss: this.dismiss, className: _classNames.hiddenPanel },
                React.createElement("div", tslib_1.__assign({ "aria-hidden": !isOpen && isAnimating }, nativeProps, { ref: this._panel, className: _classNames.root }),
                    overlay,
                    React.createElement(FocusTrapZone, tslib_1.__assign({ ignoreExternalFocusing: ignoreExternalFocusing, forceFocusInsideTrap: isHiddenOnDismiss && !isOpen ? false : forceFocusInsideTrap, firstFocusableSelector: firstFocusableSelector, isClickableOutsideFocusTrap: true }, focusTrapZoneProps, { className: _classNames.main, style: customWidthStyles, elementToFocusOnDismiss: elementToFocusOnDismiss }),
                        React.createElement("div", { className: _classNames.commands, "data-is-visible": true }, onRenderNavigation(this.props, this._onRenderNavigation)),
                        React.createElement("div", { className: _classNames.contentInner },
                            header,
                            React.createElement("div", { ref: this._allowScrollOnPanel, className: _classNames.scrollableContent, "data-is-scrollable": true }, onRenderBody(this.props, this._onRenderBody)),
                            onRenderFooter(this.props, this._onRenderFooter)))))));
    };
    PanelBase.prototype.open = function () {
        var _this = this;
        if (!this.state.isOpen) {
            this.setState({
                isOpen: true,
                isAnimating: true
            }, function () {
                _this._async.setTimeout(_this._onTransitionComplete, 200);
            });
        }
    };
    PanelBase.prototype._shouldListenForOuterClick = function (props) {
        return !!props.isBlocking && !!props.isOpen;
    };
    PanelBase.prototype._updateFooterPosition = function () {
        var scrollableContent = this._scrollableContent;
        if (scrollableContent) {
            var height = scrollableContent.clientHeight;
            var innerHeight_1 = scrollableContent.scrollHeight;
            this.setState({
                isFooterSticky: height < innerHeight_1 ? true : false
            });
        }
    };
    PanelBase.prototype._dismissOnOuterClick = function (ev) {
        var panel = this._panel.current;
        if (this.state.isOpen && panel) {
            if (!elementContains(panel, ev.target)) {
                if (this.props.onOuterClick) {
                    this.props.onOuterClick();
                    ev.preventDefault();
                }
                else {
                    this.dismiss();
                }
            }
        }
    };
    PanelBase.defaultProps = {
        isHiddenOnDismiss: false,
        isOpen: false,
        isBlocking: true,
        hasCloseButton: true,
        type: PanelType.smallFixedFar
    };
    return PanelBase;
}(BaseComponent));
export { PanelBase };
//# sourceMappingURL=Panel.base.js.map