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

177 lines (176 loc) 5 kB
"use strict"; const vue = require("vue"); const _pluginVue_exportHelper = require("../_plugin-vue_export-helper-9c783a34.js"); 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 = vue.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 vue.renderSlot(_ctx.$slots, "default", { mainItems: _ctx.mainItems, moreItems: _ctx.moreItems }); } const PriorityPlus = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main, [["render", _sfc_render]]); module.exports = PriorityPlus; //# sourceMappingURL=MtPriorityPlusNavigation.js.map