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 __());
    };
})();
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(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);
};
import * as _ from "lodash";
import * as React from "react";
import * as BootstrapTooltip from "react-bootstrap/lib/Tooltip";
import * as Overlay from "react-bootstrap/lib/Overlay";
import * as RootCloseWrapper from "react-overlays/lib/RootCloseWrapper";
import * as classnames from "classnames";
import * as PropTypes from "prop-types";
import "./Tooltip.less";
var nextID = 0;
var ESC = 27;
var Align = {
    CENTER: "center",
    JUSTIFY: "justify",
    LEFT: "left",
    RIGHT: "right",
};
var Placement = {
    BOTTOM: "bottom",
    LEFT: "left",
    RIGHT: "right",
    TOP: "top",
};
var propTypes = {
    children: PropTypes.node.isRequired,
    content: PropTypes.node.isRequired,
    delayMs: PropTypes.number,
    delayHideMs: PropTypes.number,
    hide: PropTypes.bool,
    clickTrigger: PropTypes.bool,
    placement: PropTypes.oneOf(_.values(Placement)),
    textAlign: PropTypes.oneOf(_.values(Align)),
    className: PropTypes.string,
    tooltipClassName: PropTypes.string,
};
var defaultProps = {
    placement: "top",
    textAlign: "left",
};
export var cssClass = {
    CONTENT: "Tooltip--content",
    align: function (textAlign) { return "Tooltip--content--" + textAlign; },
};
/**
 * Standardized tooltip component with fade-in/out transition and customizable positioning.
 */
var Tooltip = /** @class */ (function (_super) {
    __extends(Tooltip, _super);
    function Tooltip(props) {
        var _this = _super.call(this, props) || this;
        _this.tooltipTarget = React.createRef();
        _this.state = {
            showTooltip: false,
        };
        // react-bootstrap Tooltips require an id. We simply autogenerate them with sequential numbers.
        _this.id = "Tooltip-" + Tooltip.nextID++;
        return _this;
    }
    Tooltip.prototype.render = function () {
        var _this = this;
        var _a = this.props, children = _a.children, className = _a.className, content = _a.content, delayMs = _a.delayMs, hide = _a.hide, clickTrigger = _a.clickTrigger, tooltipClassName = _a.tooltipClassName, placement = _a.placement, textAlign = _a.textAlign, delayHideMs = _a.delayHideMs;
        var handleShowTooltip = function () {
            if (hide)
                return;
            setTimeout(function () { return _this.setState({ showTooltip: true }); }, delayMs);
        };
        var handleHideTooltip = function () {
            if (hide)
                return;
            setTimeout(function () { return _this.setState({ showTooltip: false }); }, delayHideMs);
        };
        var handleMouseEnter = clickTrigger ? undefined : handleShowTooltip;
        var handleMouseLeave = clickTrigger ? undefined : handleHideTooltip;
        var handleOnClick = function () {
            if (!clickTrigger || hide) {
                // Nothing should happen on click if clickTrigger is not set or if the tooltip is disabled
                return;
            }
            if (_this.state.showTooltip) {
                handleHideTooltip();
            }
            else {
                handleShowTooltip();
            }
        };
        var handleEscape = function (event) {
            if (event.keyCode === ESC && _this.state.showTooltip) {
                handleHideTooltip();
                event.stopPropagation();
            }
        };
        var tooltip = (React.createElement(BootstrapTooltip, { id: this.id, className: tooltipClassName, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave },
            React.createElement("div", { className: classnames(cssClass.CONTENT, cssClass.align(textAlign), className) }, content)));
        var child = React.Children.only(children);
        return (React.createElement(RootCloseWrapper, { onRootClose: handleHideTooltip },
            React.createElement(React.Fragment, null,
                React.cloneElement(child, __assign({ ref: this.tooltipTarget, tabIndex: 0, onFocus: handleShowTooltip, onBlur: handleHideTooltip, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onMouseDown: handleOnClick, onKeyUp: function (event) { return handleEscape(event); } }, child.props)),
                React.createElement(Overlay, { target: this.tooltipTarget.current, show: this.state.showTooltip, placement: placement }, tooltip))));
    };
    Tooltip.nextID = nextID;
    Tooltip.Align = Align;
    Tooltip.Placement = Placement;
    Tooltip.propTypes = propTypes;
    Tooltip.defaultProps = defaultProps;
    return Tooltip;
}(React.Component));
export default Tooltip;
