"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

var _typeof = require("@babel/runtime/helpers/typeof");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.POSITIONS = void 0;

var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));

var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));

var _uiUtilities = _interopRequireDefault(require("@teamleader/ui-utilities"));

var _classnames = _interopRequireDefault(require("classnames"));

var _lodash = _interopRequireDefault(require("lodash.omit"));

var _react = _interopRequireWildcard(require("react"));

var _reactDom = require("react-dom");

var _Transition = _interopRequireDefault(require("react-transition-group/Transition"));

var _box = _interopRequireDefault(require("../box"));

var _DocumentObjectProvider = _interopRequireWildcard(require("../hoc/DocumentObjectProvider"));

var _utils = require("../utils/utils");

var _theme = _interopRequireDefault(require("./theme.css"));

var _excluded = ["children", "className", "documentObject", "tooltip", "tooltipColor", "onTooltipEntered", "tooltipHideOnClick", "tooltipIcon", "tooltipPosition", "tooltipShowOnClick", "tooltipSize", "tooltipShowDelay", "zIndex", "onClick", "onMouseEnter", "onMouseLeave", "tooltipActive", "ComposedComponent"];

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

var POSITIONS = {
  BOTTOM: 'bottom',
  HORIZONTAL: 'horizontal',
  LEFT: 'left',
  RIGHT: 'right',
  TOP: 'top',
  VERTICAL: 'vertical'
};
exports.POSITIONS = POSITIONS;
var SIZE_MAP = {
  large: {
    padding: 4
  },
  medium: {
    padding: 3
  },
  small: {
    paddingHorizontal: 3,
    paddingVertical: 2
  }
};

var TooltippedComponent = function TooltippedComponent(_ref) {
  var children = _ref.children,
      className = _ref.className,
      documentObject = _ref.documentObject,
      tooltip = _ref.tooltip,
      _ref$tooltipColor = _ref.tooltipColor,
      tooltipColor = _ref$tooltipColor === void 0 ? 'white' : _ref$tooltipColor,
      onTooltipEntered = _ref.onTooltipEntered,
      _ref$tooltipHideOnCli = _ref.tooltipHideOnClick,
      tooltipHideOnClick = _ref$tooltipHideOnCli === void 0 ? true : _ref$tooltipHideOnCli,
      _ref$tooltipIcon = _ref.tooltipIcon,
      tooltipIcon = _ref$tooltipIcon === void 0 ? null : _ref$tooltipIcon,
      _ref$tooltipPosition = _ref.tooltipPosition,
      tooltipPosition = _ref$tooltipPosition === void 0 ? 'top' : _ref$tooltipPosition,
      _ref$tooltipShowOnCli = _ref.tooltipShowOnClick,
      tooltipShowOnClick = _ref$tooltipShowOnCli === void 0 ? false : _ref$tooltipShowOnCli,
      _ref$tooltipSize = _ref.tooltipSize,
      tooltipSize = _ref$tooltipSize === void 0 ? 'medium' : _ref$tooltipSize,
      _ref$tooltipShowDelay = _ref.tooltipShowDelay,
      tooltipShowDelay = _ref$tooltipShowDelay === void 0 ? 100 : _ref$tooltipShowDelay,
      _ref$zIndex = _ref.zIndex,
      zIndex = _ref$zIndex === void 0 ? 700 : _ref$zIndex,
      onClick = _ref.onClick,
      onMouseEnter = _ref.onMouseEnter,
      onMouseLeave = _ref.onMouseLeave,
      _ref$tooltipActive = _ref.tooltipActive,
      tooltipActive = _ref$tooltipActive === void 0 ? null : _ref$tooltipActive,
      ComposedComponent = _ref.ComposedComponent,
      other = (0, _objectWithoutProperties2.default)(_ref, _excluded);
  var tooltipRoot = (0, _react.useMemo)(function () {
    return documentObject.createElement('div');
  }, []);
  var ref = (0, _react.useRef)(null);

  var _useState = (0, _react.useState)(false),
      _useState2 = (0, _slicedToArray2.default)(_useState, 2),
      active = _useState2[0],
      setActive = _useState2[1];

  var _useState3 = (0, _react.useState)({
    position: tooltipPosition,
    top: 'auto',
    left: 'auto'
  }),
      _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
      position = _useState4[0],
      setPosition = _useState4[1];

  var activate = function activate(position) {
    documentObject.body.appendChild(tooltipRoot);
    setActive(true);
    setPosition({
      position: position.position,
      top: position.top,
      left: position.left
    });
  };

  var getPosition = function getPosition(element) {
    if (tooltipPosition === POSITIONS.HORIZONTAL) {
      var origin = element.getBoundingClientRect();

      var _getViewport = (0, _utils.getViewport)(),
          windowWidth = _getViewport.width;

      var toRight = origin.left < windowWidth / 2 - origin.width / 2;
      return toRight ? POSITIONS.RIGHT : POSITIONS.LEFT;
    } else if (tooltipPosition === POSITIONS.VERTICAL) {
      var _origin = element.getBoundingClientRect();

      var _getViewport2 = (0, _utils.getViewport)(),
          windowHeight = _getViewport2.height;

      var toBottom = _origin.top < windowHeight / 2 - _origin.height / 2;
      return toBottom ? POSITIONS.BOTTOM : POSITIONS.TOP;
    }

    return tooltipPosition;
  };

  var calculatePosition = function calculatePosition(element) {
    if (typeof (element === null || element === void 0 ? void 0 : element.getBoundingClientRect) !== 'function') {
      return {
        top: 0,
        left: 0,
        position: tooltipPosition
      };
    }

    var _element$getBoundingC = element.getBoundingClientRect(),
        top = _element$getBoundingC.top,
        left = _element$getBoundingC.left,
        height = _element$getBoundingC.height,
        width = _element$getBoundingC.width;

    var position = getPosition(element);
    var xOffset = window.scrollX || window.pageXOffset;
    var yOffset = window.scrollY || window.pageYOffset;

    if (position === POSITIONS.BOTTOM) {
      return {
        top: top + height + yOffset,
        left: left + width / 2 + xOffset,
        position: position
      };
    } else if (position === POSITIONS.TOP) {
      return {
        top: top + yOffset,
        left: left + width / 2 + xOffset,
        position: position
      };
    } else if (position === POSITIONS.LEFT) {
      return {
        top: top + height / 2 + yOffset,
        left: left + xOffset,
        position: position
      };
    } else if (position === POSITIONS.RIGHT) {
      return {
        top: top + height / 2 + yOffset,
        left: left + width + xOffset,
        position: position
      };
    }

    return {
      top: 0,
      left: 0,
      position: tooltipPosition
    };
  };

  var handleMouseEnter = function handleMouseEnter(event) {
    activate(calculatePosition(event.currentTarget));

    if (onMouseEnter) {
      onMouseEnter(event);
    }
  };

  var handleMouseLeave = function handleMouseLeave(event) {
    setActive(false);

    if (onMouseLeave) {
      onMouseLeave(event);
    }
  };

  var handleClick = function handleClick(event) {
    if (tooltipHideOnClick && active) {
      setActive(false);
    }

    if (tooltipShowOnClick && !active) {
      activate(calculatePosition(event.currentTarget));
    }

    if (onClick) {
      onClick(event);
    }
  };

  var handleTransitionExited = function handleTransitionExited() {
    documentObject.body.removeChild(tooltipRoot);
  };

  var handleTransitionEntered = function handleTransitionEntered() {
    onTooltipEntered && onTooltipEntered();
  };

  (0, _react.useEffect)(function () {
    if (tooltipActive) {
      activate(calculatePosition(ref.current));
    }

    if (tooltipActive) {
      if (tooltipActive && !active) {
        activate(calculatePosition(ref.current));
      }

      if (!tooltipActive && active) {
        setActive(false);
      }
    }
  }, [tooltipActive, active]);
  var rest = (0, _lodash.default)(other, ['onTooltipEntered', 'tooltipHideOnClick', 'tooltipPosition', 'tooltipShowOnClick', 'tooltipShowDelay', 'documentObject']);

  var childProps = _objectSpread(_objectSpread({}, rest), {}, {
    className: className,
    onClick: onClick,
    onMouseEnter: onMouseEnter,
    onMouseLeave: onMouseLeave,
    ref: ref
  });

  if (tooltipActive === null) {
    childProps = _objectSpread(_objectSpread({}, childProps), {}, {
      onClick: handleClick,
      onMouseEnter: handleMouseEnter,
      onMouseLeave: handleMouseLeave
    });
  }

  return /*#__PURE__*/_react.default.createElement(ComposedComponent, childProps, children, /*#__PURE__*/(0, _reactDom.createPortal)( /*#__PURE__*/_react.default.createElement(_Transition.default, {
    in: active,
    onExited: handleTransitionExited,
    onEntered: handleTransitionEntered,
    timeout: {
      enter: tooltipShowDelay,
      exit: 1000
    }
  }, function (state) {
    var _cx;

    var classNames = (0, _classnames.default)(_uiUtilities.default['box-shadow-200'], _theme.default['tooltip'], _theme.default[tooltipColor], _theme.default[tooltipSize], (_cx = {}, (0, _defineProperty2.default)(_cx, _theme.default['is-entering'], state === 'entering'), (0, _defineProperty2.default)(_cx, _theme.default['is-entered'], state === 'entered'), (0, _defineProperty2.default)(_cx, _theme.default['is-exiting'], state === 'exiting'), (0, _defineProperty2.default)(_cx, _theme.default[position.position], _theme.default[position.position]), _cx));
    return /*#__PURE__*/_react.default.createElement("div", {
      className: classNames,
      "data-teamleader-ui": "tooltip",
      style: {
        top: position.top,
        left: position.left,
        zIndex: zIndex
      }
    }, /*#__PURE__*/_react.default.createElement(_box.default, (0, _extends2.default)({
      className: _theme.default['inner']
    }, SIZE_MAP[tooltipSize]), tooltipIcon && /*#__PURE__*/_react.default.createElement("div", {
      className: _theme.default['icon']
    }, tooltipIcon), /*#__PURE__*/_react.default.createElement("div", {
      className: _theme.default['text']
    }, tooltip)));
  }), tooltipRoot));
};

function Tooltip(ComposedComponent) {
  return (0, _DocumentObjectProvider.default)(function (props) {
    return /*#__PURE__*/_react.default.createElement(_DocumentObjectProvider.Context.Consumer, null, function (documentObject) {
      return /*#__PURE__*/_react.default.createElement(TooltippedComponent, (0, _extends2.default)({}, props, {
        tooltip: props.tooltip,
        documentObject: documentObject,
        ComposedComponent: ComposedComponent
      }), props.children);
    });
  });
}

var _default = Tooltip;
exports.default = _default;