UNPKG

@dialpad/dialtone

Version:

Dialpad's Dialtone design system monorepo

398 lines (397 loc) 11.5 kB
import _ from "../combobox/combobox-loading-list.js"; import C from "../combobox/combobox-empty-list.js"; import { hasSlotContent as v, getUniqueString as g } from "../../common/utils/index.js"; import { resolveComponent as r, createBlock as f, openBlock as p, mergeProps as c, withCtx as l, createVNode as E, createSlots as P, createElementVNode as a, normalizeClass as A, renderSlot as d, normalizeProps as D, withKeys as y } from "vue"; import { _ as B } from "../../_plugin-vue_export-helper-CHgC5LLL.js"; import { POPOVER_CONTENT_WIDTHS as k, POPOVER_APPEND_TO_VALUES as F } from "../popover/popover-constants.js"; import W from "../popover/popover.js"; import I from "../combobox/combobox.js"; import { DROPDOWN_PADDING_CLASSES as S } from "../dropdown/dropdown-constants.js"; import { COMBOBOX_LABEL_SIZES as M } from "../combobox/combobox-constants.js"; const N = { compatConfig: { MODE: 3 }, name: "DtRecipeComboboxWithPopover", components: { DtCombobox: I, DtPopover: W, ComboboxLoadingList: _, ComboboxEmptyList: C }, 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: (t) => Object.values(M).includes(t) }, /** * 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 g(); } }, /** * 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: (t) => Object.keys(S).some((o) => o === t) }, /** * 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: (t) => k.includes(t) }, /** * 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: (t) => F.includes(t) || t 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: S, isListShown: !1, isInputFocused: !1, isListFocused: !1, externalAnchor: g(), hasSlotContent: v }; }, computed: { comboboxListeners() { return { ...this.$attrs, onSelect: this.onSelect, onEscape: this.onEscape, onHighlight: this.onHighlight }; } }, watch: { showList: { handler: function(t) { t !== null && (this.isListShown = t); }, immediate: !0 }, isListShown(t) { t ? window.addEventListener("mousedown", this.onFocusOut) : window.removeEventListener("mousedown", this.onFocusOut), this.onOpened(t); } }, methods: { handleDisplayList(t) { !this.hasSuggestionList && t && this.showComboboxList(), !this.hasSuggestionList && !t && this.closeComboboxList(); }, showComboboxList() { this.showList == null && (this.isListShown = !0); }, closeComboboxList() { this.showList == null && (this.isListShown = !1); }, onSelect(t) { this.loading || (this.$emit("select", t), this.hasSuggestionList || this.closeComboboxList()); }, onEscape() { this.$emit("escape"), this.closeComboboxList(); }, onHighlight(t) { this.loading || this.$emit("highlight", t); }, onOpened(t) { this.$emit("opened", t); }, onFocusIn(t) { var o; this.hasSuggestionList && t && ((o = this.$refs.input) == null ? void 0 : o.querySelector("input")) === t.target && this.showComboboxList(); }, onFocusOut(t) { var m, i, n; const o = (i = (m = this.$refs.popover) == null ? void 0 : m.tip) == null ? void 0 : i.popper, e = this.$refs.input; (n = t.composedPath()) != null && n.some((u) => [o, e].includes(u)) || this.closeComboboxList(); }, openOnArrowKeyPress() { this.showList !== null || this.isListShown || !this.openWithArrowKeys || this.showComboboxList(); } } }, H = ["id"], K = { ref: "header" }, T = ["onMouseleave", "onFocusout"], V = { ref: "footer" }; function z(t, o, e, m, i, n) { const u = r("combobox-loading-list"), L = r("combobox-empty-list"), w = r("dt-popover"), x = r("dt-combobox"); return p(), f(x, c({ ref: "combobox", loading: e.loading, label: e.label, "label-visible": e.labelVisible, size: e.size, description: e.description, "empty-list": e.emptyList, "empty-state-message": e.emptyStateMessage, "show-list": i.isListShown, "on-beginning-of-list": e.onBeginningOfList, "on-end-of-list": e.onEndOfList, "list-rendered-outside": !0, "list-id": e.listId, "data-qa": "dt-combobox" }, n.comboboxListeners), { input: l(({ inputProps: h }) => [ a("div", { id: i.externalAnchor, ref: "input", onFocusin: o[0] || (o[0] = (...s) => n.onFocusIn && n.onFocusIn(...s)), onKeydown: [ o[1] || (o[1] = y((s) => n.openOnArrowKeyPress(s), ["up"])), o[2] || (o[2] = y((s) => n.openOnArrowKeyPress(s), ["down"])) ] }, [ d(t.$slots, "input", { inputProps: h, onInput: n.handleDisplayList }) ], 40, H) ]), list: l(({ opened: h, listProps: s, clearHighlightIndex: b }) => [ E(w, { ref: "popover", open: i.isListShown, "onUpdate:open": o[3] || (o[3] = (O) => i.isListShown = O), "hide-on-click": !1, "max-height": e.maxHeight, "max-width": e.maxWidth, offset: e.popoverOffset, sticky: e.popoverSticky, placement: "bottom-start", "initial-focus-element": "none", padding: "none", role: "listbox", "external-anchor": i.externalAnchor, "content-width": e.contentWidth, "content-appear": !0, "content-tabindex": null, modal: !1, "auto-focus": !1, "append-to": e.appendTo, transition: e.transition, onOpened: h }, P({ content: l(() => [ a("div", { ref: "listWrapper", class: A([ "d-recipe-combobox-with-popover__list", i.DROPDOWN_PADDING_CLASSES[e.padding], e.listClass ]), onMouseleave: b, onFocusout: b }, [ e.loading ? (p(), f(u, D(c({ key: 0 }, s)), null, 16)) : e.emptyList && e.emptyStateMessage ? (p(), f(L, c({ key: 1 }, s, { message: e.emptyStateMessage }), null, 16, ["message"])) : d(t.$slots, "list", { key: 2, listProps: s }) ], 42, T) ]), _: 2 }, [ i.hasSlotContent(t.$slots.header) ? { name: "headerContent", fn: l(() => [ a("div", K, [ d(t.$slots, "header") ], 512) ]), key: "0" } : void 0, i.hasSlotContent(t.$slots.footer) ? { name: "footerContent", fn: l(() => [ a("div", V, [ d(t.$slots, "footer") ], 512) ]), key: "1" } : void 0 ]), 1032, ["open", "max-height", "max-width", "offset", "sticky", "external-anchor", "content-width", "append-to", "transition", "onOpened"]) ]), _: 3 }, 16, ["loading", "label", "label-visible", "size", "description", "empty-list", "empty-state-message", "show-list", "on-beginning-of-list", "on-end-of-list", "list-id"]); } const $ = /* @__PURE__ */ B(N, [["render", z]]); export { $ as default }; //# sourceMappingURL=combobox-with-popover.js.map