Skip to content

Instantly share code, notes, and snippets.

@dan-gamble
Created December 17, 2018 16:51
Show Gist options
  • Save dan-gamble/9451b195bd2f1d8001b72cfa7dc45722 to your computer and use it in GitHub Desktop.
Save dan-gamble/9451b195bd2f1d8001b72cfa7dc45722 to your computer and use it in GitHub Desktop.
import { getElement, getElements } from '../utils/functional'
export default class Drawers {
constructor (el) {
this.els = {
el,
body: document.body,
backdrop: getElement('.js-Drawers_Backdrop')
}
this.matches = {
trigger: '[data-module-drawers-trigger]',
triggerToggle: '[data-module-drawers-trigger-toggle]',
close: '[data-module-drawers-close]',
backdrop: '.js-Drawers_Backdrop'
}
this.classes = {
activeClass: 'drw-Drawers-active',
activeDrawerClass: 'drw-Drawer-active',
siteOverflowed: 'util-SiteOverflowed',
bodyActiveClass: 'drw-DrawerIsActive'
}
this._activeDrawerKey = ''
this.foundDrawers = getElements(this.matches.trigger).reduce((acc, el) => {
const key = el.dataset.moduleDrawersTrigger
acc[key] = this.buildDrawer(key, el)
return acc
}, {})
this.setupListeners()
window.drawers = this
}
setupListeners () {
this.els.body.addEventListener('click', e => {
const { target } = e
if (
target.closest(this.matches.trigger) === false &&
target.closest(this.matches.close) === false &&
target.closest(this.matches.backdrop) === false
) {
return
}
if (target.closest(this.matches.trigger)) {
e.preventDefault()
const matches = target.closest(this.matches.trigger)
const key = matches.dataset.moduleDrawersTrigger
if (
key in this.foundDrawers === false ||
(key in this.foundDrawers && this.drawerIsComplete(key) === false)
) {
this.foundDrawers[key] = this.buildDrawer(key, matches)
}
this.activeDrawerKey = key
if (target.matches.triggerToggle) {
matches.dataset.moduleDrawersTriggerToggleState = 'open'
}
}
if (target.closest(this.matches.triggerToggle)) {
e.preventDefault()
const matches = target.closest(this.matches.triggerToggle)
const key = matches.dataset.moduleDrawersTriggerToggle
if (
key in this.foundDrawers === false ||
(key in this.foundDrawers && this.drawerIsComplete(key) === false)
) {
this.foundDrawers[key] = this.buildDrawer(key, matches)
}
const isCurrentlyClosed =
matches.dataset.moduleDrawersTriggerToggleState === 'closed'
this.activeDrawerKey = isCurrentlyClosed ? key : ''
matches.dataset.moduleDrawersTriggerToggleState = isCurrentlyClosed
? 'open'
: 'closed'
}
if (target.closest(this.matches.close)) {
const trigger = getElement(
`[data-module-drawers-drawer-trigger="${this.activeDrawerKey}"]`
)
if (trigger.dataset.moduleDrawersTriggerToggle) {
target.dataset.moduleDrawersTriggerToggleState = 'closed'
}
this.activeDrawerKey = ''
}
if (target.closest(this.matches.backdrop)) {
this.activeDrawerKey = ''
}
})
}
buildDrawer (key, matches) {
return {
trigger: matches,
drawer: getElement(`[data-module-drawers-drawer="${key}"]`),
close: getElement(`[data-module-drawers-close="${key}"]`)
}
}
drawerIsComplete (key) {
return (
Object.values(this.foundDrawers[key]).filter(val => val != null)
.length === 0
)
}
get activeDrawerKey () {
return this._activeDrawerKey
}
set activeDrawerKey (val) {
this._activeDrawerKey = val
this.els.body.classList.toggle(this.classes.siteOverflowed, val !== '')
this.els.body.classList.toggle(this.classes.bodyActiveClass, val !== '')
this.els.el.classList.toggle(this.classes.activeClass, val !== '')
Object.entries(this.foundDrawers).forEach(([key, value]) => {
value.drawer.classList.toggle(this.classes.activeDrawerClass, key === val)
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment