radfusion/resources/assets/vendor/js/menu.js

1222 lines
42 KiB
JavaScript

const TRANSITION_EVENTS = [
"transitionend",
"webkitTransitionEnd",
"oTransitionEnd",
];
// const TRANSITION_PROPERTIES = ['transition', 'MozTransition', 'webkitTransition', 'WebkitTransition', 'OTransition']
const DELTA = 5;
class Menu {
constructor(el, config = {}, _PS = null) {
this._el = el;
this._horizontal = config.orientation === "horizontal";
this._animate = config.animate !== false;
this._accordion = config.accordion !== false;
this._showDropdownOnHover = Boolean(config.showDropdownOnHover);
this._closeChildren = Boolean(config.closeChildren);
this._rtl =
document.documentElement.getAttribute("dir") === "rtl" ||
document.body.getAttribute("dir") === "rtl";
this._onOpen = config.onOpen || (() => {});
this._onOpened = config.onOpened || (() => {});
this._onClose = config.onClose || (() => {});
this._onClosed = config.onClosed || (() => {});
this._psScroll = null;
this._topParent = null;
this._menuBgClass = null;
el.classList.add("menu");
el.classList[this._animate ? "remove" : "add"]("menu-no-animation");
if (!this._horizontal) {
el.classList.add("menu-vertical");
el.classList.remove("menu-horizontal");
const PerfectScrollbarLib = _PS || window.PerfectScrollbar;
if (PerfectScrollbarLib) {
this._scrollbar = new PerfectScrollbarLib(
el.querySelector(".menu-inner"),
{
suppressScrollX: true,
wheelPropagation: !Menu._hasClass(
"layout-menu-fixed layout-menu-fixed-offcanvas",
),
},
);
window.Helpers.menuPsScroll = this._scrollbar;
} else {
el.querySelector(".menu-inner").classList.add("overflow-auto");
}
} else {
el.classList.add("menu-horizontal");
el.classList.remove("menu-vertical");
this._inner = el.querySelector(".menu-inner");
const container = this._inner.parentNode;
this._prevBtn = el.querySelector(".menu-horizontal-prev");
if (!this._prevBtn) {
this._prevBtn = document.createElement("a");
this._prevBtn.href = "#";
this._prevBtn.className = "menu-horizontal-prev";
container.appendChild(this._prevBtn);
}
this._wrapper = el.querySelector(".menu-horizontal-wrapper");
if (!this._wrapper) {
this._wrapper = document.createElement("div");
this._wrapper.className = "menu-horizontal-wrapper";
this._wrapper.appendChild(this._inner);
container.appendChild(this._wrapper);
}
this._nextBtn = el.querySelector(".menu-horizontal-next");
if (!this._nextBtn) {
this._nextBtn = document.createElement("a");
this._nextBtn.href = "#";
this._nextBtn.className = "menu-horizontal-next";
container.appendChild(this._nextBtn);
}
this._innerPosition = 0;
this.update();
}
// Add data attribute for bg color class of menu
const menuClassList = el.classList;
for (let i = 0; i < menuClassList.length; i++) {
if (menuClassList[i].startsWith("bg-")) {
this._menuBgClass = menuClassList[i];
}
}
el.setAttribute("data-bg-class", this._menuBgClass);
// Switch to vertical menu on small screen for horizontal menu layout on page load
if (
this._horizontal &&
window.innerWidth < window.Helpers.LAYOUT_BREAKPOINT
) {
this.switchMenu("vertical");
} else {
this._bindEvents();
}
// Link menu instance to element
el.menuInstance = this;
}
_bindEvents() {
// Click Event
this._evntElClick = (e) => {
// Find top parent element
if (
e.target.closest("ul") &&
e.target.closest("ul").classList.contains("menu-inner")
) {
const menuItem = Menu._findParent(e.target, "menu-item", false);
// eslint-disable-next-line prefer-destructuring
if (menuItem) this._topParent = menuItem.childNodes[0];
}
const toggleLink = e.target.classList.contains("menu-toggle")
? e.target
: Menu._findParent(e.target, "menu-toggle", false);
if (toggleLink) {
e.preventDefault();
if (toggleLink.getAttribute("data-hover") !== "true") {
this.toggle(toggleLink);
}
}
};
if (
(!this._showDropdownOnHover && this._horizontal) ||
!this._horizontal ||
window.Helpers.isMobileDevice
)
this._el.addEventListener("click", this._evntElClick);
this._evntWindowResize = () => {
this.update();
if (this._lastWidth !== window.innerWidth) {
this._lastWidth = window.innerWidth;
this.update();
}
const horizontalMenuTemplate = document.querySelector(
"[data-template^='horizontal-menu']",
);
if (!this._horizontal && !horizontalMenuTemplate)
this.manageScroll();
};
window.addEventListener("resize", this._evntWindowResize);
if (this._horizontal) {
this._evntPrevBtnClick = (e) => {
e.preventDefault();
if (this._prevBtn.classList.contains("disabled")) return;
this._slide("prev");
};
this._prevBtn.addEventListener("click", this._evntPrevBtnClick);
this._evntNextBtnClick = (e) => {
e.preventDefault();
if (this._nextBtn.classList.contains("disabled")) return;
this._slide("next");
};
this._nextBtn.addEventListener("click", this._evntNextBtnClick);
this._evntBodyClick = (e) => {
if (
!this._inner.contains(e.target) &&
this._el.querySelectorAll(".menu-inner > .menu-item.open")
.length
)
this.closeAll();
};
document.body.addEventListener("click", this._evntBodyClick);
if (this._showDropdownOnHover) {
/** ***********************************************
* Horizontal Menu Mouse Over Event
* ? e.target !== e.currentTarget condition to disable mouseover event on whole menu navbar
* ? !e.target.parentNode.classList.contains('open') to disable mouseover events on icon, text and dropdown arrow
*/
this._evntElMouseOver = (e) => {
if (
e.target !== e.currentTarget &&
!e.target.parentNode.classList.contains("open")
) {
const toggleLink = e.target.classList.contains(
"menu-toggle",
)
? e.target
: null;
if (toggleLink) {
e.preventDefault();
if (
toggleLink.getAttribute("data-hover") !== "true"
) {
this.toggle(toggleLink);
}
}
}
e.stopPropagation();
};
if (
this._horizontal &&
window.screen.width > window.Helpers.LAYOUT_BREAKPOINT
) {
this._el.addEventListener(
"mouseover",
this._evntElMouseOver,
);
}
/** ***********************************************
* Horizontal Menu Mouse Out Event
* ? e.target !== e.currentTarget condition to disable mouseout event on whole menu navbar
* ? mouseOutEl.parentNode.classList.contains('open') to check if the mouseout element has open class or not
* ? !mouseOutEl.classList.contains('menu-toggle') to check if mouseout was from single menu item and not from the one which has submenu
* ? !mouseOverEl.parentNode.classList.contains('menu-link') to disable mouseout event for icon, text and dropdown arrow
*/
this._evntElMouseOut = (e) => {
const mainEl = e.currentTarget;
const mouseOutEl = e.target;
const mouseOverEl = e.toElement || e.relatedTarget;
// Find absolute parent of any menu item from which mouseout event triggered
if (
mouseOutEl.closest("ul") &&
mouseOutEl
.closest("ul")
.classList.contains("menu-inner")
) {
this._topParent = mouseOutEl;
}
if (
mouseOutEl !== mainEl &&
(mouseOutEl.parentNode.classList.contains("open") ||
!mouseOutEl.classList.contains("menu-toggle")) &&
mouseOverEl &&
mouseOverEl.parentNode &&
!mouseOverEl.parentNode.classList.contains("menu-link")
) {
// When mouse goes totally out of menu items, check mouse over element to confirm it's not the child of menu, once confirmed close the menu
if (
this._topParent &&
!Menu.childOf(
mouseOverEl,
this._topParent.parentNode,
)
) {
const toggleLink =
this._topParent.classList.contains(
"menu-toggle",
)
? this._topParent
: null;
if (toggleLink) {
e.preventDefault();
if (
toggleLink.getAttribute("data-hover") !==
"true"
) {
this.toggle(toggleLink);
this._topParent = null;
}
}
}
// When mouse enter the sub menu, check if it's child of the initially mouse overed menu item(Actual Parent),
// if it's the parent do not close the sub menu else close the sub menu
if (Menu.childOf(mouseOverEl, mouseOutEl.parentNode)) {
return;
}
const toggleLink = mouseOutEl.classList.contains(
"menu-toggle",
)
? mouseOutEl
: null;
if (toggleLink) {
e.preventDefault();
if (
toggleLink.getAttribute("data-hover") !== "true"
) {
this.toggle(toggleLink);
}
}
}
e.stopPropagation();
};
if (
this._horizontal &&
window.screen.width > window.Helpers.LAYOUT_BREAKPOINT
) {
this._el.addEventListener("mouseout", this._evntElMouseOut);
}
}
}
}
static childOf(/* child node */ c, /* parent node */ p) {
// returns boolean
if (c.parentNode) {
while ((c = c.parentNode) && c !== p);
return !!c;
}
return false;
}
_unbindEvents() {
if (this._evntElClick) {
this._el.removeEventListener("click", this._evntElClick);
this._evntElClick = null;
}
if (this._evntElMouseOver) {
this._el.removeEventListener("mouseover", this._evntElMouseOver);
this._evntElMouseOver = null;
}
if (this._evntElMouseOut) {
this._el.removeEventListener("mouseout", this._evntElMouseOut);
this._evntElMouseOut = null;
}
if (this._evntWindowResize) {
window.removeEventListener("resize", this._evntWindowResize);
this._evntWindowResize = null;
}
if (this._evntBodyClick) {
document.body.removeEventListener("click", this._evntBodyClick);
this._evntBodyClick = null;
}
if (this._evntInnerMousemove) {
this._inner.removeEventListener(
"mousemove",
this._evntInnerMousemove,
);
this._evntInnerMousemove = null;
}
if (this._evntInnerMouseleave) {
this._inner.removeEventListener(
"mouseleave",
this._evntInnerMouseleave,
);
this._evntInnerMouseleave = null;
}
}
static _isRoot(item) {
return !Menu._findParent(item, "menu-item", false);
}
static _findParent(el, cls, throwError = true) {
if (el.tagName.toUpperCase() === "BODY") return null;
el = el.parentNode;
while (
el.tagName.toUpperCase() !== "BODY" &&
!el.classList.contains(cls)
) {
el = el.parentNode;
}
el = el.tagName.toUpperCase() !== "BODY" ? el : null;
if (!el && throwError)
throw new Error(`Cannot find \`.${cls}\` parent element`);
return el;
}
static _findChild(el, cls) {
const items = el.childNodes;
const found = [];
for (let i = 0, l = items.length; i < l; i++) {
if (items[i].classList) {
let passed = 0;
for (let j = 0; j < cls.length; j++) {
if (items[i].classList.contains(cls[j])) passed += 1;
}
if (cls.length === passed) found.push(items[i]);
}
}
return found;
}
static _findMenu(item) {
let curEl = item.childNodes[0];
let menu = null;
while (curEl && !menu) {
if (curEl.classList && curEl.classList.contains("menu-sub"))
menu = curEl;
curEl = curEl.nextSibling;
}
if (!menu)
throw new Error(
"Cannot find `.menu-sub` element for the current `.menu-toggle`",
);
return menu;
}
// Has class
static _hasClass(cls, el = window.Helpers.ROOT_EL) {
let result = false;
cls.split(" ").forEach((c) => {
if (el.classList.contains(c)) result = true;
});
return result;
}
open(el, closeChildren = this._closeChildren) {
const item = this._findUnopenedParent(
Menu._getItem(el, true),
closeChildren,
);
if (!item) return;
const toggleLink = Menu._getLink(item, true);
Menu._promisify(
this._onOpen,
this,
item,
toggleLink,
Menu._findMenu(item),
)
.then(() => {
if (!this._horizontal || !Menu._isRoot(item)) {
if (this._animate && !this._horizontal) {
window.requestAnimationFrame(() =>
this._toggleAnimation(true, item, false),
);
if (this._accordion)
this._closeOther(item, closeChildren);
} else if (this._animate) {
this._toggleDropdown(true, item, closeChildren);
// eslint-disable-next-line no-unused-expressions
this._onOpened &&
this._onOpened(
this,
item,
toggleLink,
Menu._findMenu(item),
);
} else {
item.classList.add("open");
// eslint-disable-next-line no-unused-expressions
this._onOpened &&
this._onOpened(
this,
item,
toggleLink,
Menu._findMenu(item),
);
if (this._accordion)
this._closeOther(item, closeChildren);
}
} else {
this._toggleDropdown(true, item, closeChildren);
// eslint-disable-next-line no-unused-expressions
this._onOpened &&
this._onOpened(
this,
item,
toggleLink,
Menu._findMenu(item),
);
}
})
.catch(() => {});
}
close(el, closeChildren = this._closeChildren, _autoClose = false) {
const item = Menu._getItem(el, true);
const toggleLink = Menu._getLink(el, true);
if (
!item.classList.contains("open") ||
item.classList.contains("disabled")
)
return;
Menu._promisify(
this._onClose,
this,
item,
toggleLink,
Menu._findMenu(item),
_autoClose,
)
.then(() => {
if (!this._horizontal || !Menu._isRoot(item)) {
if (this._animate && !this._horizontal) {
window.requestAnimationFrame(() =>
this._toggleAnimation(false, item, closeChildren),
);
} else {
item.classList.remove("open");
if (closeChildren) {
const opened =
item.querySelectorAll(".menu-item.open");
for (let i = 0, l = opened.length; i < l; i++)
opened[i].classList.remove("open");
}
// eslint-disable-next-line no-unused-expressions
this._onClosed &&
this._onClosed(
this,
item,
toggleLink,
Menu._findMenu(item),
);
}
} else {
this._toggleDropdown(false, item, closeChildren);
// eslint-disable-next-line no-unused-expressions
this._onClosed &&
this._onClosed(
this,
item,
toggleLink,
Menu._findMenu(item),
);
}
})
.catch(() => {});
}
_closeOther(item, closeChildren) {
const opened = Menu._findChild(item.parentNode, ["menu-item", "open"]);
for (let i = 0, l = opened.length; i < l; i++) {
if (opened[i] !== item) this.close(opened[i], closeChildren);
}
}
toggle(el, closeChildren = this._closeChildren) {
const item = Menu._getItem(el, true);
// const toggleLink = Menu._getLink(el, true)
if (item.classList.contains("open")) this.close(item, closeChildren);
else this.open(item, closeChildren);
}
_toggleDropdown(show, item, closeChildren) {
const menu = Menu._findMenu(item);
const actualItem = item;
let subMenuItem = false;
if (show) {
if (Menu._findParent(item, "menu-sub", false)) {
subMenuItem = true;
item = this._topParent ? this._topParent.parentNode : item;
}
const wrapperWidth = Math.round(
this._wrapper.getBoundingClientRect().width,
);
const position = this._innerPosition;
const itemOffset = this._getItemOffset(item);
const itemWidth = Math.round(item.getBoundingClientRect().width);
if (itemOffset - DELTA <= -1 * position) {
this._innerPosition = -1 * itemOffset;
} else if (
itemOffset + position + itemWidth + DELTA >=
wrapperWidth
) {
if (itemWidth > wrapperWidth) {
this._innerPosition = -1 * itemOffset;
} else {
this._innerPosition =
-1 * (itemOffset + itemWidth - wrapperWidth);
}
}
actualItem.classList.add("open");
const menuWidth = Math.round(menu.getBoundingClientRect().width);
if (subMenuItem) {
if (
itemOffset + this._innerPosition + menuWidth * 2 >
wrapperWidth &&
menuWidth < wrapperWidth &&
menuWidth >= itemWidth
) {
menu.style.left = [this._rtl ? "100%" : "-100%"];
}
} else if (
itemOffset + this._innerPosition + menuWidth > wrapperWidth &&
menuWidth < wrapperWidth &&
menuWidth > itemWidth
) {
menu.style[this._rtl ? "marginRight" : "marginLeft"] =
`-${menuWidth - itemWidth}px`;
}
this._closeOther(actualItem, closeChildren);
this._updateSlider();
} else {
const toggle = Menu._findChild(item, ["menu-toggle"]);
// eslint-disable-next-line no-unused-expressions
toggle.length && toggle[0].removeAttribute("data-hover", "true");
item.classList.remove("open");
menu.style[this._rtl ? "marginRight" : "marginLeft"] = null;
if (closeChildren) {
const opened = menu.querySelectorAll(".menu-item.open");
for (let i = 0, l = opened.length; i < l; i++)
opened[i].classList.remove("open");
}
}
}
_slide(direction) {
const wrapperWidth = Math.round(
this._wrapper.getBoundingClientRect().width,
);
const innerWidth = this._innerWidth;
let newPosition;
if (direction === "next") {
newPosition = this._getSlideNextPos();
if (innerWidth + newPosition < wrapperWidth) {
newPosition = wrapperWidth - innerWidth;
}
} else {
newPosition = this._getSlidePrevPos();
if (newPosition > 0) newPosition = 0;
}
this._innerPosition = newPosition;
this.update();
}
_getSlideNextPos() {
const wrapperWidth = Math.round(
this._wrapper.getBoundingClientRect().width,
);
const position = this._innerPosition;
let curItem = this._inner.childNodes[0];
let left = 0;
while (curItem) {
if (curItem.tagName) {
const curItemWidth = Math.round(
curItem.getBoundingClientRect().width,
);
if (
left + position - DELTA <= wrapperWidth &&
left + position + curItemWidth + DELTA >= wrapperWidth
) {
if (curItemWidth > wrapperWidth && left === -1 * position)
left += curItemWidth;
break;
}
left += curItemWidth;
}
curItem = curItem.nextSibling;
}
return -1 * left;
}
_getSlidePrevPos() {
const wrapperWidth = Math.round(
this._wrapper.getBoundingClientRect().width,
);
const position = this._innerPosition;
let curItem = this._inner.childNodes[0];
let left = 0;
while (curItem) {
if (curItem.tagName) {
const curItemWidth = Math.round(
curItem.getBoundingClientRect().width,
);
if (
left - DELTA <= -1 * position &&
left + curItemWidth + DELTA >= -1 * position
) {
if (curItemWidth <= wrapperWidth)
left = left + curItemWidth - wrapperWidth;
break;
}
left += curItemWidth;
}
curItem = curItem.nextSibling;
}
return -1 * left;
}
static _getItem(el, toggle) {
let item = null;
const selector = toggle ? "menu-toggle" : "menu-link";
if (el.classList.contains("menu-item")) {
if (Menu._findChild(el, [selector]).length) item = el;
} else if (el.classList.contains(selector)) {
item = el.parentNode.classList.contains("menu-item")
? el.parentNode
: null;
}
if (!item) {
throw new Error(
`${toggle ? "Toggable " : ""}\`.menu-item\` element not found.`,
);
}
return item;
}
static _getLink(el, toggle) {
let found = [];
const selector = toggle ? "menu-toggle" : "menu-link";
if (el.classList.contains(selector)) found = [el];
else if (el.classList.contains("menu-item"))
found = Menu._findChild(el, [selector]);
if (!found.length)
throw new Error(`\`${selector}\` element not found.`);
return found[0];
}
_findUnopenedParent(item, closeChildren) {
let tree = [];
let parentItem = null;
while (item) {
if (item.classList.contains("disabled")) {
parentItem = null;
tree = [];
} else {
if (!item.classList.contains("open")) parentItem = item;
tree.push(item);
}
item = Menu._findParent(item, "menu-item", false);
}
if (!parentItem) return null;
if (tree.length === 1) return parentItem;
tree = tree.slice(0, tree.indexOf(parentItem));
for (let i = 0, l = tree.length; i < l; i++) {
tree[i].classList.add("open");
if (this._accordion) {
const openedItems = Menu._findChild(tree[i].parentNode, [
"menu-item",
"open",
]);
for (let j = 0, k = openedItems.length; j < k; j++) {
if (openedItems[j] !== tree[i]) {
openedItems[j].classList.remove("open");
if (closeChildren) {
const openedChildren =
openedItems[j].querySelectorAll(
".menu-item.open",
);
for (
let x = 0, z = openedChildren.length;
x < z;
x++
) {
openedChildren[x].classList.remove("open");
}
}
}
}
}
}
return parentItem;
}
_toggleAnimation(open, item, closeChildren) {
const toggleLink = Menu._getLink(item, true);
const menu = Menu._findMenu(item);
Menu._unbindAnimationEndEvent(item);
const linkHeight = Math.round(
toggleLink.getBoundingClientRect().height,
);
item.style.overflow = "hidden";
const clearItemStyle = () => {
item.classList.remove("menu-item-animating");
item.classList.remove("menu-item-closing");
item.style.overflow = null;
item.style.height = null;
if (!this._horizontal) this.update();
};
if (open) {
item.style.height = `${linkHeight}px`;
item.classList.add("menu-item-animating");
item.classList.add("open");
Menu._bindAnimationEndEvent(item, () => {
clearItemStyle();
this._onOpened(this, item, toggleLink, menu);
});
setTimeout(() => {
item.style.height = `${linkHeight + Math.round(menu.getBoundingClientRect().height)}px`;
}, 50);
} else {
item.style.height = `${linkHeight + Math.round(menu.getBoundingClientRect().height)}px`;
item.classList.add("menu-item-animating");
item.classList.add("menu-item-closing");
Menu._bindAnimationEndEvent(item, () => {
item.classList.remove("open");
clearItemStyle();
if (closeChildren) {
const opened = item.querySelectorAll(".menu-item.open");
for (let i = 0, l = opened.length; i < l; i++)
opened[i].classList.remove("open");
}
this._onClosed(this, item, toggleLink, menu);
});
setTimeout(() => {
item.style.height = `${linkHeight}px`;
}, 50);
}
}
static _bindAnimationEndEvent(el, handler) {
const cb = (e) => {
if (e.target !== el) return;
Menu._unbindAnimationEndEvent(el);
handler(e);
};
let duration = window.getComputedStyle(el).transitionDuration;
duration =
parseFloat(duration) * (duration.indexOf("ms") !== -1 ? 1 : 1000);
el._menuAnimationEndEventCb = cb;
TRANSITION_EVENTS.forEach((ev) =>
el.addEventListener(ev, el._menuAnimationEndEventCb, false),
);
el._menuAnimationEndEventTimeout = setTimeout(() => {
cb({ target: el });
}, duration + 50);
}
_getItemOffset(item) {
let curItem = this._inner.childNodes[0];
let left = 0;
while (curItem !== item) {
if (curItem.tagName) {
left += Math.round(curItem.getBoundingClientRect().width);
}
curItem = curItem.nextSibling;
}
return left;
}
_updateSlider(wrapperWidth = null, innerWidth = null, position = null) {
const _wrapperWidth =
wrapperWidth !== null
? wrapperWidth
: Math.round(this._wrapper.getBoundingClientRect().width);
const _innerWidth = innerWidth !== null ? innerWidth : this._innerWidth;
const _position = position !== null ? position : this._innerPosition;
if (
_innerWidth < _wrapperWidth ||
window.innerWidth < window.Helpers.LAYOUT_BREAKPOINT
) {
this._prevBtn.classList.add("d-none");
this._nextBtn.classList.add("d-none");
} else {
this._prevBtn.classList.remove("d-none");
this._nextBtn.classList.remove("d-none");
}
if (
_innerWidth > _wrapperWidth &&
window.innerWidth > window.Helpers.LAYOUT_BREAKPOINT
) {
if (_position === 0) this._prevBtn.classList.add("disabled");
else this._prevBtn.classList.remove("disabled");
if (_innerWidth + _position <= _wrapperWidth)
this._nextBtn.classList.add("disabled");
else this._nextBtn.classList.remove("disabled");
}
}
static _promisify(fn, ...args) {
const result = fn(...args);
if (result instanceof Promise) {
return result;
}
if (result === false) {
return Promise.reject();
}
return Promise.resolve();
}
get _innerWidth() {
const items = this._inner.childNodes;
let width = 0;
for (let i = 0, l = items.length; i < l; i++) {
if (items[i].tagName) {
width += Math.round(items[i].getBoundingClientRect().width);
}
}
return width;
}
get _innerPosition() {
return parseInt(
this._inner.style[this._rtl ? "marginRight" : "marginLeft"] ||
"0px",
10,
);
}
set _innerPosition(value) {
this._inner.style[this._rtl ? "marginRight" : "marginLeft"] =
`${value}px`;
return value;
}
static _unbindAnimationEndEvent(el) {
const cb = el._menuAnimationEndEventCb;
if (el._menuAnimationEndEventTimeout) {
clearTimeout(el._menuAnimationEndEventTimeout);
el._menuAnimationEndEventTimeout = null;
}
if (!cb) return;
TRANSITION_EVENTS.forEach((ev) =>
el.removeEventListener(ev, cb, false),
);
el._menuAnimationEndEventCb = null;
}
closeAll(closeChildren = this._closeChildren) {
const opened = this._el.querySelectorAll(
".menu-inner > .menu-item.open",
);
for (let i = 0, l = opened.length; i < l; i++)
this.close(opened[i], closeChildren);
}
static setDisabled(el, disabled) {
Menu._getItem(el, false).classList[disabled ? "add" : "remove"](
"disabled",
);
}
static isActive(el) {
return Menu._getItem(el, false).classList.contains("active");
}
static isOpened(el) {
return Menu._getItem(el, false).classList.contains("open");
}
static isDisabled(el) {
return Menu._getItem(el, false).classList.contains("disabled");
}
update() {
if (!this._horizontal) {
if (this._scrollbar) {
this._scrollbar.update();
}
} else {
this.closeAll();
const wrapperWidth = Math.round(
this._wrapper.getBoundingClientRect().width,
);
const innerWidth = this._innerWidth;
let position = this._innerPosition;
if (wrapperWidth - position > innerWidth) {
position = wrapperWidth - innerWidth;
if (position > 0) position = 0;
this._innerPosition = position;
}
this._updateSlider(wrapperWidth, innerWidth, position);
}
}
manageScroll() {
const { PerfectScrollbar } = window;
const menuInner = document.querySelector(".menu-inner");
if (window.innerWidth < window.Helpers.LAYOUT_BREAKPOINT) {
if (this._scrollbar !== null) {
// window.Helpers.menuPsScroll.destroy()
this._scrollbar.destroy();
this._scrollbar = null;
}
menuInner.classList.add("overflow-auto");
} else {
if (this._scrollbar === null) {
const menuScroll = new PerfectScrollbar(
document.querySelector(".menu-inner"),
{
suppressScrollX: true,
wheelPropagation: false,
},
);
// window.Helpers.menuPsScroll = menuScroll
this._scrollbar = menuScroll;
}
menuInner.classList.remove("overflow-auto");
}
}
switchMenu(menu) {
// Unbind Events
this._unbindEvents();
// const html = document.documentElement
const navbar = document.querySelector("nav.layout-navbar");
const navbarCollapse = document.querySelector("#navbar-collapse");
/* const fullNavbar = document.querySelector('.layout-navbar-full')
const contentNavbar = document.querySelector('.layout-content-navbar')
const contentWrapper = document.querySelector('.content-wrapper') */
const asideMenuWrapper = document.querySelector("#layout-menu div");
const asideMenu = document.querySelector("#layout-menu");
const horzMenuClasses = [
"layout-menu-horizontal",
"menu",
"menu-horizontal",
"container-fluid",
"flex-grow-0",
];
const vertMenuClasses = ["layout-menu", "menu", "menu-vertical"];
const horzMenuWrapper = document.querySelector(
".menu-horizontal-wrapper",
);
const menuInner = document.querySelector(".menu-inner");
const brand = document.querySelector(".app-brand");
const menuToggler = document.querySelector(".layout-menu-toggle");
const activeMenuItems = document.querySelectorAll(
".menu-inner .active",
);
/* const layoutPage = document.querySelector('.layout-page')
const layoutContainer = document.querySelector('.layout-container')
const content = document.querySelector('.container-fluid') */
// const { PerfectScrollbar } = window
if (menu === "vertical") {
this._horizontal = false;
asideMenuWrapper.insertBefore(brand, horzMenuWrapper);
asideMenuWrapper.insertBefore(menuInner, horzMenuWrapper);
asideMenuWrapper.classList.add("flex-column", "p-0");
asideMenu.classList.remove(...asideMenu.classList);
asideMenu.classList.add(...vertMenuClasses, this._menuBgClass);
brand.classList.remove("d-none", "d-lg-flex");
menuToggler.classList.remove("d-none");
// if (PerfectScrollbar !== undefined) {
// this._psScroll = new PerfectScrollbar(document.querySelector('.menu-inner'), {
// suppressScrollX: true,
// wheelPropagation: !Menu._hasClass('layout-menu-fixed layout-menu-fixed-offcanvas')
// })
// }
menuInner.classList.add("overflow-auto");
// Add open class to active items
for (let i = 0; i < activeMenuItems.length - 1; ++i) {
activeMenuItems[i].classList.add("open");
}
} else {
this._horizontal = true;
navbar.children[0].insertBefore(brand, navbarCollapse);
brand.classList.add("d-none", "d-lg-flex");
horzMenuWrapper.appendChild(menuInner);
asideMenuWrapper.classList.remove("flex-column", "p-0");
asideMenu.classList.remove(...asideMenu.classList);
asideMenu.classList.add(...horzMenuClasses, this._menuBgClass);
menuToggler.classList.add("d-none");
menuInner.classList.remove("overflow-auto");
// if (PerfectScrollbar !== undefined && this._psScroll !== null) {
// this._psScroll.destroy()
// this._psScroll = null
// }
// Remove open class from active items
for (let i = 0; i < activeMenuItems.length; ++i) {
activeMenuItems[i].classList.remove("open");
}
}
this._bindEvents();
}
destroy() {
if (!this._el) return;
this._unbindEvents();
const items = this._el.querySelectorAll(".menu-item");
for (let i = 0, l = items.length; i < l; i++) {
Menu._unbindAnimationEndEvent(items[i]);
items[i].classList.remove("menu-item-animating");
items[i].classList.remove("open");
items[i].style.overflow = null;
items[i].style.height = null;
}
const menus = this._el.querySelectorAll(".menu-menu");
for (let i2 = 0, l2 = menus.length; i2 < l2; i2++) {
menus[i2].style.marginRight = null;
menus[i2].style.marginLeft = null;
}
this._el.classList.remove("menu-no-animation");
if (this._wrapper) {
this._prevBtn.parentNode.removeChild(this._prevBtn);
this._nextBtn.parentNode.removeChild(this._nextBtn);
this._wrapper.parentNode.insertBefore(this._inner, this._wrapper);
this._wrapper.parentNode.removeChild(this._wrapper);
this._inner.style.marginLeft = null;
this._inner.style.marginRight = null;
}
this._el.menuInstance = null;
delete this._el.menuInstance;
this._el = null;
this._horizontal = null;
this._animate = null;
this._accordion = null;
this._showDropdownOnHover = null;
this._closeChildren = null;
this._rtl = null;
this._onOpen = null;
this._onOpened = null;
this._onClose = null;
this._onClosed = null;
if (this._scrollbar) {
this._scrollbar.destroy();
this._scrollbar = null;
}
this._inner = null;
this._prevBtn = null;
this._wrapper = null;
this._nextBtn = null;
}
}
window.Menu = Menu;
export { Menu };