UNPKG

@dialpad/dialtone-vue

Version:

Vue component library for Dialpad's design system Dialtone

325 lines (324 loc) • 10.4 kB
import p from "../combobox/combobox-loading-list.js"; import u from "../combobox/combobox-empty-list.js"; import { getUniqueString as l } from "../../common/utils/index.js"; import { n as d } from "../../_plugin-vue2_normalizer-DSLOjnn3.js"; import { POPOVER_CONTENT_WIDTHS as f, POPOVER_APPEND_TO_VALUES as h } from "../popover/popover-constants.js"; import c from "../popover/popover.js"; import m from "../combobox/combobox.js"; import { DROPDOWN_PADDING_CLASSES as a } from "../dropdown/dropdown-constants.js"; import { COMBOBOX_LABEL_SIZES as b } from "../combobox/combobox-constants.js"; const y = { name: "DtRecipeComboboxWithPopover", components: { DtCombobox: m, DtPopover: c, ComboboxLoadingList: p, ComboboxEmptyList: 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 }, /** * Size of the input, one of `xs`, `sm`, `md`, `lg`, `xl` * @values null, xs, sm, md, lg, xl */ size: { type: String, default: null, validator: (e) => Object.values(b).includes(e) }, /** * Description for the input */ description: { type: String, default: "" }, /** * 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 }, /** * 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(); } }, /** * Additional class for the wrapper list element. */ listClass: { type: [String, Array, Object], default: "" }, /** * 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 maximum height for the popover before overflow. * Possible units rem|px|em */ maxHeight: { type: String, default: "" }, /** * Determines maximum width for the popover before overflow. * Possible units rem|px|%|em */ maxWidth: { type: String, default: "" }, /** * Vertical padding size around the list element. */ padding: { type: String, default: "small", validator: (e) => Object.keys(a).some((t) => t === e) }, /** * Width configuration for the popover content. When its value is 'anchor', * the popover content will have the same width as the anchor. */ contentWidth: { type: String, default: null, validator: (e) => f.includes(e) }, /** * If the list should be shown by pressing up or down arrow key on the input element. * This can be set when not passing showList prop. */ openWithArrowKeys: { type: Boolean, default: !1 }, /** * Displaces the popover content box from its anchor element * by the specified number of pixels. */ popoverOffset: { type: Array, default: () => [0, 4] }, /** * If the popover sticks to the input. */ popoverSticky: { type: [Boolean, String], default: !1 }, /** * 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 }, /** * Determines when to show the skeletons and also controls aria-busy attribute. */ loading: { type: Boolean, default: !1 }, /** * Sets the list to an empty state, and displays the message from prop `emptyStateMessage`. */ emptyList: { type: Boolean, default: !1 }, /** * Message to show when the list is empty */ emptyStateMessage: { type: String, default: "" }, /** * 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: (e) => h.includes(e) || e instanceof HTMLElement }, /** * Named transition when the content display is toggled. * @see DtLazyShow */ transition: { type: String, default: "fade" } }, emits: [ /** * Event fired when item selected * * @event select * @type {Number} */ "select", /** * Event fired when 'escape' key is pressed * * @event escape */ "escape", /** * Event fired when an item is highlighted * * @event highlight * @type {Number} */ "highlight", /** * Emitted when items are shown or hidden * * @event opened * @type {Boolean | Array} */ "opened" ], data() { return { DROPDOWN_PADDING_CLASSES: a, isListShown: !1, isInputFocused: !1, isListFocused: !1, externalAnchor: l() }; }, computed: { comboboxListeners() { return { ...this.$listeners, select: this.onSelect, escape: this.onEscape, highlight: this.onHighlight }; } }, watch: { showList: { handler: function(e) { e !== null && (this.isListShown = e); }, immediate: !0 }, isListShown(e) { e ? window.addEventListener("mousedown", this.onFocusOut) : window.removeEventListener("mousedown", this.onFocusOut), this.onOpened(e); } }, methods: { handleDisplayList(e) { !this.hasSuggestionList && e && this.showComboboxList(), !this.hasSuggestionList && !e && this.closeComboboxList(); }, showComboboxList() { this.showList == null && (this.isListShown = !0); }, closeComboboxList() { this.showList == null && (this.isListShown = !1); }, onSelect(e) { this.loading || (this.$emit("select", e), this.hasSuggestionList || this.closeComboboxList()); }, onEscape() { this.$emit("escape"), this.closeComboboxList(); }, onHighlight(e) { this.loading || this.$emit("highlight", e); }, onOpened(e) { this.$emit("opened", e); }, onFocusIn(e) { var t; this.hasSuggestionList && e && ((t = this.$refs.input) == null ? void 0 : t.querySelector("input")) === e.target && this.showComboboxList(); }, onFocusOut(e) { var n, o, s; const t = (o = (n = this.$refs.popover) == null ? void 0 : n.tip) == null ? void 0 : o.popper, i = this.$refs.input; (s = e.composedPath()) != null && s.some((r) => [t, i].includes(r)) || this.closeComboboxList(); }, openOnArrowKeyPress() { this.showList !== null || this.isListShown || !this.openWithArrowKeys || this.showComboboxList(); } } }; var g = function() { var t = this, i = t._self._c; return i("dt-combobox", t._g({ ref: "combobox", attrs: { loading: t.loading, label: t.label, "label-visible": t.labelVisible, size: t.size, description: t.description, "empty-list": t.emptyList, "empty-state-message": t.emptyStateMessage, "show-list": t.isListShown, "on-beginning-of-list": t.onBeginningOfList, "on-end-of-list": t.onEndOfList, "list-rendered-outside": !0, "list-id": t.listId, "data-qa": "dt-combobox" }, scopedSlots: t._u([{ key: "input", fn: function({ inputProps: n }) { return [i("div", { ref: "input", attrs: { id: t.externalAnchor }, on: { focusin: t.onFocusIn, keydown: [function(o) { return !o.type.indexOf("key") && t._k(o.keyCode, "up", 38, o.key, ["Up", "ArrowUp"]) ? null : t.openOnArrowKeyPress(o); }, function(o) { return !o.type.indexOf("key") && t._k(o.keyCode, "down", 40, o.key, ["Down", "ArrowDown"]) ? null : t.openOnArrowKeyPress(o); }] } }, [t._t("input", null, { inputProps: n, onInput: t.handleDisplayList })], 2)]; } }, { key: "list", fn: function({ opened: n, listProps: o, clearHighlightIndex: s }) { return [i("dt-popover", { ref: "popover", attrs: { open: t.isListShown, "hide-on-click": !1, "max-height": t.maxHeight, "max-width": t.maxWidth, offset: t.popoverOffset, sticky: t.popoverSticky, placement: "bottom-start", "initial-focus-element": "none", padding: "none", role: "listbox", "external-anchor": t.externalAnchor, "content-width": t.contentWidth, "content-appear": !0, "content-tabindex": null, modal: !1, "auto-focus": !1, "append-to": t.appendTo, transition: t.transition }, on: { "update:open": function(r) { t.isListShown = r; }, opened: function(r) { return n(r, arguments[1]); } }, scopedSlots: t._u([t.$slots.header ? { key: "headerContent", fn: function() { return [i("div", { ref: "header" }, [t._t("header")], 2)]; }, proxy: !0 } : null, { key: "content", fn: function() { return [i("div", { ref: "listWrapper", class: [ "d-recipe-combobox-with-popover__list", t.DROPDOWN_PADDING_CLASSES[t.padding], t.listClass ], on: { mouseleave: s, focusout: s } }, [t.loading ? i("combobox-loading-list", t._b({}, "combobox-loading-list", o, !1)) : t.emptyList && t.emptyStateMessage ? i("combobox-empty-list", t._b({ attrs: { message: t.emptyStateMessage } }, "combobox-empty-list", o, !1)) : t._t("list", null, { listProps: o })], 2)]; }, proxy: !0 }, t.$slots.footer ? { key: "footerContent", fn: function() { return [i("div", { ref: "footer" }, [t._t("footer")], 2)]; }, proxy: !0 } : null], null, !0) })]; } }], null, !0) }, t.comboboxListeners)); }, L = [], S = /* @__PURE__ */ d( y, g, L ); const D = S.exports; export { D as default }; //# sourceMappingURL=combobox-with-popover.js.map