"use strict";

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");

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

exports.__esModule = true;
exports.default = void 0;

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

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

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

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

var _propTypes = _interopRequireDefault(require("prop-types"));

var _kebabCase = _interopRequireDefault(require("lodash/kebabCase"));

var _Transition = _interopRequireDefault(require("../Animation/Transition"));

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

var defaultProps = {
  as: 'div',
  classPrefix: 'toast-container',
  placement: 'topCenter'
};

var useMessages = function useMessages() {
  var _useState = (0, _react.useState)([]),
      messages = _useState[0],
      setMessages = _useState[1];

  var getKey = (0, _react.useCallback)(function (key) {
    if (typeof key === 'undefined' && messages.length) {
      key = messages[messages.length - 1].key;
    }

    return key;
  }, [messages]);
  var push = (0, _react.useCallback)(function (message) {
    var key = (0, _utils.guid)();
    setMessages([].concat(messages, [{
      key: key,
      visible: true,
      node: message
    }]));
    return key;
  }, [messages]);
  var clear = (0, _react.useCallback)(function () {
    // Set all existing messages to be invisible.
    setMessages(messages.map(function (msg) {
      return (0, _extends2.default)({}, msg, {
        visible: false
      });
    })); // Remove all invisible messages after 400ms.
    // The delay removal here is to preserve the animation.

    setTimeout(function () {
      setMessages([]);
    }, 400);
  }, [messages]);
  var remove = (0, _react.useCallback)(function (key) {
    // Set the message of the specified key to invisible.
    setMessages(messages.map(function (n) {
      if (n.key === getKey(key)) {
        n.visible = false;
      }

      return n;
    })); // Remove invisible messages after 400ms.

    setTimeout(function () {
      setMessages(messages.filter(function (msg) {
        return msg.visible;
      }));
    }, 400);
  }, [messages, getKey]);
  return {
    messages: messages,
    push: push,
    clear: clear,
    remove: remove
  };
};

var ToastContainer = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
  var rootRef = (0, _react.useRef)();
  var Component = props.as,
      className = props.className,
      classPrefix = props.classPrefix,
      placement = props.placement,
      rest = (0, _objectWithoutPropertiesLoose2.default)(props, ["as", "className", "classPrefix", "placement"]);

  var _useClassNames = (0, _utils.useClassNames)(classPrefix),
      withClassPrefix = _useClassNames.withClassPrefix,
      merge = _useClassNames.merge,
      rootPrefix = _useClassNames.rootPrefix;

  var classes = merge(className, withClassPrefix((0, _kebabCase.default)(placement)));

  var _useMessages = useMessages(),
      push = _useMessages.push,
      clear = _useMessages.clear,
      remove = _useMessages.remove,
      messages = _useMessages.messages;

  (0, _react.useImperativeHandle)(ref, function () {
    return {
      root: rootRef.current,
      push: push,
      clear: clear,
      remove: remove
    };
  });
  var elements = messages.map(function (item) {
    return /*#__PURE__*/_react.default.createElement(_Transition.default, {
      key: item.key,
      in: item.visible,
      exitedClassName: rootPrefix('toast-fade-exited'),
      exitingClassName: rootPrefix('toast-fade-exiting'),
      enteringClassName: rootPrefix('toast-fade-entering'),
      enteredClassName: rootPrefix('toast-fade-entered'),
      timeout: 300
    }, function (transitionProps, ref) {
      var _item$node, _item$node$props, _item$node2, _item$node2$props;

      var transitionClassName = transitionProps.className,
          rest = (0, _objectWithoutPropertiesLoose2.default)(transitionProps, ["className"]);
      return /*#__PURE__*/_react.default.cloneElement(item.node, (0, _extends2.default)({}, rest, {
        ref: ref,
        // Remove the message after the specified time.
        onClose: (0, _utils.createChainedFunction)((_item$node = item.node) === null || _item$node === void 0 ? void 0 : (_item$node$props = _item$node.props) === null || _item$node$props === void 0 ? void 0 : _item$node$props.onClose, function () {
          return remove(item.key);
        }),
        className: merge(rootPrefix('toast'), (_item$node2 = item.node) === null || _item$node2 === void 0 ? void 0 : (_item$node2$props = _item$node2.props) === null || _item$node2$props === void 0 ? void 0 : _item$node2$props.className, transitionClassName)
      }));
    });
  });
  return /*#__PURE__*/_react.default.createElement(Component, (0, _extends2.default)({}, rest, {
    ref: rootRef,
    className: classes
  }), elements);
});

ToastContainer.getInstance = function (props) {
  var container = props.container,
      rest = (0, _objectWithoutPropertiesLoose2.default)(props, ["container"]);

  var containerRef = /*#__PURE__*/_react.default.createRef();

  var mountElement = document.createElement('div');
  var containerElement = typeof container === 'function' ? container() : container; //  Parent is document.body or the existing dom element

  var parentElement = containerElement || document.body; // Add the detached element to the parent

  parentElement.appendChild(mountElement);

  function destroy() {
    (0, _reactDom.unmountComponentAtNode)(mountElement);
    parentElement.removeChild(mountElement);
  }

  (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(ToastContainer, (0, _extends2.default)({}, rest, {
    ref: containerRef
  })), mountElement);
  return [containerRef, destroy];
};

ToastContainer.displayName = 'ToastContainer';
ToastContainer.defaultProps = defaultProps;
ToastContainer.propTypes = {
  className: _propTypes.default.string,
  classPrefix: _propTypes.default.string,
  duration: _propTypes.default.number,
  placement: _propTypes.default.elementType,
  container: _propTypes.default.oneOfType([_propTypes.default.node, _propTypes.default.func])
};
var _default = ToastContainer;
exports.default = _default;