import { Utility } from '../../core/utility'; import './asidenav.scss'; const FAVORITES_BTN_CLASS = 'navbar__list-item--favorite'; const FAVORITES_BTN_ACTIVE_CLASS = 'navbar__list-item--active'; const ASIDENAV_INITIALIZED_CLASS = 'asidenav--initialized'; const ASIDENAV_EXPANDED_CLASS = 'main__aside--expanded'; const ASIDENAV_LIST_ITEM_CLASS = 'asidenav__list-item'; const ASIDENAV_SUBMENU_CLASS = 'asidenav__nested-list-wrapper'; @Utility({ selector: '[uw-asidenav]', }) export class Asidenav { _element; _asidenavSubmenus; constructor(element) { if (!element) { throw new Error('Asidenav utility cannot be setup without an element!'); } this._element = element; if (this._element.classList.contains(ASIDENAV_INITIALIZED_CLASS)) { return false; } this._initFavoritesButton(); this._initAsidenavSubmenus(); // mark initialized this._element.classList.add(ASIDENAV_INITIALIZED_CLASS); } destroy() { this._asidenavSubmenus.forEach((union) => { union.listItem.removeEventListener(union.hoverHandler); }); } _initFavoritesButton() { const favoritesBtn = document.querySelector('.' + FAVORITES_BTN_CLASS); if (favoritesBtn) { favoritesBtn.addEventListener('click', (event) => { favoritesBtn.classList.toggle(FAVORITES_BTN_ACTIVE_CLASS); this._element.classList.toggle(ASIDENAV_EXPANDED_CLASS); event.preventDefault(); }, true); } } _initAsidenavSubmenus() { this._asidenavSubmenus = Array.from(this._element.querySelectorAll('.' + ASIDENAV_LIST_ITEM_CLASS)) .map(function(listItem) { const submenu = listItem.querySelector('.' + ASIDENAV_SUBMENU_CLASS); return { listItem, submenu }; }).filter(function(union) { return union.submenu !== null; }); this._asidenavSubmenus.forEach((union) => { union.hoverHandler = this._createMouseoverHandler(union); union.listItem.addEventListener('mouseover', union.hoverHandler); }); } _createMouseoverHandler(union) { return () => { const rectListItem = union.listItem.getBoundingClientRect(); const rectSubMenu = union.submenu.getBoundingClientRect(); union.submenu.style.left = (rectListItem.left + rectListItem.width) + 'px'; if (window.innerHeight - rectListItem.top < rectSubMenu.height) { union.submenu.style.top = (rectListItem.top + rectListItem.height - rectSubMenu.height) + 'px'; } else { union.submenu.style.top = rectListItem.top + 'px'; } }; } }