@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
JavaScript
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