UNPKG

minsky-kit

Version:
139 lines (111 loc) 3.76 kB
// imports import Component from 'minsky-kit/js/components/Component'; import tippy from 'tippy.js'; // class definition export default class NavOverflow extends Component { // constructor constructor (args = {}, objectName = 'NavOverflow') { // super super(args, objectName); this.items = Array.from(this.$el.querySelectorAll('.menu__item')); this.$menuList = this.$el.querySelector('.menu__list'); this.$overlapEl = args.$overlapEl; // list this.overflowList = document.createElement('ul'); this.overflowList.classList.add('menu__overflow-list'); this.$moreEl = this.$el.querySelector('.menu__item--more'); // tippy this.tippy = tippy(this.$moreEl, { trigger: 'mouseenter focus focusin', content: this.overflowList, placement: 'bottom-start', interactive: true, }); this.overflowItems = []; // first init this.update(); } // methods destroy () { this.$el.classList.remove('menu--main--show-more'); if (this.overflowItems.length) { this.overflowItems.reverse(); this.overflowItems.forEach(($oi) => { this.$menuList.insertBefore($oi, this.$moreEl); }); } super.destroy(); } update () { // calculate overflow items if (this.hasOverlap()) { this.cut(); } else { if (this.canShift()) { this.shift(); } } } cut () { const overflowItems = []; if (!this.overflowItems.length) { overflowItems.push(this.items[this.items.length - 2]); overflowItems.push(this.items[this.items.length - 3]); } else { overflowItems.push(this.items[this.items.length - (this.overflowItems.length + 1)]); } // add them to list overflowItems.forEach(($oi) => { $oi.dataset.originalWidth = $oi.offsetWidth; this.overflowList.insertBefore($oi, this.overflowList.firstChild); }); this.overflowItems.push(...overflowItems); // add active class if (this.overflowItems.length) { this.$el.classList.add('menu--main--show-more'); } else { this.$el.classList.remove('menu--main--show-more'); } if (this.hasOverlap()) { this.cut(); } } shift () { this.$menuList.insertBefore(this.overflowItems.pop(), this.$moreEl); // add active class if (this.overflowItems.length) { this.$el.classList.add('menu--main--show-more'); } else { this.$el.classList.remove('menu--main--show-more'); } if (this.canShift()) { this.shift(); } } hasOverlap () { const overlapDimensions = this.$overlapEl.getBoundingClientRect(); const menuDimensions = this.$el.getBoundingClientRect(); return overlapDimensions.x <= menuDimensions.right; } canShift () { const overlapDimensions = this.$overlapEl.getBoundingClientRect(); const menuDimensions = this.$el.getBoundingClientRect(); // check for next el to pop if (this.overflowItems.length) { const $nextEl = this.overflowItems[0]; if ((overlapDimensions.x - menuDimensions.right) > (Number($nextEl.dataset.originalWidth) * 2)) { return true; } return false; } return false; } // getters & setters static get version () { return VERSION; } } // Utils // Event handlers