import _objectDestructuringEmpty from "@babel/runtime/helpers/objectDestructuringEmpty";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _extends from "@babel/runtime/helpers/extends";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
import _inherits from "@babel/runtime/helpers/inherits";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
var _excluded = ["children"];
var _templateObject, _templateObject2, _templateObject3, _templateObject4;
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
/** @jsx jsx */

import React, { PureComponent, useContext } from 'react';
import { css, jsx } from '@emotion/react';
import { akEditorFloatingPanelZIndex } from '@atlaskit/editor-shared-styles';
import { CustomItem, MenuGroup, Section } from '@atlaskit/menu';
import { getBooleanFF } from '@atlaskit/platform-feature-flags';
import { B100, N70, N900 } from '@atlaskit/theme/colors';
import Tooltip from '@atlaskit/tooltip';
import { DropdownMenuSharedCssClassName } from '../../styles';
import { KeyDownHandlerContext } from '../../ui-menu/ToolbarArrowKeyNavigationProvider';
import { withReactEditorViewOuterListeners } from '../../ui-react';
import DropList from '../../ui/DropList';
import Popup from '../../ui/Popup';
import { ArrowKeyNavigationProvider } from '../ArrowKeyNavigationProvider';
import { ArrowKeyNavigationType } from '../ArrowKeyNavigationProvider/types';
var wrapper = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n  /* tooltip in ToolbarButton is display:block */\n  & > div > div {\n    display: flex;\n  }\n"])));
var focusedMenuItemStyle = css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n  box-shadow: inset 0px 0px 0px 2px ", ";\n  outline: none;\n"])), "var(--ds-border-focused, ".concat(B100, ")"));
var buttonStyles = function buttonStyles(isActive, submenuActive) {
  if (isActive) {
    /**
     * Hack for item to imitate old dropdown-menu selected styles
     */
    return css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n      > span,\n      > span:hover,\n      > span:active {\n        background: ", ";\n        color: ", ";\n      }\n      :focus > span[aria-disabled='false'] {\n        ", ";\n      }\n      :focus-visible,\n      :focus-visible > span[aria-disabled='false'] {\n        outline: none;\n      }\n    "])), "var(--ds-background-selected, #6c798f)", "var(--ds-text, #fff)", focusedMenuItemStyle);
  } else {
    return css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n      > span:hover[aria-disabled='false'] {\n        color: ", ";\n        background-color: ", ";\n      }\n      ", "\n      > span[aria-disabled='true'] {\n        color: ", ";\n      }\n      :focus > span[aria-disabled='false'] {\n        ", ";\n      }\n      :focus-visible,\n      :focus-visible > span[aria-disabled='false'] {\n        outline: none;\n      }\n    "])), "var(--ds-text, ".concat(N900, ")"), "var(--ds-background-neutral-subtle-hovered, rgb(244, 245, 247))", !submenuActive && "\n          > span:active[aria-disabled='false'] {\n            background-color: ".concat("var(--ds-background-neutral-subtle-pressed, rgb(179, 212, 255))", ";\n          }"), "var(--ds-text-disabled, ".concat(N70, ")"), focusedMenuItemStyle); // The default focus-visible style is removed to ensure consistency across browsers
  }
};
var DropListWithOutsideListeners = withReactEditorViewOuterListeners(DropList);

/**
 * Wrapper around @atlaskit/droplist which uses Popup and Portal to render
 * dropdown-menu outside of "overflow: hidden" containers when needed.
 *
 * Also it controls popper's placement.
 */
var DropdownMenuWrapper = /*#__PURE__*/function (_PureComponent) {
  _inherits(DropdownMenuWrapper, _PureComponent);
  var _super = _createSuper(DropdownMenuWrapper);
  function DropdownMenuWrapper() {
    var _this;
    _classCallCheck(this, DropdownMenuWrapper);
    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }
    _this = _super.call.apply(_super, [this].concat(args));
    _defineProperty(_assertThisInitialized(_this), "state", {
      popupPlacement: ['bottom', 'left'],
      selectionIndex: -1
    });
    _defineProperty(_assertThisInitialized(_this), "popupRef", /*#__PURE__*/React.createRef());
    _defineProperty(_assertThisInitialized(_this), "handleRef", function (target) {
      _this.setState({
        target: target || undefined
      });
    });
    _defineProperty(_assertThisInitialized(_this), "updatePopupPlacement", function (placement) {
      var previousPlacement = _this.state.popupPlacement;
      if (placement[0] !== previousPlacement[0] || placement[1] !== previousPlacement[1]) {
        _this.setState({
          popupPlacement: placement
        });
      }
    });
    _defineProperty(_assertThisInitialized(_this), "handleCloseAndFocus", function () {
      var _this$state$target;
      (_this$state$target = _this.state.target) === null || _this$state$target === void 0 || (_this$state$target = _this$state$target.querySelector('button')) === null || _this$state$target === void 0 || _this$state$target.focus();
      _this.handleClose();
    });
    _defineProperty(_assertThisInitialized(_this), "handleClose", function () {
      if (_this.props.onOpenChange) {
        _this.props.onOpenChange({
          isOpen: false
        });
      }
    });
    return _this;
  }
  _createClass(DropdownMenuWrapper, [{
    key: "renderDropdownMenu",
    value: function renderDropdownMenu() {
      var _this2 = this;
      var _this$state = this.state,
        target = _this$state.target,
        popupPlacement = _this$state.popupPlacement;
      var _this$props = this.props,
        items = _this$props.items,
        mountTo = _this$props.mountTo,
        boundariesElement = _this$props.boundariesElement,
        scrollableElement = _this$props.scrollableElement,
        offset = _this$props.offset,
        fitHeight = _this$props.fitHeight,
        fitWidth = _this$props.fitWidth,
        isOpen = _this$props.isOpen,
        zIndex = _this$props.zIndex,
        shouldUseDefaultRole = _this$props.shouldUseDefaultRole,
        onItemActivated = _this$props.onItemActivated,
        arrowKeyNavigationProviderOptions = _this$props.arrowKeyNavigationProviderOptions,
        section = _this$props.section;

      // Note that this onSelection function can't be refactored to useMemo for
      // performance gains as it is being used as a dependency in a useEffect in
      // MenuArrowKeyNavigationProvider in order to check for re-renders to adjust
      // focus for accessibility. If this needs to be refactored in future refer
      // back to ED-16740 for context.
      var navigationProviderProps = arrowKeyNavigationProviderOptions.type === ArrowKeyNavigationType.COLOR ? arrowKeyNavigationProviderOptions : _objectSpread(_objectSpread({}, arrowKeyNavigationProviderOptions), {}, {
        onSelection: function onSelection(index) {
          var result = [];
          if (typeof onItemActivated === 'function') {
            result = items.reduce(function (result, group) {
              return result.concat(group.items);
            }, result);
            onItemActivated({
              item: result[index],
              shouldCloseMenu: false
            });
          }
        }
      });
      return jsx(Popup, {
        target: isOpen ? target : undefined,
        mountTo: mountTo,
        boundariesElement: boundariesElement,
        scrollableElement: scrollableElement,
        onPlacementChanged: this.updatePopupPlacement,
        fitHeight: fitHeight,
        fitWidth: fitWidth,
        zIndex: zIndex || akEditorFloatingPanelZIndex,
        offset: offset
      }, jsx(ArrowKeyNavigationProvider, _extends({}, navigationProviderProps, {
        handleClose: this.handleCloseAndFocus,
        closeOnTab: true
      }), jsx(DropListWithOutsideListeners, {
        isOpen: true,
        appearance: "tall",
        position: popupPlacement.join(' '),
        shouldFlip: false,
        shouldFitContainer: true,
        isTriggerNotTabbable: true,
        handleClickOutside: this.handleClose,
        handleEscapeKeydown: this.handleCloseAndFocus,
        handleEnterKeydown: function handleEnterKeydown(e) {
          e.preventDefault();
          e.stopPropagation();
        },
        targetRef: this.state.target
      }, jsx("div", {
        style: {
          height: 0,
          minWidth: fitWidth || 0
        }
      }), jsx("div", {
        ref: this.popupRef
      }, getBooleanFF('platform.editor.menu.group-items') && jsx(MenuGroup, {
        role: shouldUseDefaultRole ? 'group' : 'menu'
      }, items.map(function (group, index) {
        return jsx(Section, {
          hasSeparator: (section === null || section === void 0 ? void 0 : section.hasSeparator) && index > 0,
          title: section === null || section === void 0 ? void 0 : section.title,
          key: index
        }, group.items.map(function (item) {
          var _item$key;
          return jsx(DropdownMenuItem, {
            key: (_item$key = item.key) !== null && _item$key !== void 0 ? _item$key : String(item.content),
            item: item,
            onItemActivated: _this2.props.onItemActivated,
            shouldUseDefaultRole: _this2.props.shouldUseDefaultRole,
            onMouseEnter: _this2.props.onMouseEnter,
            onMouseLeave: _this2.props.onMouseLeave
          });
        }));
      })), !getBooleanFF('platform.editor.menu.group-items') && items.map(function (group, index) {
        return jsx(MenuGroup, {
          key: index,
          role: shouldUseDefaultRole ? 'group' : 'menu'
        }, group.items.map(function (item) {
          var _item$key2;
          return jsx(DropdownMenuItem, {
            key: (_item$key2 = item.key) !== null && _item$key2 !== void 0 ? _item$key2 : String(item.content),
            item: item,
            onItemActivated: _this2.props.onItemActivated,
            shouldUseDefaultRole: _this2.props.shouldUseDefaultRole,
            onMouseEnter: _this2.props.onMouseEnter,
            onMouseLeave: _this2.props.onMouseLeave
          });
        }));
      })))));
    }
  }, {
    key: "render",
    value: function render() {
      var _this$props2 = this.props,
        children = _this$props2.children,
        isOpen = _this$props2.isOpen;
      return jsx("div", {
        css: wrapper
      }, jsx("div", {
        ref: this.handleRef
      }, children), isOpen ? this.renderDropdownMenu() : null);
    }
  }, {
    key: "componentDidUpdate",
    value: function componentDidUpdate(previousProps) {
      var isOpenToggled = this.props.isOpen !== previousProps.isOpen;
      if (this.props.isOpen && isOpenToggled) {
        if (typeof this.props.shouldFocusFirstItem === 'function' && this.props.shouldFocusFirstItem()) {
          var _this$state$target2;
          var keyboardEvent = new KeyboardEvent('keydown', {
            key: 'ArrowDown',
            bubbles: true
          });
          (_this$state$target2 = this.state.target) === null || _this$state$target2 === void 0 || _this$state$target2.dispatchEvent(keyboardEvent);
        }
      }
    }
  }]);
  return DropdownMenuWrapper;
}(PureComponent);
export { DropdownMenuWrapper as default };
var DropdownMenuItemCustomComponent = /*#__PURE__*/React.forwardRef(function (props, ref) {
  var children = props.children,
    rest = _objectWithoutProperties(props, _excluded);
  return jsx("span", _extends({
    ref: ref
  }, rest, {
    style: {
      // This forces the item container back to be `position: static`, the default value.
      // This ensures the custom nested menu for table color picker still works as now
      // menu items from @atlaskit/menu all have `position: relative` set for the selected borders.
      // The current implementation unfortunately is very brittle. Design System Team will
      // be prioritizing official support for accessible nested menus that we want you to move
      // to in the future.
      position: 'static'
    }
  }), children);
});
export function DropdownMenuItem(_ref) {
  var _item$key3;
  var item = _ref.item,
    onItemActivated = _ref.onItemActivated,
    shouldUseDefaultRole = _ref.shouldUseDefaultRole,
    _onMouseEnter = _ref.onMouseEnter,
    _onMouseLeave = _ref.onMouseLeave;
  var _React$useState = React.useState(false),
    _React$useState2 = _slicedToArray(_React$useState, 2),
    submenuActive = _React$useState2[0],
    setSubmenuActive = _React$useState2[1];

  // onClick and value.name are the action indicators in the handlers
  // If neither are present, don't wrap in an Item.
  if (!item.onClick && !(item.value && item.value.name)) {
    return jsx("span", {
      key: String(item.content)
    }, item.content);
  }
  var _handleSubmenuActive = function _handleSubmenuActive(event) {
    setSubmenuActive(!!event.target.closest(".".concat(DropdownMenuSharedCssClassName.SUBMENU)));
  };
  var dropListItem = jsx("div", {
    css: function css() {
      return buttonStyles(item.isActive, submenuActive);
    },
    tabIndex: -1,
    "aria-disabled": item.isDisabled ? 'true' : 'false',
    onMouseDown: _handleSubmenuActive
  }, jsx(CustomItem, {
    item: item,
    key: (_item$key3 = item.key) !== null && _item$key3 !== void 0 ? _item$key3 : String(item.content),
    testId: "dropdown-item__".concat(String(item.content)),
    role: shouldUseDefaultRole ? 'button' : 'menuitem',
    iconBefore: item.elemBefore,
    iconAfter: item.elemAfter,
    isDisabled: item.isDisabled,
    onClick: function onClick() {
      return onItemActivated && onItemActivated({
        item: item
      });
    },
    "aria-label": item['aria-label'] || String(item.content),
    "aria-pressed": shouldUseDefaultRole ? item.isActive : undefined,
    "aria-keyshortcuts": item['aria-keyshortcuts'],
    onMouseDown: function onMouseDown(e) {
      e.preventDefault();
    },
    component: DropdownMenuItemCustomComponent,
    onMouseEnter: function onMouseEnter() {
      return _onMouseEnter && _onMouseEnter({
        item: item
      });
    },
    onMouseLeave: function onMouseLeave() {
      return _onMouseLeave && _onMouseLeave({
        item: item
      });
    }
  }, item.content));
  if (item.tooltipDescription) {
    var _item$key4;
    return jsx(Tooltip, {
      key: (_item$key4 = item.key) !== null && _item$key4 !== void 0 ? _item$key4 : String(item.content),
      content: item.tooltipDescription,
      position: item.tooltipPosition
    }, dropListItem);
  }
  return dropListItem;
}
export var DropdownMenuWithKeyboardNavigation = /*#__PURE__*/React.memo(function (_ref2) {
  var props = _extends({}, (_objectDestructuringEmpty(_ref2), _ref2));
  var keyDownHandlerContext = useContext(KeyDownHandlerContext);

  // This context is to handle the tab, Arrow Right/Left key events for dropdown.
  // Default context has the void callbacks for above key events
  return jsx(DropdownMenuWrapper, _extends({
    arrowKeyNavigationProviderOptions: _objectSpread(_objectSpread({}, props.arrowKeyNavigationProviderOptions), {}, {
      keyDownHandlerContext: keyDownHandlerContext
    })
  }, props));
});