import { resolveComponent as f, createElementBlock as i, openBlock as r, mergeProps as l, createElementVNode as n, createVNode as g, createCommentVNode as u, renderSlot as c, createTextVNode as p, toDisplayString as m, normalizeClass as y, toHandlers as C, Fragment as b, renderList as E, warn as _ } from "vue";
import { DESCRIPTION_SIZE_MODIFIERS as I, LABEL_SIZE_MODIFIERS as O } from "../../common/constants/index.js";
import { SELECT_STATE_MODIFIERS as v, SELECT_SIZE_MODIFIERS as S } from "./select-menu-constants.js";
import { addClassStyleAttrs as A, removeClassStyleAttrs as D, getUniqueString as M, getValidationState as P, hasSlotContent as V } from "../../common/utils/index.js";
import { MessagesMixin as L } from "../../common/mixins/input.js";
import { optionsValidator as T } from "./select-menu-validators.js";
import { _ as R } from "../../_plugin-vue_export-helper-CHgC5LLL.js";
import j from "../validation-messages/validation-messages.js";
const F = {
  compatConfig: { MODE: 3 },
  name: "DtSelectMenu",
  components: { DtValidationMessages: j },
  mixins: [L],
  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) => T(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
    },
    /**
     * Additional class name for the root 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.
     */
    rootClass: {
      type: [String, Object, Array],
      default: ""
    },
    /**
     * The value of the select menu
     */
    modelValue: {
      type: [String, Number],
      default: ""
    }
  },
  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: O,
      DESCRIPTION_SIZE_MODIFIERS: I,
      SELECT_SIZE_MODIFIERS: S,
      SELECT_STATE_MODIFIERS: v,
      hasSlotContent: V
    };
  },
  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 M();
    },
    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: D,
    addClassStyleAttrs: A,
    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 && _("Options are expected to be provided via prop or slot", this);
    }
  }
}, K = ["aria-details"], N = ["id"], k = ["disabled", "value"], q = ["value"];
function Z(e, d, t, w, a, s) {
  const h = f("dt-validation-messages");
  return r(), i("div", l({ class: t.rootClass }, s.addClassStyleAttrs(e.$attrs)), [
    n("label", null, [
      a.hasSlotContent(e.$slots.label) || t.label ? (r(), i("div", l({
        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", {}, () => [
          p(m(t.label), 1)
        ])
      ], 16, K)) : u("", !0),
      a.hasSlotContent(e.$slots.description) || t.description ? (r(), i("div", l({
        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", {}, () => [
          p(m(t.description), 1)
        ])
      ], 16, N)) : u("", !0),
      n("div", {
        class: y([
          "d-select",
          a.SELECT_SIZE_MODIFIERS[t.size],
          t.selectClass,
          { "d-select--disabled": t.disabled }
        ]),
        "data-qa": "dt-select-wrapper"
      }, [
        n("select", l({
          ref: "selectElement",
          class: [
            "d-select__input",
            a.SELECT_STATE_MODIFIERS[s.state]
          ]
        }, s.removeClassStyleAttrs(e.$attrs), {
          "data-qa": "dt-select",
          disabled: t.disabled,
          value: t.modelValue
        }, C(s.selectListeners, !0)), [
          c(e.$slots, "default", {}, () => [
            (r(!0), i(b, null, E(t.options, (o) => (r(), i("option", l({
              key: s.getOptionKey(o.value),
              value: o.value,
              class: t.optionClass
            }, t.optionChildProps), m(o.label), 17, q))), 128))
          ])
        ], 16, k)
      ], 2)
    ]),
    g(h, l({
      "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__ */ R(F, [["render", Z]]);
export {
  X as default
};
//# sourceMappingURL=select-menu.js.map
