Created
December 22, 2024 22:22
-
-
Save wpeasy/c6ff9c4fe811160b7fad9b9061f6c687 to your computer and use it in GitHub Desktop.
Bricks Builder Focus Trap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(() => { | |
/* INIT WPE Object */ | |
window.WPE = window.WPE || { scripts: [] }; | |
const scriptName = 'wpeFocusTrap'; /* Must be unique */ | |
const blockSelector = '.wpe-focus-trap'; | |
class MainClass { | |
constructor() { | |
this.debug = false; | |
this.init(); | |
} | |
/* use for easily disabled debugging */ | |
debugLog(...args) { | |
if (this.debug) { | |
console.log(args); | |
} | |
} | |
init() { | |
this.blocks = document.querySelectorAll(blockSelector); | |
this.blocks.forEach(blockEl => { | |
this.initFocusTrap(blockEl); | |
}); | |
} | |
initFocusTrap(blockEl) { | |
const itemSelector = blockEl.dataset.focusableItemSelector; | |
this.debugLog('itemSelector', itemSelector); | |
const items = Array.from(blockEl.querySelectorAll(itemSelector)); | |
this.debugLog('items', items); | |
if (blockEl.hasAttribute('data-click-on-focus')) { | |
blockEl.addEventListener('focusin', (event) => { | |
const focusedElement = event.target; // The element that is focused | |
if (focusedElement && typeof focusedElement.click === 'function') { | |
focusedElement.click(); | |
} | |
}); | |
} | |
blockEl.addEventListener('keydown', (event) => { | |
const currentIndex = items.findIndex((tab) => tab === document.activeElement); | |
if (currentIndex === -1) return; // Exit if no tab is focused | |
let newIndex; | |
switch (event.key) { | |
case 'ArrowUp': // Navigate to the previous tab | |
event.preventDefault(); | |
newIndex = (currentIndex - 1 + items.length) % items.length; | |
break; | |
case 'ArrowDown': // Navigate to the next tab | |
event.preventDefault(); | |
newIndex = (currentIndex + 1) % items.length; | |
break; | |
case 'Home': // Navigate to the first tab | |
event.preventDefault(); | |
newIndex = 0; | |
break; | |
case 'End': // Navigate to the last tab | |
event.preventDefault(); | |
newIndex = items.length - 1; | |
break; | |
} | |
this.focusTab(items, newIndex); | |
}); | |
} | |
focusTab(items, index) { | |
this.debugLog('focusTab', index); | |
items.forEach((tab, i) => { | |
tab.setAttribute('aria-selected', 'false'); | |
if (i === index) { | |
tab.focus(); | |
tab.setAttribute('aria-selected', 'true'); | |
} | |
}); | |
} | |
} | |
/* RUN SCRIPT ONCE */ | |
document.addEventListener('DOMContentLoaded', () => { | |
setTimeout( | |
() => { | |
if (!window.WPE.scripts[scriptName]) { | |
window.WPE.scripts[scriptName] = new MainClass(); | |
} | |
}); | |
}) | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment