import { warn as f, resolveComponent as g, openBlock as l, createElementBlock as i, normalizeProps as y, guardReactiveProps as C, createElementVNode as n, mergeProps as r, renderSlot as c, createTextVNode as u, toDisplayString as m, createCommentVNode as p, normalizeClass as E, toHandlers as b, Fragment as _, renderList as I, createVNode as O } from "vue";
import { LABEL_SIZE_MODIFIERS as v, DESCRIPTION_SIZE_MODIFIERS as A } from "../../common/constants/index.js";
import { SELECT_SIZE_MODIFIERS as S, SELECT_STATE_MODIFIERS as D } from "./select-menu-constants.js";
import { hasSlotContent as M, getValidationState as P, getUniqueString as L, removeClassStyleAttrs as R, addClassStyleAttrs as T } from "../../common/utils/index.js";
import { MessagesMixin as V } from "../../common/mixins/input.js";
import { optionsValidator as F } from "./select-menu-validators.js";
import { _ as j } from "../../_plugin-vue_export-helper-CHgC5LLL.js";
import K from "../validation-messages/validation-messages.js";
const k = {
  compatConfig: { MODE: 3 },
  name: "DtSelectMenu",
  components: { DtValidationMessages: K },
  mixins: [V],
  inheritAttrs: !1,
  props: {
    /**
     * Label for the select
     */
    label: {
      type: String,
      default: ""
    },
    /**
     * Description for the select
     */
    description: {
      type: String,
      default: ""
    },
    /**
     * Select Menu Options, overridden by default slot. Each option has the following structure:
     * `{ value: number || string (required), label: string (required) }`
     * @param {Object[]} options - Optional - A list that can be used to create a list of select menu options
     * @param {number|string} options[].value - Required - The option value
     * @param {string} options[].label - Required - The option Label
     */
    options: {
      type: Array,
      default: () => [],
      validator: (e) => F(e)
    },
    /**
     * Controls the size of the select
     * @values xs, sm, md, lg, xl
     */
    size: {
      type: String,
      default: "md",
      validator: (e) => Object.keys(S).includes(e)
    },
    /**
     * Used to customize the label container
     */
    labelClass: {
      type: [String, Array, Object],
      default: ""
    },
    /**
     * Used to customize the description container
     */
    descriptionClass: {
      type: [String, Array, Object],
      default: ""
    },
    /**
     * Used to customize the select
     */
    selectClass: {
      type: [String, Array, Object],
      default: ""
    },
    /**
     * Used to customize each option, should options be provided via prop
     */
    optionClass: {
      type: [String, Array, Object],
      default: ""
    },
    /**
     * A set of props that are passed into the label container
     */
    labelChildProps: {
      type: Object,
      default: () => ({})
    },
    /**
     * A set of props that are passed into the description container
     */
    descriptionChildProps: {
      type: Object,
      default: () => ({})
    },
    /**
     * A set of props that are passed into each option, should options be provided via prop
     */
    optionChildProps: {
      type: Object,
      default: () => ({})
    },
    /**
     * Disabled state of the select
     * @values true, false
     */
    disabled: {
      type: Boolean,
      default: !1
    }
  },
  emits: [
    /**
     * Native input event
     *
     * @event input
     * @type {String | Number}
     */
    "input",
    /**
     * Event fired to sync the modelValue prop with the parent component
     *
     * @event input
     * @type {String | Number}
     */
    "update:modelValue",
    /**
     * Native change event
     *
     * @event change
     * @type {String | Number}
     */
    "change"
  ],
  data() {
    return {
      LABEL_SIZE_MODIFIERS: v,
      DESCRIPTION_SIZE_MODIFIERS: A,
      SELECT_SIZE_MODIFIERS: S,
      SELECT_STATE_MODIFIERS: D,
      hasSlotContent: M
    };
  },
  computed: {
    selectListeners() {
      return {
        /*
         * Override input listener to as no-op. Prevents parent input listeners from being passed through onto the input
         * element which will result in the handler being called twice (once on the select element and once by the
         * emitted input event by the change listener).
        */
        input: () => {
        },
        change: (e) => this.emitValue(e.target.value, e)
      };
    },
    state() {
      return P(this.formattedMessages);
    },
    selectKey() {
      return L();
    },
    descriptionKey() {
      return `select-${this.selectKey}-description`;
    },
    labelAriaDetails() {
      return this.$slots.description || this.description ? this.descriptionKey : this.$attrs["aria-details"];
    }
  },
  mounted() {
    this.validateOptionsPresence();
  },
  beforeUpdate() {
    this.validateOptionsPresence();
  },
  methods: {
    removeClassStyleAttrs: R,
    addClassStyleAttrs: T,
    emitValue(e, d) {
      this.$emit("update:modelValue", e, d), this.$emit("input", e, d), this.$emit("change", e, d);
    },
    getOptionKey(e) {
      return `select-${this.selectKey}-option-${e}`;
    },
    validateOptionsPresence() {
      var e;
      ((e = this.options) == null ? void 0 : e.length) < 1 && !this.$slots.default && f("Options are expected to be provided via prop or slot", this);
    }
  }
}, q = ["aria-details"], z = ["id"], N = ["disabled"], Z = ["value"];
function w(e, d, t, B, a, s) {
  const h = g("dt-validation-messages");
  return l(), i("div", y(C(s.addClassStyleAttrs(e.$attrs))), [
    n("label", null, [
      a.hasSlotContent(e.$slots.label) || t.label ? (l(), i("div", r({
        key: 0,
        "aria-details": s.labelAriaDetails,
        class: [
          "d-label",
          a.LABEL_SIZE_MODIFIERS[t.size],
          t.labelClass
        ]
      }, t.labelChildProps, { "data-qa": "dt-select-label" }), [
        c(e.$slots, "label", {}, () => [
          u(m(t.label), 1)
        ])
      ], 16, q)) : p("", !0),
      a.hasSlotContent(e.$slots.description) || t.description ? (l(), i("div", r({
        key: 1,
        id: s.descriptionKey,
        class: [
          "d-description",
          a.DESCRIPTION_SIZE_MODIFIERS[t.size],
          t.descriptionClass
        ]
      }, t.descriptionChildProps, { "data-qa": "dt-select-description" }), [
        c(e.$slots, "description", {}, () => [
          u(m(t.description), 1)
        ])
      ], 16, z)) : p("", !0),
      n("div", {
        class: E([
          "d-select",
          a.SELECT_SIZE_MODIFIERS[t.size],
          t.selectClass,
          { "d-select--disabled": t.disabled }
        ]),
        "data-qa": "dt-select-wrapper"
      }, [
        n("select", r({
          ref: "selectElement",
          class: [
            "d-select__input",
            a.SELECT_STATE_MODIFIERS[s.state]
          ]
        }, s.removeClassStyleAttrs(e.$attrs), {
          "data-qa": "dt-select",
          disabled: t.disabled
        }, b(s.selectListeners, !0)), [
          c(e.$slots, "default", {}, () => [
            (l(!0), i(_, null, I(t.options, (o) => (l(), i("option", r({
              key: s.getOptionKey(o.value),
              value: o.value,
              class: t.optionClass
            }, t.optionChildProps), m(o.label), 17, Z))), 128))
          ])
        ], 16, N)
      ], 2)
    ]),
    O(h, r({
      "validation-messages": e.formattedMessages,
      "show-messages": e.showMessages,
      class: e.messagesClass
    }, e.messagesChildProps, { "data-qa": "dt-select-messages" }), null, 16, ["validation-messages", "show-messages", "class"])
  ], 16);
}
const x = /* @__PURE__ */ j(k, [["render", w]]);
export {
  x as default
};
//# sourceMappingURL=select-menu.js.map
