"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// packages/components/src/combobox-control/index.tsx
var combobox_control_exports = {};
__export(combobox_control_exports, {
  default: () => combobox_control_default
});
module.exports = __toCommonJS(combobox_control_exports);
var import_clsx = __toESM(require("clsx"), 1);
var import_i18n = require("@wordpress/i18n");
var import_element = require("@wordpress/element");
var import_compose = require("@wordpress/compose");
var import_a11y = require("@wordpress/a11y");
var import_icons = require("@wordpress/icons");
var import_styles = require("./styles.cjs");
var import_token_input = __toESM(require("../form-token-field/token-input.cjs"), 1);
var import_suggestions_list = __toESM(require("../form-token-field/suggestions-list.cjs"), 1);
var import_base_control = __toESM(require("../base-control/index.cjs"), 1);
var import_button = __toESM(require("../button/index.cjs"), 1);
var import_flex = require("../flex/index.cjs");
var import_with_focus_outside = __toESM(require("../higher-order/with-focus-outside/index.cjs"), 1);
var import_hooks = require("../utils/hooks/index.cjs");
var import_strings = require("../utils/strings.cjs");
var import_use_deprecated_props = require("../utils/use-deprecated-props.cjs");
var import_with_ignore_ime_events = require("../utils/with-ignore-ime-events.cjs");
var import_deprecated_36px_size = require("../utils/deprecated-36px-size.cjs");
var import_spinner = __toESM(require("../spinner/index.cjs"), 1);
var import_jsx_runtime = require("react/jsx-runtime");
var noop = () => {
};
var DetectOutside = (0, import_with_focus_outside.default)(class extends import_element.Component {
  handleFocusOutside(event) {
    this.props.onFocusOutside(event);
  }
  render() {
    return this.props.children;
  }
});
var getIndexOfMatchingSuggestion = (selectedSuggestion, matchingSuggestions) => selectedSuggestion === null ? -1 : matchingSuggestions.indexOf(selectedSuggestion);
function ComboboxControl(props) {
  var _currentOption$label;
  const {
    __next40pxDefaultSize = false,
    value: valueProp,
    label,
    options,
    onChange: onChangeProp,
    onFilterValueChange = noop,
    hideLabelFromVision,
    help,
    allowReset = true,
    className,
    isLoading = false,
    messages = {
      selected: (0, import_i18n.__)("Item selected.")
    },
    __experimentalRenderItem,
    expandOnFocus = true,
    placeholder
  } = (0, import_use_deprecated_props.useDeprecated36pxDefaultSizeProp)(props);
  const [value, setValue] = (0, import_hooks.useControlledValue)({
    value: valueProp,
    onChange: onChangeProp
  });
  const currentOption = options.find((option) => option.value === value);
  const currentLabel = (_currentOption$label = currentOption?.label) !== null && _currentOption$label !== void 0 ? _currentOption$label : "";
  const instanceId = (0, import_compose.useInstanceId)(ComboboxControl, "combobox-control");
  const [selectedSuggestion, setSelectedSuggestion] = (0, import_element.useState)(currentOption || null);
  const [isExpanded, setIsExpanded] = (0, import_element.useState)(false);
  const [inputHasFocus, setInputHasFocus] = (0, import_element.useState)(false);
  const [inputValue, setInputValue] = (0, import_element.useState)("");
  const inputContainer = (0, import_element.useRef)(null);
  const matchingSuggestions = (0, import_element.useMemo)(() => {
    const startsWithMatch = [];
    const containsMatch = [];
    const match = (0, import_strings.normalizeTextString)(inputValue);
    options.forEach((option) => {
      const index = (0, import_strings.normalizeTextString)(option.label).indexOf(match);
      if (index === 0) {
        startsWithMatch.push(option);
      } else if (index > 0) {
        containsMatch.push(option);
      }
    });
    return startsWithMatch.concat(containsMatch);
  }, [inputValue, options]);
  const onSuggestionSelected = (newSelectedSuggestion) => {
    if (newSelectedSuggestion.disabled) {
      return;
    }
    setValue(newSelectedSuggestion.value);
    (0, import_a11y.speak)(messages.selected, "assertive");
    setSelectedSuggestion(newSelectedSuggestion);
    setInputValue("");
    setIsExpanded(false);
  };
  const handleArrowNavigation = (offset = 1) => {
    const index = getIndexOfMatchingSuggestion(selectedSuggestion, matchingSuggestions);
    let nextIndex = index + offset;
    if (nextIndex < 0) {
      nextIndex = matchingSuggestions.length - 1;
    } else if (nextIndex >= matchingSuggestions.length) {
      nextIndex = 0;
    }
    setSelectedSuggestion(matchingSuggestions[nextIndex]);
    setIsExpanded(true);
  };
  const onKeyDown = (0, import_with_ignore_ime_events.withIgnoreIMEEvents)((event) => {
    let preventDefault = false;
    if (event.defaultPrevented) {
      return;
    }
    switch (event.code) {
      case "Enter":
        if (selectedSuggestion) {
          onSuggestionSelected(selectedSuggestion);
          preventDefault = true;
        }
        break;
      case "ArrowUp":
        handleArrowNavigation(-1);
        preventDefault = true;
        break;
      case "ArrowDown":
        handleArrowNavigation(1);
        preventDefault = true;
        break;
      case "Escape":
        setIsExpanded(false);
        setSelectedSuggestion(null);
        preventDefault = true;
        break;
      default:
        break;
    }
    if (preventDefault) {
      event.preventDefault();
    }
  });
  const onBlur = () => {
    setInputHasFocus(false);
  };
  const onFocus = () => {
    setInputHasFocus(true);
    if (expandOnFocus) {
      setIsExpanded(true);
    }
    onFilterValueChange("");
    setInputValue("");
  };
  const onClick = () => {
    setIsExpanded(true);
  };
  const onFocusOutside = () => {
    setIsExpanded(false);
  };
  const onInputChange = (event) => {
    const text = event.value;
    setInputValue(text);
    onFilterValueChange(text);
    if (inputHasFocus) {
      setIsExpanded(true);
    }
  };
  const handleOnReset = () => {
    setValue(null);
    inputContainer.current?.focus();
  };
  const handleResetStopPropagation = (event) => {
    event.stopPropagation();
  };
  (0, import_element.useEffect)(() => {
    const hasMatchingSuggestions = matchingSuggestions.length > 0;
    const hasSelectedMatchingSuggestions = getIndexOfMatchingSuggestion(selectedSuggestion, matchingSuggestions) > 0;
    if (hasMatchingSuggestions && !hasSelectedMatchingSuggestions) {
      setSelectedSuggestion(matchingSuggestions[0]);
    }
  }, [matchingSuggestions, selectedSuggestion]);
  (0, import_element.useEffect)(() => {
    const hasMatchingSuggestions = matchingSuggestions.length > 0;
    if (isExpanded) {
      const message = hasMatchingSuggestions ? (0, import_i18n.sprintf)(
        /* translators: %d: number of results. */
        (0, import_i18n._n)("%d result found, use up and down arrow keys to navigate.", "%d results found, use up and down arrow keys to navigate.", matchingSuggestions.length),
        matchingSuggestions.length
      ) : (0, import_i18n.__)("No results.");
      (0, import_a11y.speak)(message, "polite");
    }
  }, [matchingSuggestions, isExpanded]);
  (0, import_deprecated_36px_size.maybeWarnDeprecated36pxSize)({
    componentName: "ComboboxControl",
    __next40pxDefaultSize,
    size: void 0
  });
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DetectOutside, {
    onFocusOutside,
    children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_base_control.default, {
      className: (0, import_clsx.default)(className, "components-combobox-control"),
      label,
      id: `components-form-token-input-${instanceId}`,
      hideLabelFromVision,
      help,
      children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
        className: "components-combobox-control__suggestions-container",
        tabIndex: -1,
        onKeyDown,
        children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_styles.InputWrapperFlex, {
          __next40pxDefaultSize,
          children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_flex.FlexBlock, {
            children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_token_input.default, {
              className: "components-combobox-control__input",
              instanceId,
              ref: inputContainer,
              placeholder,
              value: isExpanded ? inputValue : currentLabel,
              onFocus,
              onBlur,
              onClick,
              isExpanded,
              selectedSuggestionIndex: getIndexOfMatchingSuggestion(selectedSuggestion, matchingSuggestions),
              onChange: onInputChange
            })
          }), isLoading && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_spinner.default, {}), allowReset && Boolean(value) && !isExpanded && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_button.default, {
            size: "small",
            icon: import_icons.closeSmall,
            onClick: handleOnReset,
            onKeyDown: handleResetStopPropagation,
            label: (0, import_i18n.__)("Reset")
          })]
        }), isExpanded && !isLoading && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_suggestions_list.default, {
          instanceId,
          match: {
            label: inputValue,
            value: ""
          },
          displayTransform: (suggestion) => suggestion.label,
          suggestions: matchingSuggestions,
          selectedIndex: getIndexOfMatchingSuggestion(selectedSuggestion, matchingSuggestions),
          onHover: setSelectedSuggestion,
          onSelect: onSuggestionSelected,
          scrollIntoView: true,
          __experimentalRenderItem
        })]
      })
    })
  });
}
var combobox_control_default = ComboboxControl;
//# sourceMappingURL=index.cjs.map
