This repository has been archived on 2024-10-24. You can view files and clone it, but cannot push or open issues or pull requests.
fradrive-old/frontend/src/utils/asidenav/asidenav.js
2022-10-12 09:35:16 +02:00

97 lines
3.1 KiB
JavaScript

// SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>
//
// 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';
}
};
}
}