/*! * metismenujs - v1.3.1 * MetisMenu: Collapsible menu plugin with Vanilla-JS * https://github.com/onokumus/metismenujs#readme * * Made by Osman Nuri Okumus (https://github.com/onokumus) * Under MIT License */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.MetisMenu = factory()); }(this, (function () { 'use strict'; const Default = { parentTrigger: 'li', subMenu: 'ul', toggle: true, triggerElement: 'a', }; const ClassName = { ACTIVE: 'mm-active', COLLAPSE: 'mm-collapse', COLLAPSED: 'mm-collapsed', COLLAPSING: 'mm-collapsing', METIS: 'metismenu', SHOW: 'mm-show', }; /* eslint-disable max-len */ class MetisMenu { /** * Creates an instance of MetisMenu. * * @constructor * @param {Element | string} element * @param {IMMOptions} [options] * @memberof MetisMenu */ constructor(element, options) { this.element = MetisMenu.isElement(element) ? element : document.querySelector(element); this.config = Object.assign(Object.assign({}, Default), options); this.disposed = false; this.triggerArr = []; this.init(); } static attach(el, opt) { return new MetisMenu(el, opt); } init() { const { METIS, ACTIVE, COLLAPSE } = ClassName; this.element.classList.add(METIS); [].slice.call(this.element.querySelectorAll(this.config.subMenu)).forEach((ul) => { ul.classList.add(COLLAPSE); const li = ul.closest(this.config.parentTrigger); if (li === null || li === void 0 ? void 0 : li.classList.contains(ACTIVE)) { this.show(ul); } else { this.hide(ul); } const a = li === null || li === void 0 ? void 0 : li.querySelector(this.config.triggerElement); if ((a === null || a === void 0 ? void 0 : a.getAttribute('aria-disabled')) === 'true') { return; } a === null || a === void 0 ? void 0 : a.setAttribute('aria-expanded', 'false'); a === null || a === void 0 ? void 0 : a.addEventListener('click', this.clickEvent.bind(this)); this.triggerArr.push(a); }); } clickEvent(evt) { if (!this.disposed) { const target = evt === null || evt === void 0 ? void 0 : evt.currentTarget; if (target && target.tagName === 'A') { evt.preventDefault(); } const li = target.closest(this.config.parentTrigger); const ul = li === null || li === void 0 ? void 0 : li.querySelector(this.config.subMenu); this.toggle(ul); } } update() { this.disposed = false; this.init(); } dispose() { this.triggerArr.forEach((arr) => { arr.removeEventListener('click', this.clickEvent.bind(this)); }); this.disposed = true; } on(evtType, handler, options) { this.element.addEventListener(evtType, handler, options); return this; } off(evtType, handler, options) { this.element.removeEventListener(evtType, handler, options); return this; } emit(evtType, evtData, shouldBubble = false) { const evt = new CustomEvent(evtType, { bubbles: shouldBubble, detail: evtData, }); this.element.dispatchEvent(evt); } toggle(ul) { const li = ul.closest(this.config.parentTrigger); if (li === null || li === void 0 ? void 0 : li.classList.contains(ClassName.ACTIVE)) { this.hide(ul); } else { this.show(ul); } } show(el) { var _a; const ul = el; const { ACTIVE, COLLAPSE, COLLAPSED, COLLAPSING, SHOW, } = ClassName; if (this.isTransitioning || ul.classList.contains(COLLAPSING)) { return; } const complete = () => { ul.classList.remove(COLLAPSING); ul.style.height = ''; ul.removeEventListener('transitionend', complete); this.setTransitioning(false); this.emit('shown.metisMenu', { shownElement: ul, }); }; const li = ul.closest(this.config.parentTrigger); li === null || li === void 0 ? void 0 : li.classList.add(ACTIVE); const a = li === null || li === void 0 ? void 0 : li.querySelector(this.config.triggerElement); a === null || a === void 0 ? void 0 : a.setAttribute('aria-expanded', 'true'); a === null || a === void 0 ? void 0 : a.classList.remove(COLLAPSED); ul.style.height = '0px'; ul.classList.remove(COLLAPSE); ul.classList.remove(SHOW); ul.classList.add(COLLAPSING); const eleParentSiblins = [].slice .call((_a = li === null || li === void 0 ? void 0 : li.parentNode) === null || _a === void 0 ? void 0 : _a.children) .filter((c) => c !== li); if (this.config.toggle && eleParentSiblins.length > 0) { eleParentSiblins.forEach((sibli) => { const sibUl = sibli.querySelector(this.config.subMenu); if (sibUl) { this.hide(sibUl); } }); } this.setTransitioning(true); ul.classList.add(COLLAPSE); ul.classList.add(SHOW); ul.style.height = `${ul.scrollHeight}px`; this.emit('show.metisMenu', { showElement: ul, }); ul.addEventListener('transitionend', complete); } hide(el) { const { ACTIVE, COLLAPSE, COLLAPSED, COLLAPSING, SHOW, } = ClassName; const ul = el; if (this.isTransitioning || !ul.classList.contains(SHOW)) { return; } this.emit('hide.metisMenu', { hideElement: ul, }); const li = ul.closest(this.config.parentTrigger); li === null || li === void 0 ? void 0 : li.classList.remove(ACTIVE); const complete = () => { ul.classList.remove(COLLAPSING); ul.classList.add(COLLAPSE); ul.style.height = ''; ul.removeEventListener('transitionend', complete); this.setTransitioning(false); this.emit('hidden.metisMenu', { hiddenElement: ul, }); }; ul.style.height = `${ul.getBoundingClientRect().height}px`; ul.style.height = `${ul.offsetHeight}px`; ul.classList.add(COLLAPSING); ul.classList.remove(COLLAPSE); ul.classList.remove(SHOW); this.setTransitioning(true); ul.addEventListener('transitionend', complete); ul.style.height = '0px'; const a = li === null || li === void 0 ? void 0 : li.querySelector(this.config.triggerElement); a === null || a === void 0 ? void 0 : a.setAttribute('aria-expanded', 'false'); a === null || a === void 0 ? void 0 : a.classList.add(COLLAPSED); } setTransitioning(isTransitioning) { this.isTransitioning = isTransitioning; } static isElement(element) { return Boolean(element.classList); } } return MetisMenu; }))); //# sourceMappingURL=metismenujs.js.map