@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/).
178 lines (177 loc) • 4.97 kB
JavaScript
import { defineComponent, renderSlot } from "vue";
import { _ as _export_sfc } from "../_plugin-vue_export-helper-cc2b3d55.mjs";
function getWidth(el) {
if (!el) {
return 0;
}
const styles = window.getComputedStyle(el);
const margin = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight);
return Math.ceil(el.offsetWidth + margin);
}
const _sfc_main = defineComponent({
name: "PriorityPlusMenu",
props: {
/**
* The list of navigation items to display.
*/
list: {
type: Array,
required: true,
default() {
return [];
}
},
/**
* The offset factor is used to multiply the width of the last visible item for the more button offset.
*/
offsetFactor: {
type: Number,
default: 1.5
},
/**
* The property used to identify the items in the list.
*/
identifier: {
type: String,
required: false,
default: "name"
}
},
data() {
return {
/**
* The accumulated widths of the items in the list.
* For example take this list for items with a widht of 100px each:
* [100, 200, 300, 400, 500]
*
* This list is used to search the last item index which fits into the container width.
*/
accumItemWidths: [],
/**
* This list contains the identifiers of the items which are hidden.
* The values respect the prop `identifier`.
*/
hiddenItemIdentifiers: []
};
},
computed: {
/**
* The items which are currently displayed.
*/
mainItems() {
return this.list.filter((item) => !this.hiddenItemIdentifiers.includes(item.name));
},
/**
* The items which are currently hidden.
*/
moreItems() {
return this.list.filter((item) => this.hiddenItemIdentifiers.includes(item.name));
},
hasHiddenItems() {
return !!this.moreItems.length;
},
/**
* The HTML elements of the visible items.
*/
visibleElements() {
const els = {};
this.list.forEach((item) => {
if (this.hiddenItemIdentifiers.includes(item[this.identifier])) {
return;
}
const el = this.$el.parentElement.querySelector(
`[data-priority-plus="${item[this.identifier]}"]`
);
if (!el) {
return;
}
els[item[this.identifier]] = el;
});
return els;
},
/**
* The last visible HTML element.
*/
lastVisibleElement() {
const keys = Object.keys(this.visibleElements);
const lastKey = keys[keys.length - 1];
return this.visibleElements[lastKey];
}
},
async mounted() {
await this.$nextTick();
this.storeItemWidths();
this.handleResize();
this.handleResize();
window.addEventListener("resize", this.handleResize);
},
watch: {
/**
* Watch the list for changes and recalculate the item widths.
* This is necessary if the list changes after the component is mounted.
*/
list: {
handler() {
this.handleResize();
},
deep: true
}
},
beforeUnmount() {
window.removeEventListener("resize", this.handleResize);
},
methods: {
storeItemWidths() {
let sum = 0;
this.list.forEach((item, index) => {
sum += getWidth(this.visibleElements[item[this.identifier]]);
this.accumItemWidths[index] = sum;
});
},
getContainerWidth() {
var _a, _b;
let offset = 0;
if (this.hasHiddenItems) {
const firstVisibleElement = Object.values(this.visibleElements)[0];
offset = getWidth(firstVisibleElement) * this.offsetFactor;
}
return ((_b = (_a = this.$el) == null ? void 0 : _a.nextSibling) == null ? void 0 : _b.offsetWidth) - offset;
},
getLastVisibleItemIndex() {
let index = 0;
const containerWidth = this.getContainerWidth();
while (index < this.accumItemWidths.length) {
if (this.accumItemWidths[index] > containerWidth) {
index--;
break;
}
index++;
}
return index;
},
async handleResize() {
await this.$nextTick();
const lastVisibleItemIndex = this.getLastVisibleItemIndex();
this.hiddenItemIdentifiers = [];
this.list.forEach((item, index) => {
const hidden = index > lastVisibleItemIndex;
if (!hidden) {
this.hiddenItemIdentifiers = this.hiddenItemIdentifiers.filter((id) => id !== item.name);
return;
}
this.hiddenItemIdentifiers.push(item.name);
});
}
}
});
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return renderSlot(_ctx.$slots, "default", {
mainItems: _ctx.mainItems,
moreItems: _ctx.moreItems
});
}
const PriorityPlus = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
export {
PriorityPlus as default
};
//# sourceMappingURL=MtPriorityPlusNavigation.js.map