UNPKG

@dialpad/dialtone

Version:

Dialpad's Dialtone design system monorepo

127 lines (126 loc) 4.9 kB
import N from "./dom.js"; const _ = "listElementKey is required or the referenced element doesn't exist. Received listElement: ", v = ({ // Role of the list items in the component. This is used to identify the list items // so you must update this if the role of your list items is anything other than 'option' listItemRole: h = "option", // Key of the data prop that will be added to the component. indexKey: s = "highlightIndex", idKey: n = "highlightId", // Key of the method that references the list element. listElementKey: I = "listRef", // Optional, Key of the computed prop that references the currently active item element. activeItemKey: c = "", // Optional, name of the method that toggles the list visibility. Used for // opening the list when up or down is pressed. openMethod: l = null, // Optional, method to call when the highlightIndex is changed. afterHighlightMethod: r = null, // Optional, method to call when the highlightIndex goes past the beginning of the list. beginningOfListMethod: m = null, // Optional, method to call when the highlightIndex goes past the end of the list. endOfListMethod: g = null, // Scroll the active element into view when highlighted by a keyboard event. scrollToOnHighlight: d = !0, // Focus the active element on keyboard navigation. focusOnKeyboardNavigation: f = !1 } = {}) => ({ mixins: [N], data() { return { [s]: -1, [n]: "", scrollToOnHighlight: d, focusOnKeyboardNavigation: f }; }, provide() { return { highlightId: () => this[n] }; }, methods: { // Returns the list element // this[listElement]() can return a Vue component, in which case we need to target // the $el property, or it can simply be an html element. _getListElement() { var t; return ((t = this[I]()) == null ? void 0 : t.$el) || this[I](); }, // Gets the length of all the items in the list, uses the listItemRole param to determine // whether an element is a list item. _itemsLength() { const t = this._getListItemNodes(); return t === null ? 0 : t.length; }, // Gets all the list item nodes within the list element _getListItemNodes() { const t = this._getListElement(); return t ? Array.from(t.querySelectorAll(`[role="${h}"], #sr-only-close-button`)) : (console.error(_, t), null); }, onUpKey() { l && this[l](!0), this[s] > 0 ? this.setHighlightIndex(this[s] - 1) : m && this[m](), this.scrollActiveItemIntoViewIfNeeded(), this.focusActiveItemIfNeeded(); }, onDownKey() { l && this[l](!0), this[s] < this._itemsLength() - 1 ? this.setHighlightIndex(this[s] + 1) : g && this[g](), this.scrollActiveItemIntoViewIfNeeded(), this.focusActiveItemIfNeeded(); }, onHomeKey() { this.jumpToBeginning(), this.scrollActiveItemIntoViewIfNeeded(), this.focusActiveItemIfNeeded(); }, onEndKey() { this.jumpToEnd(), this.scrollActiveItemIntoViewIfNeeded(), this.focusActiveItemIfNeeded(); }, onNavigationKey(t) { const e = this._getListItemNodes(), i = e.filter((o) => o.textContent.trim().toLowerCase().startsWith(t.toLowerCase())); if (i.length <= 0) return; const u = i.findIndex((o) => this[s] === e.indexOf(o)), a = e.indexOf( u < i.length - 1 ? i[u + 1] : i[0] ); this.setHighlightIndex(a), this.scrollActiveItemIntoViewIfNeeded(), this.focusActiveItemIfNeeded(); }, isValidLetter(t) { return t.length > 1 ? !1 : t >= "a" && t <= "z" || t >= "A" && t <= "Z"; }, jumpToBeginning() { this.setHighlightIndex(0); }, jumpToEnd() { this.setHighlightIndex(this._itemsLength() - 1); }, setHighlightIndex(t) { this[s] = t, this[n] = this._getItemId(t), this._itemsLength() && r && this[r](t); }, setHighlightId(t) { this[n] = t, this[s] = this._getItemIndex(t), this._itemsLength() && r && this[r](this._getItemIndex(t)); }, _getItemIndex(t) { const e = this._getListElement(); return e ? Array.from(e.querySelectorAll(`[role="${h}"], #sr-only-close-button`)).indexOf(e.querySelector(`#${t}`)) : void 0; }, _getItemId(t) { var i; const e = this._getListElement(); if (e) return (i = e.querySelectorAll(`[role="${h}"], #sr-only-close-button`)[t]) == null ? void 0 : i.id; }, scrollActiveItemIntoViewIfNeeded() { if (!this.scrollToOnHighlight) return; const t = this[c]; if (t) { const e = this._getListElement(); this.scrollElementIntoViewIfNeeded(t, null, null, e); } }, focusActiveItemIfNeeded() { if (!this.focusOnKeyboardNavigation) return; const t = this[c]; t && t.focus(); } } }); export { v as default }; //# sourceMappingURL=keyboard-list-navigation.js.map