83 lines
2.5 KiB
JavaScript
83 lines
2.5 KiB
JavaScript
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';
|
|
}
|
|
};
|
|
}
|
|
}
|