"use strict";

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 _react = _interopRequireWildcard(require("react"));

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

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

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

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

var _MenuItem = _interopRequireDefault(require("./MenuItem"));

var _MenuSelectableItem = _interopRequireDefault(require("./MenuSelectableItem"));

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (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; }

// Copyright 1999-2020. Plesk International GmbH. All rights reserved.
const hasIconItem = children => {
  let result = false;

  _react.Children.forEach(children, child => {
    if ( /*#__PURE__*/(0, _react.isValidElement)(child) && (child.type === _MenuSelectableItem.default || child.props.icon)) {
      result = true;
    }
  });

  return result;
};
/**
 * `Menu` component displays grouped controls for navigating the UI, performing actions on objects, or showing
 * options for [Lists](#!/List) (for example, sorting and filtering settings). `Menu` is most typically used in a
 * [Dropdown](#!/Dropdown).
 *
 * `Menu` consists of several [Menu Items](#!/MenuItem) (or [Selectable Menu
 * Items](#!/MenuSelectableItem)) which can be grouped by [Menu Headers](#!/MenuHeader)
 * or separated by [Menu Dividers](#!/MenuDivider).
 * @since 0.0.55
 */


const Menu = /*#__PURE__*/(0, _react.forwardRef)(function Menu({
  baseClassName,
  className,
  children,
  onItemClick,
  overlay,
  onKeyDown,
  onFocus,
  autoFocus,
  ...props
}, ref) {
  const rootRef = (0, _react.useRef)();
  const {
    focusNext,
    focusPrev,
    focusFirst,
    focusLast
  } = (0, _react.useMemo)(() => (0, _utils.createFocusManager)(rootRef, node => (node.getAttribute('role') === 'menuitem' || node.getAttribute('role') === 'menuitemcheckbox') && node.getAttribute('aria-disabled') !== 'true'), []);

  const handleKeyDown = e => {
    switch (e.key) {
      case 'ArrowUp':
        e.preventDefault();
        focusPrev();
        break;

      case 'ArrowDown':
        e.preventDefault();
        focusNext();
        break;

      case 'Home':
      case 'PageUp':
        e.preventDefault();
        focusFirst();
        break;

      case 'End':
      case 'PageDown':
        e.preventDefault();
        focusLast();
        break;
    }

    (0, _utils.safeInvoke)(onKeyDown, e);
  };

  const handleFocus = e => {
    if (e.target === rootRef.current && autoFocus) {
      focusFirst();
    }

    (0, _utils.safeInvoke)(onFocus, e);
  };

  let hasTabIndex = false;

  const items = _react.Children.map(children, (child, index) => {
    if (! /*#__PURE__*/(0, _react.isValidElement)(child)) {
      return child;
    }

    const props = {
      tabIndex: -1
    };

    if (onItemClick) {
      props.onClick = (0, _utils.wrapFunction)(child.props.onClick, onItemClick.bind(null, child, index));
    }

    if (!hasTabIndex && (child.type === _MenuItem.default || child.type === _MenuSelectableItem.default) && !child.props.disabled) {
      props.tabIndex = 0;
      hasTabIndex = true;
    } else {
      props.tabIndex = -1;
    }

    return /*#__PURE__*/(0, _react.cloneElement)(child, props);
  });

  return /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({
    className: (0, _classnames.default)(baseClassName, className, {
      [`${baseClassName}--icons`]: hasIconItem(children),
      [`${baseClassName}--overlay`]: overlay
    }),
    role: "menu"
  }, props, {
    ref: el => {
      rootRef.current = el;

      if (ref) {
        ref.current = el;
      }
    },
    onKeyDown: handleKeyDown,
    onFocus: handleFocus,
    tabIndex: -1
  }), items);
});
Menu.displayName = 'Menu';
Menu.propTypes = {
  /**
   * Triggered when menu item was clicked.
   * @since 0.0.56
   */
  onItemClick: _propTypes.default.func,

  /**
   * Content of the `Menu`.
   * @since 0.0.55
   */
  children: _propTypes.default.node,

  /**
   * @ignore
   */
  onKeyDown: _propTypes.default.func,

  /**
   * @ignore
   */
  onFocus: _propTypes.default.func,

  /**
   * @ignore
   */
  autoFocus: _propTypes.default.bool,

  /**
   * Show menu in overlay.
   * @ignore
   */
  overlay: _propTypes.default.bool,

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

  /**
   * @ignore
   */
  baseClassName: _propTypes.default.string
};
Menu.defaultProps = {
  onItemClick: null,
  children: null,
  overlay: false,
  className: null,
  baseClassName: `${_constants.CLS_PREFIX}menu`,
  onKeyDown: undefined,
  onFocus: undefined,
  autoFocus: undefined
};
var _default = Menu;
exports.default = _default;