Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes eslint issues in header.js #692

Merged
merged 2 commits into from
Jan 28, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 117 additions & 65 deletions js/header.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@

(function headerScript(Drupal) {
Drupal.behaviors.header = {
attach: function (context) {
attach(context) {
// Hide the search form label. We use .once() to avoid re-running.
//
// @todo: make it possible to override this without having to maintain a
// *copy* of this file.
const headerSearchFormLabel = once('header-search-label', '.lgd-region--search form label', context);
const headerSearchFormLabel = once(
'header-search-label',
'.lgd-region--search form label',
context,
);

if (headerSearchFormLabel.length) {
headerSearchFormLabel[0].classList.add('visually-hidden');
Expand All @@ -31,16 +35,50 @@
// All the interactivity here revolves around the toggles, so query them
// and we can build an object full of references to them and to their
// regions. We use .once() to avoid re-running this.
const headerToggles = once('header-toggle', headerToggleSelector, context);
const headerToggles = once(
'header-toggle',
headerToggleSelector,
context,
);

if (!headerToggles.length) {
return;
}

// General reset function to hide the menu regions and reset the toggle
// button attributes.
function handleReset() {
headerToggles.forEach((headerToggle) => {
headerToggle.setAttribute('aria-expanded', 'false');
headerToggle.classList.remove(toggleActiveClass);
});

Object.keys(navInfo).forEach((nav) => {
navInfo[nav].region.classList.remove(regionActiveClass);
});
}

// General function for when the ESC is clicked.
function handleEscKeyClick(buttonToFocus) {
context.addEventListener('keydown', (e) => {
// When on any link in the secondary menu, if you hit escape
// set focus back to:
// 1. menu button on small screens, and
// 2. services button on large screens
if (e.key === 'Escape') {
e.preventDefault();
handleReset();
buttonToFocus.focus();
}
});
}

// Looping over the discovered menu toggles, create an object containing
// references to the various DOM elements we need to work with.
headerToggles.forEach(function(toggle) {
const region = context.getElementById(toggle.getAttribute('aria-controls'));
headerToggles.forEach((toggle) => {
const region = context.getElementById(
toggle.getAttribute('aria-controls'),
);
const nav = toggle.classList.contains(primaryToggleClass)
? 'primary'
: 'secondary';
Expand All @@ -59,25 +97,13 @@
// Which menu region to show is decided by the "toggleThatWasClicked" parameter.
function handleToggleClick(toggleThatWasClicked) {
// Get the current state as a boolean.
const currentState = toggleThatWasClicked.getAttribute('aria-expanded') === 'true';
const currentState =
toggleThatWasClicked.getAttribute('aria-expanded') === 'true';

toggleThatWasClicked.setAttribute('aria-expanded', !currentState);
toggleThatWasClicked.classList.toggle(toggleActiveClass);
}

// General reset function to hide the menu regions and reset the toggle
// button attributes.
function handleReset() {
headerToggles.forEach(function(headerToggle) {
headerToggle.setAttribute('aria-expanded', 'false');
headerToggle.classList.remove(toggleActiveClass);
});

Object.keys(navInfo).forEach(function(nav) {
navInfo[nav].region.classList.remove(regionActiveClass);
});
}

// When the primary menu toggle is clicked
function handlePrimaryMenuToggleClick() {
handleToggleClick(navInfo.primary.toggle);
Expand All @@ -93,16 +119,16 @@
handleEscKeyClick(navInfo.secondary.toggle);

navInfo.secondary.region.classList.toggle(regionActiveClass);
navInfo.secondary.region.classList.contains(regionActiveClass)
? navInfo.secondary.firstLink.focus()
: null;
if (navInfo.secondary.region.classList.contains(regionActiveClass)) {
navInfo.secondary.firstLink.focus();
}
secondaryMenuRegionIsOpen = !secondaryMenuRegionIsOpen;
}
// When on the first link in the secondary menu, if you shift+tab
// set focus back to the services button
function handleSecondaryMenuShiftTabClick() {
navInfo.secondary.firstLink.addEventListener('keydown', function(e) {
if (e.shiftKey && e.key == 'Tab') {
navInfo.secondary.firstLink.addEventListener('keydown', (e) => {
if (e.shiftKey && e.key === 'Tab') {
e.preventDefault();
navInfo.secondary.toggle.focus();
}
Expand All @@ -112,37 +138,25 @@
// When on the last link in the secondary menu, if you hit tab
// set focus back to the services button
function handleSecondaryMenuTabClick() {
navInfo.secondary.lastLink.addEventListener('keydown', function(e) {
if (e.key == 'Tab') {
navInfo.secondary.lastLink.addEventListener('keydown', (e) => {
if (e.key === 'Tab') {
e.preventDefault();
navInfo.secondary.toggle.focus();
}
});
}


// General function for when the ESC is clicked.
function handleEscKeyClick(buttonToFocus) {
context.addEventListener('keydown', function(e) {
// When on any link in the secondary menu, if you hit escape
// set focus back to:
// 1. menu button on small screens, and
// 2. services button on large screens
if (e.key == 'Escape') {
e.preventDefault();
handleReset()
buttonToFocus.focus();
}
});
}

// If you click on the page, anywhere outside the secondary menu region
// or the secondary menu toggle button, close the secondary menu region
document.addEventListener('click', function(e) {
if (!e.target.closest('#lgd-header__nav--secondary') && !e.target.closest('.lgd-header__toggle--secondary') && secondaryMenuRegionIsOpen){
handleSecondaryMenuToggleClick();
}
});
document.addEventListener('click', (e) => {
if (
!e.target.closest('#lgd-header__nav--secondary') &&
!e.target.closest('.lgd-header__toggle--secondary') &&
secondaryMenuRegionIsOpen
) {
handleSecondaryMenuToggleClick();
}
});

// When the window is resized (or a device orientation changes),
// set out what happens.
Expand All @@ -153,23 +167,60 @@
function handleWindowResized() {
handleReset();

if (window.innerWidth < 768) {
if (Object.keys(navInfo).includes('secondary') && navInfo.secondary.toggle) {
navInfo.secondary.toggle.removeEventListener('click', handleSecondaryMenuToggleClick, true);
navInfo.secondary.toggle.removeEventListener('click', handleSecondaryMenuShiftTabClick, true);
navInfo.secondary.toggle.removeEventListener('click', handleSecondaryMenuTabClick, true);
if (window.innerWidth < 768) {
if (
Object.keys(navInfo).includes('secondary') &&
navInfo.secondary.toggle
) {
navInfo.secondary.toggle.removeEventListener(
'click',
handleSecondaryMenuToggleClick,
true,
);
navInfo.secondary.toggle.removeEventListener(
'click',
handleSecondaryMenuShiftTabClick,
true,
);
navInfo.secondary.toggle.removeEventListener(
'click',
handleSecondaryMenuTabClick,
true,
);
}
if (navInfo.primary.toggle) {
navInfo.primary.toggle.addEventListener('click', handlePrimaryMenuToggleClick);
navInfo.primary.toggle.addEventListener(
'click',
handlePrimaryMenuToggleClick,
);
}
} else {
if (Object.keys(navInfo).includes('primary') && navInfo.primary.toggle) {
navInfo.primary.toggle.removeEventListener('click', handlePrimaryMenuToggleClick, true);
if (
Object.keys(navInfo).includes('primary') &&
navInfo.primary.toggle
) {
navInfo.primary.toggle.removeEventListener(
'click',
handlePrimaryMenuToggleClick,
true,
);
}
if (Object.keys(navInfo).includes('secondary') && navInfo.secondary.toggle) {
navInfo.secondary.toggle.addEventListener('click', handleSecondaryMenuToggleClick);
navInfo.secondary.toggle.addEventListener('click', handleSecondaryMenuShiftTabClick);
navInfo.secondary.toggle.addEventListener('keyup', handleSecondaryMenuTabClick);
if (
Object.keys(navInfo).includes('secondary') &&
navInfo.secondary.toggle
) {
navInfo.secondary.toggle.addEventListener(
'click',
handleSecondaryMenuToggleClick,
);
navInfo.secondary.toggle.addEventListener(
'click',
handleSecondaryMenuShiftTabClick,
);
navInfo.secondary.toggle.addEventListener(
'keyup',
handleSecondaryMenuTabClick,
);
}
}
}
Expand All @@ -179,17 +230,18 @@
// near the bottom of the menu, a scrollbar comes into play which technically
// means the window size has changed.
function handleCheckIfWindowActuallyResized() {
if (window.innerWidth === windowWidth) {
return
} else {
if (window.innerWidth !== windowWidth) {
windowWidth = window.innerWidth;
handleWindowResized();
}
}

// Call our functions, initially and also when the window is resized.
handleWindowResized();
window.addEventListener('resize', Drupal.debounce(handleCheckIfWindowActuallyResized, 50, false));
}
window.addEventListener(
'resize',
Drupal.debounce(handleCheckIfWindowActuallyResized, 50, false),
);
},
};
}(Drupal));
})(Drupal);
Loading