"use strict";

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

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

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

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

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

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

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

var _reactTransitionGroup = require("react-transition-group");

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

var _constants = require("../../constants");

var _Toast = _interopRequireDefault(require("../Toast"));

var _Layer = _interopRequireDefault(require("../Layer"));

var _OnDarkContext = _interopRequireDefault(require("../OnDarkContext"));

// Copyright 1999-2020. Plesk International GmbH. All rights reserved.
let toastId = 0;

/**
 * `Toaster` is used for notifying about events happened in the system. For example, about results of performed operations.
 * @since 0.0.42
 */
class Toaster extends _react.Component {
  constructor(...args) {
    super(...args);
    (0, _defineProperty2.default)(this, "state", {
      toasts: []
    });
  }

  static getDerivedStateFromProps({
    toasts,
    maxToastsNumber
  }) {
    if (toasts) {
      return {
        toasts: toasts.slice(0, maxToastsNumber)
      };
    }

    return null;
  }

  isControlled() {
    return Boolean(this.props.toasts);
  }
  /**
   * Add a new toast
   *
   * `intent` - Visual intent color to apply to component. (Type: `oneOf` 'info', 'success', 'warning', 'danger'. *Required*.)<br>
   * `message` - Message to display in the body of the toast. (Type: `any`. Default: `undefined`.)<br>
   * `onClose` - onClose handler. (Type: `func`. Default: `undefined`.)<br>
   * `closable` - Show close control (cross mark). (Type: `boolean`. Default: `true`.)<br>
   * `autoClosable` - Whether call `onClose` after 6 seconds or not.
   * Enabled by default when the position is "top-end" and a toast has "success" intent. (Type: `boolean`. Default: 'undefined'.)<br>
   * ---
   * @param {Object} props **Toast props**:
   * @returns {string} New toast key
   * @public
   */


  add(props) {
    const key = "toast-".concat(toastId++);
    this.setState(({
      toasts
    }) => ({
      toasts: [{
        key,
        ...props
      }, ...toasts].slice(0, this.props.maxToastsNumber)
    }));
    return key;
  }
  /**
   * Update toast by key
   *
   * @param {string} key
   * @param {Object} props New props
   * @returns {string} Updated toast key
   * @public
   */


  update(key, props) {
    this.setState(({
      toasts
    }) => ({
      toasts: toasts.map(toast => toast.key === key ? { ...props,
        key
      } : toast)
    }));
    return key;
  }
  /**
   * Remove toast by key
   *
   * @param {string} key
   * @public
   */


  remove(key) {
    this.setState(({
      toasts
    }) => ({
      toasts: toasts.filter(toast => toast.key !== key)
    }));
  }
  /**
   * Clear all toasts
   *
   * @public
   */


  clear() {
    this.setState({
      toasts: []
    });
  }

  render() {
    const {
      baseClassName,
      className,
      toasts,
      maxToastsNumber,
      position,
      onToastClose,
      ...props
    } = this.props;
    let stack = this.state.toasts;

    if (position === 'bottom-end') {
      stack = [...stack];
      stack.reverse();
    }

    return /*#__PURE__*/_react.default.createElement(_OnDarkContext.default.Provider, {
      value: true
    }, /*#__PURE__*/_react.default.createElement(_Layer.default, {
      level: _constants.Z_INDEX_TOASTER
    }, /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({
      className: (0, _classnames.default)(baseClassName, {
        ["".concat(baseClassName, "--").concat(position)]: position
      }, className)
    }, props), /*#__PURE__*/_react.default.createElement(_reactTransitionGroup.TransitionGroup, {
      component: "span"
    }, stack.map(toastProps => {
      const {
        intent
      } = toastProps;
      let {
        autoClosable
      } = toastProps;

      if (autoClosable === undefined && intent === 'success' && position === 'top-end') {
        autoClosable = true;
      }

      const toastRef = /*#__PURE__*/(0, _react.createRef)();
      return /*#__PURE__*/_react.default.createElement(_reactTransitionGroup.CSSTransition, {
        key: toastProps.key,
        classNames: "".concat(_Toast.default.defaultProps.baseClassName, "-"),
        timeout: {
          enter: 300,
          exit: 300
        },
        nodeRef: toastRef
      }, /*#__PURE__*/_react.default.createElement(_Toast.default, (0, _extends2.default)({}, toastProps, {
        autoClosable: autoClosable,
        onClose: () => {
          if (!this.isControlled()) {
            this.remove(toastProps.key);
          }

          if (toastProps.onClose) {
            toastProps.onClose();
          }

          if (onToastClose) {
            onToastClose(toastProps.key);
          }
        },
        innerRef: toastRef
      })));
    })))));
  }

}

exports.default = Toaster;
(0, _defineProperty2.default)(Toaster, "defaultProps", {
  position: 'top-end',
  baseClassName: "".concat(_constants.CLS_PREFIX, "toaster")
});
(0, _defineProperty2.default)(Toaster, "create", (props = {}, container = document.body) => {
  const containerElement = document.createElement('div');
  container.appendChild(containerElement);
  return (0, _reactDom.render)( /*#__PURE__*/_react.default.createElement(Toaster, props), containerElement);
});