Files
Umbra-Bookshelf/theme/assets/js/navigation.js
bdm 5b5303186a Establish Umbra-Bookshelf as the successor repository
Continues the Bookshelf history. The three plugins tracked there are
consolidated into umbra-bookshelf/ and this repository becomes the canonical
home for the plugin and the theme.

  bd-bookshelf/  ->  theme/     separate artifact, name unchanged
  (root specs)   ->  umbra-bookshelf/spec/  aligned to Umbra Bookshelf
  old plugin zips -> archive/pre-umbra-releases/

Adds a repository README and drops the Bookshelf closure notice.
2026-10-18 19:56:26 -07:00

119 lines
3.7 KiB
JavaScript

// Copyright 2026 Umbra Tools (umbratools.com)
// SPDX-License-Identifier: Apache-2.0
/**
* Navigation JavaScript
*
* @package BD_Murphy
*/
(function() {
'use strict';
var container, button, menu, links, i, len;
container = document.getElementById('site-nav');
if (!container) {
return;
}
button = container.getElementsByClassName('menu-toggle')[0];
if ('undefined' === typeof button) {
return;
}
menu = container.getElementsByTagName('ul')[0];
if (menu.classList.contains('nav-menu') && window.innerWidth < 768) {
menu.classList.add('nav-menu-hidden');
}
menu.setAttribute('aria-expanded', 'false');
if (-1 === menu.className.indexOf('nav-menu')) {
menu.className += ' nav-menu';
}
button.onclick = function() {
if (-1 !== container.className.indexOf('toggled')) {
container.className = container.className.replace(' toggled', '');
button.setAttribute('aria-expanded', 'false');
menu.setAttribute('aria-expanded', 'false');
menu.classList.add('nav-menu-hidden');
} else {
container.className += ' toggled';
button.setAttribute('aria-expanded', 'true');
menu.setAttribute('aria-expanded', 'true');
menu.classList.remove('nav-menu-hidden');
}
};
// Close menu on click outside
document.addEventListener('click', function(event) {
if (!container.contains(event.target)) {
container.classList.remove('toggled');
button.setAttribute('aria-expanded', 'false');
menu.setAttribute('aria-expanded', 'false');
menu.classList.add('nav-menu-hidden');
}
});
// Keyboard navigation
links = menu.getElementsByTagName('a');
for (i = 0, len = links.length; i < len; i++) {
links[i].addEventListener('focus', toggleFocus, true);
links[i].addEventListener('blur', toggleFocus, true);
}
function toggleFocus() {
var self = this;
while (-1 === self.className.indexOf('menu-item')) {
if ('undefined' === typeof self.parentElement) {
break;
}
self = self.parentElement;
}
if (self.classList.contains('current-menu-item')) {
return;
}
var dropdown = self.querySelector('.sub-menu');
if (dropdown) {
dropdown.classList.toggle('focus');
}
var siblings = self.parentElement.children;
for (i = 0; i < siblings.length; i++) {
if (siblings[i] !== self) {
siblings[i].classList.remove('focus');
}
}
self.classList.toggle('focus');
}
// Sticky nav scroll effect
var banner = document.querySelector('.header-banner');
if (banner && document.body.classList.contains('has-sticky-nav')) {
window.addEventListener('scroll', function() {
var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
if (scrollTop > banner.offsetHeight) {
container.classList.add('scrolled');
} else {
container.classList.remove('scrolled');
}
}, { passive: true });
}
// Escape key closes menu
document.addEventListener('keydown', function(event) {
if (event.key === 'Escape' && container.classList.contains('toggled')) {
container.classList.remove('toggled');
button.setAttribute('aria-expanded', 'false');
menu.setAttribute('aria-expanded', 'false');
menu.classList.add('nav-menu-hidden');
button.focus();
}
});
})();