UNPKG

@shopware-ag/meteor-component-library

Version:

The meteor component library is a Vue component library developed by Shopware. It is based on the [Meteor Design System](https://shopware.design/).

272 lines (271 loc) 9.08 kB
import '../mt-select-result-list.css'; "use strict"; const vue = require("vue"); const MtPopoverDeprecated = require("./MtPopoverDeprecated.js"); const mtIcon_vue_vue_type_style_index_0_lang = require("../mt-icon.vue_vue_type_style_index_0_lang-0a28c7b6.js"); const provideInjectKeys = require("../provideInjectKeys-d5eff718.js"); const vueI18n = require("vue-i18n"); const _pluginVue_exportHelper = require("../_plugin-vue_export-helper-9c783a34.js"); const _sfc_main = vue.defineComponent({ name: "MtSelectResultList", components: { "mt-popover-deprecated": MtPopoverDeprecated, "mt-icon": mtIcon_vue_vue_type_style_index_0_lang._sfc_main }, provide() { return { setActiveItemIndex: this.setActiveItemIndex }; }, setup() { const { t } = vueI18n.useI18n({ messages: { en: { messageNoResults: "No results found." }, de: { messageNoResults: "Es wurden keine Ergebnisse gefunden." } } }); const activeItemIndex = vue.ref(0); const activeItemChangeListeners = vue.ref([]); const itemSelectByKeyboardListeners = vue.ref([]); const emitActiveItemIndex = () => { activeItemChangeListeners.value.forEach((listener) => { listener(activeItemIndex.value); }); }; const setActiveItemIndex = (index) => { activeItemIndex.value = index; emitActiveItemIndex(); }; const addToActiveItemChangeListeners = (listener) => { activeItemChangeListeners.value.push(listener); }; const removeActiveItemChangeListener = (listener) => { activeItemChangeListeners.value = activeItemChangeListeners.value.filter( (l) => l !== listener ); }; const addToItemSelectByKeyboardListeners = (listener) => { itemSelectByKeyboardListeners.value.push(listener); }; const removeItemSelectByKeyboardListener = (listener) => { itemSelectByKeyboardListeners.value = itemSelectByKeyboardListeners.value.filter( (l) => l !== listener ); }; vue.provide(provideInjectKeys.MtSelectResultAddActiveItemListener, addToActiveItemChangeListeners); vue.provide(provideInjectKeys.MtSelectResultRemoveActiveItemListener, removeActiveItemChangeListener); vue.provide(provideInjectKeys.MtSelectResultAddItemSelectByKeyboardListener, addToItemSelectByKeyboardListeners); vue.provide(provideInjectKeys.MtSelectResultRemoveItemSelectByKeyboardListener, removeItemSelectByKeyboardListener); return { t, activeItemIndex, emitActiveItemIndex, setActiveItemIndex, addToActiveItemChangeListeners, removeActiveItemChangeListener, addToItemSelectByKeyboardListeners, removeItemSelectByKeyboardListener }; }, props: { options: { type: Array, required: false, default() { return []; } }, emptyMessage: { type: String, required: false, default: null }, focusEl: { type: [Object], required: false, default() { return document; } }, isLoading: { type: Boolean, required: false, default: false }, popoverClasses: { type: Array, required: false, default() { return []; } }, popoverResizeWidth: { type: Boolean, required: false, default: true } }, data() { return { activeItemChangeListeners: [], itemSelectByKeyboardListeners: [] }; }, computed: { popoverClass() { return [...this.popoverClasses, "mt-select-result-list-popover-wrapper"]; } }, created() { this.addEventListeners(); }, mounted() { this.emitActiveItemIndex(); }, beforeUnmount() { this.removeEventListeners(); }, methods: { addEventListeners() { this.focusEl.addEventListener("keydown", this.navigate); document.addEventListener("click", this.checkOutsideClick); }, removeEventListeners() { this.focusEl.removeEventListener("keydown", this.navigate); document.removeEventListener("click", this.checkOutsideClick); }, /** * * @param event {Event} */ checkOutsideClick(event) { event.stopPropagation(); const popoverContentClicked = this.$refs.popoverContent.contains(event.target); const componentClicked = this.$el.contains(event.target); const parentClicked = this.$parent.$el.contains(event.target); if (popoverContentClicked || componentClicked || parentClicked) { return; } this.$emit("outside-click"); }, navigate({ key }) { key = key.toUpperCase(); if (key === "ARROWDOWN") { this.navigateNext(); return; } if (key === "ARROWUP") { this.navigatePrevious(); return; } if (key === "ENTER") { this.emitClicked(); } }, navigateNext() { if (this.activeItemIndex >= this.options.length - 1) { this.$emit("paginate"); return; } this.activeItemIndex += 1; this.emitActiveItemIndex(); this.updateScrollPosition(); }, navigatePrevious() { if (this.activeItemIndex > 0) { this.activeItemIndex -= 1; } this.emitActiveItemIndex(); this.updateScrollPosition(); }, updateScrollPosition() { this.$nextTick(() => { const resultContainer = document.querySelector(".mt-select-result-list__content"); const activeItem = resultContainer.querySelector(".is--active"); const itemHeight = activeItem.offsetHeight; const activeItemPosition = activeItem.offsetTop; const actualScrollTop = resultContainer.scrollTop; if (activeItemPosition === 0) { return; } if (resultContainer.offsetHeight + actualScrollTop < activeItemPosition + itemHeight) { resultContainer.scrollTop += itemHeight; } if (actualScrollTop !== 0 && activeItemPosition - actualScrollTop - itemHeight <= 0) { resultContainer.scrollTop -= itemHeight; } }); }, emitClicked() { this.$emit("item-select-by-keyboard", this.activeItemIndex); this.itemSelectByKeyboardListeners.forEach((listener) => { listener(this.activeItemIndex); }); }, onScroll(event) { if (this.getBottomDistance(event.target) !== 0) { return; } this.$emit("paginate"); }, getBottomDistance(element) { return element.scrollHeight - element.clientHeight - element.scrollTop; } } }); const mtSelectResultList_vue_vue_type_style_index_0_lang = ""; const _hoisted_1 = { class: "mt-select-result-list" }; const _hoisted_2 = { class: "mt-select-result-list__item-list" }; const _hoisted_3 = { key: 0, class: "mt-select-result-list__empty" }; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_mt_icon = vue.resolveComponent("mt-icon"); const _component_mt_popover_deprecated = vue.resolveComponent("mt-popover-deprecated"); return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [ vue.createVNode(_component_mt_popover_deprecated, { class: "mt-select-result-list-popover", "popover-class": _ctx.popoverClass, "z-index": 1100, "resize-width": _ctx.popoverResizeWidth }, { default: vue.withCtx(() => [ vue.createElementVNode("div", { ref: "popoverContent", class: vue.normalizeClass([ "mt-select-result-list__content", { "mt-select-result-list__content_empty": _ctx.isLoading && (!_ctx.options || _ctx.options.length <= 0) } ]), onScroll: _cache[0] || (_cache[0] = (...args) => _ctx.onScroll && _ctx.onScroll(...args)) }, [ vue.renderSlot(_ctx.$slots, "before-item-list"), vue.createElementVNode("ul", _hoisted_2, [ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.options, (item, index) => { return vue.renderSlot(_ctx.$slots, "result-item", vue.mergeProps({ ref_for: true }, { item, index })); }), 256)) ]), vue.renderSlot(_ctx.$slots, "after-item-list"), !_ctx.isLoading && _ctx.options && _ctx.options.length < 1 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3, [ vue.createVNode(_component_mt_icon, { name: "regular-search", size: "var(--scale-size-16)", style: { "margin-right": "var(--scale-size-4)" } }), vue.createTextVNode(" " + vue.toDisplayString(_ctx.emptyMessage || _ctx.t("messageNoResults")), 1) ])) : vue.createCommentVNode("", true) ], 34) ]), _: 3 }, 8, ["popover-class", "resize-width"]) ]); } const MtSelectResultList = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main, [["render", _sfc_render]]); module.exports = MtSelectResultList; //# sourceMappingURL=MtSelectResultList.js.map