var _excluded = ["option", "highlighted", "optionRenderer"],
  _excluded2 = ["children", "icon"],
  _excluded3 = ["disabled", "icon", "label", "loading", "options", "onClick", "optionRenderer", "children", "placement", "onKeyDown", "onFocus", "onBlur", "onMouseDown", "onMouseEnter", "onMouseLeave", "size", "variant"];
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
import { EllipsisVertical } from '@procore/core-icons/dist';
import React, { useCallback } from 'react';
import { Card } from '../Card';
import { DropdownButton } from '../Dropdown/Dropdown';
import { Portal } from '../Portal';
import { useClickOutside } from '../_hooks/ClickOutside';
import { useI18nContext } from '../_hooks/I18n';
import { mergeRefs } from '../_utils/mergeRefs';
import { defaultOptionRenderer, DropdownFlyoutContext, noop, transformOption, useDropdownFlyout, useDropdownFlyoutContext } from './DropdownFlyout.helpers';
import { StyledDropdownFlyout, StyledDropdownFlyoutItem } from './DropdownFlyout.styles';
import { rootId } from './DropdownFlyout.types';
import { useDropdownFlyoutOverlay } from './useDropdownFlyoutOverlay';
export var FlyoutCaption = /*#__PURE__*/React.forwardRef(function FlyoutCaption(_ref, ref) {
  var option = _ref.option,
    highlighted = _ref.highlighted,
    optionRenderer = _ref.optionRenderer,
    props = _objectWithoutProperties(_ref, _excluded);
  return /*#__PURE__*/React.createElement(StyledDropdownFlyoutItem, _extends({}, props, {
    ref: ref,
    "data-highlighted": highlighted,
    "data-flyout": true
  }), optionRenderer(option));
});
FlyoutCaption.displayName = 'FlyoutCaption';
export function FlyoutItem(_ref2) {
  var option = _ref2.option;
  var overlayElRef = React.useRef(null);
  var _useDropdownFlyoutCon = useDropdownFlyoutContext(),
    isHighlighted = _useDropdownFlyoutCon.isHighlighted,
    isExpanded = _useDropdownFlyoutCon.isExpanded,
    _onClick = _useDropdownFlyoutCon.onClick,
    expand = _useDropdownFlyoutCon.expand,
    collapse = _useDropdownFlyoutCon.collapse,
    optionRenderer = _useDropdownFlyoutCon.optionRenderer;
  var onMouseEnter = React.useCallback(function () {
    return expand(option);
  }, [option, expand]);
  var onMouseLeave = React.useCallback(function (e) {
    if (e.relatedTarget instanceof Node && overlayElRef.current && !overlayElRef.current.contains(e.relatedTarget)) {
      collapse(option);
    }
  }, [collapse, option]);
  var onClick = React.useCallback(function () {
    return _onClick(option);
  }, [_onClick, option]);
  var _React$useState = React.useState(null),
    _React$useState2 = _slicedToArray(_React$useState, 2),
    referenceEl = _React$useState2[0],
    setReferenceEl = _React$useState2[1];
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(FlyoutCaption, {
    ref: setReferenceEl,
    role: "listitem",
    option: option.origin,
    onClick: onClick,
    optionRenderer: optionRenderer,
    highlighted: isHighlighted(option),
    onMouseEnter: onMouseEnter,
    onMouseLeave: onMouseLeave
  }), Array.isArray(option.children) && isExpanded(option) ? /*#__PURE__*/React.createElement(Portal, null, /*#__PURE__*/React.createElement(FlyoutList, {
    referenceEl: referenceEl,
    options: option.children,
    overlayRef: overlayElRef,
    placement: "right-top"
  })) : null);
}
export function FlyoutList(_ref3) {
  var options = _ref3.options,
    placement = _ref3.placement,
    referenceEl = _ref3.referenceEl,
    overlayElRef = _ref3.overlayRef,
    _ref3$offset = _ref3.offset,
    offset = _ref3$offset === void 0 ? 0 : _ref3$offset;
  var _useDropdownFlyoutOve = useDropdownFlyoutOverlay({
      placement: placement,
      offset: {
        mainAxis: offset
      }
    }),
    overlayStyle = _useDropdownFlyoutOve.overlayStyle,
    referenceRef = _useDropdownFlyoutOve.referenceRef,
    overlayRef = _useDropdownFlyoutOve.overlayRef;
  React.useEffect(function () {
    referenceRef(referenceEl);
  }, [referenceEl, referenceRef]);
  return /*#__PURE__*/React.createElement(Card, {
    ref: mergeRefs(overlayRef, overlayElRef),
    shadowStrength: 2,
    style: overlayStyle
  }, /*#__PURE__*/React.createElement(StyledDropdownFlyout, {
    role: "list"
  }, options.map(function (option) {
    return /*#__PURE__*/React.createElement(FlyoutItem, {
      key: option.id,
      option: option
    });
  })));
}
var DefaultButton = /*#__PURE__*/React.forwardRef(function DefaultButton(_ref4, ref) {
  var children = _ref4.children,
    icon = _ref4.icon,
    props = _objectWithoutProperties(_ref4, _excluded2);
  return /*#__PURE__*/React.createElement(DropdownButton, _extends({}, props, {
    icon: props.loading ? undefined : !icon && !children ? /*#__PURE__*/React.createElement(EllipsisVertical, null) : icon,
    arrow: Boolean(React.Children.count(children)),
    ref: ref
  }), children);
});

/**

  The dropdown flyout allows for additional menu items to be nested within
  parent items, which allows more menu options for users.
  @a11y WARN: DropdownFlyotus hold no value and take an action. Focus is expected
    to be moved from a Dropdown to something else, to continue the user flow.
    If the action is inert and does not move focus, this is left to be added
    by the consumer.
  @since 10.19.0

  @see [Storybook](https://stories.core.procore.com/?path=/story/core-react_demos-dropdownflyout--demo)

  @see [Design Guidelines](https://design.procore.com/dropdown-flyout)

 */
export var DropdownFlyout = /*#__PURE__*/React.forwardRef(function DropdownFlyout(_ref5, ref) {
  var disabled = _ref5.disabled,
    icon = _ref5.icon,
    label = _ref5.label,
    loading = _ref5.loading,
    _options = _ref5.options,
    _ref5$onClick = _ref5.onClick,
    _onClick = _ref5$onClick === void 0 ? noop : _ref5$onClick,
    _ref5$optionRenderer = _ref5.optionRenderer,
    optionRenderer = _ref5$optionRenderer === void 0 ? defaultOptionRenderer : _ref5$optionRenderer,
    children = _ref5.children,
    _ref5$placement = _ref5.placement,
    placement = _ref5$placement === void 0 ? 'right-bottom' : _ref5$placement,
    _onKeyDown = _ref5.onKeyDown,
    onFocus_ = _ref5.onFocus,
    onBlur_ = _ref5.onBlur,
    onMouseDown_ = _ref5.onMouseDown,
    onMouseEnter_ = _ref5.onMouseEnter,
    onMouseLeave_ = _ref5.onMouseLeave,
    size = _ref5.size,
    _ref5$variant = _ref5.variant,
    variant = _ref5$variant === void 0 ? 'secondary' : _ref5$variant,
    props = _objectWithoutProperties(_ref5, _excluded3);
  var innerRef = React.useRef(null);
  var containerRef = ref || innerRef;
  var overlayElRef = React.useRef(null);
  var targetRef = React.useRef(null);
  var flyoutOptions = React.useMemo(function () {
    return transformOption(_options, rootId);
  }, [_options]);
  var _useDropdownFlyout = useDropdownFlyout({
      flyoutOptions: flyoutOptions,
      onClick: _onClick,
      onKeyDown: _onKeyDown
    }),
    options = _useDropdownFlyout.options,
    collapse = _useDropdownFlyout.collapse,
    expand = _useDropdownFlyout.expand,
    closeSelectedDropdown = _useDropdownFlyout.closeSelectedDropdown,
    openDropdown = _useDropdownFlyout.openDropdown,
    isOpen = _useDropdownFlyout.isOpen,
    onClick = _useDropdownFlyout.onClick,
    onKeyDown = _useDropdownFlyout.onKeyDown,
    setMouseOver = _useDropdownFlyout.setMouseOver,
    setFocused = _useDropdownFlyout.setFocused,
    isExpanded = _useDropdownFlyout.isExpanded,
    isHighlighted = _useDropdownFlyout.isHighlighted,
    closeDropdown = _useDropdownFlyout.closeDropdown;
  useClickOutside({
    onClickOutside: isOpen ? closeSelectedDropdown : noop,
    refs: [containerRef]
  });
  var element = typeof children === 'function' ? children({
    isOpen: isOpen
  }) : children;
  var I18n = useI18nContext();
  var ariaLabel = props['aria-label'] || label || I18n.t("core.dropdown.".concat(loading ? 'loading' : 'moreOptions'));
  var trigger = /*#__PURE__*/React.isValidElement(element) ? element : /*#__PURE__*/React.createElement(DefaultButton, {
    "aria-label": ariaLabel,
    children: label,
    disabled: disabled,
    loading: loading,
    icon: icon,
    size: size,
    variant: variant
  });
  function onBlur(e) {
    setFocused(false);
    closeSelectedDropdown(e);
    onBlur_ === null || onBlur_ === void 0 ? void 0 : onBlur_(e);
  }
  function onFocus(e) {
    setFocused(true);
    onFocus_ === null || onFocus_ === void 0 ? void 0 : onFocus_(e);
  }
  function onMouseDown(e) {
    var _containerRef$current;
    // Discard firing of blur event
    // when click was inside the dropdown
    if (e.target.dataset.flyout) {
      e.preventDefault();
      return;
    }
    if (e.target instanceof Node && (_containerRef$current = containerRef.current) !== null && _containerRef$current !== void 0 && _containerRef$current.contains(e.target)) {
      var _targetRef$current;
      e.preventDefault();
      (_targetRef$current = targetRef.current) === null || _targetRef$current === void 0 ? void 0 : _targetRef$current.focus();
    }
    onMouseDown_ === null || onMouseDown_ === void 0 ? void 0 : onMouseDown_(e);
  }
  function onMouseLeave(e) {
    setMouseOver(false);
    onMouseLeave_ === null || onMouseLeave_ === void 0 ? void 0 : onMouseLeave_(e);
  }
  function onMouseEnter(e) {
    setMouseOver(true);
    onMouseEnter_ === null || onMouseEnter_ === void 0 ? void 0 : onMouseEnter_(e);
  }
  var _React$useState3 = React.useState(null),
    _React$useState4 = _slicedToArray(_React$useState3, 2),
    referenceEl = _React$useState4[0],
    setReferenceEl = _React$useState4[1];

  // mergeRefs function is from shared utils.
  // eslint-disable-next-line react-hooks/exhaustive-deps
  var memoRef = useCallback(trigger.ref ? mergeRefs(trigger.ref, targetRef, setReferenceEl) : mergeRefs(targetRef, setReferenceEl), [targetRef, setReferenceEl, trigger.ref]);
  return /*#__PURE__*/React.createElement("div", _extends({}, props, {
    "aria-label": undefined,
    ref: containerRef,
    onKeyDown: onKeyDown,
    onMouseEnter: onMouseEnter,
    onMouseLeave: onMouseLeave,
    onFocus: onFocus,
    onMouseDown: onMouseDown,
    onBlur: onBlur
  }), /*#__PURE__*/React.cloneElement(trigger, {
    ref: memoRef,
    onClick: function onClick(e) {
      var _trigger$props$onClic, _trigger$props;
      (_trigger$props$onClic = (_trigger$props = trigger.props).onClick) === null || _trigger$props$onClic === void 0 ? void 0 : _trigger$props$onClic.call(_trigger$props, e);
      if (isOpen) {
        closeDropdown();
      } else {
        openDropdown();
      }
    },
    tabIndex: 0
  }), /*#__PURE__*/React.createElement(DropdownFlyoutContext.Provider, {
    value: {
      expand: expand,
      collapse: collapse,
      onClick: onClick,
      isExpanded: isExpanded,
      isHighlighted: isHighlighted,
      optionRenderer: optionRenderer
    }
  }, isOpen && /*#__PURE__*/React.createElement(Portal, null, /*#__PURE__*/React.createElement(FlyoutList, {
    options: options,
    overlayRef: overlayElRef,
    placement: placement,
    referenceEl: referenceEl,
    offset: 4
  }))));
});
//# sourceMappingURL=DropdownFlyout.js.map