Created
September 29, 2021 20:51
-
-
Save ten1seven/d7c28262c7640825265987fd5fbc9622 to your computer and use it in GitHub Desktop.
Toggle JavaScript from Urban Land Institute
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
export default class Toggle { | |
constructor(el) { | |
this.variables(el) | |
this.setup() | |
this.events() | |
} | |
variables(el) { | |
this.el = el | |
const targetId = this.el.getAttribute('aria-controls') | |
this.target = document.getElementById(targetId) | |
this.showClass = this.el.dataset.toggleClassShow || '-show' | |
this.hiddenClass = this.el.dataset.toggleClassHide || '-hide' | |
this.buttonClass = this.el.dataset.toggleButtonClass || '-expanded' | |
// is there another button that controls this element? | |
// Example: Hamburger menu opens, but Close buttons closes | |
let otherButtonIds = this.el.dataset.toggleUpdate | |
this.otherButtons = [] | |
if (otherButtonIds) { | |
otherButtonIds = otherButtonIds.split(' ') | |
for (let i=0, len=otherButtonIds.length; i < len; i++) { | |
const button = document.getElementById(otherButtonIds[i]) | |
if (button) { | |
this.otherButtons.push(button) | |
} | |
} | |
} | |
} | |
setup() { | |
const targetStyles = window.getComputedStyle(this.target) | |
const targetVisible = targetStyles.display !== 'none' && targetStyles.visibility !== 'hidden' | |
this.toggle(targetVisible) | |
} | |
events() { | |
this.el.addEventListener('click', this.onClick) | |
document.addEventListener('keyup', this.onKeyUp) | |
} | |
onKeyUp = e => { | |
if (e.key === 'Escape') { | |
this.toggle(false) | |
} | |
} | |
onClick = () => { | |
const show = !this.target.classList.contains(this.showClass) | |
this.toggle(show) | |
if (this.otherButtons.length) { | |
for (let i=0, len=this.otherButtons.length; i < len; i++) { | |
this.otherButtons[i].setAttribute('aria-expanded', show) | |
} | |
} | |
} | |
toggle = show => { | |
this.target.classList.toggle(this.showClass, show) | |
this.target.classList.toggle(this.hiddenClass, !show) | |
this.el.setAttribute('aria-expanded', show) | |
this.el.classList.toggle(this.buttonClass, show) | |
} | |
} | |
/* | |
Usage: | |
====== | |
<button | |
aria-controls="target-id" | |
data-module="toggle" | |
data-toggle-class-show="-show" | |
data-toggle-class-hide="-hide" | |
data-toggle-button-class="rotate-180" | |
data-toggle-update="header-nav-close" | |
> | |
Toggle | |
</button> | |
<div id="target-id"></div> | |
options | |
-- | |
data-toggle-class-show - class to be toggled on the target on show | |
data-toggle-class-hide - class to be toggled on the target on hide | |
data-toggle-button-class - class to be toggled on the button | |
data-toggle-update - another element to keep updated w/ this button | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment