import {
  defaultValue
} from "./chunk.GI7VDIWX.js";
import {
  defaultOptionRenderer
} from "./chunk.WBJBQ4QI.js";
import {
  filterOnlyOptgroups,
  getAllOptions,
  getAssignedElementsForSlot,
  normalizeString
} from "./chunk.UIQBHPD3.js";
import {
  scrollIntoView
} from "./chunk.WDWV53JP.js";
import {
  FormControlController
} from "./chunk.C3WIBDGG.js";
import {
  HasSlotController
} from "./chunk.IVMQWO2L.js";
import {
  getAnimation,
  setDefaultAnimation
} from "./chunk.N4LHE3QK.js";
import {
  waitForEvent
} from "./chunk.B4BZKR24.js";
import {
  LocalizeController
} from "./chunk.X3FE7OHE.js";
import {
  watch
} from "./chunk.X2OQMWGY.js";
import {
  SolidElement,
  customElement
} from "./chunk.H53WQBDK.js";
import {
  animateTo,
  stopAnimations
} from "./chunk.HQWAKJBV.js";
import {
  __decorateClass
} from "./chunk.S3NI7NKU.js";

// src/components/combobox/combobox.ts
import { css, html } from "lit";
import { ifDefined } from "lit/directives/if-defined.js";
import { property, query, state } from "lit/decorators.js";
import { unsafeHTML } from "lit/directives/unsafe-html.js";
import cx from "classix";
var SdCombobox = class extends SolidElement {
  constructor() {
    super(...arguments);
    this.formControlController = new FormControlController(this, {
      assumeInteractionOn: ["sd-blur", "sd-input"]
    });
    this.hasSlotController = new HasSlotController(this, "help-text", "label");
    this.localize = new LocalizeController(this);
    this.hasFocus = false;
    this.displayInputValue = "";
    this.selectedTextLabel = "";
    this.selectedOptions = [];
    this.filteredOptions = [];
    this.allOptions = [];
    this.showValidStyle = false;
    this.showInvalidStyle = false;
    this.deletedTagLabel = "";
    this.name = "";
    this.value = "";
    this.defaultValue = "";
    this.size = "lg";
    this.placeholder = "";
    this.maxOptionsTagLabel = "";
    this.disabled = false;
    this.visuallyDisabled = false;
    this.clearable = false;
    this.open = false;
    this.hoist = false;
    this.label = "";
    this.placement = "bottom";
    this.helpText = "";
    this.form = "";
    this.required = false;
    this.floatingLabel = false;
    this.type = "text";
    this.currentPlacement = this.placement;
    this.getOption = defaultOptionRenderer;
    this.multiple = false;
    this.useTags = true;
    this.maxOptionsVisible = 3;
    this.styleOnValid = false;
    this.filter = (option, queryString) => {
      const normalizedOption = normalizeString(option.value);
      const normalizedOptionLabel = normalizeString(option.getTextLabel());
      const normalizedQuery = normalizeString(queryString);
      return normalizedOption.includes(normalizedQuery) || normalizedOptionLabel.includes(normalizedQuery);
    };
    this.getTag = (option) => {
      return html`<sd-6-22-0-tag class="min-w-0 max-w-full" ?disabled="${this.disabled}" part="tag" exportparts="
              base:tag__base,
              content:tag__content,
              removable-indicator:tag__removable-indicator,
            " size="${this.size === "sm" ? "sm" : "lg"}" removable @keydown="${(event) => this.handleTagKeyDown(event, option)}" @sd-remove="${(event) => this.handleTagRemove(event, option)}">${option.getTextLabel()}</sd-6-22-0-tag>`;
    };
    this.handleDocumentFocusIn = (event) => {
      const path = event.composedPath();
      if (this && !path.includes(this)) {
        this.hide();
      }
    };
    this.handleDocumentKeyDown = (event) => {
      const path = event.composedPath();
      const isComboboxButton = path.some(
        (el) => el instanceof HTMLButtonElement && el.classList.contains("combobox-button")
      );
      if (this.visuallyDisabled) {
        event.preventDefault();
        event.stopPropagation();
        return;
      }
      if (isComboboxButton) {
        return;
      }
      const target = event.target;
      const isClearButton = target.closest(".combobox__clear") !== null;
      if (isClearButton) {
        return;
      }
      if (event.key === "Escape") {
        if (this.open) {
          event.preventDefault();
          event.stopPropagation();
          this.hide();
          this.displayInput.focus({ preventScroll: true });
        } else {
          this.displayInputValue = "";
        }
      }
      if (event.key === "Backspace" && this.multiple && this.displayInput.value === "") {
        this.handleTagRemove(new CustomEvent("sd-remove"), this.selectedOptions[this.selectedOptions.length - 1]);
        this.updateComplete.then(() => this.displayInput.focus({ preventScroll: true }));
        return;
      }
      if (!this.multiple && (event.key === "Backspace" || event.key === "Delete")) {
        this.clearCombobox();
        return;
      }
      if (event.key === "Enter") {
        const currentOption = this.getCurrentOption();
        const hasModifier = event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;
        if (!this.open && !hasModifier) {
          setTimeout(() => {
            if (!event.defaultPrevented) {
              this.formControlController.submit();
            }
          });
          return;
        }
        if (!this.open || (currentOption == null ? void 0 : currentOption.disabled)) {
          return;
        }
        if (currentOption && !currentOption.disabled) {
          const oldValue = this.value;
          if (this.multiple) {
            this.toggleOptionSelection(currentOption);
            this.lastOption = currentOption;
            this.setOrderedSelectedOptions(currentOption);
            this.updateComplete.then(() => {
              this.selectionChanged();
            });
          } else {
            this.setOrderedSelectedOptions(currentOption);
            this.setSelectedOptions(currentOption);
          }
          this.updateComplete.then(() => {
            this.displayInput.focus({ preventScroll: true });
            if (this.value !== oldValue) {
              this.emit("sd-input");
              this.emit("sd-change");
            }
          });
        }
        this.displayInput.focus({ preventScroll: true });
        if (!this.multiple) {
          this.hide();
          this.displayInput.focus({ preventScroll: true });
        }
        return;
      }
      if (["ArrowUp", "ArrowDown"].includes(event.key)) {
        event.preventDefault();
        event.stopPropagation();
        if (!this.open) {
          this.show();
        }
        this.selectNextOption(event.key === "ArrowDown");
      }
      if (["Home", "End"].includes(event.key)) {
        event.preventDefault();
        event.stopPropagation();
        if (event.key === "Home") {
          this.displayInput.setSelectionRange(0, 0);
        } else if (event.key === "End") {
          this.displayInput.setSelectionRange(this.displayInput.value.length, this.displayInput.value.length);
        }
      }
    };
    this.handleDocumentMouseDown = (event) => {
      const path = event.composedPath();
      if (this && !path.includes(this)) {
        this.hide();
      }
    };
  }
  connectedCallback() {
    super.connectedCallback();
    this.open = false;
  }
  firstUpdated() {
    if (!this.multiple) {
      const option = this.findOptionByValue(this.getSlottedOptions(), this.value);
      this.selectedTextLabel = (option == null ? void 0 : option.getTextLabel()) || "";
    }
    this.formControlController.updateValidity();
  }
  /** Gets the validity state object */
  get validity() {
    return this.valueInput.validity;
  }
  /** Gets the validation message */
  get validationMessage() {
    return this.valueInput.validationMessage;
  }
  get options() {
    const renderOption = (option) => {
      const queryString = this.displayInput.value;
      const optionHtml = this.getOption(option, queryString);
      option.tabIndex = 0;
      return html`${typeof optionHtml === "string" ? unsafeHTML(optionHtml) : optionHtml}`;
    };
    return this.filteredOptions.map((item) => {
      if (item.tagName.toLowerCase() === "sd-6-22-0-optgroup") {
        Array.from(item.children).forEach((option) => {
          if (option.tagName.toLowerCase() === "sd-6-22-0-option") {
            renderOption(option);
          }
        });
        return item;
      }
      return renderOption(item);
    });
  }
  get tags() {
    if (this.selectedOptions.length <= this.maxOptionsVisible) {
      return this.selectedOptions.map((option, index) => {
        if (index < this.maxOptionsVisible || this.maxOptionsVisible <= 0) {
          const tag = this.getTag(option, index);
          return html`<div @sd-remove="${(e) => this.handleTagRemove(e, option)}">${typeof tag === "string" ? unsafeHTML(tag) : tag}</div>`;
        }
        return [html``];
      });
    } else {
      return [
        html`<sd-6-22-0-tag class="min-w-0 max-w-full" ?disabled="${this.disabled}" part="tag" exportparts="
              base:tag__base,
              content:tag__content,
              removable-indicator:tag__removable-indicator,
            " size="${this.size === "sm" ? "sm" : "lg"}" removable @keydown="${(event) => this.handleTagMaxOptionsKeyDown(event)}" @sd-remove="${(event) => this.handleTagRemove(event)}">${this.selectedOptions.length} ${this.localize.term("tagsSelected")}</sd-6-22-0-tag>`
      ];
    }
  }
  addOpenListeners() {
    document.addEventListener("focusin", this.handleDocumentFocusIn);
    document.addEventListener("mousedown", this.handleDocumentMouseDown);
    if (this.getRootNode() !== document) {
      this.getRootNode().addEventListener("focusin", this.handleDocumentFocusIn);
    }
  }
  removeOpenListeners() {
    document.removeEventListener("focusin", this.handleDocumentFocusIn);
    document.removeEventListener("mousedown", this.handleDocumentMouseDown);
    if (this.getRootNode() !== document) {
      this.getRootNode().removeEventListener("focusin", this.handleDocumentFocusIn);
    }
  }
  handleFocus() {
    this.hasFocus = true;
    this.emit("sd-focus");
  }
  handleBlur() {
    this.hasFocus = false;
    this.emit("sd-blur");
  }
  handleTagKeyDown(event, option) {
    if ((event.key === "Backspace" || event.key === "Enter" || event.key === " ") && this.multiple) {
      event.preventDefault();
      event.stopPropagation();
      this.handleTagRemove(new CustomEvent("sd-remove"), option);
      this.updateComplete.then(() => this.displayInput.focus({ preventScroll: true }));
    }
  }
  handleTagMaxOptionsKeyDown(event) {
    if ((event.key === "Backspace" || event.key === "Enter" || event.key === " ") && this.multiple) {
      event.preventDefault();
      event.stopPropagation();
      this.handleTagRemove(new CustomEvent("sd-remove"), this.selectedOptions[this.selectedOptions.length - 1]);
      this.updateComplete.then(() => this.displayInput.focus({ preventScroll: true }));
    }
  }
  handleLabelClick() {
    if (this.visuallyDisabled) {
      return;
    }
    this.displayInput.focus();
  }
  handleTagRemove(event, option) {
    event.stopPropagation();
    if (!option) {
      this.clearCombobox();
    }
    if (option && !this.disabled) {
      this.toggleOptionSelection(option, false);
      this.setOrderedSelectedOptions(option);
      this.deletedTagLabel = "";
      this.deletedTagLabel = this.localize.term("removed", option.textContent);
      this.updateComplete.then(() => {
        this.selectionChanged();
        this.emit("sd-input");
        this.emit("sd-change");
      });
    }
  }
  handleComboboxMouseDown(event) {
    if (this.visuallyDisabled) {
      event.preventDefault();
      event.stopPropagation();
      return;
    }
    const path = event.composedPath();
    const isRemovableIndicator = path.some((el) => el instanceof HTMLSlotElement && el.name === "removable-indicator");
    if (this.disabled || isRemovableIndicator) {
      return;
    }
    const toggleListboxOpen = () => this.open ? this.hide() : this.show();
    toggleListboxOpen().then(() => {
      setTimeout(() => this.displayInput.focus({ preventScroll: true }));
    });
  }
  async handleComboboxKeyDown(event) {
    var _a;
    if (event.key === "Tab") {
      this.displayInputValue = "";
      this.displayInput.value = "";
      if (this.open && ((_a = this.shadowRoot) == null ? void 0 : _a.activeElement) === this.displayInput) {
        event.preventDefault();
        this.open = false;
        await this.updateComplete;
        this.displayInput.focus();
        return;
      }
      return;
    }
    this.handleDocumentKeyDown(event);
  }
  handleClearClick(event) {
    event.stopPropagation();
    this.clearCombobox();
  }
  handleSearchClick(event) {
    event.stopPropagation();
    if (this.disabled || this.visuallyDisabled) {
      return;
    }
    this.emit("sd-search");
  }
  handleNoResultsClick(event) {
    event.preventDefault();
    this.hide();
  }
  clearCombobox() {
    if (this.value !== "") {
      this.value = "";
      this.displayInputValue = "";
      this.selectedTextLabel = "";
      this.lastOption = void 0;
      this.selectedOptions = [];
      this.getSlottedOptions().forEach((option) => {
        option.selected = false;
      });
      this.displayInput.focus({ preventScroll: true });
      this.updateComplete.then(() => {
        this.emit("sd-clear");
        this.emit("sd-input");
        this.emit("sd-change");
      });
    }
  }
  preventLoosingFocus(event) {
    event.stopPropagation();
    event.preventDefault();
  }
  handleOptionClick(event) {
    const target = event.target;
    const option = target.closest("sd-6-22-0-option");
    const oldValue = this.value;
    if (option && !option.disabled) {
      if (this.multiple) {
        this.toggleOptionSelection(option);
        this.lastOption = option;
        this.setOrderedSelectedOptions(option);
        this.updateComplete.then(() => {
          this.selectionChanged();
        });
      } else {
        this.setOrderedSelectedOptions(option);
        this.setSelectedOptions(option);
      }
      this.updateComplete.then(() => {
        this.displayInput.focus({ preventScroll: true });
        if (this.value !== oldValue) {
          this.emit("sd-input");
          this.emit("sd-change");
        }
      });
      if (!this.multiple) {
        this.hide();
        this.displayInput.focus({ preventScroll: true });
      }
    }
  }
  /**
   * Selects the following or previous option.
   *
   * @param isNext - A boolean indicating whether to select the following option (true)
   *                 or the previous option (false).
   */
  selectNextOption(isNext) {
    const filteredOptions = this.getAllFilteredOptions();
    if (filteredOptions.length === 0) {
      return;
    }
    const currentOption = this.getCurrentOption();
    const currentIndex = filteredOptions.indexOf(currentOption);
    let newIndex = Math.max(0, currentIndex);
    if (isNext) {
      const nextIndex = currentIndex + 1;
      newIndex = nextIndex > filteredOptions.length - 1 ? 0 : nextIndex;
    } else {
      const previousIndex = currentIndex - 1;
      newIndex = previousIndex < 0 ? filteredOptions.length - 1 : previousIndex;
    }
    this.setCurrentOption(filteredOptions[newIndex], new KeyboardEvent("keydown"));
    scrollIntoView(this.getCurrentOption(), this.listbox, "vertical", "auto");
  }
  getAllFilteredOptions() {
    return [...this.filteredWrapper.querySelectorAll("sd-6-22-0-option")];
  }
  getCurrentOption() {
    return this.getAllFilteredOptions().find((option) => option.current);
  }
  // Sets the current option, which is the option the user is currently interacting with
  // (e.g. via keyboard). Only one option may be "current" at a time.
  setCurrentOption(option, event) {
    const allFilteredOptions = this.getAllFilteredOptions();
    this.displayInput.removeAttribute("aria-activedescendant");
    allFilteredOptions.forEach((el) => {
      el.current = false;
      el.setAttribute("aria-selected", "false");
      el.isKeyboardFocus = false;
    });
    if (option) {
      option.current = true;
      option.setAttribute("aria-selected", "true");
      this.displayInput.setAttribute("aria-activedescendant", option.id);
    }
    if (option && (event == null ? void 0 : event.type) === "keydown") {
      option.isKeyboardFocus = true;
    }
  }
  // Toggles an option's selected state
  toggleOptionSelection(option, force) {
    const allOptions = this.getSlottedOptions();
    const optionEl = allOptions.find(
      (el) => el.value && option.value ? el.value === option.value : el.getTextLabel() === option.getTextLabel()
    );
    if (optionEl) optionEl.selected = force != null ? force : !optionEl.selected;
  }
  findOptionByValue(slottedOptions, value) {
    if (!value) return void 0;
    if (Array.isArray(value)) {
      return slottedOptions.find((option) => value.includes(option.value));
    }
    return slottedOptions.find((option) => option.value === value);
  }
  selectedOptionsAndValueSynced() {
    var _a;
    if (!this.value && this.selectedOptions.length === 0) return true;
    return Array.isArray(this.value) ? this.value.length === this.selectedOptions.length : this.value === ((_a = this.selectedOptions[0]) == null ? void 0 : _a.value);
  }
  isOptionSelected(option) {
    if (option.value) {
      return this.value.includes(option.value);
    } else {
      return this.value.includes(option.getTextLabel());
    }
  }
  syncSelectedOptionsAndValue() {
    if (this.selectedOptionsAndValueSynced()) {
      return;
    }
    const allOptions = this.getSlottedOptions();
    allOptions.forEach((option) => {
      option.selected = false;
    });
    this.selectedOptions = this.getSlottedOptions().filter((option) => {
      return this.isOptionSelected(option);
    });
    this.selectedOptions.forEach((option) => {
      if (option) option.selected = true;
    });
    return Promise.resolve();
  }
  compareOptions(a, b) {
    if (a.value && b.value) {
      return a.value === b.value;
    }
    return a.getTextLabel() === b.getTextLabel();
  }
  /**
   * Updates the selected options cache, the current value, and the display value
   */
  setSelectedOptions(option) {
    const allOptions = this.getSlottedOptions();
    allOptions.forEach((el) => {
      el.selected = this.compareOptions(el, option);
    });
    this.selectionChanged();
  }
  setOrderedSelectedOptions(option) {
    const selectedSlottedOption = this.getSlottedOptions().find((el) => this.compareOptions(el, option));
    if (this.multiple) {
      if (this.selectedOptions.length > 0 && selectedSlottedOption && this.selectedOptions.find((el) => this.compareOptions(el, selectedSlottedOption))) {
        this.selectedOptions = this.selectedOptions.filter((el) => !this.compareOptions(el, selectedSlottedOption));
      } else {
        this.selectedOptions = [...this.selectedOptions, selectedSlottedOption];
      }
    } else {
      this.selectedOptions = [selectedSlottedOption];
    }
  }
  selectionChanged() {
    var _a, _b, _c;
    const hasSelectedOptions = this.selectedOptions.some((option) => {
      if (!option) return false;
      return this.isOptionSelected(option);
    });
    if (this.multiple) {
      if (!hasSelectedOptions && this.selectedOptions.length > 0) {
        this.value = [...this.value, ...this.selectedOptions.map((el) => el.value || el.getTextLabel())];
      } else {
        this.value = this.selectedOptions.map((el) => {
          return (el == null ? void 0 : el.value) || (el == null ? void 0 : el.getTextLabel()) || "";
        });
      }
      this.displayInputValue = "";
    } else {
      this.value = ((_a = this.selectedOptions[0]) == null ? void 0 : _a.value) || ((_b = this.selectedOptions[0]) == null ? void 0 : _b.getTextLabel()) || "";
      this.selectedTextLabel = ((_c = this.selectedOptions[0]) == null ? void 0 : _c.getTextLabel()) || "";
      this.displayInputValue = "";
    }
    this.updateComplete.then(() => {
      this.formControlController.updateValidity();
    });
  }
  createComboboxOptionsFromQuery(queryString) {
    const optgroups = [];
    this.filteredOptions = this.getSlottedOptions().filter((option) => {
      return this.filter(option, queryString) || queryString === "";
    }).map((option) => {
      var _a, _b, _c;
      const clonedOption = option.cloneNode(true);
      clonedOption.current = clonedOption.value === ((_a = this.lastOption) == null ? void 0 : _a.value);
      clonedOption.selected = option.selected;
      clonedOption.checkbox = option.checkbox;
      clonedOption.size = option.size;
      const hasOptgroup = ((_b = option.parentElement) == null ? void 0 : _b.tagName.toLowerCase()) === "sd-6-22-0-optgroup";
      if (!hasOptgroup) {
        return clonedOption;
      }
      const optgroup = option.parentElement;
      const optGroupLabel = (_c = optgroup.querySelector('[slot="label"]')) == null ? void 0 : _c.cloneNode(true);
      const filteredOptgroup = optgroups.find((el) => el.id === optgroup.id);
      if (filteredOptgroup) {
        filteredOptgroup == null ? void 0 : filteredOptgroup.appendChild(clonedOption);
        if (optGroupLabel) filteredOptgroup == null ? void 0 : filteredOptgroup.appendChild(optGroupLabel);
        return void 0;
      }
      const clonedOptgroup = optgroup.cloneNode();
      clonedOptgroup.appendChild(clonedOption);
      if (optGroupLabel) clonedOptgroup.appendChild(optGroupLabel);
      optgroups.push(clonedOptgroup);
      return clonedOptgroup;
    }).filter(Boolean);
  }
  handleInvalid(event) {
    this.formControlController.setValidity(false);
    this.formControlController.emitInvalidEvent(event);
    this.invalidMessage.textContent = event.target.validationMessage;
  }
  /** Receives incoming event detail from sd-6-22-0-popup and updates local state for conditional styling. */
  handleCurrentPlacement(e) {
    const incomingPlacement = e.detail;
    if (incomingPlacement) {
      this.currentPlacement = incomingPlacement;
    }
  }
  handleFilterChange() {
    this.createComboboxOptionsFromQuery(this.displayInputValue);
  }
  handleUseTagsChange() {
    const allOptions = this.getAllFilteredOptions();
    if (customElements.get("sd-6-22-0-option")) {
      allOptions.forEach((option) => {
        option.checkbox = this.multiple;
      });
    }
  }
  applySizeToOptions() {
    this.getSlottedOptions().forEach((option) => {
      option.size = this.size;
    });
  }
  handleDisabledChange() {
    this.formControlController.setValidity(this.disabled);
    if (this.disabled || this.visuallyDisabled) {
      this.open = false;
      this.handleOpenChange();
    }
  }
  handleValueChange() {
    this.syncSelectedOptionsAndValue();
    if (this.multiple) {
      this.createComboboxOptionsFromQuery(this.displayInput.value);
    } else {
      this.createComboboxOptionsFromQuery("");
    }
  }
  handleDisplayInputValueChange() {
    this.createComboboxOptionsFromQuery(this.displayInputValue);
  }
  async handleOpenChange() {
    if (this.open && (!this.disabled || !this.visuallyDisabled)) {
      this.emit("sd-show");
      this.addOpenListeners();
      await stopAnimations(this);
      this.listbox.hidden = false;
      this.popup.active = true;
      const { keyframes: keyframes2, options: options2 } = getAnimation(this, "combobox.show", { dir: this.localize.dir() });
      await animateTo(this.popup.popup, keyframes2, options2);
      this.emit("sd-after-show");
      if (this.filteredOptions.length === 0) {
        this.emit("sd-error");
      }
      return;
    }
    this.setCurrentOption(null);
    this.displayInput.removeAttribute("aria-activedescendant");
    this.emit("sd-hide");
    this.removeOpenListeners();
    await stopAnimations(this);
    const { keyframes, options } = getAnimation(this, "combobox.hide", { dir: this.localize.dir() });
    await animateTo(this.popup.popup, keyframes, options);
    this.listbox.hidden = true;
    this.popup.active = false;
    this.emit("sd-after-hide");
  }
  handleSizeChange() {
    this.size = this.floatingLabel && this.size === "sm" ? "md" : this.size;
  }
  async show() {
    if (this.open || this.disabled || this.visuallyDisabled) {
      this.open = false;
      return void 0;
    }
    this.open = true;
    return Promise.race([waitForEvent(this, "sd-after-show"), waitForEvent(this, "sd-error")]);
  }
  /** Hides the listbox. */
  async hide() {
    if (!this.open || this.disabled) {
      this.open = false;
      return void 0;
    }
    this.displayInputValue = "";
    this.open = false;
    return waitForEvent(this, "sd-after-hide");
  }
  /**
   * Checks for validity but does not show a validation message.
   * Returns `true` when valid and `false` when invalid.
   */
  checkValidity() {
    return this.valueInput.checkValidity();
  }
  /** Gets the associated form, if one exists. */
  getForm() {
    return this.formControlController.getForm();
  }
  /** Checks for validity and shows the browser's validation message if the control is invalid. */
  reportValidity() {
    this.formControlController.fakeUserInteraction();
    return this.valueInput.reportValidity();
  }
  /** Sets a custom validation message. Pass an empty string to restore validity. */
  setCustomValidity(message) {
    this.valueInput.setCustomValidity(message);
    this.formControlController.updateValidity();
  }
  /** Sets focus on the control. */
  focus(options) {
    this.displayInput.focus(options);
  }
  /** Removes focus from the control. */
  blur() {
    this.displayInput.blur();
  }
  async handleInput() {
    const inputValue = this.displayInput.value;
    this.displayInputValue = inputValue;
    await this.updateComplete;
    this.open = this.filteredWrapper.children.length > 0;
    this.formControlController.updateValidity();
    this.emit("sd-input");
  }
  handleChange() {
    if (!this.selectedOptions || !this.multiple) {
      this.selectedTextLabel = this.displayInput.value;
      this.updateComplete.then(() => {
        this.formControlController.updateValidity();
      });
      this.emit("sd-change");
    }
  }
  getSlottedOptions() {
    return getAllOptions(getAssignedElementsForSlot(this.defaultSlot)).flat();
  }
  getSlottedOptGroups() {
    return filterOnlyOptgroups(getAssignedElementsForSlot(this.defaultSlot));
  }
  async handleDefaultSlotChange() {
    if (!customElements.get("sd-6-22-0-option")) {
      customElements.whenDefined("sd-6-22-0-option").then(() => this.handleDefaultSlotChange());
      return;
    }
    const slottedOptions = this.getSlottedOptions();
    const slottedOptgroups = this.getSlottedOptGroups();
    this.applySizeToOptions();
    const selectedOption = this.findOptionByValue(slottedOptions, this.value);
    this.selectedTextLabel = (selectedOption == null ? void 0 : selectedOption.getTextLabel()) || "";
    slottedOptions.forEach((option, index) => {
      if (this.multiple) {
        option.checkbox = true;
      }
      option.id = option.id || `sd-6-22-0-combobox-option-${index}`;
    });
    slottedOptgroups.forEach((optgroup, index) => {
      optgroup.id = optgroup.id || `sd-6-22-0-combobox-optgroup-${index}`;
    });
    await this.syncSelectedOptionsAndValue();
    if (this.multiple) {
      this.createComboboxOptionsFromQuery(this.displayInputValue);
    } else {
      this.createComboboxOptionsFromQuery("");
    }
  }
  render() {
    const slots = {
      left: this.hasSlotController.test("left"),
      right: this.hasSlotController.test("right")
    };
    const hasLabelSlot = this.hasSlotController.test("label");
    const hasHelpTextSlot = this.hasSlotController.test("help-text");
    const hasLabel = this.label ? true : !!hasLabelSlot;
    const hasHelpText = this.helpText ? true : !!hasHelpTextSlot;
    const hasClearIcon = this.clearable && !this.disabled && !this.visuallyDisabled;
    const hasIconLeft = slots["left"];
    const hasValue = this.value !== null && String(this.value).length > 0;
    const isFloatingLabelActive = this.floatingLabel && hasLabel && (this.hasFocus || hasValue);
    const selectState = this.disabled ? "disabled" : this.visuallyDisabled && !this.hasFocus ? "visuallyDisabled" : this.hasFocus && this.showInvalidStyle ? "activeInvalid" : this.hasFocus && this.styleOnValid && this.showValidStyle ? "activeValid" : this.hasFocus || this.open ? "active" : this.showInvalidStyle ? "invalid" : this.styleOnValid && this.showValidStyle ? "valid" : "default";
    const cursorStyles = this.disabled || this.visuallyDisabled ? "cursor-not-allowed" : "cursor-pointer";
    const iconColor = this.disabled || this.visuallyDisabled ? "text-neutral-500" : "sd-6-22-0-icon-fill-primary";
    const iconMarginLeft = { sm: "ml-1", md: "ml-2", lg: "ml-2" }[this.size];
    const iconMarginRight = { sm: "mr-1", md: "mr-2", lg: "mr-2" }[this.size];
    const iconSize = {
      sm: "text-base",
      md: "text-lg",
      lg: "text-xl"
    }[this.size];
    const verticalPadding = this.size === "lg" ? !this.floatingLabel ? "py-2" : isFloatingLabelActive ? "py-3" : "py-4" : !this.floatingLabel ? "py-1" : isFloatingLabelActive ? "py-2" : "py-3";
    const floatingLabelHorizontalAlignmentWithIconLeft = { sm: "left-[36px]", md: "left-[44px]", lg: "left-12" }[this.size];
    return html`<div part="form-control" class="${cx(
      "relative text-left",
      cursorStyles,
      this.size === "sm" ? "text-sm" : "text-base",
      this.open && "z-50"
    )}">${hasLabel && !this.floatingLabel ? html`<div class="flex items-center gap-1 mb-2"><label id="label" part="form-control-label" class="${cx(
      hasLabel && "inline-block",
      hasLabel && (this.visuallyDisabled || this.disabled) ? "text-neutral-500" : "form-control-color-text"
    )}" aria-hidden="${hasLabel ? "false" : "true"}" @click="${this.handleLabelClick}"><slot name="label">${this.label}</slot></label></div>` : null} <span aria-live="polite" class="sr-only">${this.deletedTagLabel}</span><div part="form-control-input" class="relative w-full bg-white text-black">${hasLabel && this.floatingLabel ? html`<label id="label" part="form-control-floating-label" class="${cx(
      "absolute left-4 z-20 pointer-events-none transition-all duration-200",
      hasIconLeft ? floatingLabelHorizontalAlignmentWithIconLeft : "left-4",
      !isFloatingLabelActive ? "top-1/2 -translate-y-1/2 form-control-color-text" : this.size === "lg" ? "top-2 text-xs" : "top-1 text-xs",
      isFloatingLabelActive && "mt-1"
    )}" for="input"><span class="${cx(
      "leading-none",
      (this.visuallyDisabled || this.disabled) && "text-neutral-500",
      isFloatingLabelActive && !this.visuallyDisabled && !this.disabled && "form-control--filled__floating-label-color-text"
    )}">${this.label}</span></label>` : null}<div part="border" class="${cx(
      "absolute top-0 w-full h-full pointer-events-none border form-control-border-radius z-10 transition-[border] duration-medium ease-in-out",
      {
        disabled: "border-neutral-500",
        visuallyDisabled: "border-neutral-500",
        readonly: "form-control-color-border",
        activeInvalid: "border-error border-2",
        activeValid: "border-success border-2",
        active: "border-primary border-2",
        invalid: "border-error",
        valid: "border-success",
        default: "form-control-color-border"
      }[selectState],
      this.open && (this.currentPlacement === "bottom" ? "rounded-bl-none rounded-br-none" : "rounded-tl-none rounded-tr-none")
    )}"></div><sd-6-22-0-popup @sd-current-placement="${this.handleCurrentPlacement}" class="${cx(
      "inline-flex relative w-full",
      this.currentPlacement === "bottom" ? "origin-top" : "origin-bottom"
    )}" placement="${this.placement}" strategy="${this.hoist ? "fixed" : "absolute"}" flip shift sync="width" auto-size="vertical" auto-size-padding="10" exportparts="
              popup:popup__content,
            "><div part="combobox" class="${cx(
      "relative w-full px-4 flex flex-row items-center form-control-border-radius transition-colors hover:duration-fast ease-in-out",
      this.visuallyDisabled || this.disabled ? "hover:bg-transparent" : "hover:[@media(hover:hover)]:form-control--hover-color-background",
      this.open && "shadow transition-shadow duration-medium ease-in-out",
      ["invalid", "activeInvalid"].includes(selectState) && "form-control--invalid-color-background",
      {
        sm: "py-1 min-h-[32px]",
        md: "py-1 min-h-[40px]",
        lg: "py-2 min-h-[48px]"
      }[this.size],
      verticalPadding
    )}" slot="anchor" @keydown="${this.handleComboboxKeyDown}" @mousedown="${this.handleComboboxMouseDown}">${slots["left"] ? html`<slot part="left" name="left" class="${cx("inline-flex", iconMarginRight, iconColor, iconSize)}"></slot>` : ""}<div class="${cx("flex flex-wrap items-center gap-1 w-full min-w-0 relative", this.floatingLabel && "mt-4")}">${this.multiple && this.useTags && this.tags && this.tags.length > 0 ? html`<div part="tags" class="${cx("flex flex-wrap items-center gap-1 min-w-0", iconMarginRight)}">${this.tags}</div>` : null} <input id="display-input" name="${this.name}" form="${this.form}" part="display-input" class="${cx(
      "appearance-none outline-none bg-transparent flex-auto min-w-0",
      cursorStyles,
      this.selectedTextLabel && !this.multiple ? "placeholder:text-black" : "placeholder:text-neutral-700",
      this.size === "sm" ? isFloatingLabelActive ? "h-4" : "h-6" : isFloatingLabelActive ? "h-6" : "h-8"
    )}" type="text" placeholder="${!this.floatingLabel || isFloatingLabelActive ? this.selectedTextLabel && !this.multiple ? this.selectedTextLabel : this.placeholder || this.localize.term("comboboxDefaultPlaceholder") : ""}" .disabled="${this.disabled}" .value="${this.displayInputValue}" autocomplete="off" spellcheck="false" autocapitalize="off" aria-controls="listbox" aria-expanded="${this.open}" aria-haspopup="listbox" aria-labelledby="label" aria-disabled="${this.disabled || this.visuallyDisabled}" aria-describedby="help-text invalid-message" aria-invalid="${this.showInvalidStyle}" role="combobox" tabindex="0" @focus="${this.handleFocus}" @blur="${this.handleBlur}" aria-autocomplete="list" aria-owns="listbox" @input="${this.handleInput}" @change="${this.handleChange}"></div><div aria-live="polite" id="control-value" class="absolute top-0 left-0 opacity-0 -z-10">${this.selectedOptions.map((option) => option == null ? void 0 : option.getTextLabel()).join(", ")}</div><input class="${cx("value-input absolute top-0 left-0 w-full h-full opacity-0 -z-10", cursorStyles)}" type="text" ?disabled="${this.disabled}" ?required="${this.required}" .value="${Array.isArray(this.value) ? this.value.join(", ") : this.value}" tabindex="-1" aria-controls="control-value" aria-hidden="true" @focus="${() => this.focus()}" @invalid="${this.handleInvalid}"> ${hasClearIcon ? html`<button part="clear-button" class="${cx(
      "flex justify-center",
      iconMarginLeft,
      this.value.length > 0 ? "visible" : "invisible"
    )}" type="button" aria-label="${this.localize.term("clearEntry")}" @mousedown="${this.preventLoosingFocus}" @click="${this.handleClearClick}" tabindex="-1"><slot name="clear-icon"><sd-6-22-0-icon class="${cx("text-neutral-700", iconSize)}" name="closing-round" library="_internal"></sd-6-22-0-icon></slot></button>` : ""} ${this.showInvalidStyle ? html`<sd-6-22-0-icon part="invalid-icon" class="${cx(iconMarginLeft, iconSize, "text-error")}" library="_internal" name="risk"></sd-6-22-0-icon>` : ""} ${this.styleOnValid && this.showValidStyle ? html`<sd-6-22-0-icon part="valid-icon" class="${cx("flex-shrink-0 text-success", iconMarginLeft, iconSize)}" library="_internal" name="confirm-circle"></sd-6-22-0-icon>` : ""}<slot name="right" part="right" class="${cx(
      "inline-flex ml-2 leading-[0]",
      this.disabled || this.visuallyDisabled ? "text-neutral-500" : "sd-6-22-0-icon-fill-primary",
      iconSize
    )}">${this.type !== "search" ? html`<sd-6-22-0-icon class="${cx(
      "transition-transform duration-medium ease-in-out",
      this.open ? "rotate-180" : "rotate-0"
    )}" name="chevron-down" part="chevron" library="_internal" color="currentColor" label="${this.localize.term("open")}"></sd-6-22-0-icon>` : ""}</slot>${this.type === "search" ? html`<button class="${cx("flex items-center sd-interactive", iconMarginLeft)}" type="button" @mousedown="${this.preventLoosingFocus}" @click="${this.handleSearchClick}"><sd-6-22-0-icon class="${cx(iconColor, iconSize)}" library="_internal" name="magnifying-glass" label="${this.localize.term("search")}"></sd-6-22-0-icon></button>` : html`<button class="sd-interactive combobox-button absolute top-2 sd-color-icon-fill-primary" tabindex="-1" aria-hidden="true" @keydown="${this.handleComboboxMouseDown}" type="button"><span class="sr-only">${this.localize.term("open")}</span></button>`}</div><div id="listbox" role="${ifDefined(!this.multiple ? "listbox" : void 0)}" aria-expanded="${this.open}" aria-multiselectable="${this.multiple}" aria-labelledby="label" part="listbox" class="${cx(
      "bg-white px-2 py-3 relative border-primary overflow-y-auto",
      this.open && "shadow-listbox transition-shadow duration-medium ease-in-out",
      this.currentPlacement === "bottom" ? "border-r-2 border-b-2 border-l-2 form-control__listbox-border-bottom-right-radius form-control__listbox-border-bottom-left-radius" : "border-r-2 border-t-2 border-l-2 form-control__listbox-border-top-right-radius form-control__listbox-border-top-left-radius"
    )}" tabindex="-1" @mousedown="${this.preventLoosingFocus}" @mouseup="${this.handleOptionClick}"><div part="filtered-listbox">${this.filteredOptions.length === 0 ? html`<span id="noResults" class="px-4 flex items-center w-full transition-all text-left text-base relative text-black py-3" aria-hidden="true" @click="${this.handleNoResultsClick}">${this.localize.term("noResults")}</span>` : this.options}</div><slot id="defaultOptionsSlot" class="hidden" @slotchange="${this.handleDefaultSlotChange}"></slot></div></sd-6-22-0-popup></div><slot name="help-text" part="form-control-help-text" id="help-text" class="${cx(
      "text-sm mt-1",
      hasHelpText ? "block" : "hidden",
      this.visuallyDisabled || this.disabled ? "text-neutral-500" : "text-neutral-700"
    )}" aria-hidden="${!hasHelpText}">${this.helpText}</slot></div>${this.formControlController.renderInvalidMessage(this.size)}`;
  }
};
SdCombobox.styles = [
  ...SolidElement.styles,
  css`/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */@layer properties;@layer theme,base,components,utilities;
:host{position:relative;display:block;width:100%}:host([required]) #label::after{content:' *'}:host([disabled]) ::-moz-placeholder,:host([visually-disabled]) ::-moz-placeholder{color:rgba(var(--sd-color-text-neutral-500))}:host([disabled]) ::placeholder,:host([visually-disabled]) ::placeholder{color:rgba(var(--sd-color-text-neutral-500))}:host([visually-disabled]) input{caret-color:transparent}:host([size=sm]) .combobox-button{right:var(--sd-spacing-4);height:var(--sd-spacing-4);width:var(--sd-spacing-4)}:host([size=md]) .combobox-button{right:.85rem;height:var(--sd-spacing-6);width:var(--sd-spacing-6)}:host([size=lg]) .combobox-button{right:var(--sd-spacing-3);height:var(--sd-spacing-8);width:var(--sd-spacing-8)}[part=listbox]{max-height:var(--auto-size-available-height,auto)}sd-6-22-0-popup::part(popup){z-index:var(--sd-z-index-dropdown,900)}sd-6-22-0-tag::part(base){border-radius:var(--sd-radius);border-width:var(--sd-combobox__tag-border-width,var(--sd-spacing-0\\.25));padding-inline:var(--sd-spacing-1)}sd-6-22-0-tag::part(content){display:inline-block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:var(--tag-max-width,15ch)}sd-6-22-0-tag[size=lg]::part(base){padding-inline:var(--sd-spacing-2)}sd-6-22-0-tag[disabled=false]::part(base):hover{background-color:rgba(var(--sd-color-background-primary-100))}[part=filtered-listbox] sd-6-22-0-optgroup:first-of-type{--display-divider:none}mark{background-color:transparent;--tw-font-weight:var(--sd-font-weight-bold);font-weight:var(--sd-font-weight-bold);color:inherit}[part=chevron]{color:rgb(var(--sd-color-icon-fill-primary))}:host([disabled])::part(chevron),:host([visually-disabled])::part(chevron){color:rgba(var(--sd-color-icon-fill-neutral-500,--sd-color-neutral-500))}@property --tw-font-weight{syntax:"*";inherits:false}`
];
__decorateClass([
  query("sd-6-22-0-popup")
], SdCombobox.prototype, "popup", 2);
__decorateClass([
  query('[part="combobox"]')
], SdCombobox.prototype, "combobox", 2);
__decorateClass([
  query('[part="display-input"]')
], SdCombobox.prototype, "displayInput", 2);
__decorateClass([
  query(".value-input")
], SdCombobox.prototype, "valueInput", 2);
__decorateClass([
  query('[part="listbox"]')
], SdCombobox.prototype, "listbox", 2);
__decorateClass([
  query('[part="tags"]')
], SdCombobox.prototype, "tagWrapper", 2);
__decorateClass([
  query('[part="filtered-listbox"]')
], SdCombobox.prototype, "filteredWrapper", 2);
__decorateClass([
  query("slot:not([name])")
], SdCombobox.prototype, "defaultSlot", 2);
__decorateClass([
  query("#invalid-message")
], SdCombobox.prototype, "invalidMessage", 2);
__decorateClass([
  state()
], SdCombobox.prototype, "hasFocus", 2);
__decorateClass([
  state()
], SdCombobox.prototype, "displayInputValue", 2);
__decorateClass([
  state()
], SdCombobox.prototype, "selectedTextLabel", 2);
__decorateClass([
  state()
], SdCombobox.prototype, "selectedOptions", 2);
__decorateClass([
  state()
], SdCombobox.prototype, "filteredOptions", 2);
__decorateClass([
  state()
], SdCombobox.prototype, "allOptions", 2);
__decorateClass([
  state()
], SdCombobox.prototype, "lastOption", 2);
__decorateClass([
  state()
], SdCombobox.prototype, "showValidStyle", 2);
__decorateClass([
  state()
], SdCombobox.prototype, "showInvalidStyle", 2);
__decorateClass([
  state()
], SdCombobox.prototype, "deletedTagLabel", 2);
__decorateClass([
  property({ reflect: true })
], SdCombobox.prototype, "name", 2);
__decorateClass([
  property({
    converter: {
      fromAttribute: (value) => value.split(" "),
      toAttribute: (value) => value.join(" ")
    }
  })
], SdCombobox.prototype, "value", 2);
__decorateClass([
  defaultValue()
], SdCombobox.prototype, "defaultValue", 2);
__decorateClass([
  property({ type: String, reflect: true })
], SdCombobox.prototype, "size", 2);
__decorateClass([
  property({ type: String, reflect: true })
], SdCombobox.prototype, "placeholder", 2);
__decorateClass([
  property({ type: String, attribute: "max-options-tag-label", reflect: true })
], SdCombobox.prototype, "maxOptionsTagLabel", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], SdCombobox.prototype, "disabled", 2);
__decorateClass([
  property({ type: Boolean, reflect: true, attribute: "visually-disabled" })
], SdCombobox.prototype, "visuallyDisabled", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], SdCombobox.prototype, "clearable", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], SdCombobox.prototype, "open", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], SdCombobox.prototype, "hoist", 2);
__decorateClass([
  property({ type: String, reflect: true })
], SdCombobox.prototype, "label", 2);
__decorateClass([
  property({ type: String, reflect: true })
], SdCombobox.prototype, "placement", 2);
__decorateClass([
  property({ type: String, attribute: "help-text", reflect: true })
], SdCombobox.prototype, "helpText", 2);
__decorateClass([
  property({ type: String, reflect: true })
], SdCombobox.prototype, "form", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], SdCombobox.prototype, "required", 2);
__decorateClass([
  property({ attribute: "floating-label", type: Boolean, reflect: true })
], SdCombobox.prototype, "floatingLabel", 2);
__decorateClass([
  property({ type: String, reflect: true })
], SdCombobox.prototype, "type", 2);
__decorateClass([
  state()
], SdCombobox.prototype, "currentPlacement", 2);
__decorateClass([
  property()
], SdCombobox.prototype, "getOption", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], SdCombobox.prototype, "multiple", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], SdCombobox.prototype, "useTags", 2);
__decorateClass([
  property({ type: Number, reflect: true, attribute: "max-options-visible" })
], SdCombobox.prototype, "maxOptionsVisible", 2);
__decorateClass([
  property({ type: Boolean, reflect: true, attribute: "style-on-valid" })
], SdCombobox.prototype, "styleOnValid", 2);
__decorateClass([
  property()
], SdCombobox.prototype, "filter", 2);
__decorateClass([
  property()
], SdCombobox.prototype, "getTag", 2);
__decorateClass([
  watch("filter", { waitUntilFirstUpdate: true })
], SdCombobox.prototype, "handleFilterChange", 1);
__decorateClass([
  watch("useTags", { waitUntilFirstUpdate: true })
], SdCombobox.prototype, "handleUseTagsChange", 1);
__decorateClass([
  watch("size", { waitUntilFirstUpdate: true })
], SdCombobox.prototype, "applySizeToOptions", 1);
__decorateClass([
  watch(["disabled", "visually-disabled"], { waitUntilFirstUpdate: true })
], SdCombobox.prototype, "handleDisabledChange", 1);
__decorateClass([
  watch("value", { waitUntilFirstUpdate: true })
], SdCombobox.prototype, "handleValueChange", 1);
__decorateClass([
  watch("displayInputValue", { waitUntilFirstUpdate: true })
], SdCombobox.prototype, "handleDisplayInputValueChange", 1);
__decorateClass([
  watch("open", { waitUntilFirstUpdate: true })
], SdCombobox.prototype, "handleOpenChange", 1);
__decorateClass([
  watch(["size", "floatingLabel"])
], SdCombobox.prototype, "handleSizeChange", 1);
SdCombobox = __decorateClass([
  customElement("sd-6-22-0-combobox")
], SdCombobox);
setDefaultAnimation("combobox.show", {
  keyframes: [{ opacity: 0 }, { opacity: 1 }],
  options: { duration: "var(--sd-duration-medium, 300)", easing: "ease-in-out" }
});
setDefaultAnimation("combobox.hide", {
  keyframes: [{ opacity: 1 }, { opacity: 0 }],
  options: { duration: "var(--sd-duration-fast, 150)", easing: "ease-in-out" }
});

export {
  SdCombobox
};
