import * as React from 'react';
import PrimeReact, { localeOption, FilterService } from 'primereact/api';
import { useOverlayListener, useMountEffect, useUpdateEffect, useUnmountEffect } from 'primereact/hooks';
import { OverlayService } from 'primereact/overlayservice';
import { Tooltip } from 'primereact/tooltip';
import { classNames, ObjectUtils, DomHandler, ZIndexUtils } from 'primereact/utils';
import { CSSTransition } from 'primereact/csstransition';
import { Portal } from 'primereact/portal';
import { VirtualScroller } from 'primereact/virtualscroller';
import { Ripple } from 'primereact/ripple';

function _extends() {
  _extends = Object.assign || 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 _defineProperty(obj, key, value) {
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }

  return obj;
}

function _arrayWithHoles(arr) {
  if (Array.isArray(arr)) return arr;
}

function _iterableToArrayLimit(arr, i) {
  var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];

  if (_i == null) return;
  var _arr = [];
  var _n = true;
  var _d = false;

  var _s, _e;

  try {
    for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
      _arr.push(_s.value);

      if (i && _arr.length === i) break;
    }
  } catch (err) {
    _d = true;
    _e = err;
  } finally {
    try {
      if (!_n && _i["return"] != null) _i["return"]();
    } finally {
      if (_d) throw _e;
    }
  }

  return _arr;
}

function _arrayLikeToArray$1(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 _unsupportedIterableToArray$1(o, minLen) {
  if (!o) return;
  if (typeof o === "string") return _arrayLikeToArray$1(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$1(o, minLen);
}

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 _slicedToArray(arr, i) {
  return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray$1(arr, i) || _nonIterableRest();
}

var DropdownItem = /*#__PURE__*/React.memo(function (props) {
  var onClick = function onClick(event) {
    if (props.onClick) {
      props.onClick({
        originalEvent: event,
        option: props.option
      });
    }
  };

  var className = classNames('p-dropdown-item', {
    'p-highlight': props.selected,
    'p-disabled': props.disabled,
    'p-dropdown-item-empty': !props.label || props.label.length === 0
  }, props.option && props.option.className);
  var content = props.template ? ObjectUtils.getJSXElement(props.template, props.option) : props.label;
  return /*#__PURE__*/React.createElement("li", {
    className: className,
    onClick: onClick,
    "aria-label": props.label,
    key: props.label,
    role: "option",
    "aria-selected": props.selected
  }, content, /*#__PURE__*/React.createElement(Ripple, null));
});
DropdownItem.displayName = 'DropdownItem';

function ownKeys$1(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$1(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys$1(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$1(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
var DropdownPanel = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef(function (props, ref) {
  var virtualScrollerRef = React.useRef(null);
  var filterInputRef = React.useRef(null);
  var isEmptyFilter = !(props.visibleOptions && props.visibleOptions.length) && props.hasFilter;

  var onEnter = function onEnter() {
    props.onEnter(function () {
      if (virtualScrollerRef.current) {
        var selectedIndex = props.getSelectedOptionIndex();

        if (selectedIndex !== -1) {
          setTimeout(function () {
            return virtualScrollerRef.current.scrollToIndex(selectedIndex);
          }, 0);
        }
      }
    });
  };

  var onEntered = function onEntered() {
    props.onEntered(function () {
      if (props.filter && props.filterInputAutoFocus) {
        filterInputRef.current.focus();
      }
    });
  };

  var onFilterInputChange = function onFilterInputChange(event) {
    virtualScrollerRef.current && virtualScrollerRef.current.scrollToIndex(0);
    props.onFilterInputChange && props.onFilterInputChange(event);
  };

  var createGroupChildren = function createGroupChildren(optionGroup) {
    var groupChildren = props.getOptionGroupChildren(optionGroup);
    return groupChildren.map(function (option, j) {
      var optionLabel = props.getOptionLabel(option);
      var optionKey = j + '_' + props.getOptionRenderKey(option);
      var disabled = props.isOptionDisabled(option);
      return /*#__PURE__*/React.createElement(DropdownItem, {
        key: optionKey,
        label: optionLabel,
        option: option,
        template: props.itemTemplate,
        selected: props.isSelected(option),
        disabled: disabled,
        onClick: props.onOptionClick
      });
    });
  };

  var createEmptyMessage = function createEmptyMessage(emptyMessage, isFilter) {
    var message = ObjectUtils.getJSXElement(emptyMessage, props) || localeOption(isFilter ? 'emptyFilterMessage' : 'emptyMessage');
    return /*#__PURE__*/React.createElement("li", {
      className: "p-dropdown-empty-message"
    }, message);
  };

  var createItem = function createItem(option, index) {
    if (props.optionGroupLabel) {
      var groupContent = props.optionGroupTemplate ? ObjectUtils.getJSXElement(props.optionGroupTemplate, option, index) : props.getOptionGroupLabel(option);
      var groupChildrenContent = createGroupChildren(option);
      var key = index + '_' + props.getOptionGroupRenderKey(option);
      return /*#__PURE__*/React.createElement(React.Fragment, {
        key: key
      }, /*#__PURE__*/React.createElement("li", {
        className: "p-dropdown-item-group"
      }, groupContent), groupChildrenContent);
    } else {
      var optionLabel = props.getOptionLabel(option);
      var optionKey = index + '_' + props.getOptionRenderKey(option);
      var disabled = props.isOptionDisabled(option);
      return /*#__PURE__*/React.createElement(DropdownItem, {
        key: optionKey,
        label: optionLabel,
        option: option,
        template: props.itemTemplate,
        selected: props.isSelected(option),
        disabled: disabled,
        onClick: props.onOptionClick
      });
    }
  };

  var createItems = function createItems() {
    if (ObjectUtils.isNotEmpty(props.visibleOptions)) {
      return props.visibleOptions.map(createItem);
    } else if (props.hasFilter) {
      return createEmptyMessage(props.emptyFilterMessage, true);
    }

    return createEmptyMessage(props.emptyMessage);
  };

  var createFilterClearIcon = function createFilterClearIcon() {
    if (props.showFilterClear && props.filterValue) {
      return /*#__PURE__*/React.createElement("i", {
        className: "p-dropdown-filter-clear-icon pi pi-times",
        onClick: function onClick() {
          return props.onFilterClearIconClick(function () {
            return filterInputRef.current.focus();
          });
        }
      });
    }

    return null;
  };

  var createFilter = function createFilter() {
    if (props.filter) {
      var clearIcon = createFilterClearIcon();
      var containerClassName = classNames('p-dropdown-filter-container', {
        'p-dropdown-clearable-filter': !!clearIcon
      });
      return /*#__PURE__*/React.createElement("div", {
        className: "p-dropdown-header"
      }, /*#__PURE__*/React.createElement("div", {
        className: containerClassName
      }, /*#__PURE__*/React.createElement("input", {
        ref: filterInputRef,
        type: "text",
        autoComplete: "off",
        className: "p-dropdown-filter p-inputtext p-component",
        placeholder: props.filterPlaceholder,
        onKeyDown: props.onFilterInputKeyDown,
        onChange: onFilterInputChange,
        value: props.filterValue
      }), clearIcon, /*#__PURE__*/React.createElement("i", {
        className: "p-dropdown-filter-icon pi pi-search"
      })));
    }

    return null;
  };

  var createContent = function createContent() {
    if (props.virtualScrollerOptions) {
      var virtualScrollerProps = _objectSpread$1(_objectSpread$1({}, props.virtualScrollerOptions), {
        style: _objectSpread$1(_objectSpread$1({}, props.virtualScrollerOptions.style), {
          height: props.scrollHeight
        }),
        className: classNames('p-dropdown-items-wrapper', props.virtualScrollerOptions.className),
        items: props.visibleOptions,
        onLazyLoad: function onLazyLoad(event) {
          return props.virtualScrollerOptions.onLazyLoad(_objectSpread$1(_objectSpread$1({}, event), {
            filter: props.filterValue
          }));
        },
        itemTemplate: function itemTemplate(item, options) {
          return item && createItem(item, options.index);
        },
        contentTemplate: function contentTemplate(options) {
          var className = classNames('p-dropdown-items', options.className);
          var content = isEmptyFilter ? createEmptyMessage() : options.children;
          return /*#__PURE__*/React.createElement("ul", {
            ref: options.contentRef,
            className: className,
            role: "listbox"
          }, content);
        }
      });

      return /*#__PURE__*/React.createElement(VirtualScroller, _extends({
        ref: virtualScrollerRef
      }, virtualScrollerProps));
    } else {
      var items = createItems();
      return /*#__PURE__*/React.createElement("div", {
        className: "p-dropdown-items-wrapper",
        style: {
          maxHeight: props.scrollHeight || 'auto'
        }
      }, /*#__PURE__*/React.createElement("ul", {
        className: "p-dropdown-items",
        role: "listbox"
      }, items));
    }
  };

  var createElement = function createElement() {
    var className = classNames('p-dropdown-panel p-component', props.panelClassName);
    var filter = createFilter();
    var content = createContent();
    return /*#__PURE__*/React.createElement(CSSTransition, {
      nodeRef: ref,
      classNames: "p-connected-overlay",
      "in": props["in"],
      timeout: {
        enter: 120,
        exit: 100
      },
      options: props.transitionOptions,
      unmountOnExit: true,
      onEnter: onEnter,
      onEntering: props.onEntering,
      onEntered: onEntered,
      onExit: props.onExit,
      onExited: props.onExited
    }, /*#__PURE__*/React.createElement("div", {
      ref: ref,
      className: className,
      style: props.panelStyle,
      onClick: props.onClick
    }, filter, content));
  };

  var element = createElement();
  return /*#__PURE__*/React.createElement(Portal, {
    element: element,
    appendTo: props.appendTo
  });
}));
DropdownPanel.displayName = 'DropdownPanel';

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 _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }

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; }
var Dropdown = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef(function (props, ref) {
  var _React$useState = React.useState(''),
      _React$useState2 = _slicedToArray(_React$useState, 2),
      filterState = _React$useState2[0],
      setFilterState = _React$useState2[1];

  var _React$useState3 = React.useState(false),
      _React$useState4 = _slicedToArray(_React$useState3, 2),
      focusedState = _React$useState4[0],
      setFocusedState = _React$useState4[1];

  var _React$useState5 = React.useState(false),
      _React$useState6 = _slicedToArray(_React$useState5, 2),
      overlayVisibleState = _React$useState6[0],
      setOverlayVisibleState = _React$useState6[1];

  var elementRef = React.useRef(null);
  var overlayRef = React.useRef(null);
  var inputRef = React.useRef(props.inputRef);
  var focusInputRef = React.useRef(null);
  var searchTimeout = React.useRef(null);
  var searchValue = React.useRef(null);
  var currentSearchChar = React.useRef(null);
  var isLazy = props.virtualScrollerOptions && props.virtualScrollerOptions.lazy;
  var hasFilter = ObjectUtils.isNotEmpty(filterState);
  var appendTo = props.appendTo || PrimeReact.appendTo;

  var _useOverlayListener = useOverlayListener({
    target: elementRef,
    overlay: overlayRef,
    listener: function listener(event, _ref) {
      var type = _ref.type,
          valid = _ref.valid;

      if (valid) {
        type === 'outside' ? !isClearClicked(event) && hide() : hide();
      }
    },
    when: overlayVisibleState
  }),
      _useOverlayListener2 = _slicedToArray(_useOverlayListener, 2),
      bindOverlayListener = _useOverlayListener2[0],
      unbindOverlayListener = _useOverlayListener2[1];

  var getVisibleOptions = function getVisibleOptions() {
    if (hasFilter && !isLazy) {
      var filterValue = filterState.trim().toLocaleLowerCase(props.filterLocale);
      var searchFields = props.filterBy ? props.filterBy.split(',') : [props.optionLabel || 'label'];

      if (props.optionGroupLabel) {
        var filteredGroups = [];

        var _iterator = _createForOfIteratorHelper(props.options),
            _step;

        try {
          for (_iterator.s(); !(_step = _iterator.n()).done;) {
            var optgroup = _step.value;
            var filteredSubOptions = FilterService.filter(getOptionGroupChildren(optgroup), searchFields, filterValue, props.filterMatchMode, props.filterLocale);

            if (filteredSubOptions && filteredSubOptions.length) {
              filteredGroups.push(_objectSpread(_objectSpread({}, optgroup), {
                items: filteredSubOptions
              }));
            }
          }
        } catch (err) {
          _iterator.e(err);
        } finally {
          _iterator.f();
        }

        return filteredGroups;
      } else {
        return FilterService.filter(props.options, searchFields, filterValue, props.filterMatchMode, props.filterLocale);
      }
    } else {
      return props.options;
    }
  };

  var isClearClicked = function isClearClicked(event) {
    return DomHandler.hasClass(event.target, 'p-dropdown-clear-icon') || DomHandler.hasClass(event.target, 'p-dropdown-filter-clear-icon');
  };

  var onClick = function onClick(event) {
    if (props.disabled) {
      return;
    }

    if (DomHandler.hasClass(event.target, 'p-dropdown-clear-icon') || event.target.tagName === 'INPUT') {
      return;
    } else if (!overlayRef.current || !(overlayRef.current && overlayRef.current.contains(event.target))) {
      focusInputRef.current.focus();
      overlayVisibleState ? hide() : show();
    }
  };

  var onInputFocus = function onInputFocus(event) {
    if (props.showOnFocus && !overlayVisibleState) {
      show();
    }

    setFocusedState(true);
    props.onFocus && props.onFocus(event);
  };

  var onInputBlur = function onInputBlur(event) {
    setFocusedState(false);
    props.onBlur && props.onBlur(event);
  };

  var onPanelClick = function onPanelClick(event) {
    OverlayService.emit('overlay-click', {
      originalEvent: event,
      target: elementRef.current
    });
  };

  var onInputKeyDown = function onInputKeyDown(event) {
    switch (event.which) {
      //down
      case 40:
        onDownKey(event);
        break;
      //up

      case 38:
        onUpKey(event);
        break;
      //space

      case 32:
        overlayVisibleState ? hide() : show();
        event.preventDefault();
        break;
      //enter

      case 13:
        hide();
        event.preventDefault();
        break;
      //escape and tab

      case 27:
      case 9:
        hide();
        break;

      default:
        search(event);
        break;
    }
  };

  var onFilterInputKeyDown = function onFilterInputKeyDown(event) {
    switch (event.which) {
      //down
      case 40:
        onDownKey(event);
        break;
      //up

      case 38:
        onUpKey(event);
        break;
      //enter and escape

      case 13:
      case 27:
        hide();
        event.preventDefault();
        break;
    }
  };

  var onUpKey = function onUpKey(event) {
    if (visibleOptions) {
      var prevOption = findPrevOption(getSelectedOptionIndex());

      if (prevOption) {
        selectItem({
          originalEvent: event,
          option: prevOption
        });
      }
    }

    event.preventDefault();
  };

  var onDownKey = function onDownKey(event) {
    if (visibleOptions) {
      if (!overlayVisibleState && event.altKey) {
        show();
      } else {
        var nextOption = findNextOption(getSelectedOptionIndex());

        if (nextOption) {
          selectItem({
            originalEvent: event,
            option: nextOption
          });
        }
      }
    }

    event.preventDefault();
  };

  var findNextOption = function findNextOption(index) {
    if (props.optionGroupLabel) {
      var groupIndex = index === -1 ? 0 : index.group;
      var optionIndex = index === -1 ? -1 : index.option;
      var option = findNextOptionInList(getOptionGroupChildren(visibleOptions[groupIndex]), optionIndex);
      if (option) return option;else if (groupIndex + 1 !== visibleOptions.length) return findNextOption({
        group: groupIndex + 1,
        option: -1
      });else return null;
    }

    return findNextOptionInList(visibleOptions, index);
  };

  var findNextOptionInList = function findNextOptionInList(list, index) {
    var i = index + 1;

    if (i === list.length) {
      return null;
    }

    var option = list[i];
    return isOptionDisabled(option) ? findNextOptionInList(i) : option;
  };

  var findPrevOption = function findPrevOption(index) {
    if (index === -1) {
      return null;
    }

    if (props.optionGroupLabel) {
      var groupIndex = index.group;
      var optionIndex = index.option;
      var option = findPrevOptionInList(getOptionGroupChildren(visibleOptions[groupIndex]), optionIndex);
      if (option) return option;else if (groupIndex > 0) return findPrevOption({
        group: groupIndex - 1,
        option: getOptionGroupChildren(visibleOptions[groupIndex - 1]).length
      });else return null;
    }

    return findPrevOptionInList(visibleOptions, index);
  };

  var findPrevOptionInList = function findPrevOptionInList(list, index) {
    var i = index - 1;

    if (i < 0) {
      return null;
    }

    var option = list[i];
    return isOptionDisabled(option) ? findPrevOption(i) : option;
  };

  var search = function search(event) {
    if (searchTimeout.current) {
      clearTimeout(searchTimeout.current);
    }

    var _char = event.key;
    if (currentSearchChar.current === _char) searchValue.current = _char;else searchValue.current = searchValue.current ? searchValue.current + _char : _char;
    currentSearchChar.current = _char;

    if (searchValue.current) {
      var searchIndex = getSelectedOptionIndex();
      var newOption = props.optionGroupLabel ? searchOptionInGroup(searchIndex) : searchOption(searchIndex + 1);

      if (newOption) {
        selectItem({
          originalEvent: event,
          option: newOption
        });
      }
    }

    searchTimeout.current = setTimeout(function () {
      searchValue.current = null;
    }, 250);
  };

  var searchOption = function searchOption(index) {
    if (searchValue.current) {
      return searchOptionInRange(index, visibleOptions.length) || searchOptionInRange(0, index);
    }

    return null;
  };

  var searchOptionInRange = function searchOptionInRange(start, end) {
    for (var i = start; i < end; i++) {
      var opt = visibleOptions[i];

      if (matchesSearchValue(opt)) {
        return opt;
      }
    }

    return null;
  };

  var searchOptionInGroup = function searchOptionInGroup(index) {
    var searchIndex = index === -1 ? {
      group: 0,
      option: -1
    } : index;

    for (var i = searchIndex.group; i < visibleOptions.length; i++) {
      var groupOptions = getOptionGroupChildren(visibleOptions[i]);

      for (var j = searchIndex.group === i ? searchIndex.option + 1 : 0; j < groupOptions.length; j++) {
        if (matchesSearchValue(groupOptions[j])) {
          return groupOptions[j];
        }
      }
    }

    for (var _i = 0; _i <= searchIndex.group; _i++) {
      var _groupOptions = getOptionGroupChildren(visibleOptions[_i]);

      for (var _j = 0; _j < (searchIndex.group === _i ? searchIndex.option : _groupOptions.length); _j++) {
        if (matchesSearchValue(_groupOptions[_j])) {
          return _groupOptions[_j];
        }
      }
    }

    return null;
  };

  var matchesSearchValue = function matchesSearchValue(option) {
    var label = getOptionLabel(option).toLocaleLowerCase(props.filterLocale);
    return label.startsWith(searchValue.current.toLocaleLowerCase(props.filterLocale));
  };

  var onEditableInputChange = function onEditableInputChange(event) {
    if (props.onChange) {
      props.onChange({
        originalEvent: event.originalEvent,
        value: event.target.value,
        stopPropagation: function stopPropagation() {},
        preventDefault: function preventDefault() {},
        target: {
          name: props.name,
          id: props.id,
          value: event.target.value
        }
      });
    }
  };

  var onEditableInputFocus = function onEditableInputFocus(event) {
    setFocusedState(true);
    hide();
    props.onFocus && props.onFocus(event);
  };

  var onOptionClick = function onOptionClick(event) {
    var option = event.option;

    if (!option.disabled) {
      selectItem(event);
      focusInputRef.current.focus();
    }

    hide();
  };

  var onFilterInputChange = function onFilterInputChange(event) {
    var filter = event.target.value;
    setFilterState(filter);

    if (props.onFilter) {
      props.onFilter({
        originalEvent: event,
        filter: filter
      });
    }
  };

  var onFilterClearIconClick = function onFilterClearIconClick(callback) {
    resetFilter(callback);
  };

  var resetFilter = function resetFilter(callback) {
    setFilterState('');
    props.onFilter && props.onFilter({
      filter: ''
    });
    callback && callback();
  };

  var clear = function clear(event) {
    if (props.onChange) {
      props.onChange({
        originalEvent: event,
        value: undefined,
        stopPropagation: function stopPropagation() {},
        preventDefault: function preventDefault() {},
        target: {
          name: props.name,
          id: props.id,
          value: undefined
        }
      });
    }

    updateEditableLabel();
  };

  var selectItem = function selectItem(event) {
    if (selectedOption !== event.option) {
      updateEditableLabel(event.option);
      var optionValue = getOptionValue(event.option);

      if (props.onChange) {
        props.onChange({
          originalEvent: event.originalEvent,
          value: optionValue,
          stopPropagation: function stopPropagation() {},
          preventDefault: function preventDefault() {},
          target: {
            name: props.name,
            id: props.id,
            value: optionValue
          }
        });
      }
    }
  };

  var getSelectedOptionIndex = function getSelectedOptionIndex() {
    if (props.value != null && visibleOptions) {
      if (props.optionGroupLabel) {
        for (var i = 0; i < visibleOptions.length; i++) {
          var selectedOptionIndex = findOptionIndexInList(props.value, getOptionGroupChildren(visibleOptions[i]));

          if (selectedOptionIndex !== -1) {
            return {
              group: i,
              option: selectedOptionIndex
            };
          }
        }
      } else {
        return findOptionIndexInList(props.value, visibleOptions);
      }
    }

    return -1;
  };

  var equalityKey = function equalityKey() {
    return props.optionValue ? null : props.dataKey;
  };

  var findOptionIndexInList = function findOptionIndexInList(value, list) {
    var key = equalityKey();
    return list.findIndex(function (item) {
      return ObjectUtils.equals(value, getOptionValue(item), key);
    });
  };

  var isSelected = function isSelected(option) {
    return ObjectUtils.equals(props.value, getOptionValue(option), equalityKey());
  };

  var show = function show() {
    setOverlayVisibleState(true);
  };

  var hide = function hide() {
    setOverlayVisibleState(false);
  };

  var onOverlayEnter = function onOverlayEnter(callback) {
    ZIndexUtils.set('overlay', overlayRef.current, PrimeReact.autoZIndex, PrimeReact.zIndex['overlay']);
    alignOverlay();
    callback && callback();
  };

  var onOverlayEntered = function onOverlayEntered(callback) {
    callback && callback();
    bindOverlayListener();
    props.onShow && props.onShow();
  };

  var onOverlayExit = function onOverlayExit() {
    unbindOverlayListener();
  };

  var onOverlayExited = function onOverlayExited() {
    if (props.filter && props.resetFilterOnHide) {
      resetFilter();
    }

    ZIndexUtils.clear(overlayRef.current);
    props.onHide && props.onHide();
  };

  var alignOverlay = function alignOverlay() {
    DomHandler.alignOverlay(overlayRef.current, inputRef.current.parentElement, props.appendTo || PrimeReact.appendTo);
  };

  var scrollInView = function scrollInView() {
    var highlightItem = DomHandler.findSingle(overlayRef.current, 'li.p-highlight');

    if (highlightItem && highlightItem.scrollIntoView) {
      highlightItem.scrollIntoView({
        block: 'nearest',
        inline: 'start'
      });
    }
  };

  var updateEditableLabel = function updateEditableLabel(option) {
    if (inputRef.current) {
      inputRef.current.value = option ? getOptionLabel(option) : props.value || '';
    }
  };

  var getOptionLabel = function getOptionLabel(option) {
    return props.optionLabel ? ObjectUtils.resolveFieldData(option, props.optionLabel) : option && option['label'] !== undefined ? option['label'] : option;
  };

  var getOptionValue = function getOptionValue(option) {
    return props.optionValue ? ObjectUtils.resolveFieldData(option, props.optionValue) : option && option['value'] !== undefined ? option['value'] : option;
  };

  var getOptionRenderKey = function getOptionRenderKey(option) {
    return props.dataKey ? ObjectUtils.resolveFieldData(option, props.dataKey) : getOptionLabel(option);
  };

  var isOptionDisabled = function isOptionDisabled(option) {
    if (props.optionDisabled) {
      return ObjectUtils.isFunction(props.optionDisabled) ? props.optionDisabled(option) : ObjectUtils.resolveFieldData(option, props.optionDisabled);
    }

    return option && option['disabled'] !== undefined ? option['disabled'] : false;
  };

  var getOptionGroupRenderKey = function getOptionGroupRenderKey(optionGroup) {
    return ObjectUtils.resolveFieldData(optionGroup, props.optionGroupLabel);
  };

  var getOptionGroupLabel = function getOptionGroupLabel(optionGroup) {
    return ObjectUtils.resolveFieldData(optionGroup, props.optionGroupLabel);
  };

  var getOptionGroupChildren = function getOptionGroupChildren(optionGroup) {
    return ObjectUtils.resolveFieldData(optionGroup, props.optionGroupChildren);
  };

  var updateInputField = function updateInputField() {
    if (props.editable && inputRef.current) {
      var label = selectedOption ? getOptionLabel(selectedOption) : null;
      var value = label || props.value || '';
      inputRef.current.value = value;
    }
  };

  var getSelectedOption = function getSelectedOption() {
    var index = getSelectedOptionIndex();
    return index !== -1 ? props.optionGroupLabel ? getOptionGroupChildren(visibleOptions[index.group])[index.option] : visibleOptions[index] : null;
  };

  React.useEffect(function () {
    ObjectUtils.combinedRefs(inputRef, props.inputRef);
  }, [inputRef, props.inputRef]);
  useMountEffect(function () {
    if (props.autoFocus && focusInputRef.current) {
      focusInputRef.current.focus();
    }
  });
  useUpdateEffect(function () {
    if (overlayVisibleState && props.value) {
      scrollInView();
    }
  }, [overlayVisibleState, props.value]);
  useUpdateEffect(function () {
    if (overlayVisibleState && props.filter) {
      alignOverlay();
    }
  }, [overlayVisibleState, props.filter]);
  useUpdateEffect(function () {
    if (filterState && (!props.options || props.options.length === 0)) {
      setFilterState('');
    }

    updateInputField();

    if (inputRef.current) {
      inputRef.current.selectedIndex = 1;
    }
  });
  useUnmountEffect(function () {
    ZIndexUtils.clear(overlayRef.current);
  });

  var createHiddenSelect = function createHiddenSelect() {
    var placeHolderOption = /*#__PURE__*/React.createElement("option", {
      value: ""
    }, props.placeholder);
    var option = selectedOption ? /*#__PURE__*/React.createElement("option", {
      value: selectedOption.value
    }, getOptionLabel(selectedOption)) : null;
    return /*#__PURE__*/React.createElement("div", {
      className: "p-hidden-accessible p-dropdown-hidden-select"
    }, /*#__PURE__*/React.createElement("select", {
      ref: inputRef,
      required: props.required,
      name: props.name,
      tabIndex: -1,
      "aria-hidden": "true"
    }, placeHolderOption, option));
  };

  var createKeyboardHelper = function createKeyboardHelper() {
    return /*#__PURE__*/React.createElement("div", {
      className: "p-hidden-accessible"
    }, /*#__PURE__*/React.createElement("input", {
      ref: focusInputRef,
      id: props.inputId,
      type: "text",
      readOnly: true,
      "aria-haspopup": "listbox",
      onFocus: onInputFocus,
      onBlur: onInputBlur,
      onKeyDown: onInputKeyDown,
      disabled: props.disabled,
      tabIndex: props.tabIndex,
      "aria-label": props.ariaLabel,
      "aria-labelledby": props.ariaLabelledBy
    }));
  };

  var createLabel = function createLabel() {
    var label = ObjectUtils.isNotEmpty(selectedOption) ? getOptionLabel(selectedOption) : null;

    if (props.editable) {
      var value = label || props.value || '';
      return /*#__PURE__*/React.createElement("input", {
        ref: inputRef,
        type: "text",
        defaultValue: value,
        className: "p-dropdown-label p-inputtext",
        disabled: props.disabled,
        placeholder: props.placeholder,
        maxLength: props.maxLength,
        onInput: onEditableInputChange,
        onFocus: onEditableInputFocus,
        onBlur: onInputBlur,
        "aria-label": props.ariaLabel,
        "aria-labelledby": props.ariaLabelledBy,
        "aria-haspopup": "listbox"
      });
    } else {
      var _className = classNames('p-dropdown-label p-inputtext', {
        'p-placeholder': label === null && props.placeholder,
        'p-dropdown-label-empty': label === null && !props.placeholder
      });

      var content = props.valueTemplate ? ObjectUtils.getJSXElement(props.valueTemplate, selectedOption, props) : label || props.placeholder || 'empty';
      return /*#__PURE__*/React.createElement("span", {
        ref: inputRef,
        className: _className
      }, content);
    }
  };

  var createClearIcon = function createClearIcon() {
    if (props.value != null && props.showClear && !props.disabled) {
      return /*#__PURE__*/React.createElement("i", {
        className: "p-dropdown-clear-icon pi pi-times",
        onClick: clear
      });
    }

    return null;
  };

  var createDropdownIcon = function createDropdownIcon() {
    var iconClassName = classNames('p-dropdown-trigger-icon p-clickable', props.dropdownIcon);
    return /*#__PURE__*/React.createElement("div", {
      className: "p-dropdown-trigger",
      role: "button",
      "aria-haspopup": "listbox",
      "aria-expanded": overlayVisibleState
    }, /*#__PURE__*/React.createElement("span", {
      className: iconClassName
    }));
  };

  var visibleOptions = getVisibleOptions();
  var selectedOption = getSelectedOption();
  var hasTooltip = ObjectUtils.isNotEmpty(props.tooltip);
  var otherProps = ObjectUtils.findDiffKeys(props, Dropdown.defaultProps);
  var className = classNames('p-dropdown p-component p-inputwrapper', {
    'p-disabled': props.disabled,
    'p-focus': focusedState,
    'p-dropdown-clearable': props.showClear && !props.disabled,
    'p-inputwrapper-filled': ObjectUtils.isNotEmpty(props.value),
    'p-inputwrapper-focus': focusedState || overlayVisibleState
  }, props.className);
  var hiddenSelect = createHiddenSelect();
  var keyboardHelper = createKeyboardHelper();
  var labelElement = createLabel();
  var dropdownIcon = createDropdownIcon();
  var clearIcon = createClearIcon();
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", _extends({
    ref: elementRef,
    id: props.id,
    className: className,
    style: props.style
  }, otherProps, {
    onClick: onClick,
    onMouseDown: props.onMouseDown,
    onContextMenu: props.onContextMenu
  }), keyboardHelper, hiddenSelect, labelElement, clearIcon, dropdownIcon, /*#__PURE__*/React.createElement(DropdownPanel, _extends({
    ref: overlayRef,
    visibleOptions: visibleOptions
  }, props, {
    appendTo: appendTo,
    onClick: onPanelClick,
    onOptionClick: onOptionClick,
    filterValue: filterState,
    hasFilter: hasFilter,
    onFilterClearIconClick: onFilterClearIconClick,
    onFilterInputKeyDown: onFilterInputKeyDown,
    onFilterInputChange: onFilterInputChange,
    getOptionLabel: getOptionLabel,
    getOptionRenderKey: getOptionRenderKey,
    isOptionDisabled: isOptionDisabled,
    getOptionGroupChildren: getOptionGroupChildren,
    getOptionGroupLabel: getOptionGroupLabel,
    getOptionGroupRenderKey: getOptionGroupRenderKey,
    isSelected: isSelected,
    getSelectedOptionIndex: getSelectedOptionIndex,
    "in": overlayVisibleState,
    onEnter: onOverlayEnter,
    onEntered: onOverlayEntered,
    onExit: onOverlayExit,
    onExited: onOverlayExited
  }))), hasTooltip && /*#__PURE__*/React.createElement(Tooltip, _extends({
    target: elementRef,
    content: props.tooltip
  }, props.tooltipOptions)));
}));
Dropdown.displayName = 'Dropdown';
Dropdown.defaultProps = {
  __TYPE: 'Dropdown',
  id: null,
  inputRef: null,
  name: null,
  value: null,
  options: null,
  optionLabel: null,
  optionValue: null,
  optionDisabled: null,
  optionGroupLabel: null,
  optionGroupChildren: null,
  optionGroupTemplate: null,
  valueTemplate: null,
  itemTemplate: null,
  style: null,
  className: null,
  virtualScrollerOptions: null,
  scrollHeight: '200px',
  filter: false,
  filterBy: null,
  filterMatchMode: 'contains',
  filterPlaceholder: null,
  filterLocale: undefined,
  emptyMessage: null,
  emptyFilterMessage: null,
  editable: false,
  placeholder: null,
  required: false,
  disabled: false,
  appendTo: null,
  tabIndex: null,
  autoFocus: false,
  filterInputAutoFocus: true,
  resetFilterOnHide: false,
  showFilterClear: false,
  panelClassName: null,
  panelStyle: null,
  dataKey: null,
  inputId: null,
  showClear: false,
  maxLength: null,
  tooltip: null,
  tooltipOptions: null,
  ariaLabel: null,
  ariaLabelledBy: null,
  transitionOptions: null,
  dropdownIcon: 'pi pi-chevron-down',
  showOnFocus: false,
  onChange: null,
  onFocus: null,
  onBlur: null,
  onMouseDown: null,
  onContextMenu: null,
  onShow: null,
  onHide: null,
  onFilter: null
};

export { Dropdown };
