UNPKG

@dialpad/dialtone

Version:

Dialpad's Dialtone design system monorepo

274 lines (273 loc) 9.24 kB
"use strict"; Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } }); const vue = require("vue"); const common_constants = require("../../common/constants.cjs"); const select_menu_constants = require("./select_menu_constants.cjs"); const common_utils = require("../../common/utils.cjs"); const input = require("../../common/mixins/input.cjs"); const select_menu_validators = require("./select_menu_validators.cjs"); const _pluginVue_exportHelper = require("../../_virtual/_plugin-vue_export-helper.cjs"); const validation_messages = require("../validation_messages/validation_messages.vue.cjs"); const _sfc_main = { compatConfig: { MODE: 3 }, name: "DtSelectMenu", components: { DtValidationMessages: validation_messages.default }, mixins: [input.MessagesMixin], inheritAttrs: false, 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: * `{ index: number (optional), 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} options[].index - Optional - The index of the option * @param {number|string} options[].value - Required - The option value * @param {string} options[].label - Required - The option Label */ options: { type: Array, default: () => [], validator: (options) => select_menu_validators.optionsValidator(options) }, /** * Controls the size of the select * @values xs, sm, md, lg, xl */ size: { type: String, default: "md", validator: (s) => Object.keys(select_menu_constants.SELECT_SIZE_MODIFIERS).includes(s) }, /** * 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: false } }, emits: [ /** * Native input event * * @event input * @type {String | Number} */ "input", /** * Native change event * * @event change * @type {String | Number} */ "change" ], data() { return { LABEL_SIZE_MODIFIERS: common_constants.LABEL_SIZE_MODIFIERS, DESCRIPTION_SIZE_MODIFIERS: common_constants.DESCRIPTION_SIZE_MODIFIERS, SELECT_SIZE_MODIFIERS: select_menu_constants.SELECT_SIZE_MODIFIERS, SELECT_STATE_MODIFIERS: select_menu_constants.SELECT_STATE_MODIFIERS, hasSlotContent: common_utils.hasSlotContent }; }, 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: (event) => this.emitValue(event.target.value, event) }; }, state() { return common_utils.getValidationState(this.formattedMessages); }, selectKey() { return common_utils.getUniqueString(); }, descriptionKey() { return `select-${this.selectKey}-description`; }, labelAriaDetails() { if (this.$slots.description || this.description) { return this.descriptionKey; } return this.$attrs["aria-details"]; } }, watch: { // whenever question changes, this function will run options() { this.$nextTick(() => { this.emitValue(this.$refs.selectElement.value, null); }); } }, mounted() { this.emitValue(this.$refs.selectElement.value, null); this.validateOptionsPresence(); }, beforeUpdate() { this.validateOptionsPresence(); }, methods: { removeClassStyleAttrs: common_utils.removeClassStyleAttrs, addClassStyleAttrs: common_utils.addClassStyleAttrs, emitValue(value, event) { this.$emit("input", value, event); this.$emit("change", value, event); }, getOptionKey(value) { return `select-${this.selectKey}-option-${value}`; }, validateOptionsPresence() { var _a; if (((_a = this.options) == null ? void 0 : _a.length) < 1 && !this.$slots.default) { vue.warn("Options are expected to be provided via prop or slot", this); } } } }; const _hoisted_1 = ["aria-details"]; const _hoisted_2 = ["id"]; const _hoisted_3 = ["disabled"]; const _hoisted_4 = ["value"]; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_dt_validation_messages = vue.resolveComponent("dt-validation-messages"); return vue.openBlock(), vue.createElementBlock("div", vue.normalizeProps(vue.guardReactiveProps($options.addClassStyleAttrs(_ctx.$attrs))), [ vue.createElementVNode("label", null, [ $data.hasSlotContent(_ctx.$slots.label) || $props.label ? (vue.openBlock(), vue.createElementBlock("div", vue.mergeProps({ key: 0, "aria-details": $options.labelAriaDetails, class: [ "d-label", $data.LABEL_SIZE_MODIFIERS[$props.size], $props.labelClass ] }, $props.labelChildProps, { "data-qa": "dt-select-label" }), [ vue.renderSlot(_ctx.$slots, "label", {}, () => [ vue.createTextVNode(vue.toDisplayString($props.label), 1) ]) ], 16, _hoisted_1)) : vue.createCommentVNode("", true), $data.hasSlotContent(_ctx.$slots.description) || $props.description ? (vue.openBlock(), vue.createElementBlock("div", vue.mergeProps({ key: 1, id: $options.descriptionKey, class: [ "d-description", $data.DESCRIPTION_SIZE_MODIFIERS[$props.size], $props.descriptionClass ] }, $props.descriptionChildProps, { "data-qa": "dt-select-description" }), [ vue.renderSlot(_ctx.$slots, "description", {}, () => [ vue.createTextVNode(vue.toDisplayString($props.description), 1) ]) ], 16, _hoisted_2)) : vue.createCommentVNode("", true), vue.createElementVNode("div", { class: vue.normalizeClass([ "d-select", $data.SELECT_SIZE_MODIFIERS[$props.size], $props.selectClass, { "d-select--disabled": $props.disabled } ]), "data-qa": "dt-select-wrapper" }, [ vue.createElementVNode("select", vue.mergeProps({ ref: "selectElement", class: [ "d-select__input", $data.SELECT_STATE_MODIFIERS[$options.state] ] }, $options.removeClassStyleAttrs(_ctx.$attrs), { "data-qa": "dt-select", disabled: $props.disabled }, vue.toHandlers($options.selectListeners, true)), [ vue.renderSlot(_ctx.$slots, "default", {}, () => [ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList($props.options, (option) => { return vue.openBlock(), vue.createElementBlock("option", vue.mergeProps({ key: $options.getOptionKey(option.value), value: option.value, class: $props.optionClass }, $props.optionChildProps), vue.toDisplayString(option.label), 17, _hoisted_4); }), 128)) ]) ], 16, _hoisted_3) ], 2) ]), vue.createVNode(_component_dt_validation_messages, vue.mergeProps({ "validation-messages": _ctx.formattedMessages, "show-messages": _ctx.showMessages, class: _ctx.messagesClass }, _ctx.messagesChildProps, { "data-qa": "dt-select-messages" }), null, 16, ["validation-messages", "show-messages", "class"]) ], 16); } const select_menu = /* @__PURE__ */ _pluginVue_exportHelper.default(_sfc_main, [["render", _sfc_render]]); exports.default = select_menu; //# sourceMappingURL=select_menu.vue.cjs.map