// SPDX-FileCopyrightText: 2022 Gregor Kleen ,Sarah Vaupel ,Sarah Vaupel // // SPDX-License-Identifier: AGPL-3.0-or-later import { Utility } from '../../core/utility'; import { EventManager, EventWrapper, EVENT_TYPE } from '../../lib/event-manager/event-manager'; import './asidenav.sass'; 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; _eventManager; constructor(element) { if (!element) { throw new Error('Asidenav utility cannot be setup without an element!'); } this._element = element; this._eventManager = new EventManager(); 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._eventManager.cleanUp(); if(this._element.classList.contains(ASIDENAV_INITIALIZED_CLASS)) this._element.classList.remove(ASIDENAV_INITIALIZED_CLASS); } _initFavoritesButton() { const favoritesBtn = document.querySelector('.' + FAVORITES_BTN_CLASS); if (favoritesBtn) { const favoritesButtonEvent = new EventWrapper(EVENT_TYPE.CLICK, (event) => { favoritesBtn.classList.toggle(FAVORITES_BTN_ACTIVE_CLASS); this._element.classList.toggle(ASIDENAV_EXPANDED_CLASS); event.preventDefault(); }, favoritesBtn, true); this._eventManager.registerNewListener(favoritesButtonEvent); } } _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); let currentHoverEvent = new EventWrapper(EVENT_TYPE.MOUSE_OVER, union.hoverHandler, union.listItem); this._eventManager.registerNewListener(currentHoverEvent); }); } _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'; } }; } }