Skip to content

Instantly share code, notes, and snippets.

@ten1seven
Created September 29, 2021 20:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ten1seven/d7c28262c7640825265987fd5fbc9622 to your computer and use it in GitHub Desktop.
Save ten1seven/d7c28262c7640825265987fd5fbc9622 to your computer and use it in GitHub Desktop.
Toggle JavaScript from Urban Land Institute
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