megamenu_sdc-1.0.x-dev/components/menu_pane/menu_pane.js
components/menu_pane/menu_pane.js
(function (Drupal, once) {
const heightSignal = {
value: 0,
observers: new Set(),
set(newValue) {
this.value = newValue;
this.notify();
},
subscribe(callback) {
this.observers.add(callback);
callback(this.value); // Initial call
return () => this.observers.delete(callback);
},
notify() {
this.observers.forEach(callback => callback(this.value));
}
};
Drupal.behaviors.menuPane = {
menuId: null,
heightSelector: null,
isMobile: true,
threshold: null,
attach(context) {
once('menuPane', '[data-component-id="megamenu_sdc:menu_pane"]', context).forEach((element) => {
this.menuId = element.dataset.menuId;
this.heightSelector = element.dataset.heightSelector;
this.threshold = element.dataset.threshold ?? 768;
// Initial check
this.updateBodyClass();
// Subscribe to height changes
/*heightSignal.subscribe((height) => {
const heightSpan = document.getElementById('heightSpan');
if (heightSpan) {
heightSpan.textContent = `mobile ${height}px`;
}
});*/
window.addEventListener('resize', () => {
this.updateBodyClass();
});
});
},
updateBodyClass() {
const body = document.body;
const classMobile = `menu-pane-mobile`;
const classDesktop = `menu-pane-desktop`;
if (window.innerWidth <= this.threshold) {
this.isMobile = true;
heightSignal.set("Mobile (threshold)");
}
else {
// Skip testing if overlay is open:
if (body.classList.contains('is-overlay-active')) {
return;
}
// Test width
this.isMobile = false;
}
if (this.isMobile) {
body.classList.remove(classDesktop);
body.classList.add(classMobile);
return;
} else {
body.classList.remove(classMobile);
body.classList.add(classDesktop);
heightSignal.set('Testing desktop');
}
// Get the element based on height selector
const menuElement = document.querySelector(this.heightSelector);
if (menuElement) {
// Find direct li child
const liElement = menuElement.querySelector(':scope > li');
// If the menuElement height is more than 1.9x the item height, our menu is wrapping. Set to mobile.
if (liElement.offsetHeight * 1.9 < menuElement.offsetHeight) {
this.isMobile = true;
this.threshold = window.innerWidth;
heightSignal.set(`Test failed. Updated threshold:${this.threshold}`);
body.classList.remove(classDesktop);
body.classList.add(classMobile);
}
else {
heightSignal.set('Desktop ok. Threshold:' + this.threshold);
}
}
}
};
})(Drupal, once);
