import n from "./combobox-loading-list.js";
import o from "./combobox-empty-list.js";
import { getUniqueString as l } from "../../common/utils/index.js";
import { n as r } from "../../_plugin-vue2_normalizer-DSLOjnn3.js";
import a from "../../common/mixins/keyboard-list-navigation.js";
import { COMBOBOX_LABEL_SIZES as d } from "./combobox-constants.js";
const h = {
  name: "DtCombobox",
  components: {
    ComboboxLoadingList: n,
    ComboboxEmptyList: o
  },
  mixins: [
    a({
      indexKey: "highlightIndex",
      idKey: "highlightId",
      listElementKey: "getListElement",
      afterHighlightMethod: "afterHighlight",
      beginningOfListMethod: "beginningOfListMethod",
      endOfListMethod: "endOfListMethod",
      activeItemKey: "activeItemEl"
    })
  ],
  props: {
    /**
     * String to use for the input label.
     */
    label: {
      type: String,
      required: !0
    },
    /**
     * Determines visibility of input label.
     * @values true, false
     */
    labelVisible: {
      type: Boolean,
      default: !0
    },
    /**
     * Size of the input, one of `xs`, `sm`, `md`, `lg`, `xl`
     * @values null, xs, sm, md, lg, xl
     */
    size: {
      type: String,
      default: null,
      validator: (i) => Object.values(d).includes(i)
    },
    /**
     * Description for the input
     */
    description: {
      type: String,
      default: ""
    },
    /**
     * Sets an ID on the list element of the component. Used by several aria attributes
     * as well as when deriving the IDs for each item.
     */
    listId: {
      type: String,
      default() {
        return l();
      }
    },
    /**
     * A method that will be called when the selection goes past the beginning of the list.
     */
    onBeginningOfList: {
      type: Function,
      default: null
    },
    /**
     * A method that will be called when the selection goes past the end of the list.
     */
    onEndOfList: {
      type: Function,
      default: null
    },
    /**
     * Determines when to show the list element and also controls the aria-expanded attribute.
     * @values true, false
     */
    showList: {
      type: Boolean,
      default: !1
    },
    /**
     * If the list is rendered outside the component, like when using popover as the list wrapper.
     * @values true, false
     */
    listRenderedOutside: {
      type: Boolean,
      default: !1
    },
    /**
     * Determines when to show the skeletons and also controls aria-busy attribute.
     * @values true, false
     */
    loading: {
      type: Boolean,
      default: !1
    },
    /**
     * Sets the list to an empty state, and displays the message from prop `emptyStateMessage`.
     * @values true, false
     */
    emptyList: {
      type: Boolean,
      default: !1
    },
    /**
     * Message to show when the list is empty
     */
    emptyStateMessage: {
      type: String,
      default: ""
    },
    /**
     * Additional class name for the empty list element.
     * Can accept all of String, Object, and Array, i.e. has the
     * same api as Vue's built-in handling of the class attribute.
     */
    emptyStateClass: {
      type: [String, Object, Array],
      default: ""
    },
    /**
     * Programmatically click on the active list item element when a selection
     * comes from keyboard navigation, i.e. pressing the "Enter" key.
     * @values true, false
     */
    clickOnSelect: {
      type: Boolean,
      default: !1
    }
  },
  emits: [
    /**
     * Event fired when item selected
     *
     * @event select
     * @type {Number}
     */
    "select",
    /**
     * Event fired when pressing escape
     *
     * @event escape
     */
    "escape",
    /**
     * Event fired when the highlight changes
     *
     * @event highlight
     * @type {Number}
     */
    "highlight",
    /**
     * Event fired when list is shown or hidden
     *
     * @event opened
     * @type {Boolean}
     */
    "opened"
  ],
  data() {
    return {
      // If the list is rendered at the root, rather than as a child
      // of this component, this is the ref to that dom element. Set
      // by the onOpen method.
      outsideRenderedListRef: null
    };
  },
  computed: {
    inputProps() {
      return {
        label: this.label,
        labelVisible: this.labelVisible,
        size: this.size,
        description: this.description,
        role: "combobox",
        "aria-label": this.label,
        "aria-expanded": this.showList.toString(),
        "aria-owns": this.listId,
        "aria-haspopup": "listbox",
        "aria-activedescendant": this.activeItemId,
        "aria-controls": this.listId
      };
    },
    listProps() {
      return {
        role: "listbox",
        id: this.listId,
        // The list has to be positioned relatively so that the auto-scroll can
        // calculate the correct offset for the list items.
        class: "d-ps-relative",
        "aria-label": this.label
      };
    },
    beginningOfListMethod() {
      return this.onBeginningOfList || this.jumpToEnd;
    },
    endOfListMethod() {
      return this.onEndOfList || this.jumpToBeginning;
    },
    activeItemId() {
      if (!(!this.showList || this.highlightIndex < 0 || this.loading))
        return this.highlightId;
    },
    activeItemEl() {
      return this.highlightId ? this.getListElement().querySelector("#" + this.highlightId) : "";
    }
  },
  watch: {
    showList(i) {
      this.listRenderedOutside || (this.setInitialHighlightIndex(), this.$emit("opened", i)), !i && this.outsideRenderedListRef && (this.outsideRenderedListRef.removeEventListener("mousemove", this.onMouseHighlight), this.outsideRenderedListRef = null);
    },
    loading(i) {
      this.$nextTick(() => {
        this.setInitialHighlightIndex();
      });
    },
    $props: {
      deep: !0,
      immediate: !0,
      handler() {
        this.validateEmptyListProps();
      }
    }
  },
  created() {
    this.validateEmptyListProps();
  },
  methods: {
    onMouseHighlight(i) {
      if (this.loading) return;
      const t = i.target.closest("li");
      t && this.highlightId !== t.id && this.setHighlightId(t.id);
    },
    getListElement() {
      var i;
      return this.outsideRenderedListRef ?? ((i = this.$refs.listWrapper) == null ? void 0 : i.querySelector(`#${this.listId}`));
    },
    clearHighlightIndex() {
      this.showList && this.setHighlightIndex(-1);
    },
    afterHighlight() {
      this.loading || this.$emit("highlight", this.highlightIndex);
    },
    onEnterKey() {
      var i;
      this.loading || this.emptyList || this.highlightIndex >= 0 && (this.$emit("select", this.highlightIndex), this.clickOnSelect && ((i = this.activeItemEl) == null || i.click()));
    },
    onEscapeKey() {
      this.$emit("escape");
    },
    onOpen(i, t) {
      var s;
      this.outsideRenderedListRef = t, (s = this.outsideRenderedListRef) == null || s.addEventListener("mousemove", this.onMouseHighlight), this.$emit("opened", i), i && this.setInitialHighlightIndex();
    },
    onKeyValidation(i, t) {
      !this.showList || !this.getListElement() || this[t](i);
    },
    setInitialHighlightIndex() {
      this.showList && this.$nextTick(() => {
        this.setHighlightIndex(this.loading ? -1 : 0);
      });
    },
    validateEmptyListProps() {
      this.$slots.emptyListItem || this.emptyList && !this.emptyStateMessage && console.error(`Invalid props: you must pass both props emptyList and emptyStateMessage to show the
      empty message.`);
    }
  }
};
var p = function() {
  var t = this, s = t._self._c;
  return s("div", { on: { keydown: [function(e) {
    return !e.type.indexOf("key") && t._k(e.keyCode, "esc", 27, e.key, ["Esc", "Escape"]) ? null : (e.stopPropagation(), t.onKeyValidation(e, "onEscapeKey"));
  }, function(e) {
    return !e.type.indexOf("key") && t._k(e.keyCode, "enter", 13, e.key, "Enter") || e.ctrlKey || e.shiftKey || e.altKey || e.metaKey ? null : t.onKeyValidation(e, "onEnterKey");
  }, function(e) {
    return !e.type.indexOf("key") && t._k(e.keyCode, "up", 38, e.key, ["Up", "ArrowUp"]) ? null : (e.stopPropagation(), e.preventDefault(), t.onKeyValidation(e, "onUpKey"));
  }, function(e) {
    return !e.type.indexOf("key") && t._k(e.keyCode, "down", 40, e.key, ["Down", "ArrowDown"]) ? null : (e.stopPropagation(), e.preventDefault(), t.onKeyValidation(e, "onDownKey"));
  }, function(e) {
    return !e.type.indexOf("key") && t._k(e.keyCode, "home", void 0, e.key, void 0) ? null : (e.stopPropagation(), e.preventDefault(), t.onKeyValidation(e, "onHomeKey"));
  }, function(e) {
    return !e.type.indexOf("key") && t._k(e.keyCode, "end", void 0, e.key, void 0) ? null : (e.stopPropagation(), e.preventDefault(), t.onKeyValidation(e, "onEndKey"));
  }] } }, [s("div", { attrs: { "data-qa": "dt-combobox-input-wrapper" } }, [t._t("input", null, { inputProps: t.inputProps })], 2), t.showList ? s("div", { ref: "listWrapper", attrs: { "data-qa": "dt-combobox-list-wrapper" }, on: { mouseleave: t.clearHighlightIndex, focusout: t.clearHighlightIndex, "!mousemove": function(e) {
    return t.onMouseHighlight.apply(null, arguments);
  } } }, [t.loading && !t.listRenderedOutside ? s("combobox-loading-list", t._b({}, "combobox-loading-list", t.listProps, !1)) : t.emptyList && (t.emptyStateMessage || t.$slots.emptyListItem) && !t.listRenderedOutside ? s("combobox-empty-list", t._b({ attrs: { message: t.emptyStateMessage, "item-class": t.emptyStateClass } }, "combobox-empty-list", t.listProps, !1), [t._t("emptyListItem")], 2) : t._t("list", null, { listProps: t.listProps, opened: t.onOpen, clearHighlightIndex: t.clearHighlightIndex })], 2) : t._e()]);
}, u = [], g = /* @__PURE__ */ r(
  h,
  p,
  u
);
const I = g.exports;
export {
  I as default
};
//# sourceMappingURL=combobox.js.map
