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/).

273 lines (272 loc) 9.18 kB
import '../mt-select-result-list.css'; import { defineComponent, ref, provide, resolveComponent, openBlock, createElementBlock, createVNode, withCtx, createElementVNode, normalizeClass, renderSlot, Fragment, renderList, mergeProps, createTextVNode, toDisplayString, createCommentVNode } from "vue"; import MtPopoverDeprecated from "./MtPopoverDeprecated.js"; import { _ as _sfc_main$1 } from "../mt-icon.vue_vue_type_style_index_0_lang-2cc5f73e.mjs"; import { M as MtSelectResultAddActiveItemListener, a as MtSelectResultRemoveActiveItemListener, b as MtSelectResultAddItemSelectByKeyboardListener, c as MtSelectResultRemoveItemSelectByKeyboardListener } from "../provideInjectKeys-47aad241.mjs"; import { useI18n } from "vue-i18n"; import { _ as _export_sfc } from "../_plugin-vue_export-helper-cc2b3d55.mjs"; const _sfc_main = defineComponent({ name: "MtSelectResultList", components: { "mt-popover-deprecated": MtPopoverDeprecated, "mt-icon": _sfc_main$1 }, provide() { return { setActiveItemIndex: this.setActiveItemIndex }; }, setup() { const { t } = useI18n({ messages: { en: { messageNoResults: "No results found." }, de: { messageNoResults: "Es wurden keine Ergebnisse gefunden." } } }); const activeItemIndex = ref(0); const activeItemChangeListeners = ref([]); const itemSelectByKeyboardListeners = 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 ); }; provide(MtSelectResultAddActiveItemListener, addToActiveItemChangeListeners); provide(MtSelectResultRemoveActiveItemListener, removeActiveItemChangeListener); provide(MtSelectResultAddItemSelectByKeyboardListener, addToItemSelectByKeyboardListeners); provide(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 = resolveComponent("mt-icon"); const _component_mt_popover_deprecated = resolveComponent("mt-popover-deprecated"); return openBlock(), createElementBlock("div", _hoisted_1, [ createVNode(_component_mt_popover_deprecated, { class: "mt-select-result-list-popover", "popover-class": _ctx.popoverClass, "z-index": 1100, "resize-width": _ctx.popoverResizeWidth }, { default: withCtx(() => [ createElementVNode("div", { ref: "popoverContent", class: 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)) }, [ renderSlot(_ctx.$slots, "before-item-list"), createElementVNode("ul", _hoisted_2, [ (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.options, (item, index) => { return renderSlot(_ctx.$slots, "result-item", mergeProps({ ref_for: true }, { item, index })); }), 256)) ]), renderSlot(_ctx.$slots, "after-item-list"), !_ctx.isLoading && _ctx.options && _ctx.options.length < 1 ? (openBlock(), createElementBlock("div", _hoisted_3, [ createVNode(_component_mt_icon, { name: "regular-search", size: "var(--scale-size-16)", style: { "margin-right": "var(--scale-size-4)" } }), createTextVNode(" " + toDisplayString(_ctx.emptyMessage || _ctx.t("messageNoResults")), 1) ])) : createCommentVNode("", true) ], 34) ]), _: 3 }, 8, ["popover-class", "resize-width"]) ]); } const MtSelectResultList = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]); export { MtSelectResultList as default }; //# sourceMappingURL=MtSelectResultList.js.map