var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
import * as PropTypes from "prop-types";
import * as React from "react";
import * as _ from "lodash";
import * as classnames from "classnames";
import { TransitionGroup, CSSTransition } from "react-transition-group";
import * as RootCloseWrapper from "react-overlays/lib/RootCloseWrapper";
import MorePropTypes from "../utils/MorePropTypes";
import { NavLink } from "./NavLink";
import { NavGroup } from "./NavGroup";
import "./LeftNav.less";
var propTypes = {
    children: MorePropTypes.oneOrManyOf(PropTypes.oneOfType([
        MorePropTypes.instanceOfComponent(NavLink),
        MorePropTypes.instanceOfComponent(NavGroup),
    ])),
    className: PropTypes.string,
    closeSubNavOnBlur: PropTypes.bool,
    collapseOnSubNavOpen: PropTypes.bool,
    collapsed: PropTypes.bool,
    narrow: PropTypes.bool,
    withActiveNavGroups: PropTypes.bool,
    withTooltips: PropTypes.bool,
};
export var cssClass = {
    COLLAPSED: "LeftNav--collapsed",
    CONTAINER: "LeftNav",
    NARROW: "LeftNav--narrow",
    SUBNAV_CONTENT_ANIM: "LeftNav--subnav--content--anim",
    SUBNAV_CONTENT: "LeftNav--subnav--content",
    SUBNAV_OPEN: "LeftNav--subnav--open",
    SUBNAV: "LeftNav--subnav",
    TOPNAV_COLLAPSED: "LeftNav--topnav--collapsed",
    TOPNAV: "LeftNav--topnav",
    WITH_SUBNAV_OPEN: "LeftNav--withSubnavOpen",
};
/** NOTE: Corresponds to the `@timingSlowly` LESS constant in src/less/animations.less. */
var WIDTH_TRANSITION_DURATION_MS = 400;
var LeftNav = /** @class */ (function (_super) {
    __extends(LeftNav, _super);
    function LeftNav(props) {
        var _this = _super.call(this, props) || this;
        // If a NavLink in a NavGroup is marked as selected on initialization, we
        // should open the drawer to show it. Otherwise, don't start with the drawer open.
        var selectedNavGroup = _.find(_this._getNonEmptyChildren(props.children), function (child) {
            return child.type === NavGroup &&
                _this._getNonEmptyChildren(child.props.children).some(function (navLink) { return navLink.props.selected; });
        });
        _this.state = { openNavGroup: selectedNavGroup ? selectedNavGroup.props.id : null };
        return _this;
    }
    LeftNav.prototype._getNonEmptyChildren = function (children) {
        return _.compact(React.Children.toArray(children));
    };
    LeftNav.prototype.render = function () {
        var _this = this;
        var _a = this.props, children = _a.children, className = _a.className, collapseOnSubNavOpen = _a.collapseOnSubNavOpen, collapsed = _a.collapsed, narrow = _a.narrow, withActiveNavGroups = _a.withActiveNavGroups, withTooltips = _a.withTooltips;
        var openNavGroup = this.state.openNavGroup;
        var _collapsed = collapsed || (collapseOnSubNavOpen && !!openNavGroup);
        // Clone all of the children so that we can attach our own click handlers
        var navItems = this._getNonEmptyChildren(children).map(function (child) {
            // Configure top level NavLinks to close any open NavGroup on click
            if (child.type === NavLink) {
                return React.cloneElement(child, {
                    _collapsed: _collapsed,
                    _withTooltips: withTooltips,
                    onClick: function () {
                        _this.setState({ openNavGroup: null });
                        if (child.props.onClick) {
                            child.props.onClick();
                        }
                    },
                });
            }
            // Configure NavGroups to open/close themselves on click
            if (child.type === NavGroup) {
                var open_1 = child.props.id === openNavGroup;
                return React.cloneElement(child, {
                    _collapsed: _collapsed,
                    _open: open_1,
                    _withActiveNavGroups: withActiveNavGroups,
                    _withTooltips: withTooltips,
                    _onClick: function () { return _this.setState({ openNavGroup: open_1 ? null : child.props.id }); },
                });
            }
            return null; // Should never get here thanks to PropType validation
        });
        // Find the open NavGroup so that we can render its children NavLinks in the drawer
        var openChild = _.find(this._getNonEmptyChildren(navItems), function (item) { return item.props._open; });
        return (React.createElement(RootCloseWrapper, { onRootClose: function () { return _this._onRootClose(); } },
            React.createElement("nav", { className: classnames(cssClass.CONTAINER, _collapsed && cssClass.COLLAPSED, narrow && cssClass.NARROW, openChild && cssClass.WITH_SUBNAV_OPEN, className) },
                React.createElement("div", { className: classnames(cssClass.TOPNAV, _collapsed && cssClass.TOPNAV_COLLAPSED) }, navItems),
                React.createElement(TransitionGroup, { className: classnames(cssClass.SUBNAV, openChild && cssClass.SUBNAV_OPEN), component: "div", transitionName: cssClass.SUBNAV_CONTENT_ANIM }, openChild && (React.createElement("div", { className: cssClass.SUBNAV_CONTENT }, React.Children.map(openChild.props.children, function (child) {
                    // ^ cannot use normal array map, because open.props.children may be an array or a single react element
                    return (React.createElement(CSSTransition, { className: cssClass.SUBNAV_CONTENT_ANIM, timeout: {
                            enter: WIDTH_TRANSITION_DURATION_MS,
                            exit: WIDTH_TRANSITION_DURATION_MS,
                        } }, child));
                })))))));
    };
    LeftNav.prototype._onRootClose = function () {
        var closeSubNavOnBlur = this.props.closeSubNavOnBlur;
        if (!closeSubNavOnBlur) {
            return;
        }
        this.setState({ openNavGroup: null });
    };
    LeftNav.propTypes = propTypes;
    LeftNav.NavLink = NavLink;
    LeftNav.NavGroup = NavGroup;
    return LeftNav;
}(React.PureComponent));
export { LeftNav };
