import a from "../combobox-with-popover/combobox-with-popover.js";
import h from "../input/input.js";
import l from "../chip/chip.js";
import u from "../validation-messages/validation-messages.js";
import { validationMessageValidator as c } from "../../common/validators/index.js";
import { POPOVER_APPEND_TO_VALUES as d } from "../popover/popover-constants.js";
import { CHIP_TOP_POSITION as f, CHIP_SIZES as g, MULTI_SELECT_SIZES as m } from "./combobox-multi-select-constants.js";
import { getUniqueString as b } from "../../common/utils/index.js";
import { n as y } from "../../_plugin-vue2_normalizer-DSLOjnn3.js";
const C = {
  name: "DtRecipeComboboxMultiSelect",
  components: {
    DtRecipeComboboxWithPopover: a,
    DtInput: h,
    DtChip: l,
    DtValidationMessages: u
  },
  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
    },
    /**
     * Description for the input
     */
    description: {
      type: String,
      default: ""
    },
    /**
     * Input placeholder
     */
    placeholder: {
      type: String,
      default: "Select one or start typing"
    },
    /**
     * Input validation messages
     */
    inputMessages: {
      type: Array,
      default: () => [],
      validator: (t) => c(t)
    },
    /**
     * Show input validation message
     */
    showInputMessages: {
      type: Boolean,
      default: !0
    },
    // @TODO: https://dialpad.atlassian.net/browse/DP-52324
    // type: {
    //   type: String,
    //   values: ['input', 'select'],
    //   default: 'select',
    // },
    /**
     * Determines if the list is loading
     */
    loading: {
      type: Boolean,
      default: !1
    },
    /**
     * The message when the list is loading
     */
    loadingMessage: {
      type: String,
      default: "loading..."
    },
    /**
     * Determines when to show the list element and also controls the aria-expanded attribute.
     * Leaving this null will have the combobox trigger on input focus by default.
     * If you set this value, the default trigger behavior will be disabled and you can
     * control it as you need.
     */
    showList: {
      type: Boolean,
      default: null
    },
    /**
     * Determines maximum height for the popover before overflow.
     * Possible units rem|px|em
     */
    listMaxHeight: {
      type: String,
      default: "300px"
    },
    /**
     * The selected items
     */
    selectedItems: {
      type: Array,
      default: function() {
        return [];
      }
    },
    /**
     * Would be the maximum number of selections you can make. 0 is unlimited
     */
    maxSelected: {
      type: Number,
      default: 0
    },
    /**
     * Max select message when the max selections is exceeded with the structure:
     * `[{"message": string, "type": VALIDATION_MESSAGE_TYPES }]`
     */
    maxSelectedMessage: {
      type: Array,
      default: function() {
        return [];
      }
    },
    /**
     * Displays the list when the combobox is focused, before the user has typed anything.
     * When this is enabled the list will not close after selection.
     */
    hasSuggestionList: {
      type: Boolean,
      default: !0
    },
    /**
     * Size of the chip, one of `xs`, `sm`, `md`
     */
    size: {
      type: String,
      default: "md",
      validator: (t) => Object.values(m).includes(t)
    },
    /**
     * Sets the element to which the popover is going to append to.
     * 'body' will append to the nearest body (supports shadow DOM).
     * @values 'body', 'parent', HTMLElement,
     */
    appendTo: {
      type: [HTMLElement, String],
      default: "body",
      validator: (t) => d.includes(t) || t instanceof HTMLElement
    },
    /**
     * Named transition when the content display is toggled.
     * @see DtLazyShow
     */
    transition: {
      type: String,
      default: "fade"
    },
    /**
     * Determines whether the combobox should collapse to a single when losing focus.
     * @type {boolean}
     */
    collapseOnFocusOut: {
      type: Boolean,
      default: !1
    },
    /**
     * Determines maximum width for the popover before overflow.
     * Possible units rem|px|em
     */
    listMaxWidth: {
      type: String,
      default: ""
    },
    /**
    * Amount of reserved space (in px) on the right side of the input
    * before the chips and the input caret jump to the next line.
    * default is 64
    */
    reservedRightSpace: {
      type: Number,
      default: 64
    },
    /**
     * Determines the maximum width of a single chip. If the text within this chip exceeds the value
     * it will be truncated with ellipses.
     * Possible units rem|px|em
     */
    chipMaxWidth: {
      type: String,
      default: ""
    },
    /**
     * Additional class name for the input element.
     * Can accept String, Object, and Array, i.e. has the
     * same API as Vue's built-in handling of the class attribute.
     */
    inputClass: {
      type: [String, Object, Array],
      default: ""
    },
    /**
     * Additional class name for the input wrapper 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.
     */
    inputWrapperClass: {
      type: [String, Object, Array],
      default: ""
    }
  },
  emits: [
    /**
     * Native input event
     *
     * @event input
     * @type {String }
     */
    "input",
    /**
     * Event fired when item selected
     *
     * @event select
     * @type {Number}
     */
    "select",
    /**
     * Event fired when item removed
     *
     * @event remove
     * @type {String}
     */
    "remove",
    /**
     * Event fired when max selected items limit is reached
     *
     * @event max-selected
     * @type {Object}
     */
    "max-selected",
    /**
     * Native keyup event
     *
     * @event keyup
     * @type {KeyboardEvent}
      */
    "keyup",
    /**
     * Native keydown event
     *
     * @event keydown
     * @type {KeyboardEvent}
      */
    "keydown",
    /**
     * Event fired when combobox item is highlighted
     *
     * @event combobox-highlight
     * @type {Object}
     */
    "combobox-highlight"
  ],
  data() {
    return {
      value: "",
      popoverOffset: [0, 4],
      showValidationMessages: !1,
      resizeWindowObserver: null,
      initialInputHeight: null,
      CHIP_SIZES: g,
      inputFocused: !1,
      hideInputText: !1
    };
  },
  computed: {
    inputPlaceHolder() {
      var t;
      return ((t = this.selectedItems) == null ? void 0 : t.length) > 0 ? "" : this.placeholder;
    },
    chipListeners() {
      return {
        ...this.$listeners,
        keydown: (t) => {
          this.onChipKeyDown(t), this.$emit("keydown", t);
        }
      };
    },
    inputListeners() {
      return {
        ...this.$listeners,
        input: (t) => {
          this.$emit("input", t), this.hasSuggestionList && this.showComboboxList();
        },
        keydown: (t) => {
          this.onInputKeyDown(t);
        },
        keyup: (t) => {
          this.$emit("keyup", t);
        },
        click: () => {
          this.hasSuggestionList && this.showComboboxList();
        }
      };
    },
    selectedItemsWithKeys() {
      return this.selectedItems.map((t) => ({
        item: t,
        key: b(t)
      }));
    },
    chipWrapperClass() {
      return {
        [`d-recipe-combobox-multi-select__chip-wrapper-${this.size}--collapsed`]: !this.inputFocused && this.collapseOnFocusOut
      };
    }
  },
  watch: {
    selectedItems: {
      async handler() {
        this.initSelectedItems();
      }
    },
    chipMaxWidth: {
      async handler() {
        this.initSelectedItems();
      }
    },
    async label() {
      await this.$nextTick(), this.setChipsTopPosition();
    },
    async description() {
      await this.$nextTick(), this.setChipsTopPosition();
    },
    size: {
      async handler() {
        await this.$nextTick();
        const t = this.getInput();
        this.revertInputPadding(t), this.initialInputHeight = t.getBoundingClientRect().height, this.setInputPadding(), this.setChipsTopPosition();
      }
    }
  },
  mounted() {
    this.setInitialInputHeight(), this.resizeWindowObserver = new ResizeObserver(async () => {
      this.setChipsTopPosition(), this.setInputPadding();
    }), this.resizeWindowObserver.observe(document.body), this.initSelectedItems();
  },
  beforeDestroy() {
    var t;
    (t = this.resizeWindowObserver) == null || t.unobserve(document.body);
  },
  methods: {
    comboboxHighlight(t) {
      this.$emit("combobox-highlight", t);
    },
    async initSelectedItems() {
      await this.$nextTick(), this.setInputPadding(), this.setChipsTopPosition(), this.setInputMinWidth(), this.checkMaxSelected();
    },
    onChipRemove(t) {
      var e;
      this.$emit("remove", t), (e = this.$refs.input) == null || e.focus();
    },
    onComboboxSelect(t) {
      this.loading || (this.value = "", this.$emit("select", t));
    },
    showComboboxList() {
      var t;
      this.showList == null && ((t = this.$refs.comboboxWithPopover) == null || t.showComboboxList());
    },
    closeComboboxList() {
      var t;
      this.showList == null && ((t = this.$refs.comboboxWithPopover) == null || t.closeComboboxList());
    },
    getChipButtons() {
      return this.$refs.chips && this.$refs.chips.map((t) => t.$el.querySelector("button"));
    },
    getChips() {
      return this.$refs.chips && this.$refs.chips.map((t) => t.$el);
    },
    getLastChipButton() {
      return this.$refs.chips && this.getChipButtons()[this.getChipButtons().length - 1];
    },
    getLastChip() {
      return this.$refs.chips && this.getChips()[this.getChips().length - 1];
    },
    getFirstChip() {
      return this.$refs.chips && this.getChips()[0];
    },
    getInput() {
      var t;
      return (t = this.$refs.input) == null ? void 0 : t.$refs.input;
    },
    onChipKeyDown(t) {
      var i;
      const e = (i = t.code) == null ? void 0 : i.toLowerCase();
      e === "arrowleft" ? this.navigateBetweenChips(t.target, !0) : e === "arrowright" && (t.target.id === this.getLastChipButton().id ? this.moveFromChipToInput() : this.navigateBetweenChips(t.target, !1));
    },
    onInputKeyDown(t) {
      var i;
      const e = (i = t.code) == null ? void 0 : i.toLowerCase();
      if (this.selectedItems.length > 0 && t.target.selectionStart === 0) {
        if (t.target.selectionEnd !== t.target.selectionStart)
          return;
        (e === "backspace" || e === "arrowleft") && this.moveFromInputToChip();
      }
    },
    moveFromInputToChip() {
      var t;
      this.getLastChipButton().focus(), (t = this.$refs.input) == null || t.blur(), this.closeComboboxList();
    },
    moveFromChipToInput() {
      var t;
      this.getLastChipButton().blur(), (t = this.$refs.input) == null || t.focus(), this.showComboboxList();
    },
    navigateBetweenChips(t, e) {
      var s;
      const i = this.getChipButtons().indexOf(t), o = e ? i - 1 : i + 1;
      o < 0 || o >= ((s = this.$refs.chips) == null ? void 0 : s.length) || (this.getChipButtons()[i].blur(), this.getChipButtons()[o].focus(), this.closeComboboxList());
    },
    setChipsTopPosition() {
      const t = this.getInput();
      if (!t) return;
      const e = this.$refs.inputSlotWrapper, i = t.getBoundingClientRect().top - e.getBoundingClientRect().top, o = this.$refs.chipsWrapper;
      o.style.top = i - f[this.size] + "px";
    },
    setInputPadding() {
      const t = this.getLastChip(), e = this.getInput(), i = this.$refs.chipsWrapper;
      if (!e || (this.revertInputPadding(e), this.popoverOffset = [0, 4], !t) || this.collapseOnFocusOut && !this.inputFocused) return;
      const o = t.offsetLeft + this.getFullWidth(t), s = e.getBoundingClientRect().width - o;
      s > this.reservedRightSpace ? e.style.paddingLeft = o + "px" : e.style.paddingLeft = "4px";
      const r = i.getBoundingClientRect().height - 4, n = t.getBoundingClientRect().height - 4, p = s > this.reservedRightSpace ? t.offsetTop + 2 : r + n - 9;
      e.style.paddingTop = `${p}px`;
    },
    revertInputPadding(t) {
      t.style.paddingLeft = "", t.style.paddingTop = "", t.style.paddingBottom = "";
    },
    getFullWidth(t) {
      const e = window.getComputedStyle(t);
      return t.offsetWidth + parseInt(e.marginLeft) + parseInt(e.marginRight);
    },
    setInputMinWidth() {
      const t = this.getFirstChip(), e = this.getInput();
      e && (t ? e.style.minWidth = this.getFullWidth(t) + 4 + "px" : e.style.minWidth = "");
    },
    checkMaxSelected() {
      this.maxSelected !== 0 && (this.selectedItems.length > this.maxSelected ? (this.showValidationMessages = !0, this.$emit("max-selected")) : this.showValidationMessages = !1);
    },
    setInitialInputHeight() {
      const t = this.getInput();
      t && (this.initialInputHeight = t.getBoundingClientRect().height);
    },
    async handleInputFocusIn() {
      this.inputFocused = !0, this.collapseOnFocusOut && (this.hideInputText = !1, await this.$nextTick(), this.setInputPadding());
    },
    async handleInputFocusOut() {
      if (this.inputFocused = !1, this.collapseOnFocusOut) {
        this.hideInputText = !0;
        const t = this.getInput();
        if (!t || !t.style.paddingTop)
          return;
        this.revertInputPadding(t);
      }
    }
  }
};
var x = function() {
  var e = this, i = e._self._c;
  return i("dt-recipe-combobox-with-popover", { ref: "comboboxWithPopover", attrs: { label: e.label, "show-list": e.showList, "max-height": e.listMaxHeight, "max-width": e.listMaxWidth, "popover-offset": e.popoverOffset, "has-suggestion-list": e.hasSuggestionList, "content-width": "anchor", "append-to": e.appendTo, transition: e.transition }, on: { select: e.onComboboxSelect, highlight: e.comboboxHighlight }, scopedSlots: e._u([{ key: "input", fn: function({ onInput: o }) {
    return [i("span", { ref: "inputSlotWrapper", staticClass: "d-recipe-combobox-multi-select__input-wrapper", on: { focusin: e.handleInputFocusIn, focusout: e.handleInputFocusOut } }, [i("span", { ref: "chipsWrapper", class: ["d-recipe-combobox-multi-select__chip-wrapper", e.chipWrapperClass] }, e._l(e.selectedItemsWithKeys, function({ item: s, key: r }) {
      return i("dt-chip", e._g({ key: r, ref: "chips", refInFor: !0, class: [
        "d-recipe-combobox-multi-select__chip",
        { "d-recipe-combobox-multi-select__chip--truncate": !!e.chipMaxWidth }
      ], style: { maxWidth: e.chipMaxWidth }, attrs: { "label-class": ["d-chip__label"], size: e.CHIP_SIZES[e.size] }, on: { keydown: function(n) {
        return !n.type.indexOf("key") && e._k(n.keyCode, "backspace", void 0, n.key, void 0) ? null : e.onChipRemove(s);
      }, close: function(n) {
        return e.onChipRemove(s);
      } } }, e.chipListeners), [e._v(" " + e._s(s) + " ")]);
    }), 1), i("dt-input", e._g({ ref: "input", staticClass: "d-recipe-combobox-multi-select__input", attrs: { "input-class": [
      e.inputClass,
      {
        "d-recipe-combobox-multi-select__input--hidden": e.hideInputText
      }
    ], "input-wrapper-class": e.inputWrapperClass, "aria-label": e.label, label: e.labelVisible ? e.label : "", description: e.description, placeholder: e.inputPlaceHolder, "show-messages": e.showInputMessages, messages: e.inputMessages, size: e.size }, on: { input: o, select: function(s) {
      s.stopPropagation();
    } }, model: { value: e.value, callback: function(s) {
      e.value = s;
    }, expression: "value" } }, e.inputListeners)), i("dt-validation-messages", { attrs: { "validation-messages": e.maxSelectedMessage, "show-messages": e.showValidationMessages } })], 1)];
  } }, e.$slots.header ? { key: "header", fn: function() {
    return [i("div", { ref: "header" }, [e._t("header")], 2)];
  }, proxy: !0 } : null, { key: "list", fn: function() {
    return [i("div", { ref: "list", staticClass: "d-recipe-combobox-multi-select__list", on: { mousedown: function(o) {
      o.preventDefault();
    } } }, [e.loading ? i("div", { staticClass: "d-recipe-combobox-multi-select__list--loading" }, [e._v(" " + e._s(e.loadingMessage) + " ")]) : e._t("list")], 2)];
  }, proxy: !0 }, e.$slots.footer ? { key: "footer", fn: function() {
    return [i("div", { ref: "footer" }, [e._t("footer")], 2)];
  }, proxy: !0 } : null], null, !0) });
}, I = [], w = /* @__PURE__ */ y(
  C,
  x,
  I
);
const T = w.exports;
export {
  T as default
};
//# sourceMappingURL=combobox-multi-select.js.map
