/* COPYRIGHT Esri - https://js.arcgis.com/5.1/LICENSE.txt */
import { c as customElement } from "../../chunks/runtime.js";
import { repeat } from "lit/directives/repeat.js";
import { css, nothing, html } from "lit";
import { LitElement, createEvent, stringOrBoolean, safeClassMap } from "@arcgis/lumina";
import { useWatchAttributes, useDirection } from "@arcgis/lumina/controllers";
import { debounce } from "es-toolkit";
import { escapeRegExp } from "es-toolkit/compat";
import { createRef, ref } from "lit/directives/ref.js";
import { d as defaultMenuPlacement, r as reposition, c as connectFloatingUI, a as disconnectFloatingUI, F as FloatingCSS } from "../../chunks/floating-ui.js";
import { c as connectLabel, d as disconnectLabel, g as getLabelText } from "../../chunks/label.js";
import { s as slotChangeHasAssignedElement } from "../../chunks/dom.js";
import { g as guid } from "../../chunks/guid.js";
import { u as useT9n } from "../../chunks/useT9n.js";
import { u as useCancelable } from "../../chunks/useCancelable.js";
import { I as InternalLabel } from "../../chunks/InternalLabel.js";
import { V as Validation } from "../../chunks/Validation.js";
import { c as createObserver, u as updateRefObserver } from "../../chunks/observers.js";
import { u as useSetFocus } from "../../chunks/useSetFocus.js";
import { u as useInteractive } from "../../chunks/useInteractive.js";
import { t as toggleOpenClose } from "../../chunks/openCloseComponent.js";
import { u as useTopLayer } from "../../chunks/useTopLayer.js";
import { u as useForm } from "../../chunks/useForm.js";
const styles = css`:host([disabled]){cursor:default;-webkit-user-select:none;user-select:none;opacity:var(--calcite-opacity-disabled)}:host([disabled]) *,:host([disabled]) ::slotted(*){pointer-events:none}:host{position:relative;display:block}.input-container{position:relative;display:flex;flex:1 1 auto;flex-wrap:nowrap}.input{width:100%;--calcite-input-prefix-size: var(--calcite-autocomplete-input-prefix-size);--calcite-input-suffix-size: var(--calcite-autocomplete-input-suffix-size);--calcite-input-background-color: var(--calcite-autocomplete-input-background-color);--calcite-input-border-color: var(--calcite-autocomplete-input-border-color);--calcite-input-corner-radius: var(--calcite-autocomplete-input-corner-radius);--calcite-input-shadow: var(--calcite-autocomplete-input-shadow);--calcite-input-icon-color: var(--calcite-autocomplete-input-icon-color);--calcite-input-text-color: var(--calcite-autocomplete-input-text-color);--calcite-input-placeholder-text-color: var(--calcite-autocomplete-input-placeholder-text-color);--calcite-input-actions-background-color: var(--calcite-autocomplete-input-actions-background-color);--calcite-input-actions-background-color-hover: var(--calcite-autocomplete-input-actions-background-color-hover);--calcite-input-actions-background-color-press: var(--calcite-autocomplete-input-actions-background-color-press);--calcite-input-actions-icon-color: var(--calcite-autocomplete-input-actions-icon-color);--calcite-input-actions-icon-color-hover: var(--calcite-autocomplete-input-actions-icon-color-hover);--calcite-input-actions-icon-color-press: var(--calcite-autocomplete-input-actions-icon-color-press);--calcite-input-loading-background-color: var(--calcite-autocomplete-input-loading-background-color);--calcite-input-loading-fill-color: var(--calcite-autocomplete-input-loading-fill-color);--calcite-input-prefix-text-color: var(--calcite-autocomplete-input-prefix-text-color);--calcite-input-suffix-text-color: var(--calcite-autocomplete-input-suffix-text-color)}:host([disabled]) ::slotted([calcite-hydrated][disabled]),:host([disabled]) [calcite-hydrated][disabled]{opacity:1}.interaction-container{display:contents}.content-container{box-sizing:border-box;width:100%}.floating-ui-container{inline-size:max-content;display:none;max-inline-size:100vw;max-block-size:100vh;inset-block-start:0;left:0;z-index:var(--calcite-floating-ui-z-index)}@starting-style{.floating-ui-container{opacity:0;inset-block-start:0;left:0}}:host([top-layer-disabled]) .floating-ui-container{--calcite-floating-ui-z-index: var(--calcite-z-index-dropdown)}.floating-ui-container[popover]{padding:0;margin:0;border:none;background-color:transparent;overflow:visible;display:none}.floating-ui-container:popover-open{display:block}.floating-ui-container .calcite-floating-ui-anim{position:relative;transition-duration:var(--calcite-floating-ui-transition);transition-property:inset-block-start,left,opacity,display;transition-behavior:allow-discrete;opacity:0;box-shadow:0 0 16px #00000029;z-index:var(--calcite-z-index);border-radius:.25rem}.floating-ui-container[data-placement^=bottom] .calcite-floating-ui-anim{inset-block-start:-5px}.floating-ui-container[data-placement^=top] .calcite-floating-ui-anim{inset-block-start:5px}.floating-ui-container[data-placement^=left] .calcite-floating-ui-anim{left:5px}.floating-ui-container[data-placement^=right] .calcite-floating-ui-anim{left:-5px}.floating-ui-container[data-placement] .calcite-floating-ui-anim--active{opacity:1;inset-block-start:0;left:0}@starting-style{.floating-ui-container[data-placement] .calcite-floating-ui-anim--active{opacity:0}}.content-container .calcite-floating-ui-anim{width:100%;overflow-y:auto;box-shadow:var(--calcite-shadow-md);max-block-size:var(--calcite-autocomplete-menu-max-size-y, 45vh);color:var(--calcite-autocomplete-text-color, var(--calcite-color-text-1));background-color:var(--calcite-autocomplete-background-color, var(--calcite-color-foreground-1));border-radius:var(--calcite-autocomplete-corner-radius, var(--calcite-corner-radius-round))}.content--hidden{display:none}@media(forced-colors:active){.floating-ui-container--active{border:1px solid canvasText}}.screen-readers-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.internal-label-alignment--center{align-items:center}.internal-label-alignment--end{align-items:end}.internal-label--container{display:flex;justify-content:space-between;color:var(--calcite-color-text-1)}.internal-label-required--indicator{font-weight:var(--calcite-font-weight-medium);color:var(--calcite-color-status-danger);padding-inline:var(--calcite-spacing-base)}.internal-label-required--indicator:hover{cursor:help}.internal-label--text{line-height:1}:host([scale=s]) .internal-label-spacing--bottom{margin-block-end:var(--calcite-spacing-xxs)}:host([scale=s]) .internal-label-spacing-inline--end{margin-inline-end:var(--calcite-spacing-sm)}:host([scale=s]) .internal-label-spacing-inline--start{margin-inline-start:var(--calcite-spacing-sm)}:host([scale=s]) .internal-label--text{font-size:var(--calcite-font-size--2)}:host([scale=m]) .internal-label-spacing--bottom{margin-block-end:var(--calcite-spacing-sm)}:host([scale=m]) .internal-label-spacing-inline--end{margin-inline-end:var(--calcite-spacing-sm)}:host([scale=m]) .internal-label-spacing-inline--start{margin-inline-start:var(--calcite-spacing-sm)}:host([scale=m]) .internal-label--text{font-size:var(--calcite-font-size--1)}:host([scale=l]) .internal-label-spacing--bottom{margin-block-end:var(--calcite-spacing-sm)}:host([scale=l]) .internal-label-spacing-inline--end{margin-inline-end:var(--calcite-spacing-md)}:host([scale=l]) .internal-label-spacing-inline--start{margin-inline-start:var(--calcite-spacing-md)}:host([scale=l]) .internal-label--text{font-size:var(--calcite-font-size-0)}.validation-container{display:flex;flex-direction:column;align-items:flex-start;align-self:stretch}:host([scale=m]) .validation-container,:host([scale=l]) .validation-container{padding-block-start:.5rem}:host([scale=s]) .validation-container{padding-block-start:.25rem}::slotted(input[slot=hidden-form-input]){margin:0!important;opacity:0!important;outline:none!important;padding:0!important;position:absolute!important;inset:0!important;transform:none!important;-webkit-appearance:none!important;z-index:-1!important}:host([hidden]){display:none}[hidden]{display:none}`;
const SLOTS = {
  contentBottom: "content-bottom",
  contentTop: "content-top"
};
const CSS = {
  inputContainer: "input-container",
  input: "input",
  contentContainer: "content-container",
  contentAnimation: "content-animation",
  content: "content",
  contentHidden: "content--hidden",
  floatingUIContainer: "floating-ui-container",
  floatingUIContainerActive: "floating-ui-container--active",
  screenReadersOnly: "screen-readers-only"
};
const idPrefix = "autocomplete";
const IDS = {
  validationMessage: "autocompleteValidationMessage",
  input: (id) => `${idPrefix}-input-${id}`,
  list: (id) => `${idPrefix}-list-${id}`
};
const groupItemSelector = "calcite-autocomplete-item-group";
const itemSelector = "calcite-autocomplete-item";
class Autocomplete extends LitElement {
  constructor() {
    super();
    this.guid = guid();
    this.attributeWatch = useWatchAttributes(["autofocus", "enterkeyhint", "inputmode"], this.handleGlobalAttributesChanged);
    this.direction = useDirection();
    this.formSupport = useForm({
      inputType: "text"
    })(this);
    this.inputId = IDS.input(this.guid);
    this.listId = IDS.list(this.guid);
    this.messages = useT9n();
    this.transitionProp = "opacity";
    this.transitionRef = createRef();
    this.mutationObserver = createObserver("mutation", () => this.getAllItemsDebounced());
    this.focusSetter = useSetFocus()(this);
    this.resizeObserver = createObserver("resize", () => {
      this.setFloatingElSize();
    });
    this.cancelable = useCancelable()(this);
    this.getAllItemsDebounced = debounce(this.getAllItems, 0);
    this.interactiveContainer = useInteractive(this);
    this.topLayer = useTopLayer({
      target: () => this.floatingEl
    })(this);
    this.activeDescendant = "";
    this.activeIndex = -1;
    this.hasContentBottom = false;
    this.hasContentTop = false;
    this.items = [];
    this.groups = [];
    this.alignment = "start";
    this.disabled = false;
    this.iconFlipRtl = false;
    this.loading = false;
    this.open = false;
    this.overlayPositioning = "absolute";
    this.placement = defaultMenuPlacement;
    this.readOnly = false;
    this.required = false;
    this.scale = "m";
    this.status = "idle";
    this.topLayerDisabled = false;
    this.value = "";
    this.calciteAutocompleteBeforeClose = createEvent({ cancelable: false });
    this.calciteAutocompleteBeforeOpen = createEvent({ cancelable: false });
    this.calciteAutocompleteChange = createEvent({ cancelable: false });
    this.calciteAutocompleteClose = createEvent({ cancelable: false });
    this.calciteAutocompleteOpen = createEvent({ cancelable: false });
    this.calciteAutocompleteTextChange = createEvent({ cancelable: false });
    this.calciteAutocompleteTextInput = createEvent({ cancelable: false });
    this.listenOn(document, "click", this.documentClickHandler);
    this.listen("calciteAutocompleteItemSelect", this.handleAutocompleteItemSelect);
  }
  static {
    this.properties = { activeDescendant: [16, {}, { state: true }], activeIndex: [16, {}, { state: true }], hasContentBottom: [16, {}, { state: true }], hasContentTop: [16, {}, { state: true }], items: [16, {}, { state: true }], groups: [16, {}, { state: true }], alignment: [3, {}, { reflect: true }], autocomplete: 1, disabled: [7, {}, { reflect: true, type: Boolean }], flipPlacements: [0, {}, { attribute: false }], form: [3, {}, { reflect: true }], icon: [3, { converter: stringOrBoolean, type: String }, { reflect: true }], iconFlipRtl: [7, {}, { reflect: true, type: Boolean }], inputValue: 1, label: 1, labelText: 1, loading: [7, {}, { reflect: true, type: Boolean }], maxLength: [11, {}, { reflect: true, type: Number }], messageOverrides: [0, {}, { attribute: false }], minLength: [11, {}, { reflect: true, type: Number }], name: [3, {}, { reflect: true }], open: [7, {}, { reflect: true, type: Boolean }], overlayPositioning: [3, {}, { reflect: true }], pattern: 1, placeholder: 1, placement: [3, {}, { reflect: true }], prefixText: 1, readOnly: [7, {}, { reflect: true, type: Boolean }], required: [7, {}, { reflect: true, type: Boolean }], scale: [3, {}, { reflect: true }], status: [3, {}, { reflect: true }], suffixText: 1, topLayerDisabled: [7, {}, { reflect: true, type: Boolean }], validationIcon: [3, { converter: stringOrBoolean, type: String }, { reflect: true }], validationMessage: 1, validity: [32, {}, { readOnly: true, attribute: false }], value: 1 };
  }
  static {
    this.formAssociated = true;
  }
  static {
    this.styles = styles;
  }
  get isOpen() {
    return this.open && (this.hasContentTop || this.hasContentBottom || this.items.length > 0);
  }
  get enabledItems() {
    return this.items.filter((item) => !item.disabled);
  }
  async reposition(delayed = false) {
    const { floatingEl, referenceEl, placement, overlayPositioning, flipPlacements } = this;
    return reposition(this, {
      direction: this.direction,
      floatingEl,
      referenceEl,
      overlayPositioning,
      placement,
      flipPlacements,
      type: "menu"
    }, delayed);
  }
  async scrollContentTo(options) {
    this.transitionRef.value?.scrollTo(options);
  }
  async selectText() {
    return this.referenceEl?.selectText();
  }
  async setFocus(options) {
    return this.focusSetter(() => this.referenceEl, options);
  }
  connectedCallback() {
    super.connectedCallback();
    this.mutationObserver?.observe(this.el, {
      attributes: true,
      attributeFilter: ["selected"],
      childList: true,
      subtree: true
    });
    connectLabel(this);
    this.getAllItemsDebounced();
    connectFloatingUI(this);
    this.cancelable.add(this.getAllItemsDebounced);
  }
  async load() {
    this.getAllItemsDebounced();
  }
  willUpdate(changes) {
    if (changes.has("disabled") && (this.hasUpdated || this.disabled !== false)) {
      this.handleDisabledChange(this.disabled);
    }
    if (changes.has("open") && (this.hasUpdated || this.open !== false)) {
      this.openHandler();
    }
    if (changes.has("flipPlacements") || changes.has("overlayPositioning") && (this.hasUpdated || this.overlayPositioning !== "absolute") || changes.has("placement") && (this.hasUpdated || this.placement !== defaultMenuPlacement)) {
      this.reposition(true);
    }
    let itemsAndGroupsUpdated = false;
    if (changes.has("inputValue") && (this.hasUpdated || this.inputValue)) {
      this.inputValueMatchPattern = this.inputValue ? new RegExp(`(${escapeRegExp(this.inputValue)})`, "i") : void 0;
      this.updateItems();
      this.updateGroups();
      itemsAndGroupsUpdated = true;
    }
    if (!itemsAndGroupsUpdated && changes.has("scale") && (this.hasUpdated || this.scale !== "m")) {
      this.updateItems();
      this.updateGroups();
      itemsAndGroupsUpdated = true;
    }
    if (!itemsAndGroupsUpdated && changes.has("activeIndex") && (this.hasUpdated || this.activeIndex !== -1)) {
      this.updateItems();
    }
  }
  loaded() {
    connectFloatingUI(this);
  }
  disconnectedCallback() {
    super.disconnectedCallback();
    this.mutationObserver?.disconnect();
    this.resizeObserver?.disconnect();
    disconnectLabel(this);
    disconnectFloatingUI(this);
  }
  setFloatingElSize() {
    const { referenceEl, floatingEl } = this;
    if (!referenceEl || !floatingEl) {
      return;
    }
    floatingEl.style.inlineSize = `${referenceEl.clientWidth}px`;
  }
  handleGlobalAttributesChanged() {
    this.requestUpdate();
  }
  handleDisabledChange(value) {
    if (!value) {
      this.open = false;
    }
  }
  openHandler() {
    if (this.disabled) {
      this.open = false;
      return;
    }
    if (!this.open) {
      this.activeIndex = -1;
    }
    toggleOpenClose(this);
    this.setFloatingElSize();
    this.reposition(true);
  }
  async documentClickHandler(event) {
    if (this.disabled || event.composedPath().includes(this.el)) {
      return;
    }
    this.open = false;
  }
  async handleAutocompleteItemSelect(event) {
    this.value = event.target.value;
    this.emitChange();
    await this.setFocus();
    this.open = false;
  }
  onLabelClick() {
    this.setFocus();
  }
  onBeforeOpen() {
    this.calciteAutocompleteBeforeOpen.emit();
    this.topLayer.show();
  }
  onOpen() {
    this.calciteAutocompleteOpen.emit();
  }
  onBeforeClose() {
    this.calciteAutocompleteBeforeClose.emit();
  }
  onClose() {
    this.calciteAutocompleteClose.emit();
    this.topLayer.hide();
  }
  emitChange() {
    this.calciteAutocompleteChange.emit();
  }
  updateGroups() {
    this.groups.forEach((group, index, items) => {
      group.scale = this.scale;
      group.position = index;
      if (index === 0) {
        group.disableSpacing = true;
      }
      const nextGroupItem = items[index + 1];
      if (nextGroupItem) {
        nextGroupItem.disableSpacing = group.children.length === 0;
      }
    });
  }
  updateItems() {
    let activeDescendant = "";
    this.items.forEach((item) => {
      item.scale = this.scale;
      item.inputValueMatchPattern = this.inputValueMatchPattern;
    });
    this.enabledItems.forEach((item, index) => {
      const isActive = index === this.activeIndex;
      if (isActive) {
        activeDescendant = item.guid;
      }
      item.active = isActive;
    });
    this.activeDescendant = activeDescendant;
  }
  handleInputFocus() {
    this.open = true;
  }
  handleContentTopSlotChange(event) {
    this.hasContentTop = slotChangeHasAssignedElement(event);
  }
  handleContentBottomSlotChange(event) {
    this.hasContentBottom = slotChangeHasAssignedElement(event);
  }
  getAllItems() {
    const { el } = this;
    this.groups = Array.from(el.querySelectorAll(groupItemSelector));
    this.items = Array.from(el.querySelectorAll(itemSelector));
    this.updateItems();
    this.updateGroups();
  }
  setReferenceEl(el) {
    updateRefObserver(this.resizeObserver, this.referenceEl, el);
    this.referenceEl = el;
    connectFloatingUI(this);
  }
  keyDownHandler(event) {
    const { defaultPrevented, key } = event;
    if (defaultPrevented) {
      return;
    }
    const { open, activeIndex, enabledItems } = this;
    const activeItem = enabledItems.length && activeIndex > -1 ? enabledItems[activeIndex] : null;
    switch (key) {
      case "Escape":
        if (open) {
          this.open = false;
          event.preventDefault();
        }
        break;
      case "Tab":
        this.open = false;
        break;
      case "Enter":
        if (open && activeItem) {
          this.value = activeItem.value;
          activeItem.toggleSelection();
          this.open = false;
          event.preventDefault();
        } else if (!event.defaultPrevented && this.formSupport.active) {
          event.preventDefault();
          this.formSupport.requestSubmit();
        }
        break;
      case "ArrowDown":
        if (enabledItems.length) {
          this.open = true;
          this.activeIndex = activeIndex !== -1 ? Math.min(activeIndex + 1, enabledItems.length - 1) : 0;
          this.scrollToActiveItem();
          event.preventDefault();
        }
        break;
      case "ArrowUp":
        if (enabledItems.length) {
          this.open = true;
          this.activeIndex = activeIndex !== -1 ? Math.max(activeIndex - 1, 0) : enabledItems.length - 1;
          this.scrollToActiveItem();
          event.preventDefault();
        }
        break;
      case "Home":
        if (enabledItems.length) {
          this.open = true;
          this.activeIndex = 0;
          this.scrollToActiveItem();
          event.preventDefault();
        }
        break;
      case "End":
        if (enabledItems.length) {
          this.open = true;
          this.activeIndex = enabledItems.length - 1;
          this.scrollToActiveItem();
          event.preventDefault();
        }
        break;
    }
  }
  scrollToActiveItem() {
    this.enabledItems[this.activeIndex]?.scrollIntoView({ block: "nearest" });
  }
  changeHandler(event) {
    event.stopPropagation();
    this.inputValue = event.target.value;
    this.calciteAutocompleteTextChange.emit();
  }
  inputClickHandler(event) {
    if (event.defaultPrevented) {
      return;
    }
    this.open = true;
  }
  inputHandler(event) {
    event.stopPropagation();
    this.inputValue = event.target.value;
    this.open = this.inputValue?.length > 0;
    this.calciteAutocompleteTextInput.emit();
  }
  setFloatingEl(el) {
    this.floatingEl = el;
    connectFloatingUI(this);
  }
  render() {
    const { disabled, listId, inputId, isOpen } = this;
    const autofocus = this.el.autofocus;
    const enterKeyHint = this.el.enterKeyHint;
    const inputMode = this.el.inputMode;
    return this.interactiveContainer({ disabled, children: html`${this.labelText && InternalLabel({ labelText: this.labelText, onClick: this.onLabelClick, required: this.required, tooltipText: this.messages.required }) || ""}<div class=${safeClassMap(CSS.inputContainer)}><calcite-input .alignment=${this.alignment} aria-activedescendant=${this.activeDescendant ?? nothing} aria-controls=${listId ?? nothing} aria-label=${getLabelText(this) ?? nothing} aria-owns=${listId ?? nothing} aria-autocomplete=list .ariaExpanded=${isOpen} aria-haspopup=listbox .autocomplete=${this.autocomplete} .autofocus=${autofocus} class=${safeClassMap(CSS.input)} clearable .disabled=${disabled} enterkeyhint=${enterKeyHint ?? nothing} .form=${this.form} .icon=${this.icon ?? true} .iconFlipRtl=${this.iconFlipRtl} id=${inputId ?? nothing} inputmode=${inputMode ?? nothing} .label=${this.label} .loading=${this.loading} .maxLength=${this.maxLength} .messageOverrides=${this.messages} .minLength=${this.minLength} .name=${this.name} @calciteInputChange=${this.changeHandler} @calciteInputInput=${this.inputHandler} @calciteInternalInputFocus=${this.handleInputFocus} @click=${this.inputClickHandler} @keydown=${this.keyDownHandler} .pattern=${this.pattern} .placeholder=${this.placeholder} .prefixText=${this.prefixText} .readOnly=${this.readOnly} .required=${this.required} role=combobox .scale=${this.scale} .status=${this.status} .suffixText=${this.suffixText} type=search .value=${this.inputValue} ${ref(this.setReferenceEl)}></calcite-input>${this.renderListBox()}<div class=${safeClassMap({
      [CSS.contentContainer]: true,
      [CSS.floatingUIContainer]: true,
      [CSS.floatingUIContainerActive]: isOpen
    })} popover=manual ${ref(this.setFloatingEl)}><div class=${safeClassMap({
      [CSS.contentAnimation]: true,
      [FloatingCSS.animation]: true,
      [FloatingCSS.animationActive]: isOpen
    })} ${ref(this.transitionRef)}><div class=${safeClassMap({ [CSS.content]: true, [CSS.contentHidden]: !isOpen })}><slot name=${SLOTS.contentTop} @slotchange=${this.handleContentTopSlotChange}></slot><slot aria-hidden=true></slot><slot name=${SLOTS.contentBottom} @slotchange=${this.handleContentBottomSlotChange}></slot></div></div></div></div>${this.validationMessage && this.status === "invalid" ? Validation({ icon: this.validationIcon, id: IDS.validationMessage, message: this.validationMessage, scale: this.scale, status: this.status }) : null}` });
  }
  renderListBox() {
    return html`<ul aria-labelledby=${this.inputId ?? nothing} aria-live=polite class=${safeClassMap(CSS.screenReadersOnly)} id=${this.listId ?? nothing} role=listbox tabindex=-1>${this.renderListBoxOptions()}</ul>`;
  }
  renderListBoxOptions() {
    return repeat(this.items.filter((item) => !!(item.label || item.heading)), (item) => item.guid, (item) => html`<li .ariaDisabled=${item.disabled} .ariaLabel=${item.label} .ariaSelected=${item.selected} id=${item.guid ?? nothing} role=option tabindex=-1>${item.heading}${item.description}</li>`);
  }
}
customElement("calcite-autocomplete", Autocomplete);
export {
  Autocomplete
};
