fradrive/frontend/src/utils/navbar/navbar.js

102 lines
2.8 KiB
JavaScript

import { Utility } from '../../core/utility';
import { EventManager, EventWrapper, EVENT_TYPE } from '../../lib/event-manager/event-manager';
import './navbar.sass';
import throttle from 'lodash.throttle';
export const HEADER_CONTAINER_UTIL_SELECTOR = '.navbar__list-item--container-selector .navbar__link-wrapper';
const HEADER_CONTAINER_INITIALIZED_CLASS = 'navbar-header-container--initialized';
@Utility({
selector: HEADER_CONTAINER_UTIL_SELECTOR,
})
export class NavHeaderContainerUtil {
_element;
radioButton;
closeButton;
container;
wasOpen;
_throttleUpdateWasOpen;
_eventManager;
constructor(element) {
if (!element) {
throw new Error('Navbar Header Container utility needs to be passed an element!');
}
if (element.classList.contains(HEADER_CONTAINER_INITIALIZED_CLASS)) {
return;
}
this._element = element;
this.radioButton = document.getElementById(`${this._element.id}-radio`);
this._eventManager = new EventManager();
if (!this.radioButton) {
throw new Error('Navbar Header Container utility could not find associated radio button!');
}
this.closeButton = document.getElementById('container-radio-none');
if (!this.closeButton) {
throw new Error('Navbar Header Container utility could not find radio button for closing!');
}
this.container = document.getElementById(`${this._element.id}-container`);
if (!this.container) {
throw new Error('Navbar Header Container utility could not find associated container!');
}
const closer = this.container.querySelector('.navbar__container-list-closer');
if (closer) {
closer.classList.add('navbar__container-list-closer--hidden');
}
this.updateWasOpen();
this.throttleUpdateWasOpen = throttle(this.updateWasOpen.bind(this), 100, { leading: false, trailing: true });
this._element.classList.add(HEADER_CONTAINER_INITIALIZED_CLASS);
}
start() {
if (!this.container)
return;
const clickEv = new EventWrapper(EVENT_TYPE.CLICK, this.clickHandler.bind(this), window);
const changeEv = new EventWrapper(EVENT_TYPE.CHANGE, this.throttleUpdateWasOpen.bind(this), this.radioButton);
this._eventManager.registerListeners([clickEv, changeEv]);
}
clickHandler() {
if (!this.container.contains(event.target) && window.document.contains(event.target) && this.wasOpen) {
this.close();
}
}
close() {
this.radioButton.checked = false;
this.throttleUpdateWasOpen();
}
isOpen() {
return this.radioButton.checked;
}
updateWasOpen() {
this.wasOpen = this.isOpen();
}
destroy() {
this._eventManager.cleanUp();
this._element.classList.remove(HEADER_CONTAINER_INITIALIZED_CLASS);
}
}
export const NavbarUtils = [
NavHeaderContainerUtil,
];