"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 _utils = require("../../utils");

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

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

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

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

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

var _Button = _interopRequireDefault(require("../Button"));

var _AutoClosable = _interopRequireDefault(require("../AutoClosable"));

var _Popper = _interopRequireDefault(require("../Popper"));

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

var _Menu = require("../Menu");

var _Translate = _interopRequireDefault(require("../Translate"));

var _enUS = _interopRequireDefault(require("./locale/en-US"));

// Copyright 1999-2020. Plesk International GmbH. All rights reserved.
const createTarget = (node, {
  onToggle,
  targetRef
}) => {
  if (false === ( /*#__PURE__*/(0, _react.isValidElement)(node) && node.type !== _Translate.default)) {
    node = /*#__PURE__*/_react.default.createElement(_Button.default, {
      caret: true
    }, node);
  }

  let isKeyboardEvent = false;
  return /*#__PURE__*/(0, _react.cloneElement)(node, {
    onKeyDown: (0, _utils2.wrapFunction)(node.props.onKeyDown, e => {
      isKeyboardEvent = e.key === ' ' || e.key === 'Enter';
    }),
    onClick: (0, _utils2.wrapFunction)(node.props.onClick, e => {
      targetRef.current = e.currentTarget;
      onToggle(isKeyboardEvent);
      isKeyboardEvent = false;
    }),
    'aria-haspopup': true
  });
};

const computePlacement = placement => {
  const [side, align] = placement.split('-');

  if (align && (0, _utils.isRtl)() && ['top', 'bottom'].indexOf(side) !== -1) {
    return "".concat(side, "-").concat(align === 'start' ? 'end' : 'start');
  }

  return placement;
};

const useEnhancedMenu = (menu, {
  baseClassName,
  onClose,
  overlay,
  locale,
  autoFocus
}) => {
  const menuRef = (0, _react.useRef)();
  const triggerRef = (0, _react.useRef)();
  (0, _react.useEffect)(() => {
    if (menuRef.current && !overlay) {
      triggerRef.current = document.activeElement;
      setTimeout(() => {
        if (menuRef.current) {
          menuRef.current.focus();
        }
      });
    }
  });

  const handleClose = () => {
    if (triggerRef.current) {
      triggerRef.current.focus();
    }

    onClose();
  };

  const handleKeyDown = e => {
    e.stopPropagation();

    switch (e.key) {
      case 'Enter':
        e.preventDefault();
        document.activeElement.click();
        break;

      case 'Escape':
        e.preventDefault();
        handleClose();
        break;

      case 'Tab':
        handleClose();
        break;
    }
  };

  let {
    children
  } = menu.props;

  if (overlay) {
    children = [...menu.props.children, /*#__PURE__*/_react.default.createElement(_Menu.MenuDivider, {
      className: "".concat(baseClassName, "__overlay-menu-divider"),
      key: "divider"
    }), /*#__PURE__*/_react.default.createElement(_Menu.MenuItem, {
      onClick: handleClose,
      key: "close"
    }, /*#__PURE__*/_react.default.createElement(_Translate.default, {
      namespace: "Dropdown",
      content: "close",
      translators: locale,
      fallback: _enUS.default.close
    }))];
  }

  const clone = /*#__PURE__*/(0, _react.cloneElement)(menu, {
    onItemClick: (0, _utils2.wrapFunction)(menu.props.onItemClick, handleClose),
    className: (0, _classnames.default)("".concat(baseClassName, "__menu"), menu.props.className),
    overlay,
    ref: menuRef,
    children,
    onKeyDown: handleKeyDown,
    autoFocus
  });
  return {
    enhancedMenu: clone,
    menuRef
  };
};
/**
 * `Dropdown` component is a [Button](#!/Button) that opens a drop-down (nested) [Menu](#!/Menu).
 * Use dropdown for grouping actions that are not used often or are less important than others -- in other words,
 * for stuff that you don't want to show users all the time, especially if you have limited screen space.
 * @since 0.0.57
 */


const Dropdown = ({
  baseClassName,
  className,
  children,
  menu,
  menuPlacement,
  overlay,
  locale,
  ...props
}) => {
  const [opened, setOpened] = (0, _react.useState)(false);
  const [autoFocus, setAutoFocus] = (0, _react.useState)(false);
  const closeTimerRef = (0, _react.useRef)();
  (0, _react.useEffect)(() => {
    return () => {
      clearTimeout(closeTimerRef.current);
    };
  }, []);

  const handleOpen = isKeyboardEvent => {
    setAutoFocus(isKeyboardEvent);
    setOpened(true);
  };

  const handleClose = () => {
    closeTimerRef.current = setTimeout(() => {
      setOpened(false);
    }, 0);
  };

  const {
    enhancedMenu,
    menuRef
  } = useEnhancedMenu(menu, {
    baseClassName,
    onClose: handleClose,
    overlay,
    locale,
    autoFocus
  });
  const targetRef = (0, _react.useRef)();
  const target = createTarget(children, {
    onToggle: handleOpen,
    targetRef
  });
  return /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({
    className: (0, _classnames.default)(baseClassName, {
      ["".concat(baseClassName, "--opened")]: opened
    }, className)
  }, props), overlay ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, target, opened && /*#__PURE__*/_react.default.createElement(_Layer.default, {
    level: _constants.Z_INDEX_OVERLAY
  }, /*#__PURE__*/_react.default.createElement("div", {
    className: "".concat(baseClassName, "__overlay")
  }, /*#__PURE__*/_react.default.createElement(_AutoClosable.default, {
    onClose: handleClose,
    nodeRef: menuRef
  }, /*#__PURE__*/_react.default.createElement("div", {
    className: "".concat(baseClassName, "__overlay-menu")
  }, enhancedMenu))))) : /*#__PURE__*/_react.default.createElement(_Popper.default, {
    target: target,
    targetRef: targetRef,
    placement: computePlacement(menuPlacement),
    show: opened,
    className: "".concat(baseClassName, "__popper"),
    zIndex: _constants.Z_INDEX_DROPDOWN
  }, /*#__PURE__*/_react.default.createElement(_AutoClosable.default, {
    onClose: handleClose,
    nodeRef: menuRef
  }, enhancedMenu)));
};

Dropdown.propTypes = {
  /**
   * Dropdown [menu](#!/Menu).
   * @since 0.0.57
   */
  menu: _propTypes.default.element.isRequired,

  /**
   * Menu placement.
   * @since 0.0.60
   */
  menuPlacement: _propTypes.default.string,

  /**
   * Content of the `Dropdown`.
   * @since 0.0.57
   */
  children: _propTypes.default.node,

  /**
   * Custom localization messages.
   * @since 3.6.0
   */
  locale: _propTypes.default.shape({
    close: _propTypes.default.node
  }),

  /**
   * Display menu as overlay.
   * @ignore
   */
  overlay: _propTypes.default.bool,

  /**
   * @ignore
   */
  className: _propTypes.default.string,

  /**
   * @ignore
   */
  baseClassName: _propTypes.default.string
};
Dropdown.defaultProps = {
  menuPlacement: 'bottom-start',
  children: undefined,
  overlay: false,
  className: undefined,
  baseClassName: "".concat(_constants.CLS_PREFIX, "dropdown"),
  locale: undefined
};
var _default = Dropdown;
exports.default = _default;