function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
var _excluded = ["children", "UNSAFE_closesOnSelect", "isSelectable", "keyHandlerRef", "onScrollBottom", "onSelect", "onSearch", "scrollable", "usingHook"],
  _excluded2 = ["children", "clickable", "item"],
  _excluded3 = ["children", "index", "item", "onClick", "selected", "suggested", "onMouseMove"],
  _excluded4 = ["className", "i18nScope", "placeholder", "onChange"],
  _excluded5 = ["padding"];
function _objectDestructuringEmpty(obj) { if (obj == null) throw new TypeError("Cannot destructure " + obj); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _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(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i["return"] && (_r = _i["return"](), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
import React from 'react';
import { StyledFooter, StyledGroup, StyledHeader, StyledItem, StyledMenu, StyledOptions, StyledSearch, StyledWrapper } from '../MenuImperative/MenuImperative.styles';
import { useOverlayTriggerContext } from '../OverlayTrigger/OverlayTrigger';
import { Typeahead } from '../Typeahead/Typeahead';
import { useEventListener } from '../_hooks/EventListener';
import { useI18nContext } from '../_hooks/I18n';
import { useListNavigation } from '../_hooks/ListNavigation';
import { addSubcomponents } from '../_utils/addSubcomponents';
import { usingHookOrDefault } from '../_utils/usingHookOrDefault';
var onScrollBottomThreshold = 8;
export var isItem = function isItem(element) {
  return element.type === Item;
};
function scrollIntoView(index, element) {
  if (!element.parentElement) {
    return;
  }
  if (index === 0) {
    element.parentElement.scrollTop = 0;
    return;
  }
  var offsetTop = element.offsetTop,
    clientHeight = element.clientHeight;
  var _element$parentElemen = element.parentElement,
    scrollTop = _element$parentElemen.scrollTop,
    parentHeight = _element$parentElemen.clientHeight;
  if (offsetTop < scrollTop) {
    element.parentElement.scrollTop = offsetTop;
  } else if (offsetTop + clientHeight > scrollTop + parentHeight) {
    element.parentElement.scrollTop = offsetTop - parentHeight + clientHeight;
  }
}
function checkBottomScrollPosition(callback) {
  return function onScroll(e) {
    if (callback && e.currentTarget instanceof HTMLElement && e.currentTarget.scrollTop >= e.currentTarget.scrollHeight - e.currentTarget.clientHeight - onScrollBottomThreshold) {
      callback(e);
    }
  };
}
function noop() {}
export function useMenu(_ref) {
  var _ref$isSelectable = _ref.isSelectable,
    isSelectable = _ref$isSelectable === void 0 ? isItem : _ref$isSelectable,
    externalKeyHandlerRef = _ref.keyHandlerRef,
    _ref$multiple = _ref.multiple,
    multiple = _ref$multiple === void 0 ? false : _ref$multiple,
    onScrollBottom = _ref.onScrollBottom,
    _ref$onSearch = _ref.onSearch,
    onSearch = _ref$onSearch === void 0 ? noop : _ref$onSearch,
    _ref$onSelect = _ref.onSelect,
    onSelect = _ref$onSelect === void 0 ? noop : _ref$onSelect,
    _ref$scrollable = _ref.scrollable,
    scrollable = _ref$scrollable === void 0 ? true : _ref$scrollable;
  var listNavigation = useListNavigation({
    circular: !onScrollBottom,
    initialIndex: 0,
    size: 0
  });
  var highlighted = React.useRef(null);
  var keyHandlerRef = externalKeyHandlerRef || /*#__PURE__*/React.createRef();
  var selectItem = React.useCallback(function (selection) {
    onSelect(selection);
  }, [onSelect]);
  var _onKeyDown = React.useCallback(function (e) {
    var key = e.key;
    if (key === 'ArrowDown' || key === 'Down') {
      listNavigation.increment();
      e.preventDefault();
    } else if (key === 'ArrowUp' || key === 'Up') {
      listNavigation.decrement();
      e.preventDefault();
    } else if (key === 'Enter') {
      if (highlighted.current) {
        highlighted.current.click();
      }
    }
  }, [listNavigation]);

  // TODO - deprecate keyhandlerRef, this is just for backwards compatibility since we already exposed it
  React.useEffect(function () {
    var el;
    if (keyHandlerRef.current) {
      keyHandlerRef.current.addEventListener('keydown', _onKeyDown);
      el = keyHandlerRef.current;
    }
    return function () {
      if (el) {
        el.removeEventListener('keydown', _onKeyDown);
      }
    };
  }, [keyHandlerRef, _onKeyDown]);
  return {
    domHandlers: {
      onKeyDown: function onKeyDown(e) {
        return _onKeyDown(e.nativeEvent);
      }
    },
    highlighted: highlighted,
    isSelectable: isSelectable,
    listNavigation: listNavigation,
    multiple: multiple,
    onScrollBottom: onScrollBottom,
    onSearch: onSearch,
    scrollable: scrollable,
    selectItem: selectItem
  };
}
export var MenuHookContext = /*#__PURE__*/React.createContext(null);
export function useMenuHookContext() {
  var context = React.useContext(MenuHookContext);
  if (context === null) {
    throw new Error('Cannot find `MenuHook` context, please wrap your component in `<MenuHookContext.Provider>`');
  }
  return context;
}
export var Menu_ = /*#__PURE__*/React.forwardRef(function Menu(_ref2, ref) {
  var children = _ref2.children,
    _ref2$UNSAFE_closesOn = _ref2.UNSAFE_closesOnSelect,
    UNSAFE_closesOnSelect = _ref2$UNSAFE_closesOn === void 0 ? true : _ref2$UNSAFE_closesOn,
    _ref2$isSelectable = _ref2.isSelectable,
    isSelectable = _ref2$isSelectable === void 0 ? isItem : _ref2$isSelectable,
    keyHandlerRef = _ref2.keyHandlerRef,
    onScrollBottom = _ref2.onScrollBottom,
    _ref2$onSelect = _ref2.onSelect,
    onSelect = _ref2$onSelect === void 0 ? noop : _ref2$onSelect,
    onSearch = _ref2.onSearch,
    _ref2$scrollable = _ref2.scrollable,
    scrollable = _ref2$scrollable === void 0 ? true : _ref2$scrollable,
    usingHook = _ref2.usingHook,
    props = _objectWithoutProperties(_ref2, _excluded);
  // Don't be tempted to put this in useMenu. In order for hooks to be portable
  // across the dom tree, they should not contain context consumers.
  var overlayTriggerContext = useOverlayTriggerContext();
  var menu = usingHookOrDefault(usingHook, useMenu)({
    isSelectable: isSelectable,
    keyHandlerRef: keyHandlerRef,
    onScrollBottom: onScrollBottom,
    onSelect: onSelect,
    onSearch: onSearch,
    scrollable: scrollable
  });
  React.useEffect(function () {
    // When unmounting, reset the listNavigation index and set
    // the current highlighted item to null. we only want to run this once,
    // so don't pass any dependencies
    return function () {
      menu.listNavigation.reset();
      menu.highlighted.current = null;
    };
  }, /* eslint-disable */[] /* eslint-enable */);

  function selectItem(selection) {
    menu.selectItem(selection);
    if (UNSAFE_closesOnSelect) {
      overlayTriggerContext.hide(selection.event);
    }
  }
  return /*#__PURE__*/React.createElement(MenuHookContext.Provider, {
    value: _objectSpread(_objectSpread({}, menu), {}, {
      selectItem: selectItem
    })
  }, /*#__PURE__*/React.createElement(StyledWrapper, _extends({}, menu.domHandlers, {
    ref: ref,
    tabIndex: 0
  }), /*#__PURE__*/React.createElement(StyledMenu, props, children)));
});
export var Group = /*#__PURE__*/React.forwardRef(function Group(_ref3, ref) {
  var children = _ref3.children,
    _ref3$clickable = _ref3.clickable,
    clickable = _ref3$clickable === void 0 ? false : _ref3$clickable,
    item = _ref3.item,
    props = _objectWithoutProperties(_ref3, _excluded2);
  return /*#__PURE__*/React.createElement(StyledGroup, _extends({}, props, {
    ref: ref,
    onClick: function onClick(event) {
      // TODO: implement selecting groups?
    },
    $clickable: clickable
  }), children);
});
export var Item = /*#__PURE__*/React.forwardRef(function Item(_ref4, ref) {
  var children = _ref4.children,
    _ref4$index = _ref4.index,
    index = _ref4$index === void 0 ? 0 : _ref4$index,
    item = _ref4.item,
    _ref4$onClick = _ref4.onClick,
    _onClick = _ref4$onClick === void 0 ? noop : _ref4$onClick,
    _ref4$selected = _ref4.selected,
    selected = _ref4$selected === void 0 ? false : _ref4$selected,
    _ref4$suggested = _ref4.suggested,
    suggested = _ref4$suggested === void 0 ? false : _ref4$suggested,
    _onMouseMove = _ref4.onMouseMove,
    props = _objectWithoutProperties(_ref4, _excluded3);
  var _useMenuHookContext = useMenuHookContext(),
    highlighted = _useMenuHookContext.highlighted,
    listNavigation = _useMenuHookContext.listNavigation,
    multiple = _useMenuHookContext.multiple,
    selectItem = _useMenuHookContext.selectItem;
  var itemRef =
  // eslint-disable-next-line react-hooks/rules-of-hooks
  ref || React.useRef();
  var isHighlighted = index === listNavigation.index;
  React.useEffect(function () {
    // When mounting, check if this item is selected or suggested, and if
    // it is, then set it as the current index and scroll to it.
    // We only want to run this once, so don't pass any dependencies

    if (multiple) {
      // don't do this behavior in multiple mode
      return;
    }
    if (itemRef.current && (selected || suggested)) {
      highlighted.current = itemRef.current;
      listNavigation.set(index);
    }
  }, /* eslint-disable */[] /* eslint-enable */);

  React.useEffect(function () {
    // If this item has become highlighted, scroll to it
    if (itemRef.current && isHighlighted) {
      highlighted.current = itemRef.current;
      scrollIntoView(index, itemRef.current);
    }
  }, [highlighted, index, isHighlighted, itemRef]);
  return /*#__PURE__*/React.createElement(StyledItem, _extends({}, props, {
    onClick: function onClick(event) {
      listNavigation.set(index);
      selectItem({
        event: event.nativeEvent,
        item: item,
        group: false
      });
      _onClick(event);
    },
    onMouseMove: function onMouseMove(event) {
      if (_onMouseMove) {
        _onMouseMove(event);
      }
      if (listNavigation.index !== index) {
        listNavigation.set(index);
      }
    },
    ref: itemRef,
    $highlighted: isHighlighted,
    $selected: selected
  }), children);
});
export var Options = /*#__PURE__*/React.forwardRef(function Options(_ref5, ref) {
  var children = _ref5.children,
    className = _ref5.className,
    _ref5$scrollable = _ref5.scrollable,
    scrollable = _ref5$scrollable === void 0 ? true : _ref5$scrollable;
  var _useMenuHookContext2 = useMenuHookContext(),
    listNavigation = _useMenuHookContext2.listNavigation,
    isSelectable = _useMenuHookContext2.isSelectable,
    onScrollBottom = _useMenuHookContext2.onScrollBottom,
    menuScrollable = _useMenuHookContext2.scrollable;
  var optionsRef = ref || /*#__PURE__*/React.createRef();
  var size = React.Children.toArray(children).filter(isSelectable).length;
  React.useEffect(function () {
    listNavigation.setSize(size);
  }, [listNavigation, size]);
  useEventListener({
    event: 'scroll',
    handler: checkBottomScrollPosition(onScrollBottom),
    scope: optionsRef
  });
  var index = 0;
  return /*#__PURE__*/React.createElement(StyledOptions, {
    className: className,
    ref: optionsRef,
    $scrollable: menuScrollable || scrollable
  }, React.Children.map(children, function (child) {
    if ( /*#__PURE__*/React.isValidElement(child) && isSelectable(child)) {
      var selectableIndex = index;
      index = index + 1;
      return /*#__PURE__*/React.cloneElement(child, {
        index: selectableIndex
      });
    }
    return child;
  }));
});
export var Search = function Search(_ref6) {
  var className = _ref6.className,
    _ref6$i18nScope = _ref6.i18nScope,
    i18nScope = _ref6$i18nScope === void 0 ? 'core.menu' : _ref6$i18nScope,
    placeholder = _ref6.placeholder,
    _onChange = _ref6.onChange,
    props = _objectWithoutProperties(_ref6, _excluded4);
  var I18n = useI18nContext();
  var menu = useMenuHookContext();
  var _React$useState = React.useState(''),
    _React$useState2 = _slicedToArray(_React$useState, 2),
    value = _React$useState2[0],
    setValue = _React$useState2[1];
  var onChange = React.useCallback(function (value, event) {
    var _menu$onSearch;
    setValue(event.target.value);
    (_menu$onSearch = menu.onSearch) === null || _menu$onSearch === void 0 ? void 0 : _menu$onSearch.call(menu, event);
    menu.listNavigation.set(0);
    _onChange === null || _onChange === void 0 ? void 0 : _onChange(event);
  }, [_onChange]);
  return /*#__PURE__*/React.createElement(StyledSearch, {
    className: className
  }, /*#__PURE__*/React.createElement(Typeahead, _extends({}, props, {
    autoFocus: true,
    placeholder: placeholder || I18n.t('search', {
      scope: i18nScope
    }),
    onChange: onChange,
    value: value
  })));
};
export var Header = /*#__PURE__*/React.forwardRef(function Header(_ref7, ref) {
  var props = _extends({}, (_objectDestructuringEmpty(_ref7), _ref7));
  return /*#__PURE__*/React.createElement(StyledHeader, _extends({
    ref: ref
  }, props));
});
export var Footer = /*#__PURE__*/React.forwardRef(function Footer(_ref8, ref) {
  var _ref8$padding = _ref8.padding,
    padding = _ref8$padding === void 0 ? 'md lg' : _ref8$padding,
    props = _objectWithoutProperties(_ref8, _excluded5);
  return /*#__PURE__*/React.createElement(StyledFooter, _extends({
    ref: ref,
    padding: padding
  }, props));
});
Menu_.displayName = 'Menu';
Footer.displayName = 'Menu.Footer';
Group.displayName = 'Menu.Group';
Header.displayName = 'Menu.Header';
Item.displayName = 'Menu.Item';
Options.displayName = 'Menu.Options';
Search.displayName = 'Menu.Search';

/**

 Menus are used in conjunction with components that contain dropdowns.
 For example, multi select, single select, and dropdown.

 @since 10.19.0

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

 @see [Design Guidelines](https://design.procore.com/menu)

 */
export var Menu = addSubcomponents({
  Footer: Footer,
  Group: Group,
  Header: Header,
  Item: Item,
  Options: Options,
  Search: Search
}, Menu_);
//# sourceMappingURL=Menu.js.map