"use strict";

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

exports.__esModule = true;
exports.default = void 0;

var _taggedTemplateLiteralLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteralLoose"));

var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));

var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));

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

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

var _pick = _interopRequireDefault(require("lodash/pick"));

var _isUndefined = _interopRequireDefault(require("lodash/isUndefined"));

var _isNil = _interopRequireDefault(require("lodash/isNil"));

var _isFunction = _interopRequireDefault(require("lodash/isFunction"));

var _omit = _interopRequireDefault(require("lodash/omit"));

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

var _Picker = require("../Picker");

function _templateObject() {
  var data = (0, _taggedTemplateLiteralLoose2.default)(["none"]);

  _templateObject = function _templateObject() {
    return data;
  };

  return data;
}

var defaultProps = {
  as: 'div',
  appearance: 'default',
  classPrefix: 'picker',
  searchable: true,
  cleanable: true,
  data: [],
  disabledItemValues: [],
  valueKey: 'value',
  labelKey: 'label',
  placement: 'bottomStart',
  menuAutoWidth: true,
  menuMaxHeight: 320
};

var SelectPicker = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
  var Component = props.as,
      data = props.data,
      valueKey = props.valueKey,
      labelKey = props.labelKey,
      valueProp = props.value,
      classPrefix = props.classPrefix,
      placeholder = props.placeholder,
      defaultValue = props.defaultValue,
      disabled = props.disabled,
      cleanable = props.cleanable,
      placement = props.placement,
      menuClassName = props.menuClassName,
      menuAutoWidth = props.menuAutoWidth,
      menuMaxHeight = props.menuMaxHeight,
      menuStyle = props.menuStyle,
      groupBy = props.groupBy,
      overrideLocale = props.locale,
      toggleAs = props.toggleAs,
      style = props.style,
      searchable = props.searchable,
      disabledItemValues = props.disabledItemValues,
      virtualized = props.virtualized,
      listProps = props.listProps,
      id = props.id,
      onGroupTitleClick = props.onGroupTitleClick,
      searchBy = props.searchBy,
      onEntered = props.onEntered,
      onExited = props.onExited,
      onClean = props.onClean,
      onChange = props.onChange,
      onSelect = props.onSelect,
      onSearch = props.onSearch,
      onClose = props.onClose,
      onOpen = props.onOpen,
      sort = props.sort,
      renderValue = props.renderValue,
      renderMenu = props.renderMenu,
      renderMenuGroup = props.renderMenuGroup,
      renderMenuItem = props.renderMenuItem,
      renderExtraFooter = props.renderExtraFooter,
      rest = (0, _objectWithoutPropertiesLoose2.default)(props, ["as", "data", "valueKey", "labelKey", "value", "classPrefix", "placeholder", "defaultValue", "disabled", "cleanable", "placement", "menuClassName", "menuAutoWidth", "menuMaxHeight", "menuStyle", "groupBy", "locale", "toggleAs", "style", "searchable", "disabledItemValues", "virtualized", "listProps", "id", "onGroupTitleClick", "searchBy", "onEntered", "onExited", "onClean", "onChange", "onSelect", "onSearch", "onClose", "onOpen", "sort", "renderValue", "renderMenu", "renderMenuGroup", "renderMenuItem", "renderExtraFooter"]);
  var triggerRef = (0, _react.useRef)();
  var targetRef = (0, _react.useRef)();
  var overlayRef = (0, _react.useRef)();

  var _useCustom = (0, _utils.useCustom)('Picker', overrideLocale),
      locale = _useCustom.locale;

  var _useControlled = (0, _utils.useControlled)(valueProp, defaultValue),
      value = _useControlled[0],
      setValue = _useControlled[1]; // Used to hover the focus item  when trigger `onKeydown`


  var _useFocusItemValue = (0, _Picker.useFocusItemValue)(value, {
    data: data,
    valueKey: valueKey,
    target: function target() {
      return overlayRef.current;
    }
  }),
      focusItemValue = _useFocusItemValue.focusItemValue,
      setFocusItemValue = _useFocusItemValue.setFocusItemValue,
      onFocusItem = _useFocusItemValue.onKeyDown; // Use search keywords to filter options.


  var _useSearch = (0, _Picker.useSearch)({
    labelKey: labelKey,
    data: data,
    searchBy: searchBy,
    callback: function callback(searchKeyword, filteredData, event) {
      var _filteredData$;

      // The first option after filtering is the focus.
      setFocusItemValue(filteredData === null || filteredData === void 0 ? void 0 : (_filteredData$ = filteredData[0]) === null || _filteredData$ === void 0 ? void 0 : _filteredData$[valueKey]);
      onSearch === null || onSearch === void 0 ? void 0 : onSearch(searchKeyword, event);
    }
  }),
      searchKeyword = _useSearch.searchKeyword,
      filteredData = _useSearch.filteredData,
      updateFilteredData = _useSearch.updateFilteredData,
      setSearchKeyword = _useSearch.setSearchKeyword,
      handleSearch = _useSearch.handleSearch;

  (0, _react.useEffect)(function () {
    updateFilteredData(data);
  }, [data, updateFilteredData]); // Use component active state to support keyboard events.

  var _useState = (0, _react.useState)(false),
      active = _useState[0],
      setActive = _useState[1];

  var handleClose = (0, _react.useCallback)(function () {
    var _triggerRef$current, _triggerRef$current$c;

    (_triggerRef$current = triggerRef.current) === null || _triggerRef$current === void 0 ? void 0 : (_triggerRef$current$c = _triggerRef$current.close) === null || _triggerRef$current$c === void 0 ? void 0 : _triggerRef$current$c.call(_triggerRef$current);
  }, []);
  var handleSelect = (0, _react.useCallback)(function (value, item, event) {
    var _targetRef$current;

    onSelect === null || onSelect === void 0 ? void 0 : onSelect(value, item, event);
    (_targetRef$current = targetRef.current) === null || _targetRef$current === void 0 ? void 0 : _targetRef$current.focus();
  }, [onSelect]);
  var handleChangeValue = (0, _react.useCallback)(function (value, event) {
    onChange === null || onChange === void 0 ? void 0 : onChange(value, event);
  }, [onChange]);
  var handleMenuPressEnter = (0, _react.useCallback)(function (event) {
    if (!focusItemValue) {
      return;
    } // Find active `MenuItem` by `value`


    var focusItem = data.find(function (item) {
      return (0, _utils.shallowEqual)(item[valueKey], focusItemValue);
    });
    setValue(focusItemValue);
    handleSelect(focusItemValue, focusItem, event);
    handleChangeValue(focusItemValue, event);
    handleClose();
  }, [data, focusItemValue, handleChangeValue, handleClose, handleSelect, setValue, valueKey]);
  var handleItemSelect = (0, _react.useCallback)(function (value, item, event) {
    setValue(value);
    setFocusItemValue(value);
    handleSelect(value, item, event);
    handleChangeValue(value, event);
    handleClose();
  }, [setValue, setFocusItemValue, handleSelect, handleChangeValue, handleClose]);
  var handleClean = (0, _react.useCallback)(function (event) {
    if (disabled || !cleanable) {
      return;
    }

    setValue(null);
    setFocusItemValue(value);
    handleChangeValue(null, event);
  }, [value, disabled, cleanable, setValue, handleChangeValue, setFocusItemValue]);
  var onPickerKeyDown = (0, _Picker.useToggleKeyDownEvent)((0, _extends2.default)({
    toggle: !focusItemValue || !active,
    triggerRef: triggerRef,
    targetRef: targetRef,
    overlayRef: overlayRef,
    active: active,
    onExit: handleClean,
    onMenuKeyDown: onFocusItem,
    onMenuPressEnter: handleMenuPressEnter,
    onClose: function onClose() {
      setFocusItemValue(null);
    }
  }, rest));
  var handleExited = (0, _react.useCallback)(function () {
    setSearchKeyword('');
    setActive(false);
    onClose === null || onClose === void 0 ? void 0 : onClose();
  }, [onClose, setSearchKeyword]);
  var handleEntered = (0, _react.useCallback)(function () {
    setActive(true);
    setFocusItemValue(value);
    onOpen === null || onOpen === void 0 ? void 0 : onOpen();
  }, [onOpen, setFocusItemValue, value]);
  (0, _Picker.usePublicMethods)(ref, {
    triggerRef: triggerRef,
    overlayRef: overlayRef,
    targetRef: targetRef
  }); // Find active `MenuItem` by `value`

  var activeItem = data.find(function (item) {
    return (0, _utils.shallowEqual)(item[valueKey], value);
  });
  /**
   * 1.Have a value and the value is valid.
   * 2.Regardless of whether the value is valid, as long as renderValue is set, it is judged to have a value.
   */

  var hasValue = !!activeItem || !(0, _isNil.default)(value) && (0, _isFunction.default)(renderValue);

  var _useClassNames = (0, _utils.useClassNames)(classPrefix),
      prefix = _useClassNames.prefix,
      merge = _useClassNames.merge;

  var selectedElement = placeholder;

  if (activeItem === null || activeItem === void 0 ? void 0 : activeItem[labelKey]) {
    selectedElement = activeItem[labelKey];
  }

  if (!(0, _isNil.default)(value) && (0, _isFunction.default)(renderValue)) {
    selectedElement = renderValue(value, activeItem, selectedElement); // If renderValue returns null or undefined, hasValue is false.

    if ((0, _isNil.default)(selectedElement)) {
      hasValue = false;
    }
  }

  var renderDropdownMenu = function renderDropdownMenu(positionProps, speakerRef) {
    var left = positionProps.left,
        top = positionProps.top,
        className = positionProps.className;
    var classes = merge(className, menuClassName, prefix('select-menu'));
    var styles = (0, _extends2.default)({}, menuStyle, {
      left: left,
      top: top
    });
    var items = filteredData; // Create a tree structure data when set `groupBy`

    if (groupBy) {
      items = (0, _utils.getDataGroupBy)(items, groupBy, sort);
    } else if (typeof sort === 'function') {
      items = items.sort(sort(false));
    }

    var menu = items.length ? /*#__PURE__*/_react.default.createElement(_Picker.DropdownMenu, {
      id: id ? id + "-listbox" : undefined,
      listProps: listProps,
      disabledItemValues: disabledItemValues,
      valueKey: valueKey,
      labelKey: labelKey,
      renderMenuGroup: renderMenuGroup,
      renderMenuItem: renderMenuItem,
      maxHeight: menuMaxHeight,
      classPrefix: 'picker-select-menu',
      dropdownMenuItemClassPrefix: 'picker-select-menu-item',
      dropdownMenuItemAs: _Picker.DropdownMenuItem,
      activeItemValues: [value],
      focusItemValue: focusItemValue,
      data: items,
      group: !(0, _isUndefined.default)(groupBy),
      onSelect: handleItemSelect,
      onGroupTitleClick: onGroupTitleClick,
      virtualized: virtualized
    }) : /*#__PURE__*/_react.default.createElement("div", {
      className: prefix(_templateObject())
    }, locale === null || locale === void 0 ? void 0 : locale.noResultsText);
    return /*#__PURE__*/_react.default.createElement(_Picker.PickerOverlay, {
      ref: (0, _utils.mergeRefs)(overlayRef, speakerRef),
      autoWidth: menuAutoWidth,
      className: classes,
      style: styles,
      onKeyDown: onPickerKeyDown,
      target: triggerRef
    }, searchable && /*#__PURE__*/_react.default.createElement(_Picker.SearchBar, {
      placeholder: locale === null || locale === void 0 ? void 0 : locale.searchPlaceholder,
      onChange: handleSearch,
      value: searchKeyword
    }), renderMenu ? renderMenu(menu) : menu, renderExtraFooter === null || renderExtraFooter === void 0 ? void 0 : renderExtraFooter());
  };

  var _usePickerClassName = (0, _Picker.usePickerClassName)((0, _extends2.default)({}, props, {
    hasValue: hasValue,
    name: 'select'
  })),
      classes = _usePickerClassName[0],
      usedClassNamePropKeys = _usePickerClassName[1];

  return /*#__PURE__*/_react.default.createElement(_Picker.PickerToggleTrigger, {
    pickerProps: (0, _pick.default)(props, _Picker.pickTriggerPropKeys),
    ref: triggerRef,
    placement: placement,
    onEntered: (0, _utils.createChainedFunction)(handleEntered, onEntered),
    onExited: (0, _utils.createChainedFunction)(handleExited, onExited),
    speaker: renderDropdownMenu
  }, /*#__PURE__*/_react.default.createElement(Component, {
    className: classes,
    style: style
  }, /*#__PURE__*/_react.default.createElement(_Picker.PickerToggle, (0, _extends2.default)({}, (0, _omit.default)(rest, [].concat(_Picker.omitTriggerPropKeys, usedClassNamePropKeys)), {
    id: id,
    ref: targetRef,
    onClean: (0, _utils.createChainedFunction)(handleClean, onClean),
    onKeyDown: onPickerKeyDown,
    as: toggleAs,
    disabled: disabled,
    cleanable: cleanable && !disabled,
    hasValue: hasValue,
    inputValue: value,
    active: active,
    placement: placement
  }), selectedElement || (locale === null || locale === void 0 ? void 0 : locale.placeholder))));
});

SelectPicker.displayName = 'SelectPicker';
SelectPicker.defaultProps = defaultProps;
SelectPicker.propTypes = (0, _extends2.default)({}, _Picker.listPickerPropTypes, {
  locale: _propTypes.default.any,
  appearance: _propTypes.default.oneOf(['default', 'subtle']),
  menuAutoWidth: _propTypes.default.bool,
  menuMaxHeight: _propTypes.default.number,
  renderMenu: _propTypes.default.func,
  renderMenuItem: _propTypes.default.func,
  renderMenuGroup: _propTypes.default.func,
  onSelect: _propTypes.default.func,
  onGroupTitleClick: _propTypes.default.func,
  onSearch: _propTypes.default.func,

  /**
   * group by key in `data`
   */
  groupBy: _propTypes.default.any,
  sort: _propTypes.default.func,
  searchable: _propTypes.default.bool,
  virtualized: _propTypes.default.bool,
  searchBy: _propTypes.default.func
});
var _default = SelectPicker;
exports.default = _default;