@dialpad/dialtone-vue
Version:
Vue component library for Dialpad's design system Dialtone
325 lines (324 loc) • 10.4 kB
JavaScript
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